您的位置:首页 > 移动开发 > Android开发

Snake on a phone——Android开源项目实战,贪吃蛇游戏

2016-07-29 23:56 691 查看

Snake on a phone——Android开源项目实战,贪吃蛇游戏

本文以及后续几篇文章对贪吃蛇开源项目进行源码剖析,以此为切入点对相关知识点进行总结,最后对项目进行扩展,实现可以在手机上操作的游戏,也就是触摸操作的Snake游戏。

https://github.com/lonely917/snake-on-a-phone-fling-version

导入项目

新建项目选择sample工程,有android snake示例项目

通过文章给出的github连接下载最终扩展完成的touch版Snake游戏

项目架构

项目主要文件如下

Snake.java

SnakeView.java

TileView.java

snake_layout.xml

snake是主activity,对应布局snake_layout.xml,其中SnakeView是自定义的游戏主题View,继承自定义的TileView。

整体项目代码不多,唯一的布局文件snake_layout.xml内容如下:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<com.example.android.snake.SnakeView
android:id="@+id/snake"
android:layout_width="match_parent"
android:layout_height="match_parent"
tileSize="24" />

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >

<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:text="@string/snake_layout_text_text"
android:textColor="#ff8888ff"
android:textSize="24sp"
android:visibility="visible" />
</RelativeLayout>
</FrameLayout>


这个很简单,就是加载了一个自定义View,和一个提示性的text,重点就是我们这个snakeview是如何实现的,其中tilesize是自定义view的自定义属性,界面是网格型的,它表示每个方形网格的边长,在snakeview的讲解中会重点介绍。

项目启动流程

Snake主Activity启动加载layout布局,然后对SnakeView进行初始化,项目启动,等待用户操作,主界面显示 “press up to start game”,这个时候我们发现如何操作都不能启动项目,为什么呢,因为这个游戏试运行在带手柄的游戏设备dpad上的,因此手机是无法启动它的,使用模拟器可以进行适当的设置调出dpad操作键,当然我们最终会修改这个项目使得我们能够通过滑动去操作游戏,在此之前我们先要明白游戏是如何运行和控制的,控制接口在哪里,找到了控制接口我们再用手势操作去触发对应接口事件即可,当然重点还是在学习项目的设计逻辑。 下面是snake的oncreate函数,也是snake的主体部分。

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.snake_layout);

mSnakeView = (SnakeView) findViewById(R.id.snake);
mSnakeView.setTextView((TextView) findViewById(R.id.text));

if (savedInstanceState == null) {
// We were just launched -- set up a new game
mSnakeView.setMode(SnakeView.READY);
} else {
// We are being restored
Bundle map = savedInstanceState.getBundle(ICICLE_KEY);
if (map != null) {
mSnakeView.restoreState(map);
} else {
mSnakeView.setMode(SnakeView.PAUSE);
}
}
}


我们只看两个部分

mSnakeView = (SnakeView) findViewById(R.id.snake);
mSnakeView.setMode(SnakeView.READY);


一个是获取游戏视图,一个是设置状态,savedInstanceState是在此程序意外退出时保存的游戏状态,如果保存有状态,则对应恢复视图,这里我们可以先不考虑。由上面代码可以看出整个程序的控制逻辑都在SnakeView里面。那么究竟为何手机无法控制以及游戏逻辑实现是什么样子,我们往后看。

SnakeView和TileView概览_为何无法运行游戏

本节我们先搞清楚view的结构以及事件响应部分,后续文章会对视图绘制进行详细介绍。

SnakeView部分代码

public class SnakeView extends TileView


TileView是网格视图基类,自定义了网格的回执,可以理解为一个棋盘,游戏就是在上面进行的,SnakeView则是在其上添加了苹果和蛇,以及游戏控制逻辑。

public SnakeView(Context context, AttributeSet attrs) {
super(context, attrs);
initSnakeView();
}


构造函数,layout中的加载view的时候会调用,启动initSnakeView则实现了初始化游戏视图的功能。此函数调用完成后视图也就加载完毕,剩下的就是找事件监听的部分。

public boolean onKeyDown(int keyCode, KeyEvent msg) {

if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
if (mMode == READY | mMode == LOSE) {
/*
* At the beginning of the game, or the end of a previous one,
* we should start a new game.
*/
initNewGame();
setMode(RUNNING);
update();
return (true);
}

if (mMode == PAUSE) {
/*
* If the game is merely paused, we should just continue where
* we left off.
*/
setMode(RUNNING);
update();
return (true);
}

if (mDirection != SOUTH) {
mNextDirection = NORTH;
}
return (true);
}

if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
if (mDirection != NORTH) {
mNextDirection = SOUTH;
}
return (true);
}

if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
if (mDirection != EAST) {
mNextDirection = WEST;
}
return (true);
}

if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
if (mDirection != WEST) {
mNextDirection = EAST;
}
return (true);
}

return super.onKeyDown(keyCode, msg);
}


SnakeView重写了onKeyDown函数,也就是通过方向键去控制游戏进行,比如最初up向上开始游戏,然后通过方向键控制蛇走动的方向。这里我们看事件监听的类型

KeyEvent.KEYCODE_DPAD_UP


这是dpad设备的按键事件,自然手机没有了,这也就是我们无法启动游戏的原因,我们可以在主界面添加四个方向键然后通过他们去控制方向,但是对游戏界面覆盖体验不好,于是我想可以通过滑动手势去操纵游戏,于是就有了后文一系列探究。

手势操作的Snake游戏_拿来主义迅速上手

SnakeView的控制逻辑_追本溯源一探究竟
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息