Android实现2048小游戏

这篇文章主要为大家介绍了Android实现2048小游戏的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例介绍了Android实现2048小游戏的相关代码,分享给大家供大家参考,具体内容如下

根据界面,主要实现4*4的格子方块比较麻烦,其他的都挺简单的.总体为实现4*4的格子,自定义GridLayout,并在其中添加触摸监听事件,进行一系列的操作,从而实现游戏的逻辑,最后再添加动画效果即可完成.
下面是设计思路:

一.GameView的设计

首先自定义一个类,继承GridLayout,添加两个构造方法

 public class GameView extends GridLayout { //两个必要的构造方法 public GameView(Context context) { super(context); initView(); } public GameView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } } 

接下来在initView()中实现设置GridLayout为四列,并且添加触摸事件监听.(监听方法还可以重写onTouchEvent(),返回值为true即可),判断触摸方向,主要是通过x轴和y轴的偏移量的比较

 //初始化变量的方法 public void initView(){ //设置只有四列 setColumnCount(4); //设置监听事件 setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: setX = event.getX(); setY = event.getY(); break; case MotionEvent.ACTION_UP: offsetX = event.getX() - setX; offsetY = event.getY() - setY; //判断滑动方向 if (Math.abs(offsetX) >= Math.abs(offsetY)) { if (offsetX > 0) { swipright(); } else if (offsetX <0) { swipleft(); } } else { if (offsetY > 0) { swipdown(); } else if (offsetY <0) { swipup(); } } break; } return true; } }); } 

监听事件实现后先放在那里,接下来把4*4的里面每个小格子设计成小卡片,每个卡片就是一个TextView,卡片设计很简单,需要什么就添加什么,默认数字为0,这个时候代表是空值,也就是空卡片.

 public class Card extends FrameLayout { public Card(Context context) { super(context); tvCard = new TextView(getContext()); tvCard.setTextSize(40f); tvCard.setGravity(Gravity.CENTER); LayoutParams lp = new LayoutParams(-1,-1); lp.setMargins(15,15,0,0); addView(tvCard, lp); } //卡片上的数字 private int num; private boolean is2048 = true; private void judgeIs2048(int num){ if (is2048){ if (2048==num){ Toast.makeText(getContext(),"恭喜赵莹达到2048",Toast.LENGTH_LONG).show(); is2048 = false; } } } public int getNum() { return num; } public void setNum(int num) { this.num = num; if (num<=0){ tvCard.setText(""); }else { //这里传进去的是字符串因此需要加上空字符 tvCard.setText(num+""); } switch (num) { case 0: tvCard.setBackgroundColor(0x33ffffff); break; case 2: tvCard.setBackgroundColor(0xffeee4da); break; case 4: tvCard.setBackgroundColor(0xffede0c8); break; case 8: tvCard.setBackgroundColor(0xfff2b179); break; case 16: tvCard.setBackgroundColor(0xfff59563); break; case 32: tvCard.setBackgroundColor(0xfff67c5f); break; case 64: tvCard.setBackgroundColor(0xfff65e3b); break; case 128: tvCard.setBackgroundColor(0xffedcf72); break; case 256: tvCard.setBackgroundColor(0xffedcc61); break; case 512: tvCard.setBackgroundColor(0xffedc850); break; case 1024: tvCard.setBackgroundColor(0xffedc53f); break; case 2048: tvCard.setBackgroundColor(0xffedc22e); break; default: tvCard.setBackgroundColor(0xff3c3a32); break; } judgeIs2048(num); } //判断是否相等,用于合并 public boolean equals(Card o) { return getNum()==o.getNum(); } //用于显示数字 private TextView tvCard; public TextView getTvCard() { return tvCard; } } 

卡片设计就需要添加到GameView里面,这个时候重写onSizeChanged()函数,这个在程序打开的时候运行一次,通过他来动态设计卡片大小,并且添加卡片和开始游戏.

 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, w, oldw, oldh); Config.CARD_WIDTH = (Math.min(w,h)-10)/4; AddCard(Config.CARD_WIDTH); StartGame(); } 

添加卡片,一开始全设置为0,也就是全部添加空卡片

 //添加卡片 private void AddCard(int CARD_WIDTH){ Card c; for (int x = 0;x<4;x++){ for (int y = 0;y<4;y++){ c = new Card(getContext()); c.setNum(0); addView(c, CARD_WIDTH, CARD_WIDTH); cardMap[y][x] = c; } } } 

游戏开始需要随机添加两张卡片,数值2或者4,出现比率9:1

 //开始游戏 public void StartGame(){ for (int y = 0;y<4;y++){ for (int x = 0;x<4;x++){ cardMap[y][x].setNum(0); } } AddRandomCard(); AddRandomCard(); } 

随机添加卡片设计

 //添加随机卡片 private void AddRandomCard(){ CardPoint.clear(); for (int y = 0;y<4;y++){ for (int x = 0;x<4;x++){ if (cardMap[x][y].getNum()<=0){ CardPoint.add(new Point(x,y)); } } } //把一张空卡片换成带数字的 Point p = CardPoint.remove((int)(Math.random()*CardPoint.size())); cardMap[p.x][p.y].setNum(Math.random()>0.1?2:4); MainActivity.getMainActivity().getAnimLayer().createScaleTo1(cardMap[p.x][p.y]); } 

这样大体框架就设计好了
接下来是滑动事件,这里只举例左滑

 private void swipleft(){ boolean status = false; for (int y = 0; y <4; y++) { for (int x = 0; x <4; x++) { for (int x1 = x+1; x1 <4; x1++) { if (cardMap[x1][y].getNum()>0) { if (cardMap[x][y].getNum()<=0) { MainActivity.getMainActivity().getAnimLayer().createMoveAnim(cardMap[x1][y],cardMap[x][y], x1, x, y, y); cardMap[x][y].setNum(cardMap[x1][y].getNum()); cardMap[x1][y].setNum(0); x--; status = true; }else if (cardMap[x][y].equals(cardMap[x1][y])) { MainActivity.getMainActivity().getAnimLayer().createMoveAnim(cardMap[x1][y], cardMap[x][y],x1, x, y, y); cardMap[x][y].setNum(cardMap[x][y].getNum() * 2); cardMap[x1][y].setNum(0); MainActivity.getMainActivity().addScore(cardMap[x][y].getNum()); status = true; } break; } } } } if (status){ AddRandomCard(); checkGame(); } } 

每次添加卡片还需要判断是否结束游戏

 //结束游戏 private void checkGame(){ boolean complete = true; ALL: for (int y = 0; y <4; y++) { for (int x = 0; x <4; x++) { if (cardMap[x][y].getNum()==0|| (x>0&&cardMap[x][y].equals(cardMap[x-1][y]))|| (x<3&&cardMap[x][y].equals(cardMap[x+1][y]))|| (y>0&&cardMap[x][y].equals(cardMap[x][y-1]))|| (y<3&&cardMap[x][y].equals(cardMap[x][y+1]))) { complete = false; break ALL; } } } if (complete) { Toast.makeText(getContext(), "游戏结束" + MainActivity.getMainActivity().getScore(), Toast.LENGTH_LONG).show(); } } 

设计总体上框架就是上面说的那些.

二.动画效果

动画效果主要是创建,移动,合并这三个效果,因此重写个继承FrameLayout的class,覆盖到游戏界面上,这样的目的可以通过MainActivity中实例化当前这个类,然后可以操作其方法,然后通过滑动来设置动画

 public class AnimLayer extends FrameLayout { public AnimLayer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public AnimLayer(Context context, AttributeSet attrs) { super(context, attrs); } public AnimLayer(Context context) { super(context); } public void createMoveAnim(final Card from,final Card to,int fromX,int toX,int fromY,int toY){ final Card c = getCard(from.getNum()); LayoutParams lp = new LayoutParams(Config.CARD_WIDTH, Config.CARD_WIDTH); lp.leftMargin = fromX*Config.CARD_WIDTH; lp.topMargin = fromY*Config.CARD_WIDTH; c.setLayoutParams(lp); if (to.getNum()<=0) { to.getTvCard().setVisibility(View.INVISIBLE); } TranslateAnimation ta = new TranslateAnimation(0, Config.CARD_WIDTH*(toX-fromX), 0, Config.CARD_WIDTH*(toY-fromY)); ta.setDuration(100); ta.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationRepeat(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { to.getTvCard().setVisibility(View.VISIBLE); recycleCard(c); } }); c.startAnimation(ta); } private Card getCard(int num){ Card c; if (cards.size()>0) { c = cards.remove(0); }else{ c = new Card(getContext()); addView(c); } c.setVisibility(View.VISIBLE); c.setNum(num); return c; } private void recycleCard(Card c){ c.setVisibility(View.INVISIBLE); c.setAnimation(null); cards.add(c); } private List cards = new ArrayList(); public void createScaleTo1(Card target){ ScaleAnimation sa = new ScaleAnimation(0.1f, 1, 0.1f, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); sa.setDuration(100); target.setAnimation(null); target.getTvCard().startAnimation(sa); } } 

最后主布局文件如下

    

以上就是本文的全部内容,希望对大家的学习有所帮助。

以上就是Android实现2048小游戏的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 移动