package com.android.gameviewt;
import java.io.InputStream;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.Display;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class Avtivity01 extends Activity {
AnimView mAnimView =
null;
public void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//定义没有tile
requestWindowFeature(Window.FEATURE_NO_TITLE);
//定义全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Display display =
getWindowManager().getDefaultDisplay();
mAnimView = new
AnimView(this,display.getWidth(),display.getHeight());
setContentView(mAnimView);
}
public class AnimView
extends View implements Runnable{
//向下移动的动画
public final static int
ANIM_DOWN =0;
//向左移动动画
public final static int
ANIM_LEFT =1;
//向右移动动画
public final static int
ANIM_RIGHT =2;
//向上移动动画
public final static int
ANIM_UP =3;
//动画的总数量
public final static int
ANIM_COUNT=4;
Animation
heroAnimation[] = new Animation[ANIM_COUNT];
Paint mPaint = new
Paint();
//任意键被按下
private boolean
isAllkeyDown = false;
//下左右上键被按下
private boolean
isKeyDown = false;
private boolean
isKeyLeft = false;
private boolean
isKeyRight = false;
private boolean isKeyUp
= false;
//绘制当前动画状态的ID
int mAnimationState =
0;
//tile 块的宽高
public final static int
TILE_WIDTH =32;
public final static int
TILE_HEIGHT =32;
//tile 块的宽和高的数量
public final static int
TILE_WIDTH_COUNT = 10;
public final static int
TILE_HEIGHT_COUNT =15;
//如果数组元素为0 则什么都不画
public final static int
TILE_NULL=0;
public int[][] mMapView
={
{ 1, 1, 1, 1, 137, 137,
137, 1, 1, 1 },
{ 1, 1, 1, 1, 137, 137,
137, 1, 1, 1 },
{ 1, 1, 1, 1, 137, 137,
137, 1, 1, 1 },
{ 137, 137, 137, 137,
137, 137, 137, 137, 137, 137 },
{ 137, 137, 137, 137,
137, 137, 137, 137, 137, 137 },
{ 1, 1, 1, 1, 1, 1, 1,
1, 137, 137 },
{ 1, 1, 1, 1, 1, 1, 1,
1, 137, 137 },
{ 1, 1, 1, 1, 1, 1, 1,
1, 137, 137 },
{ 1, 1, 1, 1, 1, 1, 1,
1, 137, 137 },
{ 1, 1, 1, 1, 1, 1, 1,
1, 137, 137 },
{ 1, 1, 1, 1, 1, 1, 1,
1, 137, 137 },
{ 137, 137, 137, 137,
137, 137, 137, 137, 137, 137 },
{ 137, 137, 137, 137,
137, 137, 137, 137, 137, 137 },
{ 1, 1, 1, 1, 1, 137,
137, 137, 1, 1 },
{ 1, 1, 1, 1, 1, 137,
137, 137, 1, 1 }
};
//地图的第二层数组
public int[][]
mMapAcotor ={
{ 102, 103, 103, 104, 0,
0, 0, 194, 195, 196 },
{ 110, 111, 111, 112, 0,
0, 0, 202, 203, 204 },
{ 118, 119, 119, 120, 0,
0, 0, 210, 211, 212 },
{ 126, 127, 127, 128, 0,
0, 0, 218, 219, 220 },
{ 0, 0, 0, 0, 0, 0, 0,
0, 0, 0 },
{ 2, 2, 2, 2, 2, 2, 2,
11, 0, 0 },
{ 233, 234, 235, 236,
14, 14, 14, 14, 0, 0 },
{ 241, 242, 243, 244,
148, 148, 148, 148, 0, 0 },
{ 249, 250, 251, 252,
148, 148, 148, 148, 0, 0 },
{ 0, 258, 259, 0, 0, 0,
0, 11, 0, 0 },
{ 6, 6, 6, 6, 6, 6, 6,
6, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0,
0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0,
0, 0, 0 },
{ 102, 103, 103, 104, 0,
0, 0, 0, 143, 144 },
{ 110, 111, 111, 112, 0,
0, 0, 0, 151, 152 }
};
//地图的第三层
public int[][]
mCollision = {
{ 198, 198, 198, 198, 0,
0, 0, 198, 198, 198 },
{ 198, 198, 198, 198, 0,
0, 0, 198, 198, 198 },
{ 198, 198, 198, 198, 0,
0, 0, 198, 198, 198 },
{ 198, 198, 198, 198, 0,
0, 0, 198, 198, 198 },
{ 0, 0, 0, 0, 0, 0, 0,
0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0,
0, 0, 0 },
{ 198, 198, 198, 198, 0,
0, 0, 0, 0, 0 },
{ 198, 198, 198, 198,
198, 198, 198, 198, 0, 0 },
{ 198, 198, 198, 198,
198, 198, 198, 198, 0, 0 },
{ 198, 198, 198, 198,
198, 198, 198, 198, 0, 0 },
{ 0, 0, 0, 0, 0, 198,
198, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0,
0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0,
0, 0, 0 },
{ 198, 198, 198, 198, 0,
0, 0, 0, 198, 198 },
{ 198, 198, 198, 198, 0,
0, 0, 0, 198, 198 }
};
//游戏地图资源
Bitmap mBitmap =
null;
//资源文件
Resources mResources
= null;
//地图资源中横向纵向tile块的数量
int mWidthTileCount =
0;
int mHeightTileCount
=0;
int mBitmapWidth
=0;
int
mBitmapHeight=0;
//英雄在地图中的坐标以英雄脚底的中心为原点
int mHeroPosX =0;
int mHeroPosY =0;
//备份英雄发生碰撞以前的坐标点
int mHeroBackPosX=
0;
int mHeroBackPosY
=0;
//英雄在地图中绘制的坐标
int mHeroImageX =
0;
int mHeroImageY
=0;
//英雄在地图中二维数组的索引
int mHeroIndexX=0;
int mHeroIndexY
=0;
//屏幕宽和高的尺寸
int mScreenWidth
=0;
int mScreenHeight
=0;
//人物图片资源与实际英雄脚底板的偏移量
public final static int
OFF_HERO_X =16;
public final static int
OFF_HERO_Y =35;
//人物主角行走步长
public final static int
HERO_STEP =8;
//与实体层发生碰撞
private boolean
isAcotorCollision = false;
//与边界发生碰撞
private boolean
isBorderCollision = false;
//与人物发生碰撞
private boolean
isPersonCollision = false;
//双缓冲Bitmap
private Bitmap
mBufferBitmap = null;
//双缓冲画布
private Canvas mCanvas =
null;
//游戏zhuxiancheng
private Thread mThread =
null;
//线程循环标志
private boolean
mIsRunning = false;
public AnimView(Context
context,int screenWidth,int screenHeight){
super(context);
mPaint = new
Paint();
mScreenWidth =
screenWidth;
mScreenHeight =
screenHeight;
//双缓冲
mBufferBitmap
=
Bitmap.createBitmap(mScreenWidth,mScreenHeight,Config.ARGB_8888);
mCanvas
= new Canvas();
//bitmap绘制到双缓冲的画布上
mCanvas.setBitmap(mBufferBitmap);
initAnimation(context);
initMap(context);
initHero();
//启动游戏的主线程
mIsRunning = true;
mThread = new
Thread(this);
mThread.start();
}
private void
initHero(){
mHeroImageX = 100;
mHeroImageY =100;
//根据图片显示的坐标算出英雄脚底的坐标
mHeroPosX = mHeroImageX
+OFF_HERO_X;
mHeroPosY = mHeroImageY
+OFF_HERO_Y;
//在二维数组的位置
mHeroIndexX = mHeroPosX
/TILE_WIDTH;
mHeroIndexY = mHeroPosY
/TILE_HEIGHT;
}
private void
initMap(Context context){
mBitmap =
ReadBitMap(context,R.drawable.game);
mBitmapWidth =
mBitmap.getWidth();
mBitmapHeight =
mBitmap.getHeight();
mWidthTileCount =
mBitmapWidth/TILE_WIDTH;
mHeightTileCount =
mBitmapHeight/TILE_HEIGHT;
}
private void
initAnimation(Context context){
heroAnimation[ANIM_DOWN] = new
Animation(context,new int
[]{R.drawable.hero_down_a,R.drawable.hero_down_b,R.drawable.hero_down_c,R.drawable.hero_down_d},true);
heroAnimation[ANIM_LEFT] = new
Animation(context,new int
[]{R.drawable.hero_left_a,R.drawable.hero_left_b,R.drawable.hero_left_c,R.drawable.hero_left_d},true);
heroAnimation[ANIM_RIGHT]= new
Animation(context,new int
[]{R.drawable.hero_right_a,R.drawable.hero_right_b,R.drawable.hero_right_c,R.drawable.hero_right_d},true);
heroAnimation[ANIM_UP] = new
Animation(context,new int
[]{R.drawable.hero_up_a,R.drawable.hero_up_b,R.drawable.hero_up_c,R.drawable.hero_up_d},true);;
}
protected void
onDraw(Canvas canvas){
DrawMap(mCanvas,mPaint,mBitmap);
RenderAnimation(mCanvas);
UpdateAnimation();
if(isBorderCollision){
}
if(isAcotorCollision){
}
if(isPersonCollision){
}
canvas.drawBitmap(mBufferBitmap, 0,0, mPaint);
super.onDraw(canvas);
}
private void
UpdateAnimation(){
if(isAllkeyDown){
if(isKeyDown){
mAnimationState =
ANIM_DOWN;
mHeroPosY+=HERO_STEP;
}else
if(isKeyLeft){
mAnimationState =
ANIM_LEFT;
mHeroPosX
-=HERO_STEP;
}else
if(isKeyRight){
mAnimationState =
ANIM_RIGHT;
mHeroPosX
+=HERO_STEP;
}else if(isKeyUp){
mAnimationState =
ANIM_UP;
mHeroPosY
-=HERO_STEP;
}
//检测人物是否出屏
isBorderCollision =
false;
if(mHeroPosX<=0){
mHeroPosX =0;
isBorderCollision =
true;
}else if(mHeroPosX
>=mScreenWidth){
mHeroPosX =
mScreenWidth;
isBorderCollision =
true;
}else if(mHeroPosY
<=0){
mHeroPosY =0;
isBorderCollision =
true;
}else if(mHeroPosY
>= mScreenHeight){
mHeroPosY =
mScreenHeight;
isBorderCollision =
true;
}
//计算英雄移动后在地图二维数组中的索引
mHeroIndexX = mHeroPosX
/TILE_WIDTH;
mHeroIndexY =
mHeroPosY/TILE_HEIGHT;
//越界检测
int width
= mCollision[0].length -1;
int height =
mCollision.length -1;
if(mHeroIndexX
<=0){
mHeroIndexX = 0;
}else if(mHeroIndexX
>= width){
mHeroIndexX =
width;
}else if(mHeroIndexY
<=0){
mHeroIndexY =0;
}else if(mHeroIndexY
>=height){
mHeroIndexY =
height;
}
if(mCollision[mHeroIndexY][mHeroIndexX]>0){
mHeroPosX =
mHeroBackPosX;
mHeroPosY =
mHeroBackPosY;
isAcotorCollision =
true;
}else {
mHeroBackPosX =
mHeroPosX;
mHeroBackPosY =
mHeroPosY;
isAcotorCollision =
false;
}
mHeroImageX = mHeroPosX
-OFF_HERO_X;
mHeroImageY = mHeroPosY
-OFF_HERO_Y;
}
}
private void
RenderAnimation(Canvas canvas){
if(isAllkeyDown){
heroAnimation[mAnimationState].DrawAnimation(canvas, mPaint,
mHeroImageX, mHeroImageY);
}
else{
heroAnimation[mAnimationState].DrawFrame(canvas, mPaint,
mHeroImageX, mHeroImageY, 0);
}
}
public void
setKeyState(int keyCode ,boolean state){
switch(keyCode){
case
KeyEvent.KEYCODE_DPAD_DOWN:
isKeyDown = state;
break;
case
KeyEvent.KEYCODE_DPAD_LEFT:
isKeyLeft = state;
break;
case
KeyEvent.KEYCODE_DPAD_RIGHT:
isKeyRight =state;
break;
case
KeyEvent.KEYCODE_DPAD_UP:
isKeyUp = state;
break;
}
isAllkeyDown =
state;
}
private void
DrawMap(Canvas canvas,Paint paint,Bitmap bitmap){
int i,j;
for(i=0;i
for(j=0;j
int ViewID =
mMapView[i][j];
int AcotorID =
mMapAcotor[i][j];
//绘制第一层
if(ViewID>TILE_NULL){
DrawMapTile(ViewID,canvas,paint,bitmap, j*TILE_WIDTH,
i*TILE_HEIGHT);
}
//绘制第二层地图
if(AcotorID
>TILE_NULL){
DrawMapTile(AcotorID,canvas,paint,bitmap,
j*TILE_WIDTH,i*TILE_HEIGHT);
}
}
}
}
private void
DrawMapTile(int id,Canvas canvas,Paint paint,Bitmap bitmap,int
x,int y){
id--;
int count =
id/mWidthTileCount;
int bitmapX =
(id-(count*mWidthTileCount))*TILE_WIDTH;
int bitmapY =
count*TILE_HEIGHT;
DrawClipImage(canvas,paint,bitmap,x,y,bitmapX,bitmapY,TILE_WIDTH,TILE_HEIGHT);
}
private void
DrawClipImage(Canvas canvas,Paint paint,Bitmap bitmap,int x,int
y,int src_x,int src_y,int src_px,int src_py){
canvas.save();
canvas.clipRect(x, y, x+
src_px,y+src_py );
canvas.drawBitmap(bitmap, x-src_x, y-src_y, mPaint);
canvas.restore();
}
public Bitmap
ReadBitMap(Context context,int resId){
BitmapFactory.Options
opt = new BitmapFactory.Options();
opt.inPreferredConfig =
Bitmap.Config.ALPHA_8;
opt.inPurgeable = true;
opt.inInputShareable = true;
//获取资源图片
InputStream is =
context.getResources().openRawResource(resId);
return
BitmapFactory.decodeStream(is,null,opt);
}
public void run(){
while(mIsRunning){
try{
Thread.sleep(100);
postInvalidate();
}catch(Exception
e){
}
}
}
}
public boolean
onKeyDown(int keyCode ,KeyEvent event){
mAnimView.setKeyState(keyCode, true);
return
super.onKeyDown(keyCode, event);
}
public boolean
onKeyUp(int keyCode,KeyEvent event){
mAnimView.setKeyState(keyCode, false);
return super.onKeyDown(keyCode, event);
}
}