贪吃蛇是一款很经典的游戏,这些经典游戏给我们的童年增加了不少乐趣,今天开始我们来一步一步的在Android设备上实现一款贪吃蛇游戏,我也是第一次写这个游戏,有可能会写错,或者走弯路,但是最终希望能有一个好的结果,接下来我们一起来一步步的摸着石头开发吧。
一、建立一个工程
二、自定义View(贪吃蛇界面)
package com.example.crazysnake;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
public class MySnake extends View {
private Paint paint;
private RectF rect;
public MySnake(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
rect = new RectF();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
rect.set(50, 50, 90, 90);
paint.setColor(Color.RED);
canvas.drawRect(rect, paint);
}
}
布局文件
运行效果:
我们在界面上绘制了一个小方块,这个就是我们完成贪吃蛇的基础(就像我们要盖一座大楼的砖一样重要)
三、画一条彩蛇
先创建一个方块对象package com.example.crazysnake;
public class Box {
private int x;
private int y;
public Box(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
绘制一排方块
package com.example.crazysnake;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
public class MySnake extends View {
private Paint paint;
private RectF rect;
private int boxSize = 30;
private List boxs = new ArrayList();
private static final int[] colors = {
Color.RED,
Color.BLUE,
Color.GREEN,
Color.YELLOW
};
public MySnake(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
rect = new RectF();
initData();
}
private void initData(){
Box box;
for(int i=0; i<10; i++){
box = new Box(i*boxSize, 0);
boxs.add(box);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(int i=0; i
四、让这条彩蛇移动
重写onTouchEvent方法
@Override
public boolean onTouchEvent(MotionEvent event) {
System.out.println("onTouch");
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = event.getX();
mDownY = event.getY();
break;
case MotionEvent.ACTION_UP:
float disX = event.getX() - mDownX;
float disY = event.getY() - mDownY;
System.out.println("disX = " + disX);
System.out.println("dixY = " + disY);
if(Math.abs(disX) > Math.abs(disY)){
if(disX > 0){
System.out.println("right");
move(Derectory.RIGHT);
}else{
move(Derectory.LEFT);
}
}else{
if(disY > 0){
}else{
}
}
break;
}
return true;
}
move方法来根据方向移动
private void move(Derectory derectory){
Box box;
int bs = 0;
switch (derectory) {
case LEFT:
case TOP:
bs = - boxSize;
break;
case RIGHT:
case BOTTOM:
bs = boxSize;
break;
}
if(derectory == Derectory.LEFT || derectory == Derectory.RIGHT){
for(int i=0; i
上面代码中我们没有控制边界,需要添加判断边界条件的代码。
五、让蛇自动跑,我们来控制它
启动一个线程了让蛇自动跑
private class SnakeThread extends Thread{
private boolean stoped = false;
@Override
public void run() {
while(!stoped){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
move();
postInvalidate();
}
}
}
全部代码如下:
package com.example.crazysnake;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class MySnake extends View {
private Paint paint;
private RectF rect;
private int boxSize = 30;
private SnakeThread snakeThread;
private List boxs = new ArrayList();
private static final int[] colors = {
Color.RED,
Color.BLUE,
Color.GREEN,
Color.YELLOW
};
private enum Derectory{
LEFT,
RIGHT,
TOP,
BOTTOM;
}
private Derectory currentDerect = Derectory.RIGHT;
public MySnake(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
rect = new RectF();
initData();
startThread();
}
public void startThread(){
if(snakeThread == null){
snakeThread = new SnakeThread();
snakeThread.start();
}
}
private void initData(){
Box box;
for(int i=0; i<10; i++){
box = new Box(i*boxSize, 0);
boxs.add(box);
}
}
private float mDownX;
private float mDownY;
@Override
public boolean onTouchEvent(MotionEvent event) {
System.out.println("onTouch");
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = event.getX();
mDownY = event.getY();
break;
case MotionEvent.ACTION_UP:
float disX = event.getX() - mDownX;
float disY = event.getY() - mDownY;
System.out.println("disX = " + disX);
System.out.println("dixY = " + disY);
if(Math.abs(disX) > Math.abs(disY)){
if(disX > 0){
currentDerect = Derectory.RIGHT;
}else{
currentDerect = Derectory.LEFT;
}
}else{
if(disY > 0){
currentDerect = Derectory.BOTTOM;
}else{
currentDerect = Derectory.TOP;
}
}
break;
}
return true;
}
private class SnakeThread extends Thread{
private boolean stoped = false;
@Override
public void run() {
while(!stoped){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
move();
postInvalidate();
}
}
}
private void move(){
Box box;
if(boxs.get(0).getX() - boxSize < 0) {
currentDerect = Derectory.RIGHT;
}
if(boxs.get(boxs.size() - 1).getX() + 2 * boxSize > getWidth()){
currentDerect = Derectory.LEFT;
}
switch (currentDerect) {
case LEFT:
for(int i=0; i
今天先到这里吧,明天继续......^-^