当前位置: 代码迷 >> Android >> android 实现人物走路
  详细解决方案

android 实现人物走路

热度:10   发布时间:2016-04-28 08:04:26.0
android 实现人物行走

程序运行画面



可以通过上下左右键控制人物行走

思路

启动一个线程来不断的刷帧

在每一帧里重新绘制游戏画面

在每一帧里对鼠标点击事件作出响应,维护好游戏逻辑

需求分析

怎么实现键盘点击事件的响应。

通过Override onKeyDown函数实现。

值得注意的是

如果游戏的主画面是自定义的View,那么记得要在其初始化函数中加上setFocusable(true)

否则将不会对键盘点击事件作出响应,因为自定义的视图并没有获得焦点,因而无法对键盘点击事件作出响应。

怎么实现绘制一幅图片的特定区域。

canvas.drawBitmap函数有多个版本。

为了绘制一幅图片的指定区域,我们使用的是下面的版本

canvas.drawBitmap(Bitmap bitmap,Rect rect1,Rect rect2,Paint paint)

rect1用于指定截图区域

rect2用于指定展示区域


代码实现

MainActivity.java

package com.example.move;import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.Window;import android.view.WindowManager;public class MainActivity extends Activity {	GameView gameView;	//GameViewDrawThread gameViewDrawThread;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		requestWindowFeature(Window.FEATURE_NO_TITLE);		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);		//setContentView(R.layout.main);		gameView=new GameView(this);				setContentView(gameView);	}	@Override	public boolean onCreateOptionsMenu(Menu menu) {		// Inflate the menu; this adds items to the action bar if it is present.		getMenuInflater().inflate(R.menu.main, menu);		return true;	}}

GameViewDrawThread.java

package com.example.move;import android.graphics.Canvas;import android.view.SurfaceHolder;class GameViewDrawThread extends Thread{	private int sleepSpan=100;	private boolean flag=true;	GameView gameView;	SurfaceHolder surfaceHolder=null;	public GameViewDrawThread(GameView gameView,SurfaceHolder surfaceHolder)	{		this.gameView=gameView;		this.surfaceHolder=surfaceHolder;	}	public void run()	{		while(flag)		{			Canvas c=null;			try			{				//锁定整个画布,在内存要求比较高的情况下,建议参数不要为null				c=surfaceHolder.lockCanvas(null);				synchronized(this.surfaceHolder)				{					try					{						gameView.onDraw(c);					}					catch(Exception e){};				}			}			finally			{				if(c!=null)				{					if(c!=null)					{						surfaceHolder.unlockCanvasAndPost(c);					}				}			}			try			{				Thread.sleep(sleepSpan);			}			catch(Exception e)			{				e.printStackTrace();			}		}	}	public void setFlag(boolean flag)	{			this.flag=flag;	}}

GameView.java

package com.example.move;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.view.KeyEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.widget.Toast;class GameView extends SurfaceView implements SurfaceHolder.Callback{	MainActivity activity;	Paint paint;	Bitmap image_sprite;		GameViewDrawThread gameViewDrawThread;	Sprite sprite;	SurfaceHolder holder;	//Measures	int sprite_width=32;	int sprite_height=48;	int unit=48;	int box_x=0;	int box_y=0;	int box_width=0;	int box_height=0;	int bound_left,bound_right,bound_up,bound_down;	public GameView(MainActivity activity)	{		super(activity);		this.activity=activity;		this.sprite=new Sprite(3*unit,2*unit,sprite_width,sprite_height,0,0,0,true);		gameViewDrawThread=new GameViewDrawThread(this,getHolder());		gameViewDrawThread.start();				holder=this.getHolder();		holder.addCallback(this);		initBitmap();		setFocusable(true);	}	public void initBitmap()	{		paint=new Paint();		image_sprite=BitmapFactory.decodeResource(getResources(),R.drawable.sprite);	}	protected void onDraw(Canvas canvas)	{			//canvas.drawRect(0,0,box_width,box_height,paint);		paint.setAntiAlias(true);		canvas.drawColor(Color.WHITE);		canvas.save();		int cur_x=sprite.status*sprite.w;		int cur_y=sprite.direction*sprite.h;				Rect src = new Rect();// 图片        Rect dst = new Rect();// 屏幕位置及尺寸        //src 这个是表示绘画图片的大小        src.left =cur_x;        src.top = cur_y;        src.right =cur_x+sprite_width;        src.bottom =cur_y+sprite_height;        // 下面的 dst 是表示 绘画这个图片的位置        dst.left =sprite.x;        dst.top =sprite.y;        dst.right =sprite.x+sprite_width;           dst.bottom =sprite.y+sprite_height;        canvas.drawBitmap(image_sprite, src, dst, null);//这个方法  第一个参数是图片原来的大小,第二个参数是 绘画该图片需显示多少。也就是说你想绘画该图片的某一些地方,而不是全部图片,第三个参数表示该图片绘画的位置                src = null;        dst = null;        System.out.println(sprite.direction+" "+sprite.x+" "+sprite.y);		/*canvas.clipRect(sprite.x,sprite.y,sprite.x+sprite_width,sprite.y+sprite_height);		canvas.drawBitmap(image_sprite,sprite.x,sprite.y,paint);*/				canvas.restore();	}		public void surfaceDestroyed(SurfaceHolder holder)	{		boolean retry=true;		gameViewDrawThread.setFlag(false);//note		while(retry)		{			try			{				gameViewDrawThread.join();//不断尝试执行此行代码,直到成功				retry=false;			}			catch(InterruptedException e)			{							}		}	}	@Override	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {		// TODO Auto-generated method stub			}	@Override	public void surfaceCreated(SurfaceHolder arg0) {				// TODO Auto-generated method stub		box_width=this.getWidth();		box_height=this.getHeight();		bound_left=box_x;		bound_right=box_x+box_width-unit;		bound_up=box_y;		bound_down=box_y+box_height-unit;	}	@Override	public boolean onKeyDown(int key,KeyEvent event)	{		//Toast.makeText(activity, "HELLO", 1000);		//System.out.println("change");		int cur_direction=0;		switch(key)		{			case KeyEvent.KEYCODE_DPAD_UP:			sprite.y-=unit;			if(sprite.y<bound_up)				sprite.y=bound_up;			cur_direction=3;			break;			case KeyEvent.KEYCODE_DPAD_DOWN:			sprite.y+=unit;			if(sprite.y>bound_down)				sprite.y=bound_down;			cur_direction=0;			break;			case KeyEvent.KEYCODE_DPAD_LEFT:			sprite.x-=unit;			if(sprite.x<bound_left)				sprite.x=bound_left;			cur_direction=1;			break;			case KeyEvent.KEYCODE_DPAD_RIGHT:			sprite.x+=unit;			if(sprite.x>bound_right)				sprite.x=bound_right;			cur_direction=2;			break;		}		if(cur_direction!=sprite.direction)		{			sprite.direction=cur_direction;			sprite.status=0;		}		else		{			sprite.status=(sprite.status+1)%4;		}		return super.onKeyDown(key, event);		//return true;	}	}

sprite.java

package com.example.move;public class Sprite{	int x,y,w,h,direction,status,speed;	boolean flag;	public Sprite(int x,int y,int sw,int sh,int direction,int status,int speed,boolean flag)	{		this.x=x;		this.y=y;		this.w=sw;		this.h=sh;		this.direction=direction;		this.status=status;		this.speed=speed;		this.flag=flag;	}}

使用android实现人物行走的思路和使用Html5实现人物行走的思路是相近的,代码的写法也差不多。

具体可以参考另一篇文章

HTML5 实现人物行走


  相关解决方案