android中的贪吃蛇源码


package com.dc.app;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;

import com.dc.view.SnakeView;

public class SnakeActivity extends Activity {
private static final String tag = "SnakeActivity";
SnakeView view;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// DisplayMetrics dm = new DisplayMetrics();
// this.getWindowManager().getDefaultDisplay().getMetrics(dm);
// int screenWidth = dm.widthPixels;
// int screenHeight = dm.heightPixels;
// Log.w(tag, "screenWidth=" + screenWidth);//320
// Log.w(tag, "screenHeight=" + screenHeight);//480
view = new SnakeView(this);
setContentView(view);
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
view.onKeyDown(keyCode, event);
return super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
view.onKeyUp(keyCode, event);
return super.onKeyUp(keyCode, event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
view.onTouchEvent(event);
return super.onTouchEvent(event);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
menu.add(0, Menu.FIRST+2, 0, "继续").setShortcut('3', 'c');//设置快捷键
menu.add(0, Menu.FIRST, 0, "重新开始").setShortcut('1', 'p');//设置快捷键
menu.add(0, Menu.FIRST+1, 0, "关于...").setShortcut('2', 'a');//设置快捷键
return super.onCreateOptionsMenu(menu);
}
public boolean onPrepareOptionsMenu(Menu menu) {
view.isPaused=true;//显示菜单时暂停游戏
return super.onPrepareOptionsMenu(menu);
}

@Override
public void onOptionsMenuClosed(Menu menu) {
// TODO Auto-generated method stub
view.isPaused=false;//关闭菜单时继续游戏
super.onOptionsMenuClosed(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case Menu.FIRST:
if(view!=null){
view.setFocusable(true);
view.init();
}
break;
case Menu.FIRST+1:
Dialog aboutDialog=new AlertDialog.Builder(this)
.setTitle("贪吃蛇")
.setMessage("贪吃蛇V1.0")
.setCancelable(true)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.cancel();
}
})
.setNegativeButton("访问首页", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.cancel();
Uri uri=Uri.parse("http://www.iteye.com");
Intent intent=new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);
}
})
.create();
aboutDialog.setCanceledOnTouchOutside(true);
aboutDialog.show();
break;
case Menu.FIRST+2:
view.isPaused=false;
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}

}

这里使用了继承了View作为“画布”,实际是个控件;最好继承SurfaceView。看情况啦!

package com.dc.view;

import java.util.Random;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

public class SnakeView extends View implements Runnable{

private static final String tag="SnakeView";
public boolean isPaused=false;
public boolean isRunning=true;
private int[][] snake=new int[100][2];//100节点总数,第二维下标0代表x坐标,1代表y坐标
private int snakeNum;//已经使用的节点数
private int direction;
private final int direction_up=0;
private final int direction_down=1;
private final int direction_left=2;
private final int direction_right=3;
private int width=320,height=480;//view的宽高,不是全屏320*480
private final int SNAKEWIDTH=5;//单节蛇体宽
private int SLEEP_TIME;
private int foodX,foodY;//食物坐标
private boolean b=true;//控制食物闪烁
private Random r;
private Thread t;
private Paint paint;
public SnakeView(Context context) {
super(context);
// TODO Auto-generated constructor stub
r=new Random();
paint=new Paint();
init();
t=new Thread(this);
t.start();
}

public void init(){
snakeNum=12;
for(int i=0;i<snakeNum;i++){
snake[i][0]=100-SNAKEWIDTH*i;
snake[i][1]=100;
}
direction=direction_right;
generateFood();
SLEEP_TIME=200;
b=true;
isRunning=true;
isPaused=false;

}
@Override
public void run() {
// TODO Auto-generated method stub
while (isRunning) {
long start=System.currentTimeMillis();
if(!isPaused){
if(isGameOver()){
isPaused=true;
}else{
eatFood();
move(direction);
b=!b;
}
}

postInvalidate();//相当于repaint
long end=System.currentTimeMillis();
if(end-start<SLEEP_TIME){
try {
Thread.sleep(SLEEP_TIME-(end-start));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
width=getWidth();
height=getHeight();
Log.w(tag, "width="+width);
Log.w(tag, "height="+height);
width=canvas.getWidth();
height=canvas.getHeight();
Log.w(tag, "width=="+width);
Log.w(tag, "height=="+height);

canvas.drawColor(0xffffff);

paint.setColor(Color.BLUE);
paint.setAntiAlias(true);
paint.setStyle(Style.FILL);
for(int i=0;i<snakeNum;i++){
canvas.drawRect(snake[i][0], snake[i][1], snake[i][0]+SNAKEWIDTH, snake[i][1]+SNAKEWIDTH, paint);
}
paint.setColor(Color.WHITE);
if(b){
canvas.drawRect(foodX,foodY,foodX+SNAKEWIDTH,foodY+SNAKEWIDTH,paint);
}

}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_DOWN:
if(direction!=direction_up)
direction=direction_down;
break;
case KeyEvent.KEYCODE_DPAD_UP:
if(direction!=direction_down)
direction=direction_up;
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
if(direction!=direction_right)
direction=direction_left;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if(direction!=direction_left)
direction=direction_right;
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
isPaused=!isPaused;
break;

default:
break;
}
return super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
return super.onKeyUp(keyCode, event);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onTouchEvent(event);
}

private void eatFood(){
if(snake[0][0]==foodX&&snake[0][1]==foodY){
snakeNum++;
generateFood();
}
}

private void generateFood(){
while(true){
//确保在屏幕内产生食物
foodX=Math.abs(r.nextInt()%(width-SNAKEWIDTH+1))/SNAKEWIDTH*SNAKEWIDTH;
foodY=Math.abs(r.nextInt()%(height-SNAKEWIDTH+1))/SNAKEWIDTH*SNAKEWIDTH;
boolean b=true;
for(int i=0;i<snakeNum;i++){//确保不在蛇体上产生食物
if(foodX==snake[i][0]&&foodY==snake[i][1]){
b=false;
break;
}
}
if(b){
break;
}
}
}

private void move(int direction){
for(int i=snakeNum-1;i>0;i--){
snake[i][0]=snake[i-1][0];
snake[i][1]=snake[i-1][1];
}
switch (direction) {
case direction_up:
snake[0][1]=snake[0][1]-SNAKEWIDTH;
break;
case direction_down:
snake[0][1]=snake[0][1]+SNAKEWIDTH;
break;
case direction_left:
snake[0][0]=snake[0][0]-SNAKEWIDTH;
break;
case direction_right:
snake[0][0]=snake[0][0]+SNAKEWIDTH;
break;
default:
break;
}
}

private boolean isGameOver(){//越界判断
if(snake[0][0]<0||snake[0][0]>width-SNAKEWIDTH||snake[0][1]<0||snake[0][1]>height-SNAKEWIDTH){
return true;
}
for(int i=4;i<snakeNum;i++){//自身碰撞判断
if(snake[0][0]==snake[i][0]&&snake[0][1]==snake[i][1]){
return true;
}
}
return false;
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值