个人android 2048的玩耍
个人信息:就读于燕大本科软件工程专业 目前大四;
本人博客:google搜索“cqs_2012”即可;
个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献;
编程语言:java ;
编程坏境:Windows 7 专业版 x64;
编程工具:jdk,eclipse;
制图工具:office 2010 powerpoint;
硬件信息:7G-3 笔记本;
这篇文章意义:
这篇文章是主要记录和讲解开发android 2048游戏的一个过程。
我们首先讲解2048核心算法两个操作:
1)移动:将数据单元格跳过所有的空格,在指定方向后,靠向方向边
2)合并:将数据单元格与其相邻的单元格(其与其单元格数据相等的情况下)进行合并
3)判断是否随机生成:滑动后,发现其数据表格当前状态和其原先状态是否一致
4)判断结束条件:所有单元格都已经填满,而且任何相邻的两个单元格不能合并
主要代码
package com.example.wxj2048;
import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.TextView;
public class Card extends FrameLayout {
public Card(Context context) {
super(context);
// TODO Auto-generated constructor stub
label = new TextView(getContext());
label.setTextSize(25);
label.setGravity(Gravity.CENTER);
LayoutParams lParams = new LayoutParams(-1, -1);
addView(label, lParams);
lParams.setMargins(10, 10, 0, 0);
setNum(0);
}
public TextView label;
public Integer num;
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
label.setBackgroundColor(Color.DKGRAY);
if (num <= 0) {
label.setText(" ");
} else {
label.setText(num.toString());
switch (num) {
case 0:
label.setBackgroundColor(Color.DKGRAY);
break;
case 2:
label.setBackgroundColor(Color.GRAY);
break;
case 4:
label.setBackgroundColor(Color.GREEN);
break;
case 8:
label.setBackgroundColor(Color.LTGRAY);
break;
case 16:
label.setBackgroundColor(Color.MAGENTA);
break;
case 32:
label.setBackgroundColor(Color.RED);
break;
case 64:
label.setBackgroundColor(Color.WHITE);
break;
case 128:
label.setBackgroundColor(Color.YELLOW);
break;
case 256:
label.setBackgroundColor(Color.BLUE);
break;
case 512:
label.setBackgroundColor(0x55ffddaa);
break;
case 1024:
label.setBackgroundColor(0x55ffaadd);
break;
case 2048:
label.setBackgroundColor(0x55aaffaa);
break;
default:
label.setBackgroundColor(0x55aaffaa);
break;
}
}
}
public boolean equals(Card o) {
return this.num.intValue() == o.getNum().intValue();
}
public boolean isEmpty(){
if(this.num.intValue() <= 0)
return true;
else return false;
}
}
package com.example.wxj2048;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class Dbdao extends SQLiteOpenHelper{
private static final String DBNAME = "mldn.db";
private static final int DBVERSION = 1;
private static final String TABNAME = "game2048";
public Dbdao(Context context){
super(context, DBNAME, null, DBVERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String sql =" CREATE TABLE "+ TABNAME+" (" +
" id INTEGER ," +
" score INTEGER "+
") ";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
String sql = " DROP TABLE IF EXISTS " + TABNAME;
db.execSQL(sql);
this.onCreate(db);
}
public void insert(Integer score){
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("id", 1);
values.put("score", score);
db.insert(TABNAME, null, values);
db.close();
}
public void delete(){
SQLiteDatabase db = getWritableDatabase();
String[] data = new String[1];
data[0] = "1";
db.delete(TABNAME,"id = ?",data);
db.close();
}
public Integer query(){
SQLiteDatabase db = getWritableDatabase();
Cursor c = db.query(TABNAME, null, null, null, null, null, null);
c.moveToFirst();
int index = c.getColumnIndex("score");
String result = c.getString(index);
db.close();
return Integer.valueOf(result);
}
}
package com.example.wxj2048;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.ImageView;
public class FlashStartActivity extends Activity {
private ImageView welcomeImg = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.flash_start);
welcomeImg = (ImageView) this.findViewById(R.id.welcome_img);
AlphaAnimation anima = new AlphaAnimation(0.3f, 1.0f);
anima.setDuration(5000);
welcomeImg.startAnimation(anima);
anima.setAnimationListener(new AnimationImpl());
}
private class AnimationImpl implements AnimationListener {
@Override
public void onAnimationStart(Animation animation) {
welcomeImg.setBackgroundResource(R.drawable.welcome);
}
@Override
public void onAnimationEnd(Animation animation) {
skip(); // 动画结束后跳转到别的页面
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
private void skip() {
Intent intent = new Intent(FlashStartActivity.this,MainActivity.class);
startActivity(intent);
finish();
}
}
package com.example.wxj2048;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridLayout;
public class GameView extends GridLayout {
public GameView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
initGameView();
}
public GameView(Context context) {
super(context);
// TODO Auto-generated constructor stub
initGameView();
}
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
initGameView();
}
private void initGameView() {
setColumnCount(4);
setBackgroundColor(0xffbbadcc);
setOnTouchListener(new OnTouchListener() {
double sx, sy, ex, ey;
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
switch (arg1.getAction()) {
case MotionEvent.ACTION_DOWN:
sx = arg1.getX();
sy = arg1.getY();
break;
case MotionEvent.ACTION_UP:
ex = arg1.getX();
ey = arg1.getY();
if (Math.abs(sx - ex) > Math.abs(sy - ey)) {
if (sx > ex && isLeftSlide()) {
leftSlide();
leftMerge();
leftSlide();
addRandomNum();
} else if (sx < ex && isRightSlide()) {
rightSlide();
rightMerge();
rightSlide();
addRandomNum();
}
} else if (Math.abs(sx - ex) < Math.abs(sy - ey)) {
if (sy > ey && isUpSlide()) {
upSlide();
upMerge();
upSlide();
addRandomNum();
} else if (sy < ey && isDownSlide()) {
downSlide();
downMerge();
downSlide();
addRandomNum();
}
}
freshScore();
isEndGame();
break;
default:
break;
}
return true;
}
});
}
@Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Integer width = (w - 10) / 4;
Integer height = (h - 10) / 4;
this.addCard(width, height);
this.startGame();
}
public void addCard(Integer w, Integer h) {
Card card;
for (Integer integer = 0; integer < 4; integer++) {
for (Integer jInteger = 0; jInteger < 4; jInteger++) {
card = new Card(getContext());
card.setNum(2);
addView(card, w, h);
cardarr[integer][jInteger] = card;
}
}
}
private Card[][] cardarr = new Card[4][4];
private ArrayList<Point> emptyarrlist = new ArrayList<Point>();
public void addRandomNum() {
emptyarrlist.clear();
for (Integer integer = 0; integer < 4; integer++)
for (Integer jInteger = 0; jInteger < 4; jInteger++) {
if (cardarr[integer][jInteger].getNum() <= 0) {
emptyarrlist.add(new Point(integer, jInteger));
}
}
if (!emptyarrlist.isEmpty()) {
Point point = emptyarrlist
.remove((int) (Math.random() * emptyarrlist.size()));
cardarr[point.x][point.y].setNum(Math.random() > 0.1 ? 2 : 4);
}
}
public void startGame() {
MainActivity.scoreString.setText("score: ");
MainActivity.nowScore.setText("0 ");
for (Integer integer = 0; integer < 4; integer++)
for (Integer jInteger = 0; jInteger < 4; jInteger++)
cardarr[integer][jInteger].setNum(0);
addRandomNum();
addRandomNum();
}
public void leftSlide() {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
for (Integer integer = 0; integer < 4; integer++) {
arrayList.clear();
for (Integer j = 0; j < 4; j++) {
arrayList.add(cardarr[integer][j].getNum());
cardarr[integer][j].setNum(0);
}
arrayList = this.arraySlide(arrayList);
for (Integer j = 0; j < arrayList.size(); j++) {
cardarr[integer][j].setNum(arrayList.get(j));
}
}
}
public boolean isLeftSlide() {
boolean result = false;
ALL: for (int i = 0; i < 4; i++) {
for (int j = 1; j < 4; j++) {
if (!cardarr[i][j].isEmpty()) {
if (cardarr[i][j - 1].isEmpty()) {
result = true;
break ALL;
}
if (cardarr[i][j].equals(cardarr[i][j - 1])) {
result = true;
break ALL;
}
}
}
}
return result;
}
public boolean isRightSlide() {
boolean result = false;
ALL: for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
if (!cardarr[i][j].isEmpty()) {
if (cardarr[i][j + 1].isEmpty()) {
result = true;
break ALL;
}
if (cardarr[i][j].equals(cardarr[i][j + 1])) {
result = true;
break ALL;
}
}
}
}
return result;
}
public boolean isUpSlide() {
boolean result = false;
ALL: for (int j = 0; j < 4; j++) {
for (int i = 1; i < 4; i++) {
if (!cardarr[i][j].isEmpty()) {
if (cardarr[i - 1][j].isEmpty()) {
result = true;
break ALL;
}
if (cardarr[i][j].equals(cardarr[i - 1][j])) {
result = true;
break ALL;
}
}
}
}
return result;
}
public boolean isDownSlide() {
boolean result = false;
ALL: for (int j = 0; j < 4; j++) {
for (int i = 0; i < 3; i++) {
if (!cardarr[i][j].isEmpty()) {
if (cardarr[i + 1][j].isEmpty()) {
result = true;
break ALL;
}
if (cardarr[i][j].equals(cardarr[i + 1][j])) {
result = true;
break ALL;
}
}
}
}
return result;
}
public void leftMerge() {
for (Integer i = 0; i < 4; i++) {
for (Integer j = 0; j < 3; j++) {
if (cardarr[i][j].equals(cardarr[i][j + 1])) {
cardarr[i][j].setNum(cardarr[i][j].getNum() * 2);
cardarr[i][j + 1].setNum(0);
}
}
}
}
public void rightMerge() {
for (Integer i = 0; i < 4; i++) {
for (Integer j = 3; j > 0; j--) {
if (cardarr[i][j].equals(cardarr[i][j - 1])) {
cardarr[i][j].setNum(cardarr[i][j].getNum() * 2);
cardarr[i][j - 1].setNum(0);
}
}
}
}
public void upMerge() {
for (Integer j = 0; j < 4; j++) {
for (Integer i = 0; i < 3; i++) {
if (cardarr[i][j].equals(cardarr[i + 1][j])) {
cardarr[i][j].setNum(cardarr[i][j].getNum() * 2);
cardarr[i + 1][j].setNum(0);
}
}
}
}
public void downMerge() {
for (Integer j = 0; j < 4; j++) {
for (Integer i = 3; i > 0; i--) {
if (cardarr[i][j].equals(cardarr[i - 1][j])) {
cardarr[i][j].setNum(cardarr[i][j].getNum() * 2);
cardarr[i - 1][j].setNum(0);
}
}
}
}
public ArrayList<Integer> arraySlide(ArrayList<Integer> arr) {
ArrayList<Integer> result = new ArrayList<Integer>();
for (Integer integer = 0; integer < arr.size(); integer++) {
if (arr.get(integer) > 0)
result.add(arr.get(integer));
}
return result;
}
public void rightSlide() {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
for (Integer integer = 0; integer < 4; integer++) {
arrayList.clear();
for (Integer j = 3; j >= 0; j--) {
arrayList.add(cardarr[integer][j].getNum());
cardarr[integer][j].setNum(0);
}
arrayList = this.arraySlide(arrayList);
for (Integer j = 0; j < arrayList.size(); j++) {
cardarr[integer][3 - j].setNum(arrayList.get(j));
}
}
}
public void upSlide() {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
for (Integer j = 0; j < 4; j++) {
arrayList.clear();
for (Integer i = 0; i < 4; i++) {
arrayList.add(cardarr[i][j].getNum());
cardarr[i][j].setNum(0);
}
arrayList = arraySlide(arrayList);
for (Integer i = 0; i < arrayList.size(); i++) {
cardarr[i][j].setNum(arrayList.get(i));
}
}
}
public void downSlide() {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
for (Integer j = 0; j < 4; j++) {
arrayList.clear();
for (Integer i = 3; i >= 0; i--) {
arrayList.add(cardarr[i][j].getNum());
cardarr[i][j].setNum(0);
}
arrayList = arraySlide(arrayList);
for (Integer i = 0; i < arrayList.size(); i++) {
cardarr[3 - i][j].setNum(arrayList.get(i));
}
}
}
public void freshScore() {
Integer max = 0;
for (Integer i = 0; i < 4; i++) {
for (Integer j = 0; j < 4; j++) {
if (cardarr[i][j].getNum() > max)
max = cardarr[i][j].getNum();
}
}
MainActivity.nowScore.setText(max.toString()+" ");
}
public void isEndGame() {
boolean end = true;
ALL: for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (cardarr[i][j].getNum().intValue() <= 0) {
end = false;
break ALL;
}
}
}
if (end) {
NextAll: for (int i = 1; i < 3; i++) {
for (int j = 1; j < 3; j++) {
if (cardarr[i][j].getNum().intValue() == cardarr[i][j + 1]
.getNum().intValue()) {
end = false;
break NextAll;
} else if (cardarr[i][j].getNum().intValue() == cardarr[i][j - 1]
.getNum().intValue()) {
end = false;
break NextAll;
} else if (cardarr[i][j].getNum().intValue() == cardarr[i + 1][j]
.getNum().intValue()) {
end = false;
break NextAll;
} else if (cardarr[i][j].getNum().intValue() == cardarr[i - 1][j]
.getNum().intValue()) {
end = false;
break NextAll;
}
}
}
for (int i = 0; i < 3; i++) {
if (cardarr[0][i].getNum().intValue() == cardarr[0][i + 1]
.getNum().intValue()) {
end = false;
break;
}
if (cardarr[3][i].getNum().intValue() == cardarr[3][i + 1]
.getNum().intValue()) {
end = false;
break;
}
if (cardarr[i][0].getNum().intValue() == cardarr[i + 1][0]
.getNum().intValue()) {
end = false;
break;
}
if (cardarr[i][3].getNum().intValue() == cardarr[i + 1][3]
.getNum().intValue()) {
end = false;
break;
}
}
}
if (end) {
freshMaxScore();
new AlertDialog.Builder(getContext())
.setTitle("你好")
.setMessage("恭喜你获得高分: " + MainActivity.nowScore.getText().toString().trim())
.setPositiveButton("突破一下",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0,
int arg1) {
// TODO Auto-generated method stub
startGame();
}
}).show();
}
}
public void freshMaxScore(){
String nowScoreString = MainActivity.nowScore.getText().toString().trim();
int nowScore = Integer.valueOf(nowScoreString).intValue();
String maxScoreString = MainActivity.maxScore.getText().toString().trim();
int maxScore = Integer.valueOf(maxScoreString);
if(nowScore > maxScore)
{
GameApplication.dbdao.delete();
GameApplication.dbdao.insert(nowScore);
MainActivity.maxScore.setText(nowScore+" ");
}
}
}
<pre name="code" class="java">package com.example.wxj2048;
import android.app.Application;
public class GameApplication extends Application{
public static Dbdao dbdao;
}
package com.example.wxj2048;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
public static TextView scoreString;
public static TextView nowScore;
public static TextView maxString;
public static TextView maxScore;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scoreString = (TextView) findViewById(R.id.scoreString);
scoreString.setTextColor(Color.BLACK);
scoreString.setTextSize(21);
nowScore = (TextView) findViewById(R.id.nowScore);
nowScore.setTextColor(Color.BLUE);
nowScore.setTextSize(21);
maxString = (TextView) findViewById(R.id.maxString);
maxString.setTextColor(Color.BLACK);
maxString.setTextSize(21);
maxScore = (TextView) findViewById(R.id.maxScore);
maxScore.setTextColor(Color.RED);
maxScore.setTextSize(21);
loadScore();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void loadScore(){
Dbdao helper = new Dbdao(this);
GameApplication.dbdao = helper;
helper.insert(0);
Integer score = helper.query();
maxString.setText("max score : ");
maxScore.setText(score.toString());
}
}
主要一些
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id = "@+id/scoreString"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/nowScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id = "@+id/maxString"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/maxScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<com.example.wxj2048.GameView
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/gameView"
>
</com.example.wxj2048.GameView>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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"
tools:context=".FlashStartActivity" >
<ImageView
android:id="@+id/welcome_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>