android如何编写一个贪食蛇游戏,贪食蛇游戏android详解

2023-10-07 00:20

本文主要是介绍android如何编写一个贪食蛇游戏,贪食蛇游戏android详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这句代码是获取res/value/attrs.xml下自定义的属性值,attrs.xml中如下定义:

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

mTileSize = a.getInt(R.styleable.TileView_tileSize, 12);

这句是获取layout文件定义的UI参数中tileSize的值,没有定义则返回缺省值12。mTileSize代表小方格的尺寸。

接下来要把游戏的界面分成很多个小方格来绘画,首先我们要知道界面可以分成几个空格,可以在onSzieChanged中获取初始化数据,onSizeChanged在View第一次启动时加载

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

protectedstaticintmXTileCount;

protectedstaticintmYTileCount;

privatestaticintmXOffset;

privatestaticintmYOffset;

privateint[][] mTileGrid;

@Override

protectedvoidonSizeChanged(intw ,inth,intoldw,intoldh){

mXTileCount = (int) Math.floor(w/mTileSize);

mYTileCount = (int) Math.floor(h/mTileSize);

//不能分成整数个,得出剩余x y 的尺寸

mXOffset = ((w-(mTileSize * mXTileCount))/2);

mYOffset = ((h-(mTileSize * mYTileCount))/2);

mTileGrid =newint[mXTileCount][mYTileCount];

clearTiles();

}

publicvoidclearTiles(){

for(intx =0; x

for(inty=0; y

setTile(0, x, y);

}

}

}

publicvoidsetTile(inttileindex,intx,inty){

mTileGrid[x][y]=tileindex;

}

protected static int mXTileCount;

protected static int mYTileCount;

private static int mXOffset;

private static int mYOffset;

private int[][] mTileGrid;

@Override

protected void onSizeChanged(int w ,int h, int oldw,int oldh){

mXTileCount = (int) Math.floor(w/mTileSize);

mYTileCount = (int) Math.floor(h/mTileSize);

//不能分成整数个,得出剩余x y 的尺寸

mXOffset = ((w-(mTileSize * mXTileCount))/2);

mYOffset = ((h-(mTileSize * mYTileCount))/2);

mTileGrid = new int[mXTileCount][mYTileCount];

clearTiles();

}

public void clearTiles(){

for(int x = 0; x

for(int y=0; y

setTile(0, x, y);

}

}

}

public void setTile(int tileindex, int x, int y){

mTileGrid[x][y]=tileindex;

}

clearTiles()函数初始化mTileGrid,把mTileGrid所有值设为0,mTileGrid代表界面的所有方格

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

privateBitmap[] mTileArray;

publicvoidresetTiles(inttilecount) {

mTileArray =newBitmap[tilecount];

}

publicvoidloadTile(intkey, Drawable tile){

Bitmap bitmap =Bitmap.createBitmap(mTileSize,mTileSize,Bitmap.Config.ARGB_8888);//创建位图

Canvas canvas=newCanvas(bitmap);//获取位图的canvas

tile.setBounds(0,0, mTileSize ,mTileSize);

tile.draw(canvas);//把tile所表示的图片画到canvas中

mTileArray[key]=bitmap;

}

private Bitmap[] mTileArray;

public void resetTiles(int tilecount) {

mTileArray = new Bitmap[tilecount];

}

public void loadTile(int key, Drawable tile){

Bitmap bitmap =Bitmap.createBitmap(mTileSize,mTileSize,Bitmap.Config.ARGB_8888); //创建位图

Canvas canvas= new Canvas(bitmap);//获取位图的canvas

tile.setBounds(0, 0, mTileSize ,mTileSize);

tile.draw(canvas); //把tile所表示的图片画到canvas中

mTileArray[key]=bitmap;

}

mTileArray用来存方格所用到的图片resetTiles(int)函数初始化图片的数量,loadTile(int

key,Drawable)加载图片存进mTileArray[key]中

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

//覆盖onDraw类,操作canvas实现绘图

Paint mPaint=newPaint();

@Override

publicvoidonDraw(Canvas canvas){

super.onDraw(canvas);

for(intx=0; x

for(inty=0; y

if(mTileGrid[x][y]>0){

canvas.drawBitmap(mTileArray[mTileGrid[x][y]],

mXOffset+x * mTileSize,

mYOffset+y * mTileSize,

mPaint);

}

}

}

}

//覆盖onDraw类,操作canvas实现绘图

Paint mPaint=new Paint();

@Override

public void onDraw(Canvas canvas){

super.onDraw(canvas);

for(int x=0; x

for(int y=0; y

if(mTileGrid[x][y]>0){

canvas.drawBitmap(mTileArray[mTileGrid[x][y]],

mXOffset+x * mTileSize,

mYOffset+y * mTileSize,

mPaint);

}

}

}

}

4.

接下来看看SnakeView类

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

//创建SnakeView,SnakeView继承TileView,重写构造函数

publicSnakeViewExm(Context context , AttributeSet attrs){

super(context,attrs);

initSnakeView();

}

publicSnakeViewExm(Context context, AttributeSet attrs,intdefStyle) {

super(context, attrs, defStyle);

// TODO Auto-generated constructor stub

initSnakeView();

}

privatevoidinitSnakeView(){

setFocusable(true);//获得焦点

Resources r=getContext().getResources();

resetTiles(4);

loadTile(RED_STAR,r.getDrawable(R.drawable.redstar));

loadTile(YELLOW_STAR,r.getDrawable(R.drawable.yellowstar));

loadTile(GREEN_STAR,r.getDrawable(R.drawable.greenstar));

}

privatestaticfinalintRED_STAR =1;

privatestaticfinalintYELLOW_STAR =2;

privatestaticfinalintGREEN_STAR =3;

//创建SnakeView,SnakeView继承TileView,重写构造函数

public SnakeViewExm(Context context , AttributeSet attrs){

super(context,attrs);

initSnakeView();

}

public SnakeViewExm(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

// TODO Auto-generated constructor stub

initSnakeView();

}

private void initSnakeView(){

setFocusable(true);//获得焦点

Resources r=getContext().getResources();

resetTiles(4);

loadTile(RED_STAR,r.getDrawable(R.drawable.redstar));

loadTile(YELLOW_STAR,r.getDrawable(R.drawable.yellowstar));

loadTile(GREEN_STAR,r.getDrawable(R.drawable.greenstar));

}

private static final int RED_STAR = 1;

private static final int YELLOW_STAR = 2;

private static final int GREEN_STAR = 3;

initSnakeView()函数中设置了mTileArray的长度,并加载了三张图片

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

//贪吃蛇当前的方向mDirection,下一刻方向mNextDirection

privateintmDirection= NORTH;

privateintmNextDirection =NORTH;

privatestaticfinalintNORTH=1;

privatestaticfinalintSOUTH=2;

privatestaticfinalintEAST=3;

privatestaticfinalintWEST=4;

privatelongmScore =0;//得分

privatelongmMoveDelay =600;//600毫秒后,自动行走

//贪吃蛇由几个方格组成,Coordiante 是表示一个方格的坐标类

//mAppleList 苹果列表,也就是给贪吃蛇吃的那个东西,

privateArrayList mSnakeTrail =newArrayList();

privateArrayList mAppleList=newArrayList();

privatevoidinitNewGame(){

mSnakeTrail.clear();

mAppleList.clear();

//贪吃蛇的坐标

mSnakeTrail.add(newCoordinate(7,7));

mSnakeTrail.add(newCoordinate(6,7));

mSnakeTrail.add(newCoordinate(5,7));

mSnakeTrail.add(newCoordinate(4,7));

mSnakeTrail.add(newCoordinate(3,7));

mSnakeTrail.add(newCoordinate(2,7));

mNextDirection = NORTH;

addRandomApple();

addRandomApple();

mMoveDelay =600;

mScore =0;

}

privateclassCoordinate{

publicintx;

publicinty;

publicCoordinate(intnewX,intnewY){

x=newX;

y=newY;

}

publicbooleanequals(Coordinate other){

if(x==other.x && y==other.y){

returntrue;

}

returnfalse;

}

@Override

publicString toString(){

return"Coordinate:["+ x +","+ y +"]";

}

}

//贪吃蛇当前的方向mDirection,下一刻方向mNextDirection

private int mDirection= NORTH;

private int mNextDirection =NORTH;

private static final int NORTH=1;

private static final int SOUTH=2;

private static final int EAST=3;

private static final int WEST=4;

private long mScore = 0; //得分

private long mMoveDelay = 600; //600毫秒后,自动行走

//贪吃蛇由几个方格组成,Coordiante 是表示一个方格的坐标类

//mAppleList 苹果列表,也就是给贪吃蛇吃的那个东西,

private ArrayList mSnakeTrail = new ArrayList();

private ArrayList mAppleList=new ArrayList();

private void initNewGame(){

mSnakeTrail.clear();

mAppleList.clear();

//贪吃蛇的坐标

mSnakeTrail.add(new Coordinate(7, 7));

mSnakeTrail.add(new Coordinate(6, 7));

mSnakeTrail.add(new Coordinate(5, 7));

mSnakeTrail.add(new Coordinate(4, 7));

mSnakeTrail.add(new Coordinate(3, 7));

mSnakeTrail.add(new Coordinate(2, 7));

mNextDirection = NORTH;

addRandomApple();

addRandomApple();

mMoveDelay = 600;

mScore = 0;

}

private class Coordinate{

public int x;

public int y;

public Coordinate(int newX, int newY){

x=newX;

y=newY;

}

public boolean equals(Coordinate other){

if(x==other.x && y==other.y){

return true;

}

return false;

}

@Override

public String toString(){

return "Coordinate:["+ x + "," + y + "]";

}

}

addRandomApplet()随进产生苹果的坐标位置,代码如下

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

privatestaticfinalRandom RNG =newRandom();

privatevoidaddRandomApple(){

Coordinate newCoord =null;

booleanfound =false;

while(!found){

intnewX =1+ RNG.nextInt(mXTileCount-2);

intnewY =1+ RNG.nextInt(mYTileCount-2);

newCoord =newCoordinate(newX, newY);

booleancollision =false;

intsnakelength = mSnakeTrail.size();

//生成的位置不能和贪吃蛇的坐标一样

for(intindex =0; index

if(mSnakeTrail.get(index).equals(newCoord)){

collision=true;

}

}

found=!collision;

}

if(newCoord ==null){

Log.e(TAG,"Somehow ended up with a null newCoord");

}

mAppleList.add(newCoord);

}

private static final Random RNG =new Random();

private void addRandomApple(){

Coordinate newCoord = null;

boolean found = false;

while(!found){

int newX =1 + RNG.nextInt(mXTileCount-2);

int newY =1 + RNG.nextInt(mYTileCount-2);

newCoord = new Coordinate(newX, newY);

boolean collision = false;

int snakelength = mSnakeTrail.size();

//生成的位置不能和贪吃蛇的坐标一样

for(int index =0; index< snakelength;index++){

if(mSnakeTrail.get(index).equals(newCoord)){

collision=true;

}

}

found=!collision;

}

if(newCoord == null){

Log.e(TAG,"Somehow ended up with a null newCoord");

}

mAppleList.add(newCoord);

}

游戏初始化的参数在上面已经完成了,接下来是要给SnakeView添加事件响应

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

//游戏状态的标识变量

privateintmMode = READY;

publicstaticfinalintPAUSE=0;

publicstaticfinalintREADY=1;

publicstaticfinalintRUNNING=2;

publicstaticfinalintLOSE=3;

@Override

publicbooleanonKeyDown(intkeyCode, KeyEvent msg){

//向上,如果是READY或LOST,则开始游戏

if(keyCode==KeyEvent.KEYCODE_DPAD_UP){

if(mMode ==READY | mMode ==LOSE){

initNewGame();//初始化

setMode(RUNNING);//设置状态

return(true);

}

if(mMode == PAUSE){

setMode(RUNNING);

update();

return(true);

}

//贪吃蛇不是向下走时,才可以向上

if(mDirection != SOUTH) {

mNextDirection = NORTH;

}

return(true);

}

if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN){

//贪吃蛇不是向上走时,才可以向下

if(mDirection!=NORTH){

mNextDirection=SOUTH;

}

return(true);

}

if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {

//贪吃蛇不是向右走时,才可以向左

if(mDirection != EAST) {

mNextDirection = WEST;

}

return(true);

}

if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {

if(mDirection != WEST) {

mNextDirection = EAST;

}

return(true);

}

returnsuper.onKeyDown(keyCode, msg);

}

//游戏状态的标识变量

private int mMode = READY;

public static final int PAUSE=0;

public static final int READY=1;

public static final int RUNNING=2;

public static final int LOSE=3;

@Override

public boolean onKeyDown(int keyCode, KeyEvent msg){

//向上,如果是READY或LOST,则开始游戏

if(keyCode==KeyEvent.KEYCODE_DPAD_UP){

if(mMode ==READY | mMode ==LOSE){

initNewGame(); //初始化

setMode(RUNNING);//设置状态

return(true);

}

if(mMode == PAUSE){

setMode(RUNNING);

update();

return (true);

}

//贪吃蛇不是向下走时,才可以向上

if (mDirection != SOUTH) {

mNextDirection = NORTH;

}

return (true);

}

if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN){

//贪吃蛇不是向上走时,才可以向下

if(mDirection!=NORTH){

mNextDirection=SOUTH;

}

return (true);

}

if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {

//贪吃蛇不是向右走时,才可以向左

if (mDirection != EAST) {

mNextDirection = WEST;

}

return (true);

}

if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {

if (mDirection != WEST) {

mNextDirection = EAST;

}

return (true);

}

return super.onKeyDown(keyCode, msg);

}

按下键盘键后,如果是刚开始游戏或者重新游戏时会调用update(),而其他状态则不会在这里调用更新,可以看出update()这个函数游戏中是一直在被调用的,下面我们看下代码这么实现update(),并且实现update()的循环调用

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

privatelongmLastMove;

publicvoidupdate(){

//只有在运行中才会有数据更新

if(mMode==RUNNING){

longnow =System.currentTimeMillis();

//等待mMoveDelay时间,游戏自动更新

if(now - mLastMove >mMoveDelay){

clearTiles();

updateWalls();

updateSnake();

updateApples();

mLastMove=now;

}

mRedrawHandler.sleep(mMoveDelay);

}

}

privatevoidupdateWalls(){

//设置屏幕上下两边的方格图片

for(intx=0;x

setTile(GREEN_STAR, x,0);

setTile(GREEN_STAR, x,mYTileCount -1);

}

//设置屏幕左右两边的方格图片

for(inty=1;y

setTile(GREEN_STAR,0,y);

setTile(GREEN_STAR, mXTileCount -1,y);

}

}

privatevoidupdateSnake(){

booleangrowSnake =false;

Coordinate head =mSnakeTrail.get(0);

Coordinate newHead =newCoordinate(1,1);

mDirection =mNextDirection;

//获取下一步的坐标

switch(mDirection){

caseEAST:{

newHead =newCoordinate(head.x+1,head.y);

break;

}

caseWEST:{

newHead =newCoordinate(head.x-1,head.y);

break;

}

caseNORTH:{

newHead=newCoordinate(head.x,head.y-1);

break;

}

caseSOUTH:{

newHead=newCoordinate(head.x,head.y+1);

break;

}

}

//是否碰到“墙壁”

if((newHead.x<1)||(newHead.y<1)||(newHead.x>mXTileCount-2)

||(newHead.y>mYTileCount-2)){

setMode(LOSE);

return;

}

intsnakelength =mSnakeTrail.size();

//碰到自己

for(intsnakeindex=0;snakeindex

Coordinate c=mSnakeTrail.get(snakeindex);

if(c.equals(newHead)){

setMode(LOSE);

return;

}

}

intapplecount=mAppleList.size();

//吃到苹果

for(intappleindex =0;appleindex

Coordinate c=mAppleList.get(appleindex);

if(c.equals(newHead)){

mAppleList.remove(c);

addRandomApple();

mScore++;

mMoveDelay *=0.9;

growSnake =true;

}

}

mSnakeTrail.add(0,newHead);

if(!growSnake){

mSnakeTrail.remove(mSnakeTrail.size()-1);

}

//设置贪吃蛇的图片,第一个方格和其他方格不一样

intindex=0;

for(Coordinate c:mSnakeTrail){

if(index==0){

setTile(YELLOW_STAR, c.x,c.y);

}else{

setTile(RED_STAR,c.x,c.y);

}

index++;

}

}

//设置苹果的图片

privatevoidupdateApples(){

for(Coordinate c:mAppleList){

setTile(YELLOW_STAR,c.x,c.y);

}

}

private long mLastMove;

public void update(){

//只有在运行中才会有数据更新

if(mMode==RUNNING){

long now =System.currentTimeMillis();

//等待mMoveDelay时间,游戏自动更新

if(now - mLastMove >mMoveDelay){

clearTiles();

updateWalls();

updateSnake();

updateApples();

mLastMove=now;

}

mRedrawHandler.sleep(mMoveDelay);

}

}

private void updateWalls(){

//设置屏幕上下两边的方格图片

for(int x=0;x

setTile(GREEN_STAR, x,0);

setTile(GREEN_STAR, x,mYTileCount -1);

}

//设置屏幕左右两边的方格图片

for(int y=1;y

setTile(GREEN_STAR, 0,y);

setTile(GREEN_STAR, mXTileCount -1,y);

}

}

private void updateSnake(){

boolean growSnake =false;

Coordinate head =mSnakeTrail.get(0);

Coordinate newHead =new Coordinate(1,1);

mDirection =mNextDirection;

//获取下一步的坐标

switch(mDirection){

case EAST:{

newHead =new Coordinate(head.x+1,head.y);

break;

}

case WEST:{

newHead =new Coordinate(head.x-1,head.y);

break;

}

case NORTH:{

newHead=new Coordinate(head.x,head.y-1);

break;

}

case SOUTH:{

newHead=new Coordinate(head.x,head.y+1);

break;

}

}

//是否碰到“墙壁”

if((newHead.x<1)||(newHead.y<1)||(newHead.x>mXTileCount-2)

||(newHead.y>mYTileCount-2)){

setMode(LOSE);

return;

}

int snakelength =mSnakeTrail.size();

//碰到自己

for(int snakeindex=0;snakeindex

Coordinate c=mSnakeTrail.get(snakeindex);

if(c.equals(newHead)){

setMode(LOSE);

return;

}

}

int applecount=mAppleList.size();

//吃到苹果

for(int appleindex =0;appleindex

Coordinate c=mAppleList.get(appleindex);

if(c.equals(newHead)){

mAppleList.remove(c);

addRandomApple();

mScore++;

mMoveDelay *=0.9;

growSnake =true;

}

}

mSnakeTrail.add(0,newHead);

if(!growSnake){

mSnakeTrail.remove(mSnakeTrail.size()-1);

}

//设置贪吃蛇的图片,第一个方格和其他方格不一样

int index=0;

for(Coordinate c:mSnakeTrail){

if(index==0){

setTile(YELLOW_STAR, c.x,c.y);

}else{

setTile(RED_STAR,c.x,c.y);

}

index++;

}

}

//设置苹果的图片

private void updateApples(){

for(Coordinate c:mAppleList){

setTile(YELLOW_STAR,c.x,c.y);

}

}

上面update()函数中调用了mRedrawHandler.sleep(mMoveDelay);

mRedrawHandler对象是RedrawHandle的实例,mRedrawHandler继承Handler类

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

privateRefreshHandler mRedrawHandler=newRefreshHandler();

classRefreshHandlerextendsHandler{

@Override

publicvoidhandleMessage(Message msg){

SnakeViewExm.this.update();

SnakeViewExm.this.invalidate();//重新调用onDraw()

}

publicvoidsleep(longdelayMillis){

this.removeMessages(0);

sendMessageDelayed(obtainMessage(0),delayMillis);//调用sendMessageDelayed函数,线程等待delayMillis时间后发送信息,发送信息会调用handleMessage(msg)函数

}

}

private RefreshHandler mRedrawHandler=new RefreshHandler();

class RefreshHandler extends Handler{

@Override

public void handleMessage(Message msg){

SnakeViewExm.this.update();

SnakeViewExm.this.invalidate(); //重新调用onDraw()

}

public void sleep(long delayMillis){

this.removeMessages(0);

sendMessageDelayed(obtainMessage(0),delayMillis);//调用sendMessageDelayed函数,线程等待delayMillis时间后发送信息,发送信息会调用handleMessage(msg)函数

}

}

到这里键盘事件响应就完成了,之前还有一个setMode(int)设置状态的函数没说,接下了就说它

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

privateTextView mStatusText;//textView用来显示不同状态的信息

//可以通过Activity调用setTextView来实例化,这样就可以通过layout来配置textView的位置

publicvoidsetTextView(TextView newView){

mStatusText=newView;

}

publicvoidsetMode(intnewMode){

intoldMode = mMode;

mMode =newMode;

if(newMode==RUNNING & oldMode!=RUNNING){

mStatusText.setVisibility(View.INVISIBLE);//不显示TextView提示信息

update();

return;

}

Resources res=getContext().getResources();

CharSequence str="";

if(newMode ==PAUSE){

str=res.getText(R.string.mode_pause);//从资源文件string.xml中获取值

}

if(newMode==READY){

str=res.getText(R.string.mode_ready);

}

if(newMode==LOSE){

str=res.getString(R.string.mode_lose_prefix)+mScore

+res.getString(R.string.mode_lose_suffix);

}

mStatusText.setText(str);

mStatusText.setVisibility(View.VISIBLE);//显示TextView提示信息

}

private TextView mStatusText; //textView用来显示不同状态的信息

//可以通过Activity调用setTextView来实例化,这样就可以通过layout来配置textView的位置

public void setTextView(TextView newView){

mStatusText=newView;

}

public void setMode(int newMode){

int oldMode = mMode;

mMode =newMode;

if(newMode==RUNNING & oldMode!=RUNNING){

mStatusText.setVisibility(View.INVISIBLE);//不显示TextView提示信息

update();

return;

}

Resources res=getContext().getResources();

CharSequence str="";

if(newMode ==PAUSE){

str=res.getText(R.string.mode_pause);//从资源文件string.xml中获取值

}

if(newMode==READY){

str=res.getText(R.string.mode_ready);

}

if(newMode==LOSE){

str=res.getString(R.string.mode_lose_prefix)+mScore

+res.getString(R.string.mode_lose_suffix);

}

mStatusText.setText(str);

mStatusText.setVisibility(View.VISIBLE);//显示TextView提示信息

}

string.xml的配置可以在google sdk

自带的sample/snake里面找到,这里就不贴出来了;现在SnakeView功能基本齐全了,下面来看看Activity类

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

publicclassSnakeextendsActivity {

privateSnakeView mSnakeView;

privatestaticString ICICLE_KEY ="snake-view";

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// No Title bar

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.snake_layout);//layout文件自己在sdk sample/snake中找

mSnakeView = (SnakeView) findViewById(R.id.snake);

mSnakeView.setTextView((TextView) findViewById(R.id.text));

if(savedInstanceState ==null) {

// We were just launched -- set up a new game

mSnakeView.setMode(SnakeView.READY);

}else{

// We are being restored

Bundle map = savedInstanceState.getBundle(ICICLE_KEY);

if(map !=null) {

mSnakeView.restoreState(map);

}else{

mSnakeView.setMode(SnakeView.PAUSE);

}

}

}

@Override

protectedvoidonPause() {

super.onPause();

// Pause the game along with the activity

mSnakeView.setMode(SnakeView.PAUSE);

}

@Override

publicvoidonSaveInstanceState(Bundle outState) {

//Store the game state

outState.putBundle(ICICLE_KEY, mSnakeView.saveState());

}

}

public class Snake extends Activity {

private SnakeView mSnakeView;

private static String ICICLE_KEY = "snake-view";

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// No Title bar

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.snake_layout);//layout文件自己在sdk sample/snake中找

mSnakeView = (SnakeView) findViewById(R.id.snake);

mSnakeView.setTextView((TextView) findViewById(R.id.text));

if (savedInstanceState == null) {

// We were just launched -- set up a new game

mSnakeView.setMode(SnakeView.READY);

} else {

// We are being restored

Bundle map = savedInstanceState.getBundle(ICICLE_KEY);

if (map != null) {

mSnakeView.restoreState(map);

} else {

mSnakeView.setMode(SnakeView.PAUSE);

}

}

}

@Override

protected void onPause() {

super.onPause();

// Pause the game along with the activity

mSnakeView.setMode(SnakeView.PAUSE);

}

@Override

public void onSaveInstanceState(Bundle outState) {

//Store the game state

outState.putBundle(ICICLE_KEY, mSnakeView.saveState());

}

}

Snake类很简单,只是重写了onCreate、onPause和onSaveInstanceState函数,

其中onSaveInstanceState函数会在activity被杀掉之前被调用。上面调用了SnakeView中的saveState()函数返回游戏数据,和restoreState()函数还原保持的数据状态。

下面来看看SnakeView里面这两个函数的代码

Java代码 a4c26d1e5885305701be709a3d33442f.png a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

//保存数据

publicBundle saveState(){

Bundle map =newBundle();

map.putIntArray("mAppleList",coordArrayListToArray(mAppleList));//bundle只能存基本类型,所有要把ArrayList转换为int[],调用coordArrayListToArray进行转换

map.putInt("mDirection",Integer.valueOf(mDirection));

map.putInt("mNextDirection", Integer.valueOf(mNextDirection));

map.putLong("mMoveDelay", Long.valueOf(mMoveDelay));

map.putLong("mScore", Long.valueOf(mScore));

map.putIntArray("mSnakeTrail", coordArrayListToArray(mSnakeTrail));

returnmap;

}

privateint[] coordArrayListToArray(ArrayList cvec){

intcount =cvec.size();

int[] array =newint[count*2];

for(intindex=0; index

Coordinate c=cvec.get(index);

array[2*index]=c.x;

array[2*index+1]=c.y;

}

returnarray;

}

//还原数据

publicvoidrestoreState(Bundle icicle){

setMode(PAUSE);

mAppleList =coordArrayToArrayList(icicle.getIntArray("mAppleList"));

mDirection=icicle.getInt("mDirection");

mNextDirection=icicle.getInt("mNextDirection");

mMoveDelay=icicle.getLong("mMoveDelay");

mScore=icicle.getLong("mScore");

mSnakeTrail=coordArrayToArrayList(icicle.getIntArray("mSnakeTrail"));

}

privateArrayList coordArrayToArrayList(int[] rawArray){

ArrayList coordArrayList =newArrayList();

intcoordCount =rawArray.length;

for(intindex=0;index

Coordinate c=newCoordinate(rawArray[index],rawArray[index+1]);

coordArrayList.add(c);

}

returncoordArrayList;

}

//保存数据

public Bundle saveState(){

Bundle map =new Bundle();

map.putIntArray("mAppleList",coordArrayListToArray(mAppleList)); //bundle只能存基本类型,所有要把ArrayList转换为int[],调用coordArrayListToArray进行转换

map.putInt("mDirection",Integer.valueOf(mDirection));

map.putInt("mNextDirection", Integer.valueOf(mNextDirection));

map.putLong("mMoveDelay", Long.valueOf(mMoveDelay));

map.putLong("mScore", Long.valueOf(mScore));

map.putIntArray("mSnakeTrail", coordArrayListToArray(mSnakeTrail));

return map;

}

private int[] coordArrayListToArray(ArrayList cvec){

int count =cvec.size();

int[] array =new int[count*2];

for(int index=0; index

Coordinate c=cvec.get(index);

array[2*index]=c.x;

array[2*index+1]=c.y;

}

return array;

}

//还原数据

public void restoreState(Bundle icicle){

setMode(PAUSE);

mAppleList =coordArrayToArrayList(icicle.getIntArray("mAppleList"));

mDirection=icicle.getInt("mDirection");

mNextDirection=icicle.getInt("mNextDirection");

mMoveDelay=icicle.getLong("mMoveDelay");

mScore=icicle.getLong("mScore");

mSnakeTrail=coordArrayToArrayList(icicle.getIntArray("mSnakeTrail"));

}

private ArrayList coordArrayToArrayList(int[] rawArray){

ArrayList coordArrayList =new ArrayList();

int coordCount =rawArray.length;

for(int index=0;index

Coordinate c=new Coordinate(rawArray[index],rawArray[index+1]);

coordArrayList.add(c);

}

return coordArrayList;

}

到这里所有的类都讲解完,AndroidManifest.xml文件我这就不说了,请大家自己去看。这个游戏其实还有很多不完善的,比如说这个游戏并不支持暂停,只能玩到死,还有其他很多可以改善的地方,(我很懒的~~这里就不写了)大家如果有兴趣可以自己动手改下

这篇关于android如何编写一个贪食蛇游戏,贪食蛇游戏android详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/154873

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo