您的位置:首页 > 其它

推箱子游戏开发(二) 键盘事件监听 角色在屏幕上移动

2013-01-15 15:32 645 查看
先看一下效果图。









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

下面是程序的基本框图。



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

[java]
view plaincopyprint?

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;

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;
}
}


[java]
view plaincopyprint?

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;

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();
}
}
}
}


[java]
view plaincopyprint?

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.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 );
}
}


[java]
view plaincopyprint?

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.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) {
}
}
}

}


[java]
view plaincopyprint?

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();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐