贪吃蛇是一款很经典的游戏,这些经典游戏给我们的童年增加了不少乐趣,今天开始我们来一步一步的在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); } }布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <com.example.crazysnake.MySnake android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>运行效果:
我们在界面上绘制了一个小方块,这个就是我们完成贪吃蛇的基础(就像我们要盖一座大楼的砖一样重要)
三、画一条彩蛇
先创建一个方块对象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<Box> boxs = new ArrayList<Box>(); 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<boxs.size(); i++){ paint.setColor(colors[i % colors.length]); rect.set(boxs.get(i).getX(), boxs.get(i).getY(), boxs.get(i).getX() + boxSize, boxSize); canvas.drawRect(rect, paint); } } }
四、让这条彩蛇移动
重写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<boxs.size(); i++){ box = boxs.get(i); box.setX(box.getX() + bs); } }else{ for(int i=0; i<boxs.size(); i++){ box = boxs.get(i); box.setY(box.getY() + bs); } } invalidate(); }
上面代码中我们没有控制边界,需要添加判断边界条件的代码。
五、让蛇自动跑,我们来控制它
启动一个线程了让蛇自动跑
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<Box> boxs = new ArrayList<Box>(); 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<boxs.size(); i++){ box = boxs.get(i); box.setX(box.getX() - boxSize); } break; case RIGHT: for(int i=0; i<boxs.size(); i++){ box = boxs.get(i); box.setX(box.getX() + boxSize); } break; case TOP: break; case BOTTOM: break; } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for(int i=0; i<boxs.size(); i++){ paint.setColor(colors[i % colors.length]); rect.set(boxs.get(i).getX(), boxs.get(i).getY(), boxs.get(i).getX() + boxSize, boxSize); canvas.drawRect(rect, paint); } } }
今天先到这里吧,明天继续......^-^