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.javaSnakeView.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的控制逻辑_追本溯源一探究竟
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories