20172321 20172333 2017-2018 暑假作业APP
20172321 20172333 2017-2018 暑假作业APP
项目介绍
项目成员
- 吴恒佚 20172321
- 严域俊 20172333
项目简介
- 从理论上来说,这是一个贪吃蛇游戏。
- 《贪吃蛇》:控制小蛇前进的方向,尽可能吃更多的东西使自己变长,首先不能咬到自己的尾巴,不能撞到墙壁。————360百科
- 本游戏玩法:用按钮上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴(目前只支持无限模式,后期应该会有闯关等新模式)
代码地址
提取码:cnq6
项目展示
运行展示
分区展示
- 首先介绍的是app图标
这是导入自己喜欢的图片后,在以下代码中修改自己喜欢的名字和图片地址
- 之后进入这个页面,这是个菜单页面,理论上来说,可以选择要玩的游戏和查看攻略以及历史评分之类的,不过现在还没有完成这些功能
- 最后就是游戏界面,目前是简朴复古流,游戏画面清晰易懂、操作按钮简单朴实、没有花里胡哨的闯关地图,在小小的方形地图中挑战极限 ...可计分、暂停、加速。
制作过程
开始操作之前
- 在严域俊小胖友的诚挚邀请下我来到了他的家,两个热爱编程的人在一起能干什么呢?还能干什么呢?
- 暑假编程不还没写吗?王老师不是说可以编个小游戏吗?
- 要不来个俄罗斯方块,感觉没什么难度。。。
- 去贴吧里看看编程思路好了
- 算了算了,有没有什么简单点的。。。
- 之后我们一起参观了B站老哥的教学视频,主要是学习蛇体的运动方式,和食物是否被吃的判定。
关键代码解析
- 最开始肯定是生成一个30*30的背景墙并且设置墙壁
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
width = getWidth();
height = getHeight();
pixl = width / SnakeConfig.snakeNum;
if (!isInit) {
initPoint();
isInit = true;
}
mPaint.setStrokeWidth(pixl * 2);
snakePaint.setStrokeWidth(pixl - 2);
initWall(canvas);
initSnake(canvas);
drawSnakeBuf(canvas);
}
private void initWall(Canvas canvas) {
RectF rel;
paintWall.setStyle(Paint.Style.FILL_AND_STROKE);
paintWall.setColor(Color.BLACK);
for (int i = bengin; i < width - pixl; i += pixl) {
for (int j = bengin; j < width - pixl; j += pixl) {
if (i == bengin || j == bengin || i > width - 2 * pixl || j > width - 2 * pixl) {
rel = new RectF(i, j, i + pixl, j + pixl);
canvas.drawRoundRect(rel, 10, 10, paintWall);
}
}
}
paintWall.setStyle(Paint.Style.STROKE);
paintWall.setColor(Color.LTGRAY);
for (int i = bengin; i < width - pixl; i += pixl) {
for (int j = bengin; j < width - pixl; j += pixl) {
if (i == bengin || j == bengin || i > width - 2 * pixl || j > width - 2 * pixl) {
} else {
rel = new RectF(i, j, i + pixl, j + pixl);
canvas.drawRoundRect(rel, 4, 4, paintWall);
}
}
}
}
- 蛇体的移动是通过在移动方向的前一个格子生成蛇体并且消除蛇尾的最后一个格子的蛇体实现,例如向右移动
private void moveToRight() {
int len = snakeDatas.size();
for (int i = len - 1; i > 0; i--) {
snakeDatas.get(i).x = snakeDatas.get(i - 1).x;
snakeDatas.get(i).y = snakeDatas.get(i - 1).y;
}
snakeDatas.get(0).x = snakeDatas.get(0).x + pixl;
}
- 还有一个关键的判定:判断两个点是否在同一个位置。用来判断蛇头和其他点的位置
- 如果蛇头的和蛇体或者墙壁重合则死亡
- 如果蛇头和食物重合则增加一分并且随机再生成一个代表食物的点
public boolean isSamePoint(Snake snake, Snake snakeBuf2) {
if ((snake.x - snakeBuf2.x) < -2 || (snake.x - snakeBuf2.x) > 2) {
return false;
}
if ((snake.y - snakeBuf2.y) < -2 || (snake.y - snakeBuf2.y) > 2) {
return false;
}
return true;
}
按钮生成
- 以向上按钮为例
- 首先我们找到一个差不多看起来像方向指针的图片
- 然后用一个
up.xml
把图片引用,就得到了一个按钮。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/up_p" android:state_pressed="true"></item>
<item android:drawable="@drawable/up_n"></item>
</selector>
- 王老师指出,这样就不能用电脑键盘操作了,不过我们本来就是手机app嘛,[摊手] 。
可扩展功能
- 就是一些花里胡哨的的贪吃蛇版本嘛
- 闯关冒险、限时得分、娱乐道具
- 网上计分、匹配对战、排名挑战
- 会员开通、充值酷炫皮肤、购买复活加分道具
- 3D模式(如果技术允许)
游戏中所阐述的哲理
- 在这个游戏中,两位创作人并不只是想向人们展示一个简朴的贪吃蛇游戏,而是想借此为人们生动的阐述一些哲理,谨在此例举两例
- 在控制小蛇不断吞食小豆的路上,偶尔小豆不会自动生成,需要自己动手点击一下启动键。我们想告诉大家的是:取得成果的机会不总是努力寻找就可以得到的,偶尔也要自己去创造。
- 当一局游戏失败之后开始新的一局,分数会从0开始,但是在结束后一局游戏时,你会发现,总分会是两局得分之和。大家应该明白:在前进的路上总会有许许多多的失败,偶尔要重写开始,但是,你以前的付出绝对不是毫无意义的,它也是你所取得的成绩的重要部分。
写在最后
“程序员的宿命啊,就是被扔,这代码啊,是写了扔,扔了写。”
- 在和吴恒佚(金银铜铁刚)编写这个贪吃蛇的过程中,从无到有,这之间不过十天左右的时间,代码很简陋,从构思做什么app再到基本的框架构建,上下左右,加速,暂停,吃豆豆这些方法的实现,具现在AS上也不过600行代码,大部分知识都是从别人视频里面学的,有些时候从这位大佬上学点从帧数调整上使贪吃蛇加速,有时从另外一位大佬上学学限制贪吃蛇框架构建。整个APP都是东拼西凑出来的东西,有时候几十行代码写了出来,发现不适合,没办法只能扔掉,扔掉又重新写,写出来再扔掉,往复直到将就适合。有的BUG都完全没办法解决(技术不到位,莫得办法),只能一步一步推倒回去,直到不再出错,再重新找到其他方法重新开始。如果说其他职业的每一步工作都有自己应有的价值,再怎么废弃也是一定价值的,那么程序员就是一个极端,出BUG删掉重写、程序写完后闪退重写、方法由于类型值不符合重写、就一直扔一直写,写到那唯一的一条路上successful。得亏编写的过程中也不只有BUG,也有欢乐与成就。两个人共用一个电脑桌,桌上摆着两杯奶茶,码累了,往落地窗外看看成都的风景,过去的行人,在篮球场挥霍汗水的男女生,伸个懒腰,继续开始一次又一次的调试与视频学习。在这样没有deadline的日子悠闲的编程也算是一次另类的暑假娱乐了吧。
——强调了自己姓名的严域俊先生