是男人就下100层【第四层】——Crazy贪吃蛇(1)

贪吃蛇是一款很经典的游戏,这些经典游戏给我们的童年增加了不少乐趣,今天开始我们来一步一步的在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);
		}
	}
}

今天先到这里吧,明天继续......^-^

转载于:https://www.cnblogs.com/lanzhi/p/6468871.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值