贪吃蛇是一款非常经典的游戏,这些经典游戏给我们的童年添加了不少乐趣,今天開始我们来一步一步的在Android设备上实现一款贪吃蛇游戏,我也是第一次写这个游戏,有可能会写错,或者走弯路,可是终于希望能有一个好的结果,接下来我们一起来一步步的摸着石头开发吧。

一、建立一个project

二、自己定义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)的更多相关文章

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

    在上一篇<是男人就下100层[第四层]--Crazy贪吃蛇(1)>中我们让贪吃蛇移动了起来,接下来我们来实现让贪吃蛇能够绕着手机屏幕边线移动而且能够改变方向 一.加入状态并改动代码 首先我 ...

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

    上一篇<是男人就下100层[第四层]--Crazy贪吃蛇(2)>实现了贪吃蛇绕着屏幕四周移动,这一篇我们来完成贪吃蛇的所有功能. 一.随机产生苹果 private void addAppl ...

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

    超多经典 canvas 实例 普及:<canvas> 元素用于在网页上绘制图形.这是一个图形容器,您可以控制其每一像素,必须使用脚本来绘制图形. 注意:IE 8 以及更早的版本不支持 &l ...

  4. Unity经典游戏教程之:是男人就下100层

    版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...

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

    项目流程 市场调研(可行性分析)--> 可行性报告书  需求分析师.客户经理 需求分析--> 需求说明书  项目经理.需求分析师 概要设计--> 概要设计说明书(ER图, UML)  ...

  6. Cocos2d-x 版本小游戏 《是男人就下100层》 项目开源

    这个是很久就开始动手写的一个小游戏了,直到最近才把它收尾了,拖拖拉拉的毛病总是很难改啊. 项目是基于 cocos2d-x v2.2 版本 ,目前只编译到了 Win8 平台上,并且已经上传到了商店,支持 ...

  7. 『HTML5挑战经典』是英雄就下100层-开源讲座(二)危险!英雄

    本篇为<『HTML5挑战经典』是英雄就下100层-开源讲座>第二篇,需要用到开源引擎lufylegend,可以到这里下载: 下载地址:http://lufylegend.googlecod ...

  8. 『HTML5挑战经典』是英雄就下100层-开源讲座(一)从天而降的英雄

    是英雄就下100层是一款经典的手机小游戏,以前是在诺基亚手机上十分有名.今天我们就用HTML5和lufylegend一步步地实现它. 一,准备工作 首先,你需要下载lufylegend,下载地址如下: ...

  9. gdufe1538-是男人就上100层-(三维bfs)

    Problem Description: 桐老爷和UGO终于来到了名为“是男人就上一百层的塔”的下面,听说大祭司在第100层沉睡.为了题目需要,我把这个塔的层数随机打乱,层数的话大家就忘了前面的100 ...

随机推荐

  1. MysqL的root用户不允许远程连接

    原文:MysqL的root用户不允许远程连接 今天程序报了异常:java.sql.SQLException: Access denied for user 'root'@'RJB-Z' (using ...

  2. H.265/HEVC Codec 编解码 (MP4 和 TS)

    1. H.265/HEVC 播放器 1) VLC media player 2.1.3 (眼下不支持H.265 TS播放) 2)ffmpeg中的ffplay (如:ffplay  hevc.ts) 3 ...

  3. bsh for android : 北京

    beanshell : bjtime.bsh source("/sdcard/com.googlecode.bshforandroid/extras/bsh/android.bsh" ...

  4. Java 新特性(3) - JDK7 新特性

    http://www.ibm.com/developerworks/cn/java/j-lo-jdk7-1/ JSR292:支持动态类型语言(InvokeDynamic) 近 年来越来越多的基于 JV ...

  5. Meld Diff for windows 安装和配置

    Meld Diff for windows 安装和配置 假设你在ubuntu 正在开发中, meld diff 此工具你肯定不会感到陌生. 而且很容易使用. 在网上看 meld for Windows ...

  6. Swift 学习Using Swift mix and match, network: 写rss读者

    有使用第三方库.因此,需要使用mix and match财产. 请指出错误,谢谢! rss 阅读器,非常easy的代码.仅仅是为了学习swift语言而写. 1、BaseViewController.s ...

  7. Android 异步消息处理机制 让你在深入了解 Looper、Handler、Message之间的关系

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 非常多人面试肯定都被问到过,请问And ...

  8. CentOS7 安装kubernetes

    2台机器,1台为Master,1台为Node 修改Host Master为dmaster,Node为dslave 安装K8s and Etcd 在Master机器上安装 yum install etc ...

  9. apache 提示You don't have permission to access /test.php on this server.怎样解决

    原文:apache 提示You don't have permission to access /test.php on this server.怎样解决 关键字: Apache   403  For ...

  10. SVD在推荐系统中的应用

    一.奇异值分解SVD 1.SVD原理 SVD将矩阵分为三个矩阵的乘积,公式: 中间矩阵∑为对角阵,对角元素值为Data矩阵特征值λi,且已经从大到小排序,即使去掉特征值小的那些特征,依然可以很好地重构 ...