Android高仿2048小游戏实现代码
作者:Json_Jerry
这篇文章主要介绍了Android高仿2048小游戏实现代码的相关资料,非常不错具有一定的参考借鉴价值,需要的朋友可以参考下
刚开始进入Splash界面:
1.SplashActivity.Java(两秒后进入开始界面,Splash界面的布局只有一个图片,在博客后,会展示给大家看)
public class SplashActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); Intent intent=new Intent(SplashActivity.this, LoginActivity.class); startActivity(intent); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finish(); } }).start(); } }
2.LoginActivity(登陆界面)
private Button btn1,btn2; private EditText etAcount,etPassword; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); initView(); } private void initView() { btn1=(Button) findViewById(R.id.btn_login); btn2=(Button) findViewById(R.id.btn_register); etAcount=(EditText) findViewById(R.id.et_account); etPassword=(EditText) findViewById(R.id.et_pwd); btn1.setOnClickListener(new OnClickListener() { //登录按钮的监听 @Override public void onClick(View v) { SharedPreferences sharedPreferences=getSharedPreferences("user", MODE_PRIVATE); String number=sharedPreferences.getString("number", ""); int a,b; if (number=="") { a=0;//记录用户个数 }else { a=Integer.parseInt(number); } String account; String password; for (b=0;b<a;b++) { account="account"+b; password="password"+b; String jname=sharedPreferences.getString(account,""); String jpwd=sharedPreferences.getString(password, ""); if (jname.equals(etAcount.getText().toString())||jpwd.equals(etPassword.getText().toString())) { if (jname.equals(etAcount.getText().toString())&&jpwd.equals(etPassword.getText().toString())) { finish(); Intent intent=new Intent(LoginActivity.this, MainActivity.class); startActivity(intent); break; }else if (jname.equals(etAcount.getText().toString())) { Toast.makeText(LoginActivity.this, "密码错误", Toast.LENGTH_SHORT).show(); } } } if (b==a) { Toast.makeText(LoginActivity.this, "用户未注册", Toast.LENGTH_SHORT).show(); } } }); //注册按钮的监听 btn2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String account; String password; SharedPreferences sharedPreferences=getSharedPreferences("user",MODE_PRIVATE); String number=sharedPreferences.getString("number", ""); int a; int b; if (number=="") { a=0; }else { a=Integer.parseInt(number); } for (b = 0; b <a; b++) { account="account"+b; password="password"+b; String jname=sharedPreferences.getString(account,""); if (jname.equals(etAcount.getText().toString())) { break; } } if (b==a) { if (etAcount.getText().toString().equals("")&&etPassword.getText().toString().equals("")) { Toast.makeText(LoginActivity.this,"用户名密码不能为空", Toast.LENGTH_SHORT).show(); }else { account="account"+b; password="password"+b; a++; SharedPreferences.Editor editor=sharedPreferences.edit(); editor.putString(account,etAcount.getText().toString()); editor.putString(password,etPassword.getText().toString()); editor.putString("number",a+""); editor.commit(); Toast.makeText(LoginActivity.this,"注册成功", Toast.LENGTH_SHORT).show(); } }else { Toast.makeText(LoginActivity.this,"该账户已存在", Toast.LENGTH_SHORT).show(); } } }); } }
LoginActivity的布局如下:
<ImageView android:id="@+id/img_head" android:layout_width="match_parent" android:layout_height="260dp" android:background="@drawable/head_game" /> <EditText android:id="@+id/et_account" android:layout_width="match_parent" android:layout_height="50dp" android:layout_below="@id/img_head" android:layout_marginLeft="50dp" android:layout_marginRight="50dp" android:layout_marginTop="40dp" android:background="@drawable/set_charge_top" android:drawableLeft="@drawable/login_img2" android:hint="请输入账号" /> <EditText android:id="@+id/et_pwd" android:layout_width="match_parent" android:layout_height="50dp" android:layout_below="@id/et_account" android:layout_marginLeft="50dp" android:layout_marginTop="10dp" android:layout_marginRight="50dp" android:background="@drawable/set_charge_top" android:drawableLeft="@drawable/login_img3" android:hint="请输入密码" /> <Button android:id="@+id/btn_login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登录" android:layout_below="@id/et_pwd" android:layout_marginTop="10dp" android:layout_marginLeft="70dp"/> <Button android:id="@+id/btn_register" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="注册" android:layout_below="@id/et_pwd" android:layout_toRightOf="@id/btn_login" android:layout_marginTop="10dp" android:layout_marginLeft="60dp"/>
3.MainActivity.java(主页面)
public class MainActivity extends Activity { private TextView tvScore; private Animation animation; private static MainActivity mainActivity = null; private int score = 0; private ImageView imageView; private GameView gameView; public static MainActivity getMainActivity() { return mainActivity; } public MainActivity() { mainActivity = this; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvScore = (TextView) findViewById(R.id.tvScore); imageView=(ImageView) findViewById(R.id.img_monkey); } public void onClick(View view) { switch (view.getId()) { case R.id.btn_help://帮助按钮,弹出对话框 animation=AnimationUtils.loadAnimation(this,R.anim.anim_monkey); AlertDialog.Builder dialog2=new AlertDialog.Builder(this); dialog2.setTitle("嘲讽+藐视"); dialog2.setMessage("这么简单的游戏你还要帮助!!你咋不上天呢"); dialog2.setPositiveButton("给我绑个窜天猴", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { imageView.startAnimation(animation);//为ImageView设置动画 } }); dialog2.setNegativeButton("继续玩~", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog2.show(); break; case R.id.btn_quit://退出按钮的点击事件 AlertDialog.Builder dialog = new AlertDialog.Builder(this); dialog.setTitle("提示:"); dialog.setMessage("主人,你真的要离开我么?"); dialog.setPositiveButton("确定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { System.exit(0); } }); dialog.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog.show(); break; default: break; } } public void clearScore() {//清除分数 score = 0; showScore(); } public void showScore() {//展示分数 tvScore.setText(score + ""); } public void addScore(int s) {//添加分数 score += s; showScore(); } }
MainActivity的布局文件
<LinearLayout 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" android:orientation="vertical" tools:context="com.jerry.game2048.MainActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="#574336" > <TextView android:layout_marginLeft="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/score" android:textSize="24sp" android:textColor="#FFFFFF" android:textStyle="bold"/> <TextView android:id="@+id/tvScore" android:textSize="25sp" android:textColor="#FFFFFF" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <com.jerry.game2048.GameView android:id="@+id/gameView" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" ></com.jerry.game2048.GameView> <ImageView android:id="@+id/img_monkey" android:layout_width="60dp" android:layout_height="60dp" android:visibility="visible" android:layout_gravity="center_horizontal" android:src="@drawable/icon10" android:scaleType="fitXY" /> <LinearLayout android:id="@+id/ly_btns" android:layout_marginTop="20dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="#ddada0" > <Button android:id="@+id/btn_help" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:text="游戏帮助" android:textSize="20sp" android:onClick="onClick"/> <Button android:id="@+id/btn_quit" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="退出游戏" android:layout_marginRight="20dp" android:textSize="20sp" android:onClick="onClick"/> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="40dp" android:singleLine="true" android:ellipsize="marquee" android:focusable="true" android:focusableInTouchMode="true" android:marqueeRepeatLimit="marquee_forever" android:scrollHorizontally="true" android:textSize="30sp" android:background="#000000" android:textColor="#ffffff" android:text="这里写实际项目中,你所需要添加广告信息,这是一个跑马灯的效果,遇到问题,可在本博客下留下邮箱和问题,可以为您解答,转载请注明出处,谢谢"/> </LinearLayout>
4.Card.java(卡片类)
public class Card extends FrameLayout { private int num=0; private TextView label; public Card(Context context) { super(context); label=new TextView(getContext()); label.setTextSize(32); label.setGravity(Gravity.CENTER); label.setBackgroundColor(0x33ffffff);//设置每个卡片的颜色 LayoutParams lp=new LayoutParams(-1,-1);//该类用来初始化layout控件textView里的宽高属性 lp.setMargins(10, 10, 0, 0);//设置间隔 addView(label,lp); setNum(0); } public int getNum() { return num; } public void setNum(int num) { this.num=num; if (num<=0) { label.setText(""); }else { label.setText(num+""); } } //重写equals方法,判断卡片绑定的数字是否相等 public boolean equals(Card o) { return getNum()==o.getNum(); } }
5.GameView.java(主要逻辑)
public class GameView extends GridLayout { private Card[][] cardsMap = new Card[4][4]; //用来存放cardsMap下标用的Point类的集合 private List<Point> emptyPoints = new ArrayList<Point>(); public GameView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initGameView(); } public GameView(Context context) { super(context); initGameView(); } public GameView(Context context, AttributeSet attrs) { super(context, attrs); initGameView(); } private void initGameView() { setColumnCount(4); setBackgroundColor(0xffddada0); setOnTouchListener(new OnTouchListener() { // 添加触摸事件 开始 private float startX, startY, offsetX, offsetY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startX = event.getX(); startY = event.getY(); break; case MotionEvent.ACTION_UP: offsetX = event.getX() - startX;// 大于0则代表向右滑 offsetY = event.getY() - startY;// 小于0代表向上滑 if (Math.abs(offsetX) > Math.abs(offsetY)) { if (offsetX > 5) { swipeRight(); } else if (offsetX < -5) { swipeLeft(); } } else { if (offsetY > 5) { swipeDown(); } else if (offsetY < -5) { swipeUp(); } } break; } return true; } }); } //根据卡片宽和高 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { //该方法就是宽高发生改变的时候我们可以得到当前的宽高是多少 //该方法也是在游戏一被创建的时候就调用,也就是用来初始宽高的方法 super.onSizeChanged(w, h, oldw, oldh); //获取手机较窄的长度,-10是用来间隔每个卡片的距离,用手机的宽除以4就是每个卡片的长度了 int cardWidth = (Math.min(w, h) - 10) / 4; addCards(cardWidth, cardWidth); startGame(); } //增加卡片,形成4*4的矩阵 private void addCards(int cardWidth, int cardHeight) { Card c; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { c = new Card(getContext()); c.setNum(2); addView( c, cardWidth, cardHeight); //顺便把初始化时新建的卡片存放在新建的二维数组中 cardsMap[x][y] = c; } } } //开始游戏,初始化16个card public void startGame() { MainActivity.getMainActivity().clearScore(); for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { cardsMap[x][y].setNum(0); } } addRondomNum(); addRondomNum(); } //判断游戏结束 private void endGame(){ boolean isfull=true;//判断卡片是否铺满的标志变量 for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (cardsMap[x][y].getNum()==0 ||(x>0&&cardsMap[x][y].equals(cardsMap[x-1][y])) ||(x<3&&cardsMap[x][y].equals(cardsMap[x+1][y])) ||(y>0&&cardsMap[x][y].equals(cardsMap[x][y-1])) ||(y<3&&cardsMap[x][y].equals(cardsMap[x][y+1]))) { isfull=false; break; } } } if (isfull) { AlertDialog.Builder dialog=new AlertDialog.Builder(getContext()); dialog.setTitle("Game Over!"); dialog.setMessage("你太菜了!想要再玩一次么?"); dialog.setCancelable(false); dialog.setPositiveButton("重新开始",new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { startGame(); } }); dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); dialog.show(); } } private void addRondomNum() { //把这个point清空,每次调用添加随机数时就清空之前的emptyPoints emptyPoints.clear(); //对所有的位置进行遍历:即为每个卡片加上了可以控制的Point for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { if (cardsMap[x][y].getNum() <= 0) { emptyPoints.add(new Point(x, y)); } } } //通过随机的从存放了的Point的List集合里去获取Card的位置,并给这个card设置文本属性,并且只能存2或 //通过point对象来充当下标的角色来控制存放card的二维数组cardsMap,然后随机给定位到的card对象赋值 Point p = emptyPoints.remove((int) (Math.random() * emptyPoints.size())); cardsMap[p.x][p.y].setNum(Math.random() > 0.1 ? 2 : 4); } //左移 private void swipeLeft() { boolean add=false; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { for (int x1 = x + 1; x1 < 4; x1++) { if (cardsMap[x1][y].getNum() > 0) {//除了第一列以外的数,如果存在一个数大于0 if (cardsMap[x][y].getNum() <= 0) {//如果左边没有数 cardsMap[x][y].setNum(cardsMap[x1][y].getNum());//将右边的数移到左边 cardsMap[x1][y].setNum(0);//右边数清零 x--; add=true; break; } else if (cardsMap[x][y].equals(cardsMap[x1][y])) { cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2); cardsMap[x1][y].setNum(0); MainActivity.getMainActivity().addScore( cardsMap[x][y].getNum()); add=true; } break; } } } } if (add) { addRondomNum(); endGame();//判断是否结束 } } //右移 private void swipeRight() { boolean add=false; for (int y = 0; y < 4; y++) { for (int x = 3; x >= 0; x--) { for (int x1 = x - 1; x1 >= 0; x1--) { if (cardsMap[x1][y].getNum() > 0) { if (cardsMap[x][y].getNum() <= 0) { cardsMap[x][y].setNum(cardsMap[x1][y].getNum()); cardsMap[x1][y].setNum(0); x++; add=true; break; } else if (cardsMap[x][y].equals(cardsMap[x1][y])) { cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2); cardsMap[x1][y].setNum(0); MainActivity.getMainActivity().addScore( cardsMap[x][y].getNum()); add=true; } break; } } } } if (add) { addRondomNum(); endGame(); } } private void swipeUp() { boolean add=false; for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { for (int y1 = y + 1; y1 < 4; y1++) { if (cardsMap[x][y1].getNum() > 0) { if (cardsMap[x][y].getNum() <= 0) { cardsMap[x][y].setNum(cardsMap[x][y1].getNum()); cardsMap[x][y1].setNum(0); y--; add=true; break; } else if (cardsMap[x][y].equals(cardsMap[x][y1])) { cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2); cardsMap[x][y1].setNum(0); MainActivity.getMainActivity().addScore( cardsMap[x][y].getNum()); add=true; } break; } } } } if (add) { addRondomNum(); endGame(); } } private void swipeDown() { boolean add=false; for (int x = 0; x < 4; x++) { for (int y = 3; y >= 0; y--) { for (int y1 = y - 1; y1 >= 0; y1--) { if (cardsMap[x][y1].getNum() > 0) { if (cardsMap[x][y].getNum() <= 0) { cardsMap[x][y].setNum(cardsMap[x][y1].getNum()); cardsMap[x][y1].setNum(0); y++; add=true; break; } else if (cardsMap[x][y].equals(cardsMap[x][y1])) { cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2); cardsMap[x][y1].setNum(0); MainActivity.getMainActivity().addScore( cardsMap[x][y].getNum()); add=true; } break; } } } } if (add) { addRondomNum(); endGame(); } } }
6.最后不要忘记在清单配置文件中配置信息
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jerry.game2048" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="17" android:targetSdkVersion="21" /> <application android:allowBackup="true" android:icon="@drawable/game2048" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.jerry.game2048.MainActivity" android:label="@string/app_name" //设置屏幕为竖屏 android:screenOrientation="portrait" > </activity> <activity android:name=".SplashActivity" android:label="@string/title_activity_splash" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".LoginActivity" android:label="@string/title_activity_login" > </activity> </application> </manifest>
7.其中的窜天猴的动画效果实现如下:
在res文件下新建一个anim文件夹
在anim文件夹下新建一个anim_monky.xml的布局文件
anim_monky.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0" android:toXDelta="40" android:fromYDelta="0" android:toYDelta="-5000" android:duration="4000"/> <alpha android:fromAlpha="1" android:toAlpha="0" android:duration="5000" /> </set>
效果图如下:
以上所述是小编给大家介绍的Android高仿2048小游戏实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!