Android游戏——2048的设计(2).doc_第1页
Android游戏——2048的设计(2).doc_第2页
Android游戏——2048的设计(2).doc_第3页
Android游戏——2048的设计(2).doc_第4页
Android游戏——2048的设计(2).doc_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Android游戏2048的设计(2)游戏运行界面如下:实现的功能有: 1.有4x4,5x5,6x6三种规则 2.记录历史最高分 3.使用纯色块 4.保存游戏 5.开启音效 6.更换背景图开发工具用的是Android Studio游戏的思路并不复杂,甚至可以说是挺简单的。 首先要自定义一个View,作为可滑动的方块(其实滑动效果是通过改变数字与颜色来模拟实现的),这个View要继承于FrameLayout 每一种不同数值的方块有不同的颜色,通过设置“setBackgroundColor”来实现。public class Card extends FrameLayout private TextView label; private int num = 0; /用于判断是否纯色块 public boolean flag; public Card(Context context) super(context); label = new TextView(context); label.setGravity(Gravity.CENTER); label.setTextSize(24); label.setBackgroundColor(Color.parseColor(#77E8E2D8); LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); lp.setMargins(5, 5, 0, 0); addView(label, lp); public void setNum(int num) this.num = num; if (num = 0) label.setText(); label.setBackgroundColor(Color.parseColor(#77E8E2D8); else if(!flag) label.setText(num + ); changeCardColor(); public int getNum() return num; public void changeCardColor() switch (num) case 2: label.setBackgroundColor(Color.parseColor(#5DB8E8); break; case 4: label.setBackgroundColor(Color.parseColor(#A52812); break; case 8: label.setBackgroundColor(Color.parseColor(#0E7171); break; case 16: label.setBackgroundColor(Color.parseColor(#C0BB39); break; case 32: label.setBackgroundColor(Color.parseColor(#623889); break; case 64: label.setBackgroundColor(Color.parseColor(#5C7235); break; case 128: label.setBackgroundColor(Color.parseColor(#826FA3); break; case 256: label.setBackgroundColor(Color.parseColor(#355659); break; case 512: label.setBackgroundColor(Color.parseColor(#BB719B); break; case 1024: label.setBackgroundColor(Color.parseColor(#9B8B53); break; case 2048: label.setBackgroundColor(Color.parseColor(#196A5D); break; default: label.setBackgroundColor(Color.parseColor(#8A7760); public boolean equals(Card c) return this.getNum() = c.getNum(); 此外,可以看到不管是4x4规则的或者5x5,6x6的,整个可滑动区域都是一个正方形,方块平均分布,因此可以自定义一个View,继承于GridLayout,为之添加多个Card 。 GameView 的重点在于方块的滑动判断以及实现滑动效果。 SoundPool 的使用方法在Android5.0之后发生了改变,所以需要在代码中判断当前系统版本,从而使用不同的初始化方法。public class GameView extends GridLayout / 存储所有方块 private Card Cards; / 当前游戏的行数与列数 private int Row; / 游戏记录 private SharedPreferences gameRecord; / 存储游戏音效开关记录 private SharedPreferences GameSettings; private SharedPreferences.Editor grEditor; public ScoreChangeListen scoreChangeListen=null; private Context context; /当前得分 private int Score; public SoundPool soundPool; / private HashMap soundID; private int soundID; private boolean soundSwitch; private class Point public Point(int x, int y) this.x = x; this.y = y; int x; int y; public GameView(Context context, AttributeSet attrs, int defStyleAttr) super(context, attrs, defStyleAttr); this.context = context; TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.ViewSet); Row = mTypedArray.getInt(R.styleable.ViewSet_Row, 5); mTypedArray.recycle(); super.setColumnCount(Row); init(); public GameView(Context context, AttributeSet attrs) super(context, attrs); this.context = context; TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.ViewSet); Row = mTypedArray.getInt(R.styleable.ViewSet_Row, 5); mTypedArray.recycle(); super.setColumnCount(Row); init(); public GameView(Context context) super(context); this.context = context; init(); / 初始化 private void init() gameRecord = context.getSharedPreferences(GameRecord, Context.MODE_PRIVATE); GameSettings = context.getSharedPreferences(GameSettings, Context.MODE_PRIVATE); boolean flag=GameSettings.getBoolean(SolidColorSwitch,false); soundSwitch=GameSettings.getBoolean(SoundSwitch,false); /SoundPool的构建方法在5.0系统之后发生了变化 if (Build.VERSION.SDK_INT 21) soundPool = new SoundPool(1,AudioManager.STREAM_MUSIC,0); else SoundPool.Builder builder = new SoundPool.Builder(); builder.setMaxStreams(1); AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder(); attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC); builder.setAudioAttributes(attrBuilder.build(); soundPool = builder.build(); soundID=soundPool.load(context,R.raw.sound,1); grEditor = gameRecord.edit(); Cards = new CardRowRow; for (int y = 0; y Row; y+) for (int x = 0; x Row; x+) Cardsxy = new Card(context); Cardsxy.flag=flag; / 添加两个初始方块 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) - 5) / Row; / 添加方块 addCard(cardWidth); / 计算分数 private void countScore(int num) Score = Score + num; if(scoreChangeListen!=null) scoreChangeListen.OnNowScoreChange(Score); if(soundSwitch) soundPool.play(soundID, 1, 1, 0, 0, 1); / 添加方块 private void addCard(int cardWidth) for (int y = 0; y Row; y+) for (int x = 0; x Row; x+) addView(Cardsxy, cardWidth, cardWidth); / 生成伪随机方块 private void randomCard() List points = new ArrayList(); for (int x = 0; x Row; x+) for (int y = 0; y Row; y+) / 如果还有空白方块 if (Cardsxy.getNum() = 0) points.add(new Point(x, y); if (points.size() = 0) return; int index = points.size() / 2; Cardspoints.get(index).xpoints.get(index).y.setNum(2); / 左移 private void moveLeftCard() allMoveLeft(); for (int y = 0; y Row; y+) for (int x = 0; x Row - 1; x+) if (Cardsxy.getNum() != 0) if (Cardsxy.equals(Cardsx + 1y) int num = Cardsxy.getNum(); Cardsxy.setNum(2 * num); Cardsx + 1y.setNum(0); countScore(num); allMoveLeft(); randomCard(); / 右移 private void moveRightCard() allMoveRight(); for (int y = 0; y 0; x-) if (Cardsxy.getNum() != 0) if (Cardsxy.equals(Cardsx - 1y) int num = Cardsxy.getNum(); Cardsxy.setNum(2 * num); Cardsx - 1y.setNum(0); countScore(num); allMoveRight(); randomCard(); / 上移 private void moveUpCard() allMoveUp(); for (int x = 0; x Row; x+) for (int y = 0; y Row - 1; y+) if (Cardsxy.getNum() != 0) if (Cardsxy.equals(Cardsxy + 1) int num = Cardsxy.getNum(); Cardsxy.setNum(2 * num); Cardsxy + 1.setNum(0); countScore(num); allMoveUp(); randomCard(); / 下移 private void moveDownCard() allMoveDown(); for (int x = 0; x 0; y-) if (Cardsxy.getNum() != 0) if (Cardsxy.equals(Cardsxy - 1) int num = Cardsxy.getNum(); Cardsxy.setNum(2 * num); Cardsxy - 1.setNum(0); countScore(num); allMoveDown(); randomCard(); / 全部左移 private void allMoveLeft() for (int y = 0; y Row; y+) int i = 0; for (int x = 0; x Row; x+) if (Cardsxy.getNum() != 0) int num = Cardsxy.getNum(); Cardsxy.setNum(0); Cardsi+y.setNum(num); / 全部右移 private void allMoveRight() for (int y = 0; y -1; x-) if (Cardsxy.getNum() != 0) int num = Cardsxy.getNum(); Cardsxy.setNum(0); Cardsi-y.setNum(num); / 全部上移 private void allMoveUp() for (int x = 0; x Row; x+) int i = 0; for (int y = 0; y Row; y+) if (Cardsxy.getNum() != 0) int num = Cardsxy.getNum(); Cardsxy.setNum(0); Cardsxi+.setNum(num); / 全部下移 private void allMoveDown() for (int x = 0; x -1; y-) if (Cardsxy.getNum() != 0) int num = Cardsxy.getNum(); Cardsxy.setNum(0); Cardsxi-.setNum(num); / 触屏事件监听 float X; float Y; float OffsetX; float OffsetY; int HintCount = 0; public boolean isHalfway = true; public boolean onTouchEvent(MotionEvent event) / 为了避免当游戏结束时消息多次提示 if (HintCount = 1) return true; 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) moveRightCard(); else if (OffsetY 5) moveDownCard(); HintMessage(); break; return true; / 判断游戏是否结束 private boolean isOver() for (int y = 0; y Row; y+) for (int x = 0; x = 0 & Cardsx - 1y.equals(Cardsxy) | (x + 1 = 0 & Cardsxy - 1.equals(Cardsxy) | (y + 1 = Row - 1 & Cardsxy + 1.equals(Cardsxy) return false; return true; / 当游戏结束时提示信息 private oid HintMessage() if (isOver() Toast.makeText(getContext(), 游戏结束啦, Toast.LENGTH_SHORT).show(); HintCount=1; /重新开始 public void restart() for (int y = 0; y Row; y+) for (int x = 0; x Row; x+) Cardsxy.setNum(0); Score=0; HintCount=0; / 添加两个初始方块 randomCard(); randomCard(); /保存游戏 public void saveGame() grEditor.clear(); grEditor.putInt(Row, Row); grEditor.putInt(Score,Score); int k = 0; for (int i = 0; i Row; i+) for (int j = 0; j Row; j+) k+; String str = k + ; grEditor.putInt(str, Cardsij.getNum(); if( grEmit() Toast.makeText(context, 保存成功, Toast.LENGTH_SHORT).show(); else Toast.makeText(context, 保存失败,请重试, Toast.LENGTH_SHORT).show(); / 恢复游戏 public void recoverGame() int k = 0; for (int i = 0; i Row; i+) for (int j = 0; j Row; j+) k+; String str = k + ; int num = gameRecord.getInt(str, 0); Cardsij.setNum(num); Score=gameRecord.getInt(Score,0); scoreChangeListen.OnNowScoreChange(Score); 要注意的是,在GameView的构造函数中,需要读取GameView的一个自定义属性“Row”,如果没有指定则默认为5。该属性的定义在values文件夹的attrs.xml文件中。 这样,在布局文件中使用GameView时,先加上属性声明然后就可以为GameView设置显示行数了整个游戏界面是由GameActivity呈现的,该Activity通过Bundle 携带的数据使用不同的布局文件。public class GameActivity extends AppCompatActivity private GameView gameView; private TextView text_nowScore; private TextView text_highestScore; private TextView text_restart; private TextView text_saveGame; private ScoreChangeListen scoreChangeListen; / 游戏设置 private SharedPreferences gameSettings; private SharedPreferences.Editor gsEditor; / 历史最高分 private int highestScore; / 用于实现“在点击一次返回键退出程序”的效果 private boolean isExit = false; private boolean flag; private int temp; private Handler mHandler = new Handler() public void handleMessage(Message msg) super.handleMessage(msg); isExit = false; ; protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); getSupportActionBar().hide(); Intent intent = getIntent(); Bundle bundle = intent.getExtras(); int row = bundle.getInt(Row, 4); if (row = 4) setContentView(R.layout.activity_four); else if (row = 5) setContentView(R.layout.activity_five); else setContentView(R.layout.activity_six); init(); /判断是否需要恢复游戏记录 if (bundle.getBoolean(RecoverGame, false) gameView.recoverGame(); / 初始化 public void init() gameView = (GameView) findViewById(R.id.gameView_five); text_nowScore = (TextView) findViewById(R.id.nowScore); text_highestScore = (TextView) findViewById(R.id.highestScore); text_restart = (TextView) findViewById(R.id.restart); text_saveGame = (TextView) findViewById(R.id.save_game); gameSettings = getSharedPreferences(GameSettings, Context.MODE_PRIVATE); gsEditor = gameSettings.edit(); highestScore = gameSettings.getInt(HighestScore, 0); text_nowScore.setText(当前得分n + 0); text_highestScore.setText(最高得分n + highestScore); flag = true; LinearLayout rootLayout = (LinearLayout) findViewById(R.id.rootLayout); int themeIndex = gameSettings.getInt(ThemeIndex, 1); switch (themeIndex) case 1: rootLayout.setBackgroundResource(R.drawable.back1); break; case 2: rootLayout.setBackgroundResource(R.drawable.back2); break; case 3: rootLayout.setBackgroundResource(R.drawable.back3); break; case 4: rootLayout.setBackgroundResource(R.drawable.back4); break; case 5: rootLayout.setBackgroundResource(R.drawable.back5);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论