Android应用程序入门 推箱子游戏开发(二) 键盘事件监听 角色在屏幕上移动

 先看一下效果图。

Android应用程序入门 推箱子游戏开发(二) 键盘事件监听 角色在屏幕上移动_第1张图片Android应用程序入门 推箱子游戏开发(二) 键盘事件监听 角色在屏幕上移动_第2张图片Android应用程序入门 推箱子游戏开发(二) 键盘事件监听 角色在屏幕上移动_第3张图片Android应用程序入门 推箱子游戏开发(二) 键盘事件监听 角色在屏幕上移动_第4张图片

        我们的目标是:通过键盘按键,控制人物在屏幕上自由移动。要实现这个目标,只要完成下面三件事就行:1. 监听键盘,获取按键值 2. 根据按键值,修改人物在屏幕上的坐标 3. 在新的坐标位置显示人物

下面是程序的基本框图。

Android应用程序入门 推箱子游戏开发(二) 键盘事件监听 角色在屏幕上移动_第5张图片

        如上图所示:主Activity依次:创建人物、创建键盘监听线程、启动键盘监听线程、显示游戏界面。在游戏界面启动后,游戏界面绘图线程随之启动。绘图线程每隔固定时间对屏幕进行一次刷新。键盘监听线程启动后,会捕获按键值,然后根据按键值来修改人物显示坐标。人物显示坐标改变后,下次绘图线程就可以新的地方把人物画出来。

package com.mapAndSprit;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;

public class MapAndSpritActivity extends Activity {

	//游戏界面
	GameView gameView;
	//人物
	MySprite mySprite;
	//键盘监听线程
	KeyThread kt;
	
	//键盘动作
	int action = 0;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		gameView = new GameView( this );
		mySprite = new MySprite( this );
		kt = new KeyThread( this );
		kt.start();
		
		//显示游戏界面
		setContentView( gameView );		
	}
	
	//按键按下
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		// TODO Auto-generated method stub
		if(keyCode == 19){//上
    		action = action | 0x08;
    	}
    	if(keyCode == 20){//下
    		action = action | 0x04;
    	}    	
    	if(keyCode == 21){//左
    		action = action | 0x02;
    	}    	
    	if(keyCode == 22){//右
    		action = action | 0x01;
    	}
		return false;		
	}

	//按键抬起
	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event)
	{
		// TODO Auto-generated method stub
		if(keyCode == 19){//上
    		action = action & 0x37;
    	}
    	if(keyCode == 20){//下
    		action = action & 0x3B;
    	}    	
    	if(keyCode == 21){//左
    		action = action & 0x3D;
    	}    	
    	if(keyCode == 22){//右
    		action = action & 0x3E;
    	}
		return false;
	}
}


 

package com.mapAndSprit;

public class KeyThread extends Thread {

	MapAndSpritActivity mapAndSpritActivity;
	boolean flag = true;	
	int sleepSpan = 50;
	int action;
	
	boolean KEY_UP = false;
	boolean KEY_DOWN = false;
	boolean KEY_LEFT = false;
	boolean KEY_RIGHT = false;
	
	public KeyThread( MapAndSpritActivity mapAndSpritActivity )
	{
		this.mapAndSpritActivity = mapAndSpritActivity;		
	}
	
	public void run()
	{
		while( flag )
		{
			action = mapAndSpritActivity.action;
			if((action & 0x08) != 0){//上
				KEY_UP = true;
			}
			else{
				KEY_UP = false;
			}
			if((action & 0x04) != 0){//下
				KEY_DOWN = true;
			}
			else{
				KEY_DOWN = false;
			}
			if((action & 0x02) != 0){//左
				KEY_LEFT = true;
			}
			else{
				KEY_LEFT = false;
			}
			if((action & 0x01) != 0){//右
				KEY_RIGHT = true;
			}
			else{
				KEY_RIGHT = false;
			} 
			
			if( KEY_UP )
			{
				if( !( mapAndSpritActivity.mySprite.curJ < 1 ) )
				{					
					mapAndSpritActivity.mySprite.curJ -= 1;
				}				
			}
			if( KEY_DOWN )
			{
				if( !( mapAndSpritActivity.mySprite.curJ >15 ) )
				{					
					mapAndSpritActivity.mySprite.curJ += 1;
				}				
			}
			if( KEY_LEFT )
			{
				if( !( mapAndSpritActivity.mySprite.curI < 1 ) )
				{					
					mapAndSpritActivity.mySprite.curI -= 1;
				}				
			}
			if( KEY_RIGHT )
			{
				if( !( mapAndSpritActivity.mySprite.curI > 10 ) )
				{					
					mapAndSpritActivity.mySprite.curI += 1;
				}				
			}
			
			try{
				//睡眠sleepSpan毫秒
				Thread.sleep( sleepSpan );
			}
			catch(Exception e){
				e.printStackTrace();
			}
		}
	}
}


 

package com.mapAndSprit;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;

public class MySprite {
	
	MapAndSpritActivity mapAndSpritActivity;
	Bitmap man;
	
	//人物在地图显示的位置
	int curI = 0;
	int curJ = 0;
	int curX = 0;
	int curY = 0;
	
	public MySprite( MapAndSpritActivity mapAndSpritActivity )
	{
		this.mapAndSpritActivity = mapAndSpritActivity;		
		man = BitmapFactory.decodeResource( mapAndSpritActivity.getResources(), R.drawable.a1 );
	}
	
	public void drawSelf( Canvas c, Paint paint )
	{
		//把屏幕分成虚拟的10 * 15的网格,每个格子大小 20 * 20
		//每次走动一个格子
		curX = this.mapAndSpritActivity.gameView.initX + curI * 20;
		curY = this.mapAndSpritActivity.gameView.initX + curJ * 20;
		c.drawBitmap( man, curX, curY, paint );
	}	
}


 

package com.mapAndSprit;

import android.graphics.Canvas;
import android.graphics.Color;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameView extends SurfaceView implements SurfaceHolder.Callback
{
	MapAndSpritActivity mapAndSpritActivity;
	GameViewDrawThread gameViewDrawThread;
	SurfaceHolder holder;	
	
	//人物能在屏幕上显示的最左上角的位置
	int initX = 20;
	int initY = 20;
	
	public GameView( MapAndSpritActivity mapAndSpritActivity )
	{
		super( mapAndSpritActivity );
		this.mapAndSpritActivity = mapAndSpritActivity;
		holder = getHolder();
		holder.addCallback( this );
		
		gameViewDrawThread = new GameViewDrawThread( this, holder );
	}

	public void onDraw( Canvas c )
	{
		c.drawColor( Color.BLUE );
		mapAndSpritActivity.mySprite.drawSelf( c, null );
	}
	
	@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
		gameViewDrawThread.setFlag( true );
		gameViewDrawThread.start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		boolean retry = true;
		//停止刷帧线程
		gameViewDrawThread.setFlag(false);
		//不断地循环,直到等待的线程结束
        while (retry) {
            try {
            	//等待刷帧线程结束
            	gameViewDrawThread.join();
                retry = false;
            } 
            catch (InterruptedException e) {
            }
        }
	}
	
}


 

package com.mapAndSprit;

import android.graphics.Canvas;
import android.view.SurfaceHolder;

public class GameViewDrawThread extends Thread {
	private GameView gameView;
	private SurfaceHolder holder;
	boolean isRun;	
	int sleepSpan = 200;
	
	public GameViewDrawThread( GameView gameView, SurfaceHolder holder )
	{
		this.gameView = gameView;
		this.holder = holder;
		isRun = true;
	}
	
	public void setFlag( boolean flag )
	{
		isRun = flag;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while( isRun )
		{
			Canvas c = null;
			try
			{
				c = holder.lockCanvas();
				synchronized( holder )
				{
					//调用绘图函数
					gameView.onDraw( c );						
				}
			}finally
			{
				if( c != null )
				{
					holder.unlockCanvasAndPost( c );
				}
			}
			
			try{
				//睡眠200毫秒
				Thread.sleep( sleepSpan );
			}
			catch(Exception e){
				e.printStackTrace();
			}
		}
	}
}


 

你可能感兴趣的:(thread,游戏,exception,android,Class,action)