Android开发之2048安卓版
来源:互联网 发布:java 多条件组合查询 编辑:程序博客网 时间:2024/04/30 19:12
之前是在eclipse上写的,后面换成了android sudio。
2048游戏的UI整体可以采用线性布局,即LinearLayout,其中嵌套一个线性布局和一个GridLayout,内嵌的线性布局填充文本框,以显示分数,GridLayout中填充4×4的继承自FrameLayout的card类作为主要的游戏界面。由于大部分操作都在GridLayout中进行,可以自定义一个继承自GridLayout的类GameView,类中定义判定上下左右滑动的方法和每次滑动后自动添加一个随机数字的方法以及每次滑动后判断游戏是否可以继续进行的方法。
主布局activity_main.xml代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
//match_parent表示布局充满整个屏幕
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.administractor.game2048.MainActivity"
//里面的组件垂直放置
android:orientation="vertical"
tools:ignore="MergeRootFrame">
<LinearLayout
//宽度充满整个屏幕,高度自适应。
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
//显示当前分数的文本框
<TextViewandroid:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Your Score:"/>
<TextView
android:id="@+id/tvScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
//使用自定义的GridLayout
<com.example.administractor.game2048.GameView
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/GameView">
</com.example.administractor.game2048.GameView>
</LinearLayout>
GameView.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
packagecom.example.administrator.game2048;
importjava.util.ArrayList;
import java.util.List;
import android.app.AlertDialog;
importandroid.content.Context;
import android.content.DialogInterface;
importandroid.graphics.Point;
import android.util.AttributeSet;
importandroid.view.MotionEvent;
import android.view.View;
importandroid.widget.GridLayout;
publicclassGameViewextendsGridLayout{
//调用类构造方法
publicGameView(Contextcontext,AttributeSetattrs,intdefStyle){
super(context,attrs,defStyle);
//初始化游戏
InitGameView();
}
publicGameView(Contextcontext,AttributeSetattrs){
super(context,attrs);
InitGameView();
}
publicGameView(Contextcontext){
super(context);
InitGameView();
}
privatevoidInitGameView(){
//设置为4x4个方格
setColumnCount(4);
//设置背景颜色
setBackgroundColor(0xffeee4da);
//判定滑动方向
setOnTouchListener(newOnTouchListener(){
privatefloatstartx,starty,offsetx,offsety;
@Override
publicbooleanonTouch(Viewv,MotionEventevent){
switch(event.getAction()){
caseMotionEvent.ACTION_DOWN:
startx=event.getX();
starty=event.getY();
break;
caseMotionEvent.ACTION_UP:
offsetx=event.getX()-startx;
offsety=event.getY()-starty;
if(Math.abs(offsetx)>Math.abs(offsety)){
if(offsetx<-5){
swipeLeft();
}elseif(offsetx>5){
swipeRight();
}
}else{
if(offsety<-5){
swipeUp();
}elseif(offsetx>3){
swipeDown();
}
}
break;
}
returntrue;
}
});
}
//适应不同大小的屏幕
@Override
protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){
super.onSizeChanged(w,h,oldw,oldh);
intcardWidth=(Math.min(h,w))/4;
addCards(cardWidth,cardWidth);
startGame();
}
//在4x4的方格上添加满卡片
publicvoidaddCards(intcardwidth,intcardheight){
Cardc;
for(inty=0;y<4;y++){
for(intx=0;x<4;x++){
c=newCard(getContext());
c.setNum(0);
addView(c,cardwidth,cardheight);
cardmap[x][y]=c;
}
}
}
//游戏开始时每个卡片默认值设为0,并随机添加两张带数字的卡片
privatevoidstartGame(){
MainActivity.getMainActivity().clearScore();
for(inty=0;y<4;y++){
for(intx=0;x<4;x++){
cardmap[x][y].setNum(0);
}
}
addRandomNum();
addRandomNum();
}
privatevoidaddRandomNum(){
//使用emptypoints将数字为0的card提取出来,并随即选择一个空card赋值
emptyPoints.clear();
for(inty=0;y<4;y++){
for(intx=0;x<4;x++){
if(cardmap[x][y].getNum()<=0){
emptyPoints.add(newPoint(x,y));
}
}
}
Pointp=emptyPoints.remove((int)(Math.random()*emptyPoints.size()));
//2和4出现的概率控制在1:9
cardmap[p.x][p.y].setNum(Math.random()>0.1?2:4);
}
//左滑方法
privatevoidswipeLeft(){
//merge作为判断能否滑动的flag
booleanmerge=false;
for(inty=0;y<4;y++){
for(intx=0;x<4;x++){
for(intx1=x+1;x1<4;x1++){
if(cardmap[x1][y].getNum()>0){
if(cardmap[x][y].getNum()<=0){
cardmap[x][y].setNum(cardmap[x1][y].getNum());
cardmap[x1][y].setNum(0);
merge=true;
x--;
}elseif(cardmap[x][y].equal(cardmap[x1][y])){
cardmap[x][y].setNum(cardmap[x][y].getNum()*2);
cardmap[x1][y].setNum(0);
MainActivity.getMainActivity().addScore(cardmap[x][y].getNum());
merge=true;
}
break;
}
}
}
}
if(merge){
addRandomNum();
checkComplete();
}
}
//下滑
privatevoidswipeDown(){
booleanmerge=false;
for(intx=0;x<4;x++){
for(inty=3;y>=0;y--){
for(inty1=y-1;y1>=0;y1--){
if(cardmap[x][y1].getNum()>0){
if(cardmap[x][y].getNum()<=0){
cardmap[x][y].setNum(cardmap[x][y1].getNum());
cardmap[x][y1].setNum(0);
y++;
merge=true;
}elseif(cardmap[x][y].equal(cardmap[x][y1])){
cardmap[x][y].setNum(cardmap[x][y].getNum()*2);
cardmap[x][y1].setNum(0);
MainActivity.getMainActivity().addScore(cardmap[x][y].getNum());
merge=true;
}
break;
}
}
}
}
if(merge){
addRandomNum();
checkComplete();
}
}
//上滑
privatevoidswipeUp(){
booleanmerge=false;
for(intx=0;x<4;x++){
for(inty=0;y<4;y++){
for(inty1=y+1;y1<4;y1++){
if(cardmap[x][y1].getNum()>0){
if(cardmap[x][y].getNum()<=0){
cardmap[x][y].setNum(cardmap[x][y1].getNum());
cardmap[x][y1].setNum(0);
y--;
merge=true;
}elseif(cardmap[x][y].equal(cardmap[x][y1])){
cardmap[x][y].setNum(cardmap[x][y].getNum()*2);
cardmap[x][y1].setNum(0);
MainActivity.getMainActivity().addScore(cardmap[x][y].getNum());
merge=true;
}
break;
}
}
}
}
if(merge){
addRandomNum();
checkComplete();
}
}
//右滑
privatevoidswipeRight(){
booleanmerge=false;
for(inty=0;y<4;y++){
for(intx=3;x>=0;x--){
for(intx1=x-1;x1>=0;x1--){
if(cardmap[x1][y].getNum()>0){
if(cardmap[x][y].getNum()<=0){
cardmap[x][y].setNum(cardmap[x1][y].getNum());
cardmap[x1][y].setNum(0);
x++;
merge=true;
}elseif(cardmap[x][y].equal(cardmap[x1][y])){
cardmap[x][y].setNum(cardmap[x][y].getNum()*2);
cardmap[x1][y].setNum(0);
MainActivity.getMainActivity().addScore(cardmap[x][y].getNum());
merge=true;
}
break;
}
}
}
}
if(merge){
addRandomNum();
checkComplete();
}
}
//如果有空卡片或者相邻的值相同卡片则游戏还能进行
publicvoidcheckComplete(){
booleancomplete=true;
ALL:
for(inty=0;y<4;y++){
for(intx=0;x<4;x++){
if(cardmap[x][y].getNum()==0||
x>0&&cardmap[x][y].equal(cardmap[x-1][y])||
x<3&&cardmap[x][y].equal(cardmap[x+1][y])||
y>0&&cardmap[x][y].equal(cardmap[x][y-1])||
y<3&&cardmap[x][y].equal(cardmap[x][y+1])){
complete=false;
breakALL;
}
}
}
//游戏结束弹出alert提示窗口
if(complete){
newAlertDialog.Builder(getContext()).setTitle("大林哥温馨提示").setMessage("游戏结束").setPositiveButton("重来",newDialogInterface.OnClickListener(){
@Override
publicvoidonClick(DialogInterfacearg0,intarg1){
startGame();
}
}).show();
}
}
privateCard[][]cardmap=newCard[4][4];
privateList<Point>emptyPoints=newArrayList<Point>();
}
主类MainActivity.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
packagecom.example.administrator.game2048;
importandroid.app.Activity;
import android.os.Bundle;
importandroid.widget.TextView;
publicclassMainActivityextendsActivity{
publicMainActivity(){
mainActivity=this;
}
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvscore=(TextView)findViewById(R.id.tvScore);
}
publicvoidclearScore(){
score=0;
showScore();
}
publicvoidshowScore(){
tvscore.setText(score+"");
}
publicvoidaddScore(ints){
score+=s;
showScore();
}
privateTextViewtvscore;
privateintscore=0;
publicstaticMainActivitymainActivity=null;
publicstaticMainActivitygetMainActivity(){
returnmainActivity;
}
}
Card.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
packagecom.example.administrator.game2048;
importandroid.content.Context;
import android.view.Gravity;
importandroid.view.View;
import android.widget.FrameLayout;
importandroid.widget.TextView;
publicclassCardextendsFrameLayout{
publicCard(Contextcontext){
super(context);
LayoutParamslp=null;
Viewbackground=newView(getContext());
//参数-1表示layoutparams填充满整个父容器
lp=newLayoutParams(-1,-1);
//设置卡片之间有10像素的间隔
lp.setMargins(10,10,0,0);
background.setBackgroundColor(0x33ffffff);
addView(background,lp);
label=newTextView(getContext());
label.setTextSize(28);
label.setGravity(Gravity.CENTER);
lp=newLayoutParams(-1,-1);
lp.setMargins(10,10,0,0);
addView(label,lp);
setNum(0);
}
privateintn=0;
publicintgetNum(){
returnn;
}
//设置数字及对应的背景颜色
publicvoidsetNum(intn){
this.n=n;
if(n<=0){
label.setText("");
}else{
label.setText(n+"");
}
switch(n){
case0:
label.setBackgroundColor(0x00000000);
break;
case2:
label.setBackgroundColor(0xffeee4da);
break;
case4:
label.setBackgroundColor(0xffede0c8);
break;
case8:
label.setBackgroundColor(0xfff2b179);
break;
case16:
label.setBackgroundColor(0xfff59563);
break;
case32:
label.setBackgroundColor(0xfff67c5f);
break;
case64:
label.setBackgroundColor(0xfff65e3b);
break;
case128:
label.setBackgroundColor(0xffedcf72);
break;
case256:
label.setBackgroundColor(0xffedcc61);
break;
case512:
label.setBackgroundColor(0xffedc850);
break;
case1024:
label.setBackgroundColor(0xffedc53f);
break;
case2048:
label.setBackgroundColor(0xffedc22e);
break;
default:
label.setBackgroundColor(0xff3c3a32);
break;
}
}
//判断卡片是否相等
publicbooleanequal(Cardo){
returngetNum()==o.getNum();
}
privateTextViewlabel;
}
转载请注明:静觅 »Android开发之2048安卓版
0 0
- Android开发之2048安卓版
- android开发日志之2048安卓版
- Android开发之蓝牙开发
- Android 开发之 手势开发
- Android开发之Hybrid开发
- Android开发之开发入门教程
- android 开发之蓝牙开发
- Android开发之Hybrid开发
- android开发之TabActivity
- android 开发之布局
- android之NDK开发
- Android开发之计算器
- Android开发之PreferenceActivity
- Android开发之ListView
- Android开发之PopupWindow
- Android开发之Linkify
- Android开发之SurfaceView
- Android开发之PreferenceActivity .
- 617C. Watering Flowers【几何】
- js显示当前日期或者前几天的日期
- 常用几何计算算法
- 19个MySQL性能优化要点解析
- (Genymotion)解决android: The connection to adb is down, and a severe error has occured.
- Android开发之2048安卓版
- 1. A "Getting Started" Guide for ROS and TurtleBot
- python 闭包
- Mac OS X上设置adb命令的环境变量。
- usb端点四种传输类型
- android 震动的实现
- Linux相关
- 迭代器模式
- Websocket(2)--接口说明