双缓冲 android,Android 利用双缓冲技术来是游戏更流畅

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

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值