Android 2048的设计
来源:互联网 发布:淘宝怎样装修店铺 编辑:程序博客网 时间:2024/06/17 02:40
假期时无意间在微信上看到有人转发了2048的游戏链接,就想试着自己写一个,于是用了五天的时间完成了这个小游戏
游戏截图如下:
整个游戏的基础功能的实现十分简单,仅需要用到三个类,分别是卡片类:Card.java,游戏界面组件:GameView.java,主Activity类:MainActivity。
Card类用来生成游戏中的每个方格,继承了FrameLayout,所以Card也是一个布局类,当中包含了一个TextView组件,用来显示每个方格的数值Num,并提供了getNum()和setNum()来设置和获取其数值。代码如下:
public class Card extends FrameLayout { private TextView label; private int num; public Card(Context context) { super(context); label = new TextView(getContext()); label.setBackgroundColor(0x33ffffff); label.setTextSize(32); label.setGravity(Gravity.CENTER); LayoutParams lp = new LayoutParams(-1, -1); lp.setMargins(10, 10, 0, 0); addView(label, lp); } public int getNum() { return num; } public void setNum(int num) { this.num = num; if (num == 0) { label.setText(""); return; } label.setText(num + ""); } public boolean equals(Card c) { return this.getNum() == c.getNum(); }}
GameView类用来生成游戏的主界面,继承了GridLayout类,所以GameView也是一个布局类。因为2048的游戏区域是一个n行n列的正方形区域,则GameView当中即包含了n*n个Card对象。通过设定每个方格的数值变化即可实现相应的“左移”,“右移”,“合并”等多种操作。
该注意的是,当手指向左滑动时,要实现全部方块向左移动,相邻且数值相同的方块要合并在一起,实现方法是LeftCard()。Left()函数用来实现所有方块向左移动的功能,但不包括数值检测与合并。LeftCard()方法首先执行一次Left(),然后从左往右检测是否有相邻方法数值相同,有则合并,且再执行一次Left()。代码如下:
public class GameView extends GridLayout { private Card[][] cards; public GameView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public GameView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public GameView(Context context) { super(context); init(); } //初始化 public void init() { setBackgroundColor(0xffbbada0); cards = new Card[4][4]; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { cards[x][y] = new Card(getContext()); } } RandomCard(); RandomCard(); } protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); int cardWidth = (Math.min(w, h) - 10) / 4; addCard(cardWidth); } public void addCard(int cardWidth) { for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { addView(cards[x][y], cardWidth, cardWidth); } } } //生成随机数字 public void RandomCard() { int i = 0; for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (cards[x][y].getNum() == 0) { i++; } } } if (i == 0) { return; } int random = new Random().nextInt(16); int x = random / 4; int y = random % 4; while (cards[x][y].getNum() != 0) { random = new Random().nextInt(16); x = random / 4; y = random % 4; } cards[x][y].setNum(2); } //左移 public void LeftCard() { Left(); for (int y = 0; y < 4; y++) { for (int x = 0; x < 3; x++) { if (cards[x][y].getNum() != 0) { if (cards[x][y].equals(cards[x + 1][y])) { int num = 2 * cards[x][y].getNum(); cards[x][y].setNum(num); cards[x + 1][y].setNum(0); Left(); } } } } RandomCard(); } //右移 public void RightCard() { Right(); for (int y = 0; y < 4; y++) { for (int x = 3; x > 0; x--) { if (cards[x][y].getNum() != 0) { if (cards[x][y].equals(cards[x - 1][y])) { int num = 2 * cards[x][y].getNum(); cards[x][y].setNum(num); cards[x - 1][y].setNum(0); Right(); } } } } RandomCard(); } //上移 public void TopCard() { Top(); for (int x = 0; x < 4; x++) { for (int y = 0; y < 3; y++) { if (cards[x][y].getNum() != 0) { if (cards[x][y].equals(cards[x][y + 1])) { int num = 2 * cards[x][y].getNum(); cards[x][y].setNum(num); cards[x][y + 1].setNum(0); Top(); } } } } RandomCard(); } //下移 public void BottomCard() { Bottom(); for (int x = 0; x < 4; x++) { for (int y = 3; y > 0; y--) { if (cards[x][y].getNum() != 0) { if (cards[x][y].equals(cards[x][y - 1])) { int num = 2 * cards[x][y].getNum(); cards[x][y].setNum(num); cards[x][y - 1].setNum(0); Bottom(); } } } } RandomCard(); } //全部向左 public void Left() { for (int y = 0; y < 4; y++) { int i = 0; for (int x = 0; x < 4; x++) { if (cards[x][y].getNum() != 0) { int num = cards[x][y].getNum(); cards[x][y].setNum(0); cards[i++][y].setNum(num); } } } } //全部向右 public void Right() { for (int y = 0; y < 4; y++) { int i = 3; for (int x = 3; x > -1; x--) { if (cards[x][y].getNum() != 0) { int num = cards[x][y].getNum(); cards[x][y].setNum(0); cards[i--][y].setNum(num); } } } } //全部向上 public void Top() { for (int x = 0; x < 4; x++) { int i = 0; for (int y = 0; y < 4; y++) { if (cards[x][y].getNum() != 0) { int num = cards[x][y].getNum(); cards[x][y].setNum(0); cards[x][i++].setNum(num); } } } } //全部向下 public void Bottom() { for (int x = 0; x < 4; x++) { int i = 3; for (int y = 3; y > -1; y--) { if (cards[x][y].getNum() != 0) { int num = cards[x][y].getNum(); cards[x][y].setNum(0); cards[x][i--].setNum(num); } } } } //屏幕触摸事件 float X; float Y; float OffsetX; float OffsetY; public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: X = event.getX(); Y = event.getY(); break; case MotionEvent.ACTION_UP: OffsetX = event.getX() - X; OffsetY = event.getY() - Y; if (Math.abs(OffsetX) > (Math.abs(OffsetY))) { if (OffsetX < -5) { LeftCard(); } else if (OffsetX > 5) { RightCard(); } } else { if (OffsetY < -5) { TopCard(); } else if (OffsetY > 5) { BottomCard(); } } break; } return true; }}
这样,向主Activity设置的布局文件activity_main.xml中增添GameView组件,就可以实现游戏的基本功能了。代码如下:
<?xml version="1.0"?><LinearLayout xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <chen.zy.game2048.GameView android:id="@+id/gameView" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:columnCount="4" android:rowCount="4" > </chen.zy.game2048.GameView></LinearLayout>
仅依靠这三个类,就可以实现2048的基础功能,代码虽然简洁,但实现的效果肯定也没有我上述的截图好,其他功能需要自己再来后续添加,如保存游戏记录、音效、主题等。
这里提供代码下载地址:Android游戏——2048源码
- Android 2048的设计
- Android 2048的设计(2)
- Android的组件设计
- android的ui设计
- 设计Android的用户界面
- Android的设计依据
- Android的设计尺寸
- Android的设计模式
- Android的MVC设计
- android设计模式 App的设计架构
- 设计Android的用户界面(一)
- Android的用户界面设计《一》
- 设计自己的Android Preference
- 设计自己的Android Preference
- 设计自己的Android Preference
- android 的ui设计技巧
- android的UI设计原则
- Android的icon设计指南
- Android 自定义View
- Python 练手程序合集(二)
- 线性规划与网络流24题 太空飞行计划问题 (最小割及输出方案)
- NDK编译源码
- 移植opencv2.4.9到android过程记录
- Android 2048的设计
- Source Insight 常用设置和快捷键大全
- gulp教程之gulp-imagemin
- Java强引用、 软引用、 弱引用、虚引用
- Android布局优化之Merge Include ViewStub使用与源码分析
- Codeforces 368B
- android-Implementing Effective Navigation,Creating Swipe Views with Tabs
- C#中DataTable排序、检索、合并等操作实例
- 编程技巧之如何让一份代码多适应底层硬件