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

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

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

时间: 2024-10-05 09:47:23

是男人就下100层【第四层】——Crazy贪吃蛇(1)的相关文章

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

在上一篇<是男人就下100层[第四层]--Crazy贪吃蛇(1)>中我们让贪吃蛇移动了起来,接下来我们来实现让贪吃蛇可以绕着手机屏幕边线移动并且可以改变方向 一.添加状态并修改代码 首先我们来用另外一种方式实现上一版本中的刷新界面,在Crazy贪吃蛇(1)中我们自定义了一个线程每隔1s钟刷新界面,在线程中我们使用了postInvalidate()方法通知主线程重绘界面,我们打开View的源代码看看到底是如何通知主线程的,原代码如下: public void postInvalidate(int

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

上一篇<是男人就下100层[第四层]--Crazy贪吃蛇(2)>实现了贪吃蛇绕着屏幕四周移动,这一篇我们来完成贪吃蛇的所有功能. 一.随机产生苹果 private void addAppleBox(){ int randomX = random.nextInt(xMaxBoxCount); int randomY = random.nextInt(yMaxBoxCount); for(int i=0; i<boxs.size(); i++){ if(boxs.get(i).getX()

是男人就下100层【第五层】——2048游戏

前言: 在"阳光小强"的实战系列博文<是男人就下100层>的上一层我们一起从零开始完成了我们自己的贪吃蛇游戏--CrazySnake,可能很多朋友还不过瘾,那么我们今天就来玩一玩最近一直比较火的2048游戏,让大家再过一把瘾.由于"阳光小强"目前并没有从事Android的游戏开发工作,所以这些游戏的实现并不需要很专业的游戏开发知识,如果你有Android的基础就可以一起来参与进来共同完成这个游戏.有些朋友可能就会说"这些小游戏,会不会有点简单,

是男人就下100层【第五层】——2048游戏从源码到发布市场

上一篇<是男人就下100层[第五层]--换肤版2048游戏>中阳光小强对2048游戏用自己的方式进行了实现,并分享了核心源码,这一篇阳光小强打算将该项目的所有源代码公开并结合这个实例在这篇文章中介绍一下如何添加广告和实现分享功能. 最终运行效果如下(更多运行效果请看<是男人就下100层[第五层]--换肤版2048游戏>): 一.如何实现换肤 换肤的思路其实很简单,在ActionBar中添加菜单,当用户选择某一个皮肤后就将当前的皮肤状态修改并保存到SharedPreference中,

超多经典 canvas 实例,动态离子背景、移动炫彩小球、贪吃蛇、坦克大战、是男人就下100层、心形文字等等等

超多经典 canvas 实例 普及:<canvas> 元素用于在网页上绘制图形.这是一个图形容器,您可以控制其每一像素,必须使用脚本来绘制图形. 注意:IE 8 以及更早的版本不支持 <canvas> 元素. 贴士:全部例子都分享在我的 GayHub - https://github.com/bxm0927/canvas-special 尤雨溪个人主页炫彩三角纽带效果,点击还可变换 GitHub源码 . Demo演示 知乎登录注册页动态离子背景效果 GitHub源码 . Demo演

【编程马拉松】【026-是男人就下100层】

[编程马拉松算法目录] [026-是男人就下100层][工程下载>>>] 1 题目描述 相信大家都听说过"是男人就下100层"系列游戏,游戏中包括多个长度和高度各不相同的平台,地面是最低的平台,高度为零,长度无限. 一个男人在开始的时候从高于所有平台的某处开始下落,它的下落速度始终为1米/秒.当他落到某个平台上时,游戏者选择让他向左或向右跑,跑动的速度也是1米/秒.当他跑到平台的边缘时会继续下落.要求每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束. 请帮忙

HTML5游戏开发_是男人就下100层

项目流程 市场调研(可行性分析)--> 可行性报告书  需求分析师.客户经理 需求分析--> 需求说明书  项目经理.需求分析师 概要设计--> 概要设计说明书(ER图, UML)  项目经理.项目组长 详细设计--> 详细设计说明书(流程图) 数据库建好.项目周期表(甘特图) office project visio 项目组长.开发人员 编码 --> 测试(单元测试) 提交svn 测试用例  开发人员 测试 --> 集成测试.黑白盒测试.冒烟测试  测试人员 --&g

是男人就下100层【第六层】——高仿豆瓣客户端

前一段时间阳光小强安装了一个豆瓣客户端,第一次打开就被这种界面风格吸引了,今天早上起来在打开豆瓣听音乐的时候,突然产生一个念头,来试着实现一下这种效果,打开客户端分析了一下发现其实这种效果的实现并不是想象中的那么难,下面我先分析一下这种效果的实现思路,然后一步步解释实现的过程,希望大家能提出意见和建议,一起交流学习. 先给大家展示一下我的成果吧: 其实豆瓣客户端的界面上还有其他的文字和菜单,但是这两个的实现效果和其他几个类似,可以作为代表,所以就不绘制那么多组件了. 转载请说明出处:http:/

是男人就下100层【第三层】——高仿交通银行手机客户端界面

http://blog.csdn.net/seiyagoo/article/details/46554133 http://blog.csdn.net/seiyagoo/article/details/46554135 http://blog.csdn.net/seiyagoo/article/details/46554141 http://blog.csdn.net/seiyagoo/article/details/46554151 http://blog.csdn.net/seiyagoo/