android 简单实现贪吃蛇源码
一:实现原理
通过自定义view,然后根据小蛇的移动速度来不停的更新,绘制界面。
三:核心实现
1:小蛇的位置是由很多点来绘制完成的,里面的点全部装在里面ArrayList里面。
”private ArrayList
”
snakePoint 的代码如下
class snakePoint {
/**
* 小蛇某个点x的位置
*/
int x;
/**
* 小蛇某个y的位置
*/
int y;
snakePoint(int x, int y) {
this.x = x;
this.y = y;
}
}
2:在ondraw里面绘制出来这些点,区别蛇头和蛇尾
for (int i = 0; i < SpointList.size(); i++) {
snakePoint sp = SpointList.get(i);
Rect rect_showPosition = new Rect(sp.x - snakeSize, sp.y - snakeSize, sp.x + snakeSize, sp.y + snakeSize);
if(i==0){//蛇头
canvas.drawBitmap(snake_head, rect, rect_showPosition, paint);
}else{ //蛇尾
canvas.drawBitmap(snake_body, rect, rect_showPosition, paint);
}
}
3:食物的绘制,通过随机的方法生成一个小与手机屏幕宽高的点,通过ondraw在绘制出来。
/***
* 随机添加食物
*/
private void initFoot() {
footPointList.clear();
Random random = new Random();
int fWide = GetFoodPosition(random.nextInt(ScreenWide));
int fHeight = GetFoodPosition(random.nextInt(ScreenHeight));
snakePoint sPoint = new snakePoint(fWide, fHeight);
footPointList.add(sPoint);
}
4:当小蛇移动的时候其实就是删除SpointList里面的最后一个点,在添加一个最新的点在SpointList为0 的位置,最新的位置依据小蛇移动的方向来做判断。然后在重新绘制就会给人感觉小蛇移动了一步的感觉。
当小蛇移动的那个点与食物的点坐标相同,即判断已经吃掉食物。这个时候的操作和小蛇移动的时候类似,但区别在于小蛇的数组SpointList不在删除最后一个,这样小蛇的长度就会增加。然后在重新绘制食物。
private void StartGame() {
int Rundistance = snakeSize * 2;//跑动的距离
switch (nowDirection) {
case 0://东
if (!isLose(Rundistance)) {//判断时候吃掉了食物,撞墙等
snakePoint spoint = new snakePoint(SpointList.get(0).x + Rundistance, SpointList.get(0).y);
SpointList.add(0, spoint);
} else {
return;
}
break;
case 1://南
if (!isLose(Rundistance)) {
snakePoint spoint_height = new snakePoint(SpointList.get(0).x, SpointList.get(0).y + Rundistance);
SpointList.add(0, spoint_height);
} else {
return;
}
break;
case 2://西
if (!isLose(Rundistance)) {
snakePoint spoint_weath = new snakePoint(SpointList.get(0).x - Rundistance, SpointList.get(0).y);
SpointList.add(0, spoint_weath);
} else {
return;
}
break;
case 3://北
if (!isLose(Rundistance)) {
snakePoint spoint_north = new snakePoint(SpointList.get(0).x, SpointList.get(0).y - Rundistance);
SpointList.add(0, spoint_north);
} else {
return;
}
break;
}
invalidate();
mRedrawHandler.sleep(SnakeSpeedDelay);
5:游戏结束,当小蛇撞墙或者碰着自己的时候就会结束游戏,小蛇碰着自己和小蛇吃食物的时候类似,判断前进的那个点是否包含在自己本身的SpointList里面,如果在表示小蛇碰撞了自己。至于边界,只需要判断小蛇前进的位置是否超过了手机屏幕的宽高就可以了。
private boolean isLose(int Rundistance) {
int snakeAfterPointx = 0;
int snakeAfterPointy = 0;
snakePoint snakePoint = SpointList.get(0);
snakePoint footpoint = footPointList.get(0);
if (footpoint.x == snakePoint.x && footpoint.y == snakePoint.y) {
//吃掉了食物,需要重新初始化食物;
score++;
double DoubleSnakeSpeedDelay = SnakeSpeedDelay *0.9;
SnakeSpeedDelay = (int) DoubleSnakeSpeedDelay;
initFoot();//重新初始化
} else {
SpointList.remove(SpointList.size() - 1);//移除最后一个
}
switch (nowDirection) {
case 0:
snakeAfterPointx = SpointList.get(0).x + Rundistance;
snakeAfterPointy = SpointList.get(0).y;
if (SpointList.get(0).x + Rundistance >= ScreenWide) {
loseGame();
return true;
}
break;
case 1:
snakeAfterPointx = SpointList.get(0).x;
snakeAfterPointy = SpointList.get(0).y + Rundistance;
if (SpointList.get(0).y + Rundistance >= ScreenHeight) {
loseGame();
return true;
}
break;
case 2:
snakeAfterPointx = SpointList.get(0).x - Rundistance;
snakeAfterPointy = SpointList.get(0).y;
if (SpointList.get(0).x - Rundistance <= 0) {
loseGame();
return true;
}
break;
case 3:
snakeAfterPointx = SpointList.get(0).x;
snakeAfterPointy = SpointList.get(0).y - Rundistance;
if (SpointList.get(0).y - Rundistance <= 0) {
loseGame();
return true;
}
break;
}
snakePoint snakeAfterPoint = new snakePoint(snakeAfterPointx, snakeAfterPointy);
if (snakeStrikeself(snakeAfterPoint)) { //判断是否会自撞
loseGame();
return true;
}
return false;
}
以上简单的基本功能就实现了。