如果聊天感觉有点累, 在 [小萌伴] 中还可以玩一些小游戏, 包括 H5 游戏和原生游戏, 之前介绍了 H5 小游戏 (4399), 现在来说说原生小游戏.
[小萌伴] 2048.jpg
作为一个休闲娱乐类 App 的辅助模块, 我对小游戏的看法是应当包含一些当前流行的, 代码量小易于开发的轻量级游戏; 于是, 我选择了当时流行的《2048》,《小鸟》,《飞机》,《贪吃蛇》四款游戏 (后来《贪吃蛇》移除了).
一, 2048
该游戏代码上主要包含两部分, 显示数字的 Card 控件和 N*N 继承 GridLayout 的 GameView.
Card
Card 包含一个 TextView, 显示当前数字 num, 比较关键的是它有一个 equals 方法:
- // 重写 equals 方法, 使它能够判断两个卡片的数是否相等
- public boolean equals(Card o) {
- return getNum() == o.getNum();
- }
- GameView
首先是确定控件宽高, 因为该游戏是 N*N 的正方形界面, 所以, width 和 height 取较小值, 并将两者重置为相等:
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- w = Math.min(w, h);
- h = w;
- super.onSizeChanged(w, h, oldw, oldh);
- }
- @Override
- public void setLayoutParams(Android.view.ViewGroup.LayoutParams params) {
- params.width = Math.min(params.width, params.height);
- params.height = params.width;
- super.setLayoutParams(params);
- }
在 onSizeChanged 执行完毕后, 获取其宽度, 然后增加 Card, 并开始游戏:
- // 对宽高取最小值
- int cardWidth = (w - 10) / COLUMN;
- // 因为卡片是正方形的, 所以宽高一样
- addCard(cardWidth, cardWidth);
- // 开始游戏
- startGame();
addCard 实际上应该是 initCard, 利用嵌套 for 循环将 Card 添加到 CardView 中;
startGame 第一步是将所有 Card 的 num 置为 0, 然后添加两张随机的卡片.
- // 写一个二维数组来存储卡片
- private Card[][] cardsMap = new Card[COLUMN][COLUMN];
- // 用于临时存储卡片位置, Point 的 x,y 其实就是 cardsMap 的行和列
- private List<Point> emptyPoints = new ArrayList<Point>();
- // 添加一个随机数
- private void addRandomNum(){
- emptyPoints.clear();
- for (int y = 0; y <COLUMN; y++) {
- for (int x = 0; x < COLUMN; x++) {
- // 该位置必须为 0
- if(cardsMap[x][y].getNum() <= 0){
- emptyPoints.add(new Point(x, y));
- }
- }
- }// end for
- // 随机取出一个卡片, 并且移除那个卡片
- Point p = emptyPoints.remove((int)(Math.random()*emptyPoints.size()));
- // 在移除掉的那个点上添加 2 或者 4,2 和 4 出现的概率是 9:1
- cardsMap[p.x][p.y].setNum(Math.random()> 0.1 ? 2 : 4);
- }
然后是移动事件:
通过监听 onTouch 实现, 并根据移动方向来处理相应逻辑, 定义了 swipeLeft,swipeRight,swipeUp,swipeDown 四个方法, 它们的实现类似: 通过三层 for 循环处理移动, 碰撞及合并:
- private void swipeLeft(){
- boolean merge = false;
- for (int y = 0; y <COLUMN; y++) {
- for (int x = 0; x < COLUMN; x++) {
- for (int x1 = x+1; x1 < COLUMN; x1++) {
- if(cardsMap[x1][y].getNum()> 0){
- if(cardsMap[x][y].getNum() <= 0){
- cardsMap[x][y].setNum(cardsMap[x1][y].getNum());
- cardsMap[x1][y].setNum(0);
- x--;
- merge = true;
- }else if (cardsMap[x][y].equals(cardsMap[x1][y])) {
- cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2);
- cardsMap[x1][y].setNum(0);
- // 在合并的时候增加分数
- Game2048Activity.getMainActivity().addScore(cardsMap[x][y].getNum());
- merge = true;
- }
- break;
- }
- }// end x1 for
- }
- }
- // 如果有动作, 那么就添加一个新的随机数, 再判断是否满足结束游戏的条件
- if(merge){
- addRandomNum();
- checkComplete();
- }
- }
这个方法的最后, 移动完毕后, 随机增加一个 Card, 并判断是否游戏结束 (当不所有 Card 的 num 都不为 0, 且相邻 Card 没有相等值时, 表示不可以再移动, 即游戏结束), 此时弹窗提示, 并显示分数.
IT 老五 (it-lao5): 关注公众号, 一起源创, 一起学习!
相关内容:
1.[小萌伴 Android] 思量再三, 终于鼓起勇气开源~
2.[小萌伴 Android] 机器人陪聊模块分享
3.[小萌伴 Android] 新闻 / H5 游戏模块及广告过滤
4.[小萌伴 Android] 段子趣图模块及其实现 及 如何从第三方导出笑话数据到自己的服务器
来源: http://www.jianshu.com/p/7215fe7d8635