android游戏开发入门: 贪吃蛇 源代码分析


贪吃蛇是一款足够经典的游戏。它的经典,在于用户操作的简单,在于技术实现的简介,在于他的经久不衰。

这里的贪吃蛇的android实现,是SDK Samples中的开源例程。可能各位都有看过~界面如下图啦~


作为一个刚入门或者还没入门的新手,着实花了我一些力气来理解这段代码。

对于各种不懂的地方,慢慢查询资料,对于新的方法,通过修改代码尝试效果。到现在终于能算个一知半解。

在代码中,对于自己有所收获的地方,我都做了相应的注释。

回过头来,觉得从这段代码中,能学到不少东西~~

包括android应用的基本架构,他的面向对象的思想,以及代码的简洁明了。

于是,我想到,何不将这些东西分享出来,如果碰巧对感兴趣的朋友们有搜帮助,那就更好了~

好了,闲话不说~代码和注释如下(处于对源码的敬意,原本的英文注释部分都没有删去~大家可以配合理解):

PS:最近我正在写自己的“贪吃蛇”,说事贪吃蛇,其实完全颠覆了这个经典版本的设计理念和操作方式。具体细节先卖一个关子,作品准备参加这次第二届大学生android应用开发大赛。

应该一个月内能完成,到时候也会开源出代码来~欢迎大家讨论指正·~

************************************************************************************************************************************

Snake工程中,总共有三个文件: *TileView是基于Android的View类实现的方块图类,用来支撑上层类的调用,绘制方块图的显示界面。通过这些代码,能打之了解如何 扩展View,实现特色的界面效果。 *SnakeView调用了TileView,实现了游戏逻辑 和 具体的显示。 *Snake为主Activity类。

建议大家按照上面的顺序看三个文件,可能逻辑上更舒服一点~~

下面贴上代码和注释。

PS:  调试版本为android2.2。 其他版本应该也没问题吧,不过得用虚拟机。因为它是上下左右按键操作,现在大多数android机是没有方向键的吧。

TileView.java

package com.example.android.snake;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;


/**
 * TileView: a View-variant designed for handling arrays of "icons" or other
 * drawables.
 * 
 */

public class TileView extends View {

    /**
     * Parameters controlling the size of the tiles and their range within view.
     * Width/Height are in pixels, and Drawables will be scaled to fit to these
     * dimensions. X/Y Tile Counts are the number of tiles that will be drawn.
     */

    protected static int mTileSize; //每个tile的边长的像素数量

    protected static int mXTileCount; //屏幕内能容纳的 X方向上方块的总数量
    protected static int mYTileCount;//屏幕内能容纳的 Y方向上方块的总数量

    private static int mXOffset; //原点坐标,按pixel计。
    private static int mYOffset;


    /**
     * A hash that maps integer handles specified by the subclasser to the
     * drawable that will be used for that reference
     * 存储着不同种类的bitmap图。通过resetTiles,loadTile,将游戏中的方块加载到这个数组。
     * 可以理解为 砖块字典
     */
    private Bitmap[] mTileArray;    

    /**
     * A two-dimensional array of integers in which the number represents the
     * index of the tile that should be drawn at that locations
     * 存储整个界面内每个tile位置应该绘制的tile。
     * 可看作是我们直接操作的画布。
     * 通过setTile、clearTile 进行图形显示的修改操作。 
     * 
     */
    private int[][] mTileGrid; 

    //画笔,canvas的图形绘制,需要画笔Paint实现。
    private final Paint mPaint = new Paint();

    
    public TileView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        //使用TypedArray,获取在attrs.xml中为TileView定义的新属性tileSize 。参考: http://weizhulin.blog.51cto.com/1556324/311453
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TileView);
        mTileSize = a.getInt(R.styleable.TileView_tileSize, 12);
        a.recycle();
    }

    public TileView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TileView);
        mTileSize = a.getInt(R.styleable.TileView_tileSize, 12);
        a.recycle();
    }

    
    
    /**
     * Rests the internal array of Bitmaps used for drawing tiles, and
     * sets the maximum index of tiles to be inserted
     * 重置清零mTileArray,在游戏初始的时候使用。
     * 即清空砖块字典
     * @param tilecount
     */
    public void resetTiles(int tilecount) {
    	mTileArray = new Bitmap[tilecount];
    }

    
    /*
     * 当改变屏幕大小尺寸时,同时修改tile的相关计数指标。
     */
    
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        mXTileCount = (int) Math.floor(w / mTileSize);
        mYTileCount = (int) Math.floor(h / mTileSize);

        //mXOffset mYOffset是绘图的起点坐标。
        mXOffset = ((w - (mTileSize * mXTileCount)) / 2);
        mYOffset = ((h - (mTileSize * mYTileCount)) / 2);

        mTileGrid = new int[mXTileCount][mYTileCount];
        clearTiles();
    }

    
    /**
     * Function to set the specified Drawable as the tile for a particular
     * integer key.
     * 加载具体的砖块图片 到 砖块字典。
     * 即将对应的砖块的图片 对应的加载到 mTileArray数组中
     * @param key
     * @param tile
     */
    public void loadTile(int key, Drawable tile) {
        //这里做了一个 Drawable 到 bitmap 的转换。由于外部程序使用的时候是直接读取资源文件中的图片,
    	//是drawable格式,而我们的数组是bitmap格式,方便最终的绘制。所以,需要进行一次到 bitmap的转换。
    	Bitmap bitmap = Bitmap.createBitmap(mTileSize, mTileSize, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        tile.setBounds(0, 0, mTileSize, mTileSize);
        tile.draw(canvas);
        
        mTileArray[key] = bitmap;
    }

    /**
     * Used to indicate that a particular tile (set with loadTil
  • 38
    点赞
  • 93
    收藏
    觉得还不错? 一键收藏
  • 45
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 45
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值