当前位置: 移动技术网 > 移动技术>移动开发>Android > Android高仿2048小游戏实现代码

Android高仿2048小游戏实现代码

2019年07月24日  | 移动技术网移动技术  | 我要评论

刚开始进入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小游戏实现代码,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网