服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - 基于Android平台实现拼图小游戏

基于Android平台实现拼图小游戏

2022-09-08 16:27qq_3526022 Android

这篇文章主要为大家详细介绍了基于Android平台实现拼图小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一、需求描述

拼图是一款益智类经典游戏了,本游戏学习了一些前辈们的经验,整体来说讲,将图片用切图工具进行切割,监听用户手指滑动事件,当用户对凌乱的图片,在一定的时间内拼凑恢复成原来的样子,则成功闯关。 根据游戏不同的关卡对图片进行动态的切割。玩家可以在随意交换任意两张图片,通过遍历切割好的每块图片,将用户选中的图片,进行替换;
其中主要的功能为:

  • 动态对图片进行切割成所需要的份数。
  • 玩家任意点击的两张图片能够进行正确交换。
  • 实现交换图片的动画切换效果。
  • 实现过关逻辑。
  • 实现游戏时间逻辑控制。
  • 游戏结束和暂停。

二、主要功能分析

在拼图游戏开发过程中,实现的主要的功能;提供给用户所使用,具体功能分析如下所示:

1、编写切片工具:由于拼图游戏需要准备一个完整的图片,从直观上来看,我们不能每次都将一个完整的图片进行分割,如果是3*3,分成9块,4*4分成16份,这样带来的图片资源极大的混乱,不利于后期的维护,然后Andorid就提供了具体的方法来实现对特定图片的切图工具,通过传入的参数的不同,对图片分割成所需要的矩阵,并设置每块的宽高。利用两个for循环进行切图。并设置每块图片的大小位置和每块图片的块号下标Index。

2、自定义容器:自定义相对布局文件,用来存放切割好的图片,并设置图片之间的间隙,以及确定图片上下左右的关系。以及设置图片与容器的内边距设置。

3、实现图片交换:实现手指的监听事件,将对选中的两张图片进行位置的变换。

4、实现交换图片的动画效果:构造动画层,设置动画,监听动画

5、实现游戏过关逻辑:成功的判断,关卡的回调。

6、实现游戏时间逻辑:游戏时间的更新,以及Handler不断的回调,时间超时后游戏状态的处理,以及成功闯关后,游戏时间的变更。

7、游戏的结束与暂停:当用户返回主页面的时候,游戏能够暂停,当用户返回游戏的时候,游戏可以重新开始。

三、概要设计

1、**切图工具类**ImagePiece和ImageSplitterUtil。其中ImagePiece对Bitmap图片的块号与每一块图片的位置进行属性的基本设置;在切图工具类ImageSplitterUtil中,提供一个切图方法splitImage,将传入的Bitmap图片分割成Piece*Piece块,并设置每块宽度,将分割好的图片放入到List中。

2、自定义View:GamePintuLayout.java中运用的主要工具有:
单位转换:将传入的数值进行单位转换成3PX,使得屏幕可识别。

?
1
2
3
//单位的转换
mMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
 3, getResources().getDisplayMetrics());
?
1
2
3
4
5
6
7
8
9
/*获取多个参数的最小值*/
 private int min(int... params) {
 int min = params[0];
 for (int param : params) {
  if (param < min)
  min = param;
 }
 return min;
 }

3、图片乱序的实现:

?
1
2
3
4
5
6
// 使用sort完成我们的乱序
Collections.sort(mItemBitmaps, new Comparator<ImagePiece>() {
  public int compare(ImagePiece a, ImagePiece b) {
  return Math.random() > 0.5 ? 1 : -1;
  }
 });

4、图片的交换:在监听事件中,当用户选中了两张图片,则对图片进行交换,并对第一次选中的图片,进行样式的设置。如果用户重复点击一张图片,则消除图片的选中状态。通过给图片设置的Tag,找到Id, 然后找到Bitmap图片的index,然后进行交换同时交换Tag。

?
1
2
3
4
5
6
String firstTag = (String) mFirst.getTag();
String secondTag = (String) mSecond.getTag();
mFirst.setImageBitmap(secondBitmap);
mSecond.setImageBitmap(firstBitmap);
mFirst.setTag(secondTag);
mSecond.setTag(firstTag);

5、图片动画切换:构造动画层,mAnimLayout并addView,然后在exchangeView中,先构造动画层,复制两个ImageView,为两个ImageView设置动画,监听动画的开始,让原本的View隐藏,结束以后,将图片交换,将图片显示,移除动画层。

6、通过接口对关卡进行回调:实现关卡进阶、时间控制、游戏结束接口。并利用Handler更新UI,在nextLevel方法中实现移除之前的View布局,以及将动画层设置为空,增加mColumn++,然后初始化initBitmap()进行重新切图乱序并InitItem()设置图片的图片宽高。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public interface GamePintuListener {
 void nextLevel(int nextLevel);
 void timechanged(int currentTime);
 void gameover();
 }
 
public GamePintuListener mListener;
 /*
 * 设置接口回调
 */
public void setOnGamePintuListener(GamePintuListener mListener) {
 this.mListener = mListener;
 }

7、根据当前等级设置游戏的时间:mTime = (int)Math.pow(2, level)*60;进而更行我们的Handler。mHandler.sendEmptyMessageDelayed(TIME_CHANGED, 1000)使得时间动态的减一。

8、游戏暂停开始:

mHandler.removeMessages(TIME_CHANGED);
而重新开始游戏则是:mHandler.sendEmptyMessage(TIME_CHANGED);

四、系统实现

工具类:

  • ImagePiece.java
  • ImageSplitterUtil.java

自定义容器:

  • GamePintuLayout.java

ImagePiece.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
package com.example.utils;
import android.graphics.Bitmap;
public class ImagePiece {
 
 private int index;// 当前第几块
 private Bitmap bitmap;// 指向当前图片
 
 public ImagePiece()
 {
 }
 
 public ImagePiece(int index, Bitmap bitmap) {
 this.index = index;
 this.bitmap = bitmap;
 }
 
 public int getIndex() {
 return index;
 }
 
 public void setIndex(int index) {
 this.index = index;
 }
 
 public Bitmap getBitmap() {
 return bitmap;
 }
 
 public void setBitmap(Bitmap bitmap) {
 this.bitmap = bitmap;
 }
 
 public String toString() {
 return "ImagePiece [index=" + index + ", bitmap=" + bitmap + "]";
 }
}

ImageSplitterUtil.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
//ImageSplitterUtil.java
package com.example.utils;
 
import java.util.ArrayList;
import java.util.List;
 
import android.graphics.Bitmap;
 
public class ImageSplitterUtil {
 /*
 * 传入Bitmap切成Piece*piece块,返回List<ImagePiece>
 */
 public static List<ImagePiece> splitImage(Bitmap bitmap, int piece) {
 List<ImagePiece> imagePieces = new ArrayList<ImagePiece>();
 
 int width = bitmap.getWidth();
 int height = bitmap.getHeight();
 
 // 每一块的宽度
 int pieceWidth = Math.min(width, height) / piece;
 
 for (int i = 0; i < piece; i++)// 行
 {
  for (int j = 0; j < piece; j++)// 列
  {
  ImagePiece imagePiece = new ImagePiece();
  imagePiece.setIndex(j + i * piece);
 
  int x = j * pieceWidth;
  int y = i * pieceWidth;
  imagePiece.setBitmap(Bitmap.createBitmap(bitmap, x, y,
   pieceWidth, pieceWidth));
  imagePieces.add(imagePiece);
  }
 }
 
 return imagePieces;
 }
}

GamePintuLayout.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
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
package com.example.game_pintu.view;
 
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
 
import com.example.game_pintu.R;
import com.example.utils.ImagePiece;
import com.example.utils.ImageSplitterUtil;
 
public class GamePintuLayout extends RelativeLayout implements OnClickListener {
 
 private int mColumn = 3;
 /*
 * 容器内边距
 */
 private int mPadding;
 /*
 * 每张小图之间的距离(横纵)dp
 */
 private int mMargin = 3;
 
 private ImageView[] mGamePintuItems;
 private int mItemWidth;
 
 /*
 * 游戏的图片
 */
 private Bitmap mBitmap;
 
 private List<ImagePiece> mItemBitmaps;
 private boolean once;
 /*
 * 游戏面板的宽度
 */
 private int mWidth;
 private boolean isGameSuccess;
 private boolean isGameOver;
 
 public interface GamePintuListener {
 void nextLevel(int nextLevel);
 
 void timechanged(int currentTime);
 
 void gameover();
 }
 
 public GamePintuListener mListener;
 
 /*
 * 设置接口回调
 */
 public void setOnGamePintuListener(GamePintuListener mListener) {
 this.mListener = mListener;
 }
 
 private int level = 1;
 private static final int TIME_CHANGED = 0x110;
 private static final int NEXT_LEVEL = 0x111;
 
 private Handler mHandler = new Handler() {
 public void handleMessage(android.os.Message msg) {
  switch (msg.what) {
  case TIME_CHANGED:
  if(isGameSuccess||isGameOver||isPause)
   return;
 
  if(mListener !=null)
  {
   mListener.timechanged(mTime);
   if(mTime ==0)
   {
   isGameOver = true;
   mListener.gameover();
   return;
   }
  }
  mTime--;
  mHandler.sendEmptyMessageDelayed(TIME_CHANGED, 1000);
 
  break;
  case NEXT_LEVEL:
  level = level + 1;
  if (mListener != null) {
   mListener.nextLevel(level);
  } else {
   nextLevel();
  }
  break;
 
  default:
  break;
  }
 };
 };
 
 private boolean isTimeEnabled = false;
 private int mTime;
 /*
 * 设置是否开启时间
 */
 public void setTimeEnabled(boolean isTimeEnabled) {
 this.isTimeEnabled = isTimeEnabled;
 }
 
 public GamePintuLayout(Context context) {
 this(context, null);
 }
 
 public GamePintuLayout(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 
 }
 
 public GamePintuLayout(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 init();
 }
 
 private void init() {
 /*
  * 单位的转换3--px
  */
 mMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
  3, getResources().getDisplayMetrics());
 mPadding = min(getPaddingLeft(), getPaddingRight(), getPaddingTop(),
  getPaddingBottom());
 
 }
 
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 // 取宽和高的最小值
 mWidth = Math.min(getMeasuredHeight(), getMeasuredWidth());
 
 if (!once) {
  // 进行切图,以及排序
  initBitmap();
  // 设置ImageView(Item)宽高等属性
  initItem();
 
  //判断是否开启时间
  checkTimeEnable();
 
  once = true;
 }
 setMeasuredDimension(mWidth, mWidth);
 }
 
 private void checkTimeEnable() {
 if(isTimeEnabled){
  //根据当前等级设置时间
  contTimeBaseLevel();
  mHandler.sendEmptyMessage(TIME_CHANGED);
 }
 }
 
 private void contTimeBaseLevel() {
 mTime = (int)Math.pow(2, level)*60;
 }
 
 // 进行切图,以及排序
 private void initBitmap() {
 // TODO Auto-generated method stub
 if (mBitmap == null) {
  mBitmap = BitmapFactory.decodeResource(getResources(),
   R.drawable.image1);
 
 }
 mItemBitmaps = ImageSplitterUtil.splitImage(mBitmap, mColumn);
 // 使用sort完成我们的乱序
 Collections.sort(mItemBitmaps, new Comparator<ImagePiece>() {
  public int compare(ImagePiece a, ImagePiece b) {
  return Math.random() > 0.5 ? 1 : -1;
  }
 });
 }
 
 // 设置ImageView(Item)宽高等属性
 private void initItem() {
 mItemWidth = (mWidth - mPadding * 2 - mMargin * (mColumn - 1))
  / mColumn;
 mGamePintuItems = new ImageView[mColumn * mColumn];
 
 // 生成Item, 设置Rule;
 for (int i = 0; i < mGamePintuItems.length; i++) {
  ImageView item = new ImageView(getContext());
  item.setOnClickListener(this);
 
  item.setImageBitmap(mItemBitmaps.get(i).getBitmap());
 
  mGamePintuItems[i] = item;
  item.setId(i + 1);
  // item中tag存储了index
 
  item.setTag(i + "_" + mItemBitmaps.get(i).getIndex());
 
  RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
   mItemWidth, mItemWidth);
 
  // 设置item艰横向间隙,通过RightMargin
  // 不是最后一列
  if ((i + 1) % mColumn != 0) {
  lp.rightMargin = mMargin;
  }
  // 不是第一列
  if (i % mColumn != 0) {
  lp.addRule(RelativeLayout.RIGHT_OF,
   mGamePintuItems[i - 1].getId());
  }
  // 如果不是第一行,设置TopMargin and rule
  if ((i + 1) > mColumn) {
  lp.topMargin = mMargin;
  lp.addRule(RelativeLayout.BELOW,
   mGamePintuItems[i - mColumn].getId());
  }
  addView(item, lp);
 
 }
 }
 public void restart()
 {
 isGameOver = false;
 mColumn--;
 nextLevel();
 }
 private boolean isPause;
 public void pause()
 {
 isPause = true;
 mHandler.removeMessages(TIME_CHANGED);
 }
 public void resume()
 {
 if(isPause)
 {
  isPause = false;
  mHandler.sendEmptyMessage(TIME_CHANGED);
 }
 }
 public void nextLevel() {
 this.removeAllViews();
 mAnimLayout = null;
 mColumn++;
 isGameSuccess = false;
 checkTimeEnable();
 initBitmap();
 initItem();
 }
 
 /*
 * 获取多个参数的最小值
 */
 private int min(int... params) {
 int min = params[0];
 for (int param : params) {
  if (param < min)
  min = param;
 }
 return min;
 }
 
 private ImageView mFirst;
 private ImageView mSecond;
 
 public void onClick(View v) {
 
 if (isAniming)
  return;
 
 // 两次点击同一个Item
 if (mFirst == v) {
  mFirst.setColorFilter(null);
  mFirst = null;
  return;
 }
 if (mFirst == null) {
  mFirst = (ImageView) v;
  mFirst.setColorFilter(Color.parseColor("#55FF0000"));
 } else {
  mSecond = (ImageView) v;
  // 交换我们的Item
  exchangeView();
 }
 }
 
 /*
 * 动画层
 */
 private RelativeLayout mAnimLayout;
 private boolean isAniming;
 
 /*
 * 交换Item
 */
 private void exchangeView() {
 mFirst.setColorFilter(null);
 // 构造动画层
 setUpAnimLayout();
 
 ImageView first = new ImageView(getContext());
 final Bitmap firstBitmap = mItemBitmaps.get(
  getImageIdByTag((String) mFirst.getTag())).getBitmap();
 first.setImageBitmap(firstBitmap);
 LayoutParams lp = new LayoutParams(mItemWidth, mItemWidth);
 lp.leftMargin = mFirst.getLeft() - mPadding;
 lp.topMargin = mFirst.getTop() - mPadding;
 first.setLayoutParams(lp);
 mAnimLayout.addView(first);
 
 ImageView second = new ImageView(getContext());
 final Bitmap secondBitmap = mItemBitmaps.get(
  getImageIdByTag((String) mSecond.getTag())).getBitmap();
 second.setImageBitmap(secondBitmap);
 LayoutParams lp2 = new LayoutParams(mItemWidth, mItemWidth);
 lp2.leftMargin = mSecond.getLeft() - mPadding;
 lp2.topMargin = mSecond.getTop() - mPadding;
 second.setLayoutParams(lp2);
 mAnimLayout.addView(second);
 
 // 设置动画
 TranslateAnimation anim = new TranslateAnimation(0, mSecond.getLeft()
  - mFirst.getLeft(), 0, mSecond.getTop() - mFirst.getTop());
 anim.setDuration(300);
 anim.setFillAfter(true);
 first.startAnimation(anim);
 
 TranslateAnimation animSecond = new TranslateAnimation(0,
  -mSecond.getLeft() + mFirst.getLeft(), 0, -mSecond.getTop()
   + mFirst.getTop());
 animSecond.setDuration(300);
 animSecond.setFillAfter(true);
 second.startAnimation(animSecond);
 
 // 监听动画
 anim.setAnimationListener(new AnimationListener() {
 
  @Override
  public void onAnimationStart(Animation animation) {
  mFirst.setVisibility(View.INVISIBLE);
  mSecond.setVisibility(View.INVISIBLE);
 
  isAniming = true;
  }
 
  @Override
  public void onAnimationRepeat(Animation animation) {
 
  }
 
  @Override
  public void onAnimationEnd(Animation animation) {
  String firstTag = (String) mFirst.getTag();
  String secondTag = (String) mSecond.getTag();
 
  mFirst.setImageBitmap(secondBitmap);
  mSecond.setImageBitmap(firstBitmap);
 
  mFirst.setTag(secondTag);
  mSecond.setTag(firstTag);
 
  mFirst.setVisibility(View.VISIBLE);
  mSecond.setVisibility(View.VISIBLE);
 
  mFirst = mSecond = null;
  // 判断游戏用户是否成功
  checkSuccess();
  isAniming = false;
  }
 
 });
 
 }
 
 private void checkSuccess() {
 boolean isSuccess = true;
 for (int i = 0; i < mGamePintuItems.length; i++) {
  ImageView imageView = mGamePintuItems[i];
  if (getImageIndexByTag((String) imageView.getTag()) != i) {
  isSuccess = false;
  }
 }
 if (isSuccess) {
  isGameSuccess = true;
  mHandler.removeMessages(TIME_CHANGED);
 
  Toast.makeText(getContext(), "Success, level up!",
   Toast.LENGTH_LONG).show();
  mHandler.sendEmptyMessage(NEXT_LEVEL);
 }
 }
 
 public int getImageIdByTag(String tag) {
 String[] split = tag.split("_");
 return Integer.parseInt(split[0]);
 }
 
 public int getImageIndexByTag(String tag) {
 String[] split = tag.split("_");
 return Integer.parseInt(split[1]);
 }
 
 /**
 * 构造我们的动画层
 */
 private void setUpAnimLayout() {
 if (mAnimLayout == null) {
  mAnimLayout = new RelativeLayout(getContext());
  addView(mAnimLayout);
 } else {
  mAnimLayout.removeAllViews();
 }
 }
 
}

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
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
package com.example.game_pintu;
 
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.widget.TextView;
 
import com.example.game_pintu.view.GamePintuLayout;
import com.example.game_pintu.view.GamePintuLayout.GamePintuListener;
 
public class MainActivity extends Activity {
 
 private GamePintuLayout mGamePintuLayout;
 private TextView mLevel;
 private TextView mTime;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mTime = (TextView) findViewById(R.id.id_time);
 mLevel = (TextView) findViewById(R.id.id_level);
 mGamePintuLayout = (GamePintuLayout) findViewById(R.id.id_gamepintu);
 mGamePintuLayout.setTimeEnabled(true);
 mGamePintuLayout.setOnGamePintuListener(new GamePintuListener() {
 
  @Override
  public void timechanged(int currentTime) {
  mTime.setText("" + currentTime);
  }
 
  @Override
  public void nextLevel(final int nextLevel) {
  new AlertDialog.Builder(MainActivity.this)
   .setTitle("GAME INFO").setMessage("LEVEL UP!!!")
   .setPositiveButton("NEXT LEVEL", new OnClickListener() {
 
    @Override
    public void onClick(DialogInterface dialog,
     int which) {
    mGamePintuLayout.nextLevel();
    mLevel.setText("" + nextLevel);
    }
 
   }).show();
  }
 
  @Override
  public void gameover() {
  new AlertDialog.Builder(MainActivity.this)
   .setTitle("GAME INFO").setMessage("GAME OVER!!!")
   .setPositiveButton("RESTART", new OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog,
     int which) {
    // mGamePintuLayout.nextLevel();
    mGamePintuLayout.restart();
    }
 
   }).setNegativeButton("QUIT", new OnClickListener() {
 
    @Override
    public void onClick(DialogInterface dialog,
     int which) {
    finish();
    }
   }).show();
  }
 });
 }
 @Override
 protected void onPause() {
 super.onPause();
 mGamePintuLayout.pause();
 }
 @Override
 protected void onResume() {
 super.onResume();
 mGamePintuLayout.resume();
 }
}

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
34
35
36
37
38
39
40
41
42
43
44
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context="${relativePackage}.${activityClass}" >
 
 <com.example.game_pintu.view.GamePintuLayout
 android:id="@+id/id_gamepintu"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:layout_centerInParent="true"
 android:padding="3dp" />
 
 <RelativeLayout
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:layout_above="@id/id_gamepintu" >
 
 <TextView
  android:id="@+id/id_level"
  android:layout_width="40dp"
  android:layout_height="40dp"
  android:background="@drawable/textbg"
  android:gravity="center"
  android:padding="4dp"
  android:text="1"
  android:textColor="#EA7821"
  android:textSize="10sp"
  android:textStyle="bold" />
 
 <TextView
  android:id="@+id/id_time"
  android:layout_width="40dp"
  android:layout_height="40dp"
  android:layout_alignParentRight="true"
  android:background="@drawable/textbg"
  android:gravity="center"
  android:padding="4dp"
  android:text="50"
  android:textColor="#EA7821"
  android:textSize="10sp"
  android:textStyle="bold" />
 </RelativeLayout>
</RelativeLayout>

in drawable new textbg.xml

?
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="oval" >
 <stroke
 android:width="2px"
 android:color="#1579DB"
 />
 <solid android:color="#B4CDE6"/>
</shape>

五、测试

开始游戏

基于Android平台实现拼图小游戏

成功

基于Android平台实现拼图小游戏

成功进阶

基于Android平台实现拼图小游戏

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_35260622/article/details/51690256

延伸 · 阅读

精彩推荐