Android游戏2048的实现
程序员文章站
2024-03-16 20:42:16
...
MainActivity
package xiaoye.com.game2048;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.drawable.GradientDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.widget.GridLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity{
private int num=4;
private boolean isstart=true,isback=false,haveitem=false;
private int score=0,maxscore=0,backcount=0,max=0,oldmax=0;
private SharedPreferences sp;
private float X1,X2,Y1,Y2,X,Y;
private GridLayout layout;
private MenuItem item2;
LinearLayout.LayoutParams params;
private TextView card[][]=new TextView[7][7],tv1,tv2;
private int[] colornum={0,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072};
private int[] colorid={R.color.color0,R.color.color2,R.color.color4,R.color.color8,R.color.color16,R.color.color32,R.color.color64,R.color.color128,R.color.color256,R.color.color512,R.color.color1024,R.color.color2048,R.color.color4096,R.color.color8192,R.color.color16384,R.color.color32768,R.color.color65536};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
find();
startGame(false,true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.main, menu);
item2= menu.findItem(R.id.item2);
haveitem=true;
item2.setTitle("撤销("+backcount+"次)");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()) {
case R.id.item1://开始新游戏
new AlertDialog.Builder(this)
.setTitle("通知")
.setMessage("您真的要开始新游戏吗")
.setNegativeButton("取消", null)
.setPositiveButton("是的",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startGame(true,true);
}
}).show();
return true;
case R.id.item2://撤销
back();
item2.setTitle("撤销("+backcount+"次)");
return true;
case R.id.item3://版本信息
new AlertDialog.Builder(this)
.setTitle("版本信息")
.setMessage(this.getResources().getString(R.string.版本信息))
.setNegativeButton("确定", null).show();
return true;
case R.id.item4://游戏规则
new AlertDialog.Builder(this)
.setTitle("游戏规则")
.setMessage(this.getResources().getString(R.string.游戏规则))
.setNegativeButton("确定", null).show();
return true;
case R.id.item5://选择模式
new AlertDialog.Builder(this)
.setTitle("请选择模式" )
.setIcon(android.R.drawable.ic_dialog_info)
.setSingleChoiceItems(new String[] {"4*4", "5*5", "6*6" }, num-4 ,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog1, final int which) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("请选择" )
.setIcon(android.R.drawable.ic_dialog_info)
.setSingleChoiceItems(new String[] {"新游戏", "读取存档"},0 ,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog2, final int which1) {
num = which + 4;
find();
switch (which1) {
case 0:
startGame(true,true);
break;
case 1:
startGame(false,false);
break;
}
dialog2.dismiss();
}
}).setNegativeButton("取消" , null ).show();
dialog1.dismiss();
}
}
)
.setNegativeButton("取消" , null ).show();
return true;
}
return super.onOptionsItemSelected(item);
}
private void find(){
tv1=(TextView)findViewById(R.id.textView1);
tv2=(TextView)findViewById(R.id.textView2);
layout=(GridLayout)findViewById(R.id.layout);
layout.removeAllViews();
layout.setColumnCount(num);
layout.setRowCount(num);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
params=new LinearLayout.LayoutParams((dm.widthPixels-40)/num, (dm.widthPixels-40)/num);
for(int i=1;i<=num;i++) {
for (int j=1;j<=num;j++) {
card[i][j]=new TextView(this);
if (num == 4) {
card[i][j].setTextSize(15);
}else if(num==5){
card[i][j].setTextSize(13);
}else if(num==6){
card[i][j].setTextSize(11);
}
card[i][j].setTextColor(0xffffffff);
card[i][j].setGravity(Gravity.CENTER);
card[i][j].setLayoutParams(params);
layout.addView(card[i][j]);
}
}
}
private void reshow(){
layout.removeAllViews();
for(int i=1;i<=num;i++) {
for (int j=1;j<=num;j++) {
card[i][j].setLayoutParams(params);
layout.addView(card[i][j]);
}
}
}
private void startGame(boolean start,boolean isNumNull){
boolean flag=true;
isstart=true;
init();
if(!start)
open(isNumNull);
getMaxScore();
for(int i=1;i<=num;i++){
for(int j=1;j<=num;j++){
if(getNum(i,j)!=0){
flag=false;
}
}
}
if(checkGameOver()==true)
new AlertDialog.Builder(this)
.setTitle("通知")
.setMessage("GameOver")
.setPositiveButton("开始新游戏",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startGame(true,true);
}
})
.setNegativeButton("取消", null)
.show();
else if(flag){
addRandomNum();
addRandomNum();
}
setColor();
save();
}
private void init(){
score=maxscore=max=oldmax=backcount=0;
if(haveitem)
item2.setTitle("撤销("+backcount+"次)");
setScore();
for(int i=1;i<=num;i++){
for(int j=1;j<=num;j++){
setNum(i,j,0);
}
}
}
private void addRandomNum(){
int x=(int)(Math.random()*num+1);
int y=(int)(Math.random()*num+1);
while(getNum(x,y)!=0){
x=(int)(Math.random()*num+1);
y=(int)(Math.random()*num+1);
}
setNum(x,y,Math.random()>0.1?2:4);
setColor();
}
private void setColor(){
int cardnum = 0;
for(int i=1;i<=num;i++){
for(int j=1;j<=num;j++){
for(int k=0;k<colornum.length;k++){
if(getNum(i,j)<=65536) {
cardnum = getNum(i, j);
}else{
cardnum = getNum(i, j) / 65536;
}
if(cardnum==colornum[k]){
card[i][j].setBackgroundResource(R.drawable.backgroundnum);
GradientDrawable drawable = (GradientDrawable) card[i][j].getBackground();
drawable.setColor(getResources().getColor(colorid[k]));
drawable.setStroke(3*(10-(num-4)*3), getResources().getColor(R.color.color0));
}
}
}
}
}
private void setNum(int i,int j,int cardnum){
if(cardnum==0)
card[i][j].setText("");
else
card[i][j].setText(cardnum+"");
if(cardnum>130000) {
if (num == 4) {
card[i][j].setTextSize(15);
}else if(num==5){
card[i][j].setTextSize(13);
}else if(num==6){
card[i][j].setTextSize(11);
}
}
}
private int getNum(int i,int j){
String numstr=card[i][j].getText().toString();
if(numstr.equals(""))
return 0;
else return Integer.valueOf(card[i][j].getText().toString()).intValue();
}
private boolean swipeLeft(){
boolean swipe=false;
for (int x=1;x<=num;x++) {
for (int y = 1; y <=num; y++) {
for (int y1 = y+1; y1 <= num; y1++) {
if (getNum(x,y1)>0) {
if (getNum(x,y)<=0){
setNum(x,y,getNum(x,y1));
setNum(x,y1,0);
y--;
swipe = true;
}else if (getNum(x,y)==getNum(x,y1)){
setNum(x,y,getNum(x,y)*2);
setNum(x,y1,0);
score+=getNum(x,y);
swipe = true;
}
break;
}
}
}
}
reshow();
return swipe;
}
private boolean swipeRight(){
boolean swipe=false;
for (int x=1;x<=num;x++) {
for (int y = num; y >=1; y--) {
for (int y1 = y-1; y1 >=1; y1--) {
if (getNum(x,y1)>0) {
if (getNum(x,y)<=0) {
setNum(x,y,getNum(x,y1));
setNum(x,y1,0);
y++;
swipe = true;
}else if (getNum(x,y)==getNum(x,y1)) {
setNum(x,y,getNum(x,y)*2);
setNum(x,y1,0);
score+=getNum(x,y);
swipe = true;
}
break;
}
}
}
}
reshow();
return swipe;
}
private boolean swipeUp(){
boolean swipe=false;
for (int y=1;y<=num;y++) {
for (int x=1;x<=num;x++) {
for (int x1 = x+1; x1 <=num; x1++) {
if (getNum(x1,y)>0) {
if (getNum(x,y)<=0) {
setNum(x,y,getNum(x1,y));
setNum(x1,y,0);
x--;
swipe = true;
}else if (getNum(x,y)==getNum(x1,y)) {//这层判断是判断相邻两个数相同的情况
setNum(x,y,getNum(x,y)*2);
setNum(x1,y,0);
score+=getNum(x,y);
swipe = true;
}
break;
}
}
}
}
reshow();
return swipe;
}
private boolean swipeDown(){
boolean swipe=false;
for (int y=1;y<=num;y++) {
for (int x = num; x >=1; x--) {
for (int x1 = x-1; x1 >=1; x1--) {
if (getNum(x1,y)>0) {
if (getNum(x,y)<=0) {
setNum(x,y,getNum(x1,y));
setNum(x1,y,0);
x++;
swipe = true;
}else if (getNum(x,y)==getNum(x1,y)) {
setNum(x,y,getNum(x,y)*2);
setNum(x1,y,0);
score+=getNum(x,y);
swipe = true;
}
break;
}
}
}
}
reshow();
return swipe;
}
private boolean checkGameOver(){
for(int i=1;i<=num;i++){
for(int j=1;j<=num;j++){
if(getNum(i,j)==0)
return false;
if(i-1>=1&&getNum(i,j)==getNum(i-1,j)||i+1<=4&&getNum(i,j)==getNum(i+1,j)||j-1>=1&&getNum(i,j)==getNum(i,j-1)||j+1<=4&&getNum(i,j)==getNum(i,j+1))
return false;
}
}
return true;
}
private void setScore(){
if(score>maxscore)
maxscore=score;
tv1.setText(""+maxscore);
tv2.setText(""+score);
int maxnum=0;
for(int i=1;i<=num;i++){
for(int j=1;j<=num;j++){
if(getNum(i,j)>maxnum){
maxnum=getNum(i,j);
}
}
}
max=maxnum;
if(!isstart&&max>oldmax){
Toast.makeText(MainActivity.this,"已合成"+max+",获得撤销机会一次",Toast.LENGTH_SHORT).show();
backcount++;
if(haveitem)
item2.setTitle("撤销("+backcount+"次)");
oldmax=max;
save();
}
if(haveitem)
item2.setTitle("撤销("+backcount+"次)");
}
private void save(){
sp = getSharedPreferences("CardDate",MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
for(int i=1;i<=num;i++) {
for (int j = 1; j <= num; j++) {
editor.putInt("OldCard"+num+i+j,sp.getInt("Card"+num+i+j,0));
editor.putInt("Card"+num+i+j,getNum(i,j));
}
}
editor.putInt("num",num);
editor.putInt("OldScore"+num,sp.getInt("Score"+num,0));
editor.putInt("OldMaxScore"+num,sp.getInt("MaxScore"+num,0));
editor.putInt("Score"+num,score);
editor.putInt("MaxScore"+num,maxscore);
editor.putInt("backcount"+num,backcount);
editor.putInt("max"+num,max);
editor.putInt("oldmax"+num,oldmax);
editor.commit();
}
private void open(boolean isNumNull){
sp = getSharedPreferences("CardDate",MODE_PRIVATE);
if(isNumNull)
num=sp.getInt("num",4);
find();
for(int i=1;i<=num;i++) {
for (int j = 1; j <= num; j++) {
setNum(i,j,sp.getInt("Card"+num+i+j,0));
}
}
score=sp.getInt("Score"+num,0);
maxscore=sp.getInt("MaxScore"+num,0);
backcount=sp.getInt("backcount"+num,0);
max=sp.getInt("max"+num,0);
oldmax=sp.getInt("oldmax"+num,0);
setScore();
}
private void back(){
if(backcount<=0) {
Toast.makeText(MainActivity.this, "撤销机会已用光", Toast.LENGTH_SHORT).show();
}else if(isstart) {
Toast.makeText(MainActivity.this, "游戏刚开始,无法撤销", Toast.LENGTH_SHORT).show();
}else if(isback){
Toast.makeText(MainActivity.this,"刚刚撤销一次,无法撤销",Toast.LENGTH_SHORT).show();
}else{
sp = getSharedPreferences("CardDate",MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
for(int i=1;i<=num;i++) {
for (int j = 1; j <= num; j++) {
editor.putInt("Card"+num+i+j,sp.getInt("OldCard"+num+i+j,0));
}
}
editor.putInt("num",num);
editor.putInt("Score"+num,sp.getInt("OldScore"+num,0));
editor.putInt("MaxScore"+num,sp.getInt("OldMaxScore"+num,0));
editor.commit();
num=sp.getInt("num",4);
for(int i=1;i<=num;i++) {
for (int j = 1; j <= num; j++) {
setNum(i,j,sp.getInt("Card"+num+i+j,0));
}
}
score=sp.getInt("Score"+num,0);
maxscore=sp.getInt("MaxScore"+num,0);
max=sp.getInt("max"+num,0);
oldmax=sp.getInt("oldmax"+num,0);
setScore();
setColor();
backcount--;
}
isback=true;
}
private void getMaxScore(){
sp = getSharedPreferences("CardDate",MODE_PRIVATE);
maxscore=sp.getInt("MaxScore"+num,0);
setScore();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean swipe=false;
if(event.getAction()==MotionEvent.ACTION_DOWN) {
X1 = event.getX();
Y1 = event.getY();
}
else if(event.getAction()==MotionEvent.ACTION_UP){
X2 = event.getX();
Y2 = event.getY();
X=X2-X1;
Y=Y2-Y1;
if(Math.abs(X)>(Math.abs(Y))){
if(X<-5)
swipe=swipeLeft();
else if (X>5)
swipe=swipeRight();
}else{
if(Y<-5)
swipe=swipeUp();
else if (Y>5)
swipe=swipeDown();
}
if(swipe==true){
addRandomNum();
setScore();
save();
isstart=false;
isback=false;
}
if(checkGameOver()==true)
new AlertDialog.Builder(this)
.setTitle("通知")
.setMessage("GameOver")
.setPositiveButton("开始新游戏",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startGame(true,true);
}
})
.setNegativeButton("取消", null)
.show();
}
return super.onTouchEvent(event);
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<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"
android:background="@drawable/background"
tools:context="xiaoye.com.game2048.MainActivity">
<GridLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:padding="20px"></GridLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp"
android:background="@drawable/background1296db">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="最高分"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="25dp"/>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="0"
android:textColor="#ffffff"
android:layout_marginTop="5dp"
android:textSize="25dp"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp"
android:background="@drawable/background1296db">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="得 分"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="25dp"/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="0"
android:textColor="#ffffff"
android:layout_marginTop="5dp"
android:textSize="25dp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
menu_main
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/item1"
android:title="开始新游戏"
android:orderInCategory="100"
app:showAsAction="never|withText"/>
<item
android:id="@+id/item2"
android:title="撤销"
android:orderInCategory="100"
app:showAsAction="ifRoom|withText"/>
<item
android:id="@+id/item3"
android:title="版本信息"
android:orderInCategory="100"
app:showAsAction="never|withText"/>
<item
android:id="@+id/item4"
android:title="游戏规则"
android:orderInCategory="100"
app:showAsAction="never|withText"/>
<item
android:id="@+id/item5"
android:title="选择模式"
android:orderInCategory="100"
app:showAsAction="never|withText"/>
</menu>
下一篇: [Android]自己动手做个拼图游戏