Android高仿2048小游戏实现代码
程序员文章站
2024-03-04 09:50:17
刚开始进入splash界面:
1.splashactivity.java(两秒后进入开始界面,splash界面的布局只有一个图片,在博客后,会展示给大家看)
p...
刚开始进入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小游戏实现代码,希望对大家有所帮助
下一篇: 面试题 01.06. 字符串压缩