贪吃蛇游戏是一款经典休闲游戏,本文将在android上实现经典的贪吃蛇游戏,操作界面和以前那些游戏机一样。


游戏空间界面

该游戏的实现思路主要是在一个View中将贪吃蛇的游戏界面绘制出来,游戏空间由16*32个小方块组成,使用一个LinkedList记录当前蛇的位置和用一个变量记录食物的位置。

private int snakeFood; // 记录当前食物的位置,横坐标*100+纵坐标private LinkedList snakeArray; // 记录蛇的位置信息,每一节的坐标和食物的一致,横坐标*100+纵坐标
新建SnakeSpace继承自View。在onDraw方法中绘制游戏空间的界面,如下代码:
    @Override    protected void onDraw(Canvas canvas) {        int width = getWidth();        int height = getHeight();        int dx = width / 16;        Paint paint = new Paint();        paint.setStrokeWidth(4);        canvas.drawColor(0xffFCBD00);        canvas.drawLine(0, 0, width, 0, paint);        canvas.drawLine(width, 0, width, height, paint);        canvas.drawLine(0, height, width, height, paint);        canvas.drawLine(0, 0, 0, height, paint);        Paint paint2 = new Paint();        paint2.setColor(0x50000000);        for (int i = 0; i < 16; i++){            for (int j = 0; j < 32; j++) {                if (snakeArray.contains(i*100+j) || snakeFood == (i*100+j)){                    canvas.drawRect((dx * i) + 1, (dx * j) + 1, (dx * i) + dx - 1, (dx * j) + dx - 1, paint);                }else{                    canvas.drawRect((dx * i) + 1, (dx * j) + 1, (dx * i) + dx - 1, (dx * j) + dx - 1, paint2);                }            }        }        super.onDraw(canvas);    }

在代码中,首先获取width和height以便后续绘图使用,绘制空间周围的小黑边,然后双重循环绘制控制中的26*32个小方块,这里判断绘制的坐标如果是蛇或者食物,则绘制全黑的方块,否则绘制有透明度的方块。这样的话,在游戏过程中,改变蛇和食物变量的值,即可改变界面显示。

移动蛇

按下界面上的上下左右按键可以让蛇移动,这里将蛇移动的方法暴露出来,通过Dir参数设置移动的方向。

    public static final int DIRECTION_UP = 1;    public static final int DIRECTION_DOWN = 2;    public static final int DIRECTION_LEFT = 3;    public static final int DIRECTION_RIGHT = 4;    private int direction;
    public void move(int dir){        if ((dir <= 2 && direction <= 2) || (dir > 2 && direction > 2)){            return;        }        direction = dir;    }    public void move(){        int firstIndex = snakeArray.getFirst();        switch (direction){            case DIRECTION_LEFT:                if (firstIndex >= 100){                    firstIndex -= 100;                }else{                    return;                }                break;            case DIRECTION_UP:                if (firstIndex%100 > 0){                    firstIndex -= 1;                }else{                    return;                }                break;            case DIRECTION_RIGHT:                if (firstIndex < 1500){                    firstIndex += 100;                }else{                    return;                }                break;            case DIRECTION_DOWN:                if (firstIndex%100 < 31){                    firstIndex += 1;                }else{                    return;                }                break;        }        snakeArray.addFirst(firstIndex);        if (firstIndex == snakeFood){            showFood();        }else{            snakeArray.removeLast();        }        postInvalidate();    }

代码中主要是设置蛇头和蛇尾的位置,因为每一次移动只移动一步,所以都是只需要改变蛇头和蛇尾而已。在该方法中做了食物处理,即蛇吃到食物后,随机显示下一个食物,蛇身变长。

随机显示食物

    private void showFood(){        int x = (int) Math.round(Math.random() * 16);        int y = (int) Math.round(Math.random() * 32);        // 该方法存在一个很大的BUG,即可能在生成食物时会占用大量的时间甚至进入死循环,即游戏空间上已经没有合适的位置了。后续的文章中将修改这个。        while (snakeArray.contains(x*100 + y)){ // 判断直到随机产生的位置是一个空位置,            x = (int) Math.round(Math.random() * 16);            y = (int) Math.round(Math.random() * 32);        }        Log.e("SnakeSpace", "food pos = " + snakeFood);        snakeFood = x*100 + y;    }

使用贪吃蛇View

在MainActivity的布局文件中引入我们创建的贪吃蛇View,和上下左右四个按键。

<?xml version="1.0" encoding="utf-8"?>                                    

在MainActivity中的使用代码如下:

class MainActivity : AppCompatActivity() {    private val glRenderer: GLRenderer? = null    private lateinit var snake: SnakeSpace    private var mTimer: Timer? = null    private var mTimerTask: TimerTask? = null    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        snake = findViewById(R.id.snake_view)        startTimer()    }    private fun startTimer(){        stopTimer()        mTimer = Timer()        mTimerTask = object : TimerTask(){            override fun run() {                snake.move()            }        }        mTimer!!.schedule(mTimerTask, 1000, 500)    }    private fun stopTimer(){        if (mTimer != null){            mTimer!!.cancel()            mTimer = null        }        if (mTimerTask != null){            mTimerTask!!.cancel()            mTimerTask = null        }    }    public fun upMove(view: View){        snake.move(SnakeSpace.DIRECTION_UP)    }    public fun downMove(view: View){        snake.move(SnakeSpace.DIRECTION_DOWN)    }    public fun leftMove(view: View){        snake.move(SnakeSpace.DIRECTION_LEFT)    }    public fun rightMove(view: View){        snake.move(SnakeSpace.DIRECTION_RIGHT)    }
代码主要思路是使用定时器控制游戏速度,上下左右按键改变蛇的移动方向。

至此,已经实现了一个简单的可以移动的贪吃蛇游戏雏形了,项目源码可参考Github项目。

https://github.com/dgutkai/RetroSnake.git

https://github.com/dgutkai/RetroSnake.gi

更多相关文章

  1. GitHub 标星 2.5K+!教你通过玩游戏的方式学习 VIM!
  2. android 更改avd路径
  3. 快速构建Android应用原型实践
  4. android ListView使用的三种方法汇总(通过继承BaseAdapter,使用Si
  5. 八款常见的Android游戏引擎
  6. Android定位入门(1)了解定位管理器--LocationManager 类
  7. Android手游转电视游戏之模拟操控
  8. android 拼图小游戏
  9. 关于Android中的位置服务解读

随机推荐

  1. Android(安卓)消息机制之Message
  2. Android(安卓)利用drawable中的gradient
  3. Android(安卓)Layout XML属性
  4. Android学习路线
  5. Android(安卓)核心分析 之八------Androi
  6. 如何解决:Android中 Error generating fin
  7. 分享17个老罗Android开发视频教程(免费下
  8. Android(安卓)进程间通信:AIDL
  9. Android(安卓)内存溢出解决方案(OOM) 整理
  10. android:shape的使用