首页 > 编程学习 > Snake on a phone——Android开源项目实战,贪吃蛇游戏

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

  1. 手势操作的Snake游戏_拿来主义迅速上手
  2. SnakeView的控制逻辑_追本溯源一探究竟
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000