• 是男人就下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);
    		}
    	}
    }

    今天先到这里吧,明天继续......^-^
  • 相关阅读:
    sqlite遇到database is locked问题的完美解决
    Delphi使程序的窗口出现在最前面并激活
    win10 家庭版不支持gpedit.msc的解决办法
    Delphi Record To Stream
    SQL Server 查看CPU情况
    JavaScript 获取 Url 上的参数(QueryString)值
    关于EF分页查询报错(Count must have a non-negative value.)的解决方案
    调用微信退款接口时出现System.Security.Cryptography.CryptographicException: 出现了内部错误 解决办法
    Javascript中“==”与“===”的区别
    IE浏览器各版本的CSS Hack
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6468871.html
Copyright © 2020-2023  润新知