`

【Android2D游戏开发之四】Android 游戏框架(一个游戏角色在屏幕行走的demo)

阅读更多
Himi  原创, 转载请注明! 谢谢。

  原文地址: http://blog.csdn.net/xiaominghimi/archive/2010/12/21/6090631.aspx

              各位童鞋请你们注意:surfaceview中确实有 onDraw这个方法,但是surfaceview不会自己去调用!!!

  而我代码中的ondraw 也好 draw 也好,都是我自己定义的一个方法。。。放在线程中不断调用的,一定要注意!!

        其实上一篇分析surfaceview的文章就是一个简单的游戏框架了,当然这里再强调一下,简单的游戏框架,所以不要高手们不要乱喷~

这个Demo是给群里一童鞋写的一个对图片操作以及按键处理,游戏简单框架的一个demo,这里放出给大家分享~

package com.himi;    
import android.content.Context;    
import android.content.res.Resources;    
import android.graphics.Bitmap;    
import android.graphics.BitmapFactory;    
import android.graphics.Canvas;    
import android.graphics.Color;    
import android.graphics.Paint;    
import android.util.Log;    
import android.view.KeyEvent;    
import android.view.SurfaceHolder;    
import android.view.SurfaceView;    
import android.view.SurfaceHolder.Callback;    
public class MySurfaceView extends SurfaceView implements Callback, Runnable {    
    private Thread th = new Thread(this);    
    private SurfaceHolder sfh;    
    private int SH, SW;    
    private Canvas canvas;    
    private Paint p;    
    private Paint p2;    
    private Resources res;    
    private Bitmap bmp;    
    private int bmp_x = 100, bmp_y = 100;    
    private boolean UP, DOWN, LEFT, RIGHT;    
    private int animation_up[] = { 3, 4, 5 };    
    private int animation_down[] = { 0, 1, 2 };    
    private int animation_left[] = { 6, 7, 8 };    
    private int animation_right[] = { 9, 10, 11 };    
    private int animation_init[] = animation_down;    
    private int frame_count;    
    public MySurfaceView(Context context) {    
        super(context);    
        this.setKeepScreenOn(true);    
        res = this.getResources();    
        bmp = BitmapFactory.decodeResource(res, R.drawable.enemy1);    
        sfh = this.getHolder();    
        sfh.addCallback(this);    
        p = new Paint();    
        p.setColor(Color.YELLOW);    
        p2 = new Paint();    
        p2.setColor(Color.RED);    
        p.setAntiAlias(true);    
        setFocusable(true);  //备注1  
    }    
    public void surfaceCreated(SurfaceHolder holder) {    
        SH = this.getHeight();    
        SW = this.getWidth();    
        th.start();    
    }    
    public void draw() {    
        canvas = sfh.lockCanvas();    
        canvas.drawRect(0, 0, SW, SH, p);   //备注2  
        canvas.save();   //备注3  
        canvas.drawText("Himi", bmp_x-2, bmp_y-10, p2);    
        canvas.clipRect(bmp_x, bmp_y, bmp_x + bmp.getWidth() / 13, bmp_y+bmp.getHeight());    
        if (animation_init == animation_up) {    
            canvas.drawBitmap(bmp, bmp_x - animation_up[frame_count] * (bmp.getWidth() / 13), bmp_y, p);    
        } else if (animation_init == animation_down) {    
            canvas.drawBitmap(bmp, bmp_x - animation_down[frame_count] * (bmp.getWidth() / 13), bmp_y, p);    
        } else if (animation_init == animation_left) {    
            canvas.drawBitmap(bmp, bmp_x - animation_left[frame_count] * (bmp.getWidth() / 13), bmp_y, p);    
        } else if (animation_init == animation_right) {    
            canvas.drawBitmap(bmp, bmp_x - animation_right[frame_count] * (bmp.getWidth() / 13), bmp_y, p);    
        }    
        canvas.restore();  //备注3  
        sfh.unlockCanvasAndPost(canvas);    
    }    
    public void cycle() {    
        if (DOWN) {    
            bmp_y += 5;    
        } else if (UP) {    
            bmp_y -= 5;    
        } else if (LEFT) {    
            bmp_x -= 5;    
        } else if (RIGHT) {    
            bmp_x += 5;    
        }    
        if (DOWN || UP || LEFT || RIGHT) {    
            if (frame_count < 2) {    
                frame_count++;    
            } else {    
                frame_count = 0;    
            }    
        }    
        if (DOWN == false && UP == false && LEFT == false && RIGHT == false) {    
            frame_count = 0;    
        }    
    }    
    @Override    
    public boolean onKeyDown(int key, KeyEvent event) {    
        if (key == KeyEvent.KEYCODE_DPAD_UP) {    
            if (UP == false) {    
                animation_init = animation_up;    
            }    
            UP = true;    
        } else if (key == KeyEvent.KEYCODE_DPAD_DOWN) {    
            if (DOWN == false) {    
                animation_init = animation_down;    
            }    
            DOWN = true;    
        } else if (key == KeyEvent.KEYCODE_DPAD_LEFT) {    
            if (LEFT == false) {    
                animation_init = animation_left;    
            }    
            LEFT = true;    
        } else if (key == KeyEvent.KEYCODE_DPAD_RIGHT) {    
            if (RIGHT == false) {    
                animation_init = animation_right;    
            }    
            RIGHT = true;    
        }    
        return super.onKeyDown(key, event);    
    }    
    /* (non-Javadoc)  
     * @see android.view.View#onKeyUp(int, android.view.KeyEvent)  
     */    
    @Override    
    public boolean onKeyUp(int keyCode, KeyEvent event) {    
        if (DOWN) {    
            DOWN = false;    
        } else if (UP) {    
            UP = false;    
        } else if (LEFT) {    
            LEFT = false;    
        } else if (RIGHT) {    
            RIGHT = false;    
        }    
        return super.onKeyUp(keyCode, event);    
    }    
    @Override    
    public void run() {    
        // TODO Auto-generated method stub    
        while (true) {    
            draw();    
            cycle();    
            try {    
                Thread.sleep(100);    
            } catch (Exception ex) {    
            }    
        }    
    }    
    @Override    
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    
        // TODO Auto-generated method stub    
    }    
    @Override    
    public void surfaceDestroyed(SurfaceHolder holder) {    
        // TODO Auto-generated method stub    
    }    
}


备注1

   此方法是用来响应按键!如果是自己定义一个继承自View的类,重新实现onKeyDown方法后,只有当该View获得焦点时才会调用onKeyDown方法,Actvity中的onKeyDown方法是当所有控件均没有处理该按键事件时,才会调用.

备注2

   这里也是对屏幕进行刷屏操作,其实这也只是一种,之前文章里我也用到drawRGB的方法同样实现,当然也可以用fillRect等来刷屏。

    那么这里我想说下,在继承view中,因为onDraw方法是系统自动调用的,不像在surfaceview这里这样去在run里面自己去不断调用,在view中我们可以抵用 invalidate()/postInvalidate() 这两种方法实现让系统调用onDraw方法,这里也是和surfaceview中的不同之一!

备注3

   这里canvas.save();和canvas.restore();是两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的。这里稍微解释一下,

   当我们对画布进行旋转,缩放,平移等操作的时候其实我们是想对特定的元素进行操作,比如图片,一个矩形等,但是当你用canvas的方法来进行这些操作的时候,其实是对整个画布进行了操作,那么之后在画布上的元素都会受到影响,所以我们在操作之前调用canvas.save()来保存画布当前的状态,当操作之后取出之前保存过的状态,这样就不会对其他的元素进行影响

对于 canvas.save();和canvas.restore();  还有不少童鞋不懂,OK、我再补充点:

代码段1:

public void draw() {   
  Canvas canvas = sfh.lockCanvas();    
  canvas.drawColor(Color.BLACK);  
  canvas.drawBitmap(bmp1, 0,0,paint);  
  canvas.save();   
  canvas.scale(1.5f, 1.5f);  
  canvas.restore();   
  canvas.drawBitmap(bmp2, 0,0,paint);  
  sfh.unlockCanvasAndPost(canvas);    
}


代码段2:
public void draw() {   
  Canvas canvas = sfh.lockCanvas();    
  canvas.drawColor(Color.BLACK);  
  canvas.drawBitmap(bmp1, 0,0,paint);  
  canvas.scale(1.5f, 1.5f);  
  canvas.drawBitmap(bmp2, 0,0,paint);  
  sfh.unlockCanvasAndPost(canvas);    
}


上面这两个代码片段中我们都假设有两张图片 bmp1和bmp2,并且都画在画布上!

那么代码段1和代码段2的不同:

代码段1中我们进行画布缩放的之前保存了画布状态,做了缩放操作之后又取出之前保存的状态,这样做是为了保证bmp2正常画出来不收到缩放的影响!

代码段2里,画了bmp1后就执行了缩放操作,并且没有保存状态!紧接着画了bmp2,那么bmp2也会一样受到缩放的影响!!
分享到:
评论

相关推荐

    android游戏小Demo

    本“android游戏小Demo”就是一个很好的起点,它提供了基础的游戏开发框架,帮助学习者理解Android游戏开发的基本概念和流程。 首先,我们来讨论Android游戏开发的基础。Android游戏通常基于Java或Kotlin语言编写,...

    android游戏开发Demo

    在Android游戏开发领域,"android游戏开发Demo"是一个非常实用的学习资源,它为开发者提供了实践游戏框架搭建的基础。这个Demo程序代码集可以帮助初学者更好地理解游戏开发的核心概念和技术,同时也为有经验的开发者...

    android人物行走demo

    这个“android人物行走demo”就是这样一个示例,它展示了如何在Android上创建和控制一个角色进行动态行走的效果。下面我们将深入探讨这个主题,讲解其中涉及到的关键知识点。 首先,我们关注的是Android的图形绘制...

    android开发MVC框架demo

    在Android应用开发中,MVC(Model-View-...总的来说,这个"android开发MVC框架demo"项目提供了一个实际应用MVC模式的实例,通过学习和实践,开发者可以掌握如何在Android开发中有效地组织代码,提升应用的质量和效率。

    Android 游戏Demo

    这个"Android游戏Demo"是一个专门为初学者设计的学习资源,旨在帮助他们理解并掌握Android 2D游戏开发的基础知识。 首先,我们来看看核心组件——`app-release.apk`。这是一个Android应用程序的打包文件,包含了...

    Android 游戏 Demo 学习

    在Android游戏开发领域,Demo是一种演示程序,通常包含基本的游戏机制和功能,旨在展示游戏的潜在玩法和设计。本资源“Android游戏Demo学习”显然提供了一个可以实践和探索的平台,帮助开发者理解和学习如何构建...

    android框架布局demo

    在Android开发中,布局(Layout)是构建用户界面的核心元素,它定义了屏幕上各个组件的排列方式和相互关系。本示例"android框架布局demo"旨在帮助开发者更好地理解和运用Android中的布局管理技术。通过这个简单易懂...

    Android 串口开发demo

    "Android 串口开发demo"是一个实例,它展示了如何在Android应用中通过串行通信接口(Serial Port)发送命令到硬件设备,并接收其反馈。下面将详细阐述Android串口开发的相关知识点。 1. **Android权限管理**: 在...

    Android mvvm 框架,最流行的mvvm demo

    本项目“Android mvvm 框架,最流行的mvvm demo”旨在提供一个无bug的示例,帮助开发者深入理解并实践MVVM框架在Android应用中的应用。 MVVM模式源于微软的WPF开发,近年来在Android开发中逐渐流行,它通过解耦视图...

    Android Wifi开发Demo示例

    总结,这个Android Wi-Fi开发Demo示例提供了一个完整的流程,从查找可用的Wi-Fi网络,到连接选定的网络,再到通过Wi-Fi进行数据交换,为开发者提供了实践和学习Android Wi-Fi编程的基础。理解并掌握这些知识点,有助...

    android游戏开发框架

    ### Android游戏开发框架知识点 #### 一、游戏运行平台及技术要求 - **目标支持的手机类型**:明确指出游戏将支持的手机型号,如诺基亚系列(6108、7650、3650)、索尼爱立信系列(T628、T618)和摩托罗拉系列等。...

    Android和ReactNative混合开发Demo

    本教程通过"Android和React Native混合开发Demo",将详细介绍如何在Android应用中集成React Native,实现原生代码与React Native组件之间的双向通信。 首先,Android原生加载RN页面是混合开发的基础。这涉及到在...

    基于Android studio无障碍开发demo源码.zip

    本项目"基于Android studio无障碍开发demo源码.zip"提供了一个示例,演示了如何在Android Studio中配置无障碍环境,并实现自动点击、滑动以及EditText输入等功能。 1. **无障碍服务基础** - **无障碍服务API**:...

    android 下的屏幕录制demo

    总的来说,这个“android 下的屏幕录制demo”涵盖了Android多媒体框架、权限管理、多线程编程等多个关键领域,对于想要实现Android屏幕录制功能的开发者来说是一个宝贵的参考资料。通过深入学习和理解这些知识点,...

    Android官方提供的SipDemo

    Android SipDemo是一个官方提供的示例应用,用于演示如何在Android平台上使用SIP(Session Initiation Protocol)进行VoIP(Voice over IP)通信。这个项目对于开发者来说,尤其是那些想要在自己的应用中集成语音...

    Android四等分布局Demo

    "Android四等分布局Demo"是一个典型的实例,它展示了如何将屏幕划分为四个相等的部分,为用户提供清晰、均衡的显示效果。这种布局常用于创建网格系统,如卡片式展示、游戏界面或者控制面板等。 在Android中实现四等...

    android游戏demo

    在Android平台上,游戏开发是一个广阔且充满活力的领域。这个"android游戏demo"为我们提供了一个研究和学习Android游戏开发的良好起点。在这个demo中,我们可以深入理解Android游戏的基本架构、编程逻辑以及图形渲染...

    Android View游戏框架Demo源码.rar

    这里的"Android View游戏框架Demo源码"很可能是一个示例项目,它展示了如何利用Android的View系统来开发简单游戏。让我们深入探讨一下这个话题。 首先,Android的View系统是UI界面的基础,包括了各种屏幕元素,如...

    一个Android App快速开发框架.zip

    一个Android App快速开发框架。.zip,AndroidQuick项目旨在提供一套进行Android APP快速开发的代码库。 AndroidQuick包含了开发一个APP所涉及到的常用的架构、模块、功能、技术点、解决方案等,每个部分附以详细的...

    android 串口测试demo 代码简单 无bug 完美运行

    android 串口测试demo 代码简单 无bug 完美运行 android 串口测试demo 代码简单 无bug 完美运行 android 串口测试demo 代码简单 无bug 完美运行 android 串口测试demo 代码简单 无bug 完美运行 android 串口测试demo...

Global site tag (gtag.js) - Google Analytics