项目总结
一、Game2048
1)开发流程:
1.使用LinearLayout作为界面主布局(搭建不同显示区域);
2.编写游戏主类GameView(继承至GridLayout并实现相应构造方法),并通过修改xml文件中的标签实现绑定;
<!-- 游戏界面布局-->
<com.mertrix.game2048.GameView
android:id="@+id/gameView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
3. 实现触控交互(判断手势意图)
setOnTouchListener(new View.OnTouchListener() {
private float startX, startY, offsetX, offsetY;
//手势意图判断
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
break;
case MotionEvent.ACTION_UP:
offsetX = event.getX() - startX;
offsetY = event.getY() - startY;
if (Math.abs(offsetX) > Math.abs(offsetY)) {
if (offsetX < -5) {
swipeLeft();
} else if (offsetX > 5) {
swipeRight();
}
} else {
if (offsetY < -5) {
swipeUp();
} else if (offsetY > 5) {
swipeDown();
}
}
break;
}
return true; //通知系统触摸监听事件触发成功
}
});
4.实现游戏卡片类(继承至FrameLayout并实现相应构造方法)
- 创建文本框对象,设置相应参数
- 创建成员变量分数,并使用setNum()和gteNum()进行修改;
- 在添加时传递一个创建好的LayoutParams
public class Card extends FrameLayout {
public Card(@NonNull Context context) {
super(context);
//卡片视图设计
label = new TextView(getContext());
label.setTextSize(34);
label.setBackgroundColor(0x33ffffff); //设置卡牌背景颜色
label.setGravity(Gravity.CENTER); //文本居中
LayoutParams lp = new LayoutParams(-1, -1); //填满父级容器
lp.setMargins(10, 10, 10, 0);
addView(label, lp); //添加文本框到view界面
setNum(0);
}
5.添加2048游戏卡片(GameView.class 类中配置)
- 设置屏幕保持直立(在AndroidManifest.xml文件中配置)
android:screenOrientation="portrait" //屏幕始终保持直立(水平布局)状态,不能旋转
- 自动获取屏幕宽高,计算每张卡片的尺寸 【onSizeChanged(int w……,int oldh)动态获取】
/*动态获取卡片宽高,实现屏幕自适应*/
@Override
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; //10px的间隔
addCards(cardWidth, cardWidth);
startGame(); //执行开始游戏方法
}
- 创建4*4卡片矩阵, x-行坐标 y-列坐标
private Card[][] cardMap = new Card[4][4]; //创建二维数组存放卡片数据
/*创建4*4卡片矩阵,y:列坐标 x:行坐标*/
private void addCards(int cardWidth, int cardHeight) {
Card c;
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
c = new Card(getContext());
c.setNum(0); //初始卡片值全部设为0,默认不显示
addView(c, cardWidth, cardHeight); //将卡片依次添加GameView视图
cardMap[x][y] = c; //利用二维数组存储卡牌元素
}
}
}
#错误:未换行
setColumnCount(4); //指定GameView(GridLayout)布局为4列
6.添加随机数
private List<Point> emptyPoints = new ArrayList<>(); //存放点的位置(数值为空的-空点)
/*添加随机数值*/
private void addRandomNum() {
emptyPoints.clear(); //清理数组
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
/*判断仅允许空点添加数字*/
if (cardMap[x][y].getNum() <= 0) {
emptyPoints.add(new Point(x, y));
}
}
}
Point p = emptyPoints.remove((int) (Math.random() * emptyPoints.size()));
cardMap[p.x][p.y].setNum(Math.random() > 0.1 ? 2 : 4); //!!使2 4出现的概率为9:1
}
move((int) (Math.random() * emptyPoints.size()));
cardMap[p.x][p.y].setNum(Math.random() > 0.1 ? 2 : 4); //!!使2 4出现的概率为9:1
}