大家好,今天我来给大家带来贪吃蛇的实现思路,这里我是采用二级缓存的策略来实现背景,蛇身和食物的绘制,操作图片实现蛇身的移动.好了见下图:
这就是最后的效果图,其中的笑脸表情是在QQ的安装包中找到的。
1.要搞清楚手势,这里采用的是SimpleOnGestureListener的监听实现类,这里我重写了
SimpleOnGestureListeneronFling()方法,在这里控制蛇身的移动方向
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//确定方向
float x = e2.getX() - e1.getX();
float y = e2.getY() - e1.getY();
if (Math.abs(x) > Math.abs(y)) {
//x方向的手势
if (x > 0) {
right();
} else {
left();
}
} else {
//y轴方向
if (y > 0) {
down();
} else {
up();
}
}
return super.onFling(e1, e2, velocityX, velocityY);
}
//food
class Food {
//食物的坐标位置
private Point mFoodPoint;
private Random mRandom;
public final int size = mSize;
private Bitmap mIcon;
public Food() {
mRandom = new Random();
mFoodPoint = new Point(mRandom.nextInt(mBg.getWidth() - size), mRandom.nextInt(mBg.getHeight() - size));
mIcon = listBiaoqing.get(myRandom.nextInt(listBiaoqing.size()));
}
public void changeFood() {
mFoodPoint.setX(mRandom.nextInt(mBg.getWidth() - size));
mFoodPoint.setY(mRandom.nextInt(mBg.getHeight() - size));
mIcon = listBiaoqing.get(myRandom.nextInt(listBiaoqing.size()));
}
//绘制食物
public void drawFoodPoint() {
mCanvas.drawBitmap(mIcon, mFood.mFoodPoint.getX(), mFood.mFoodPoint.getY(), mPaint);
}
}
//user
class User {
private LinkedList<Point> mUserList;
private LinkedList<Bitmap> mUserIcon;
public User() {
mUserList = new LinkedList<>();
mUserIcon = new LinkedList<>();
Bitmap b = listBiaoqing.get(myRandom.nextInt(listBiaoqing.size()));
Point point = new Point(mSize, mSize);
mUserList.addFirst(point);
mUserIcon.addFirst(b);
}
//绘制蛇身
public void drawUserPoint() {
for (int i = 0; i < mUserList.size(); i++) {
Bitmap bb = Bitmap.createScaledBitmap(mUserIcon.get(i), mUserIcon.get(i).getWidth(), mUserIcon.get(i).getHeight(), true);
Point p = mUserList.get(i);
mCanvas.drawBitmap(bb, p.getX(), p.getY(), mPaint);
}
}
public void reSet() {
Bitmap b = listBiaoqing.get(myRandom.nextInt(listBiaoqing.size()));
Point point = new Point(mSize, mSize);
mUserList.addFirst(point);
mUserIcon.addFirst(b);
}
}
3.让蛇身移动起来
private void move() {
Point first = mUser.mUserList.getFirst();
Point last = mUser.mUserList.getLast();
switch (mState) {
case UP:
last.setX(first.getX());
last.setY(first.getY() - mSize);
break;
case DOWN:
last.setX(first.getX());
last.setY(first.getY() + mSize);
break;
case LEFT:
last.setX(first.getX() - mSize);
last.setY(first.getY());
break;
case RIGHT:
last.setX(first.getX() + mSize);
last.setY(first.getY());
break;
}
mUser.mUserList.addFirst(last);
mUser.mUserList.removeLast();
}
4.吃掉食物的检查
public void checkEat() {
Point user = mUser.mUserList.getFirst();
float x = Math.abs(user.getX() - mFood.mFoodPoint.getX());
float y = Math.abs(user.getY() - mFood.mFoodPoint.getY());
if (x <= mSize && x >= 0) {
if (y <= mSize && y >= 0) {
//吃了
mUser.mUserIcon.addLast(listBiaoqing.get(myRandom.nextInt(listBiaoqing.size())));
Point p = mUser.mUserList.getLast();
Point now = new Point(p.getX(), p.getY());
switch (mState) {
case UP:
now.setX(p.getX());
now.setY(p.getY() + mSize);
break;
case DOWN:
now.setX(p.getX());
now.setY(p.getY() - mSize);
break;
case LEFT:
now.setX(p.getX() + mSize);
now.setY(p.getY());
break;
case RIGHT:
now.setX(p.getX());
now.setY(p.getY() - mSize);
break;
}
mUser.mUserList.addLast(now);
//改变事物
mFood.changeFood();
}
}
}
5.碰撞检查
public boolean check() {
//是否撞到墙
Point p = mUser.mUserList.getFirst();
if (p.getX() < 0 || p.getX() > mBg.getWidth() - mSize) {
//撞墙
return true;
}
if (p.getY() < 0 || p.getY() > mBg.getHeight() - mSize) {
//撞墙
return true;
}
//是否被自己撞到了
if (mUser.mUserList.size() < 3) {
return false;
}
for (int i = 2; i < mUser.mUserList.size(); i++) {
Point point = mUser.mUserList.get(i);
float x = Math.abs(point.getX() - p.getX());
float y = Math.abs(point.getY() - p.getY());
if (x < mSize) {
if (y < mSize) {
return true;
}
}
}
return false;
}
好了,就是这几个比较重要的步骤,通过Canvas,在BitMap上绘制图形,通过不断的绘制BitMap来让蛇身动起来,最后通过SurfaceView的画布将图片绘制到View中,这样复杂的绘制工作交给图片了,减轻了View的负担,更加高效。
源码,请见https://github.com/yzzAndroid/Snake。