先看一下效果图。




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

如上图所示:主Activity依次:创建人物、创建键盘监听线程、启动键盘监听线程、显示游戏界面。在游戏界面启动后,游戏界面绘图线程随之启动。绘图线程每隔固定时间对屏幕进行一次刷新。键盘监听线程启动后,会捕获按键值,然后根据按键值来修改人物显示坐标。人物显示坐标改变后,下次绘图线程就可以新的地方把人物画出来。
[java] view plain copy print ?
- 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) {
-
- 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)
- {
-
- 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)
- {
-
- 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 plain copy print ?
- 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{
-
- 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 plain copy print ?
- 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 )
- {
-
-
- 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 plain copy print ?
- 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) {
-
-
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder arg0) {
-
- gameViewDrawThread.setFlag( true );
- gameViewDrawThread.start();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder arg0) {
-
- 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 plain copy print ?
- 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() {
-
- while( isRun )
- {
- Canvas c = null;
- try
- {
- c = holder.lockCanvas();
- synchronized( holder )
- {
-
- gameView.onDraw( c );
- }
- }finally
- {
- if( c != null )
- {
- holder.unlockCanvasAndPost( c );
- }
- }
-
- try{
-
- Thread.sleep( sleepSpan );
- }
- catch(Exception e){
- e.printStackTrace();
- }
- }
- }
- }