写在前面:为期近一个学期的小组软件项目就快要完工了,在这里借助本学期的最后一次实验博客,对我们小组的游戏做一个分析
0 分析系统架构
- 1.这里主要分析一下,游戏界面的主要结构
Card类
该类是自定义Fragment类,里面传入了两个布局一个用来表示背景View,一个用来显示数字的TextView。该类是用来显示2048游戏中的数字卡片
Config类
该类是用来管理游戏模式:4 or 6
GameView类
该类就是玩游戏的具体布局界面了。同样也是自定义的Fragment类,它里面传入了4 or 6 个Linerlayout,而每个LinerLayout里面有传入了4 or 6个Card,所以GameiView里面相当于放入了44or66个Card布局
AnimaLayer
该类是用来实现GameView中移动Card的动画效果的实现,自定义两种动画效果:createMoveAnim(这是用来控制Card移动的动画效果);createScaleTo1(这是用来控制随机的卡片出现的动画效果)
- 所以游戏布局所用到的结构大体就是这些,GameView基于Card和Config类,AnimaLayer同样基于Card类,而AnimaLayer和GameView相结合来控制游戏的逻辑。
2.其次要分析下游戏界面中悬浮按钮的系统结构
UnfoldButton类是从开源库上下载的源码,它的addElement()方法可以加入悬浮按钮,通过setmRotatable,setmScale,setLength,setAngle来自定义。我们用这个类来设置游戏的重新开始,游戏模式的选择,游戏背景音乐的开关。
1 编译、运行、测试系统
git clone
AndroidStudio运行
游戏界面
2 修改系统
这次借着这个机会,刚好再次把我们的UnfoldButton的系统重新构建一次,如图:
最开始的系统由三个按钮:
- 蓝色按钮:用来重新开始游戏,调用GameView类中startGame()方法。
- 绿色按钮:这是用来将游戏模式调换成4*4模式
- 白色按钮:这是用来将游戏模式调换成6*6模式
为什么要修改这个系统
首先要我们想要加入一个新按钮用来控制背景音乐服务,而又不想更改当前的三按钮样式
其次我们在一开始设计模式切换的方式的时候,没有考虑太多,当时具体思路如下:
unfoldButton.addElement(R.drawable.ic_action_tiles_small, R.color.darkcyan, new View.OnClickListener() { @Override public void onClick(View v) { Config.setLines(4); Intent intent = new Intent(MainActivity.this,MainActivity.class); startActivity(intent); finish(); } });
- 通过代码可以知道所谓的模式切换就是重新打开一个游戏界面的Activit,并且关闭原来的游戏界面。这样做有个不可避免的弊端:每次切换模式后,由于前一个Activity被关闭,新的Activity被重新打开的时候,屏幕会闪退一下,然后再次加载,虽然时间很短,但是凭借肉眼还是能看出来。这就对整个游戏软件的流畅性产生了很大的影响。而且背景音乐的服务同样加载这个Activity中,如果不修改这个系统,那么每次切换模式音乐都会重新播放,不连贯。
具体的修改思路是:更换模式后只是重置界面的具体游戏的布局,而不是重新启动一个Activity,如图中黑色框
如果想要如此实现,那么就必须更改GameView类的方法,同时AnimaLayer类的方法也应该做出相应的更改,这里只写出大体的实现过程:
1.GameView实际上是通过Layoutprams传入了多个子布局。初始传入了66个Card,所以如果要将GameView里面的布局变为44,那么转换方法中就必须现将原来布局清除掉,然后添加新的布局.
2.一旦重新向GameView中添加新的布局后,那么AnimaLayer的设置也应该随之相应的更改,这需要一系列的操作,最后的结果如下
3 分析数据结构、排序、查找算法的应用
- 这里主要分析游戏逻辑的数据结构,我们借助二维数组来实现:
private Card[][] cardsMap = new Card[Config.LINES][Config.LINES]; private ListemptyPoints = new ArrayList ();
- cradsMap是用来指向GameView中传入的每个Card,emptyPoints是用来记录卡片的<x,y>坐标。
private void addCards(int cardWidth, int cardHeight) { Card c; LinearLayout line; LinearLayout.LayoutParams lineLp; for (int y = 0; y < Config.LINES; y++) { line = new LinearLayout(getContext()); lineLp = new LinearLayout.LayoutParams(-1, cardHeight); addView(line, lineLp); for (int x = 0; x < Config.LINES; x++) { c = new Card(getContext()); line.addView(c, cardWidth, cardHeight); cardsMap[x][y] = c; } } }
示例:
关于查找算法的实现,我们打算做一个排行榜界面,玩家可以通过时间查找自己的得分。而排序算法倒是不会用到。