DANH SÁCH BÀI VIẾT Lập trình ứng dụng GamePlay(Trò chơi giải trí offline) trên Android Studio Lập trình game 2048 trên Android Studio – Mã nguồn game 2048 Lập trình Ứng dụng Máy tính bỏ túi trên Android Studio Xây dựng game Freaking Math trên Android – Lập trình android
Nhắc đến tựa game 2048 có lẽ là không ai không biết đến trò chơi trí tuệ hấp dẫn này. Ra đời vào năm 2014, Game 2048 đã làm mưa làm gió trong suốt thời gian dài và cho đến tận bây giờ thì tựa game này vẫn luôn lọt top các trò chơi trí tuệ, hấp dẫn nhất mọi thời đại.
Trong bài viết hôm nay mình sẽ chia sẻ mã nguồn Lập trình game 2048 trên Android Studio – Mã nguồn game 2048 cùng theo dõi nhé.
Lập trình game 2048 trên Android Studio
Video dưới đây là demo mà mình đã xây dựng và sẽ chia sẻ Source Code trong bài viết hôm nay, bạn xem qua nhé.
- Kiếm tiền Accesstrade, kiếm tiền tại nhà với Accesstrade.vn – Tiếp thị liên kết
- MegaURL – Rút gọn link kiếm tiền có giá cao tại Việt Nam
- Top 4 App kiếm tiền online trên điện thoại tốt nhất 2022
Ý tưởng thuật toán
Ý tưởng thuật toán mà mình sử dụng thì cũng tương đối đơn giản. Trò chơi sẽ bão gồm 16 ô với kích thước 4×4, vậy tương ứng mình sẽ sử dụng một mảng 2 chiều kích thước 4×4 để lưu các giá trị của các ô trong trò chơi.
Với các ô trống, giá trí mảng mình sẽ lưu là 0, các ô khác mảng lưu giá trị tương ứng đang có của ô đó. Dựa vào mảng này để hiển thị trạng thái trò chơi và màu sắc của các ô ra màn hình.
Khi người chơi tiến hành vuốt màn hình lên, xuống, trái hoặc phải, chúng ta sẽ sử dụng thuật toán để dồn mảng về phía đó, 2 ô đang có giá trị giống nhau mà cạnh nhau hoặc 2 ô có giá trị giống nhau và ở giữa chúng là các ô trống thì 2 ô này sẽ được ghép thành ô có giá trị lớn hơn.
Sau mỗi lần người chơi thao tác vuốt, một ô mang giá trị 2 hoặc 4 sẽ sinh ngẫu nhiên tại ô đang trống.
Cụ thể hàm phát hiện cử chỉ vuốt và thao tác dồn mảng mình viết như bên dưới.
//Kế thừa từ lớp GestureDetector.SimpleOnGestureListener để xử dụng được thao tác cử chỉ màn hình
class CuChiManHinh extends GestureDetector.SimpleOnGestureListener {
//*Hàm thao tác cử chỉ màn hình
// MotionEvent e1 là vị trí tọa độ màn hình khi mình chạm màn hình, e2 là tọa độ khi mình nhấc tay lên
//velocityX, velocityY tạm hiểu là tốc độ vuốt theo trục x và y
//*
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean check = false;
setLuumatrix();
//*Vuốt sang trái
//e1.getX() - e2.getX() > 100 đảm bảo thao tác vuốt theo trục X khoảng cách lớn hơn 100 điểm ảnh (khoảng cách tối thiểu để đủ nhận biết đó là thao tác vuôt)
//Math.abs(e1.getY() - e2.getY()) < Math.abs(e1.getX() - e2.getX()) - Đảm bảo khoảng cách thao tác vuốt theo trục X phải lớn hơn theo trục Y
//Math.abs(velocityX) > 100 - Tốc độ vuốt phải đủ nhanh
//*
if(e1.getX() - e2.getX() > 100 && Math.abs(e1.getY() - e2.getY()) < Math.abs(e1.getX() - e2.getX()) && Math.abs(velocityX) > 100){
//Vòng lặp để dồn mảng về phía trái
for(int i=1;i<5;i++){
for(int j=1;j<4;j++)
{
if(matrix[i][j]!=0)
{
for(int k=j+1; k<5;k++)
{
if(matrix[i][k]==matrix[i][j])
{
check = true;
matrix[i][j]+=matrix[i][k];
scores+=matrix[i][j];
matrix[i][k]=0;j=k;break;
}else if(matrix[i][k]!=0) break;
}
}
}
for(int j=1;j<4;j++)
{
if(matrix[i][j] == 0)
{
for(int k=j+1; k<5;k++)
{
if(matrix[i][k]!=0)
{
check = true;
matrix[i][j]=matrix[i][k];
matrix[i][k]=0; break;
}
}
}
}
}
}
//Vuốt sang phải (Tương tự bên trên)
else if(e2.getX() - e1.getX() > 100 && Math.abs(e1.getY() - e2.getY()) < Math.abs(e1.getX() - e2.getX()) && Math.abs(velocityX) > 100)
{
for(int i=1;i<5;i++){
for(int j=4;j>1;j--){
if( matrix[i][j]!=0)
{
for(int k=j-1; k>0;k--)
{
if(matrix[i][k]==matrix[i][j])
{
check =true;
matrix[i][j]+=matrix[i][k];
scores+=matrix[i][j];
matrix[i][k]=0; j = k; break;
}else if(matrix[i][k]!=0) break;
}
}
}
for(int j=4;j>1;j--)
{
if(matrix[i][j] == 0)
{
for(int k=j-1; k>0;k--)
{
if(matrix[i][k]!=0)
{
check = true;
matrix[i][j]=matrix[i][k];
matrix[i][k]=0; break;
}
}
}
}
}
}
//vuot len
else if(e1.getY() - e2.getY() > 100 && Math.abs(e1.getX() - e2.getX()) < Math.abs(e1.getY() - e2.getY()) && Math.abs(velocityY) > 100){
for(int i=1;i<5;i++)
{
for(int j=1;j<4;j++){
if(matrix[j][i]!=0)
{
for(int k=j+1;k<5;k++)
{
if(matrix[k][i]==matrix[j][i])
{
check=true;
matrix[j][i] += matrix[k][i];
scores+=matrix[j][i];
matrix[k][i]=0; j=k; break;
}if(matrix[k][i]!=0) break;
}
}
}
for(int j=1;j<4;j++)
{
if(matrix[j][i] == 0)
{
for(int k=j+1;k<5;k++)
{
if(matrix[k][i]!=0)
{
check = true;
matrix[j][i] = matrix[k][i];
matrix[k][i]=0; break;
}
}
}
}
}
}
//vuot xuong
else if(e2.getY() - e1.getY() > 100 && Math.abs(e1.getX() - e2.getX()) < Math.abs(e1.getY() - e2.getY()) && Math.abs(velocityY) > 100)
{
for(int i=1;i<5;i++)
{
for(int j=4;j>1;j--)
{
if(matrix[j][i] != 0)
{
for(int k=j-1;k>0;k--)
{
if(matrix[k][i]==matrix[j][i])
{
check=true;
matrix[j][i]+= matrix[k][i];
scores+=matrix[j][i];
matrix[k][i]=0; j=k; break;
}else if(matrix[k][i] != 0) break;
}
}
}
for(int j=4;j>1;j--)
{
if(matrix[j][i] == 0)
{
for(int k=j-1;k>0;k--)
{
if(matrix[k][i]!=0)
{
check = true;
matrix[j][i] = matrix[k][i];
matrix[k][i]=0; break;
}
}
}
}
}
}
if(check==true)randdomnumber();
gameove();
setBOX();
return super.onFling(e1, e2, velocityX, velocityY);
}
}
public void randdomnumber()
{
Random random = new Random();
while(true)
{
int i=random.nextInt(4)+1, j=random.nextInt(4)+1;
if(matrix[i][j]==0)
{
if(random.nextInt(11) < 10
) matrix[i][j]=2;
else matrix[i][j]=4;
break;
}
}
}
Một số hình ảnh trò chơi
Mã nguồn trò chơi
TẢI XUỐNG MÃ NGUỒN
Link SourceCode: https://tuicocach.com/shortlink/?c=source-game-2048
TẢI XUỐNG FILE APK
Link file .APK: https://tuicocach.com/shortlink/?c=app_2048
Ứng dụng xây dựng gồm 1 số file java và file giao diện XML như sau:
Database.java – Lớp thao tác với Cơ sở dữ liệu SQLite
package com.example.game2048;
import android.app.admin.DelegatedAdminReceiver;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class Database extends SQLiteOpenHelper {
public Database(@Nullable Context context) {
super(context, "Database.SQLite", null, 1);
try{
SQLiteDatabase database = getWritableDatabase();
database.execSQL("INSERT INTO Game2048 VALUES('hang1','2','0','0','0','0')");
database.execSQL("INSERT INTO Game2048 VALUES('hang2','0','0','0','0','0')");
database.execSQL("INSERT INTO Game2048 VALUES('hang3','0','0','2','0','0')");
database.execSQL("INSERT INTO Game2048 VALUES('hang4','0','0','0','0','0')");
database.close();
}catch (Exception e)
{
}
}
public Cursor getData(String sql)
{
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS Game2048(hang text primary key, cot1 TEXT, cot2 text,cot3 text,cot4 text,diemcao text)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public String getDiemcao2048(Context context)
{
Cursor cursor = new Database(context).getData("SELECT *FROM Game2048");
cursor.move(1);
return cursor.getString(5);
}
public void setDiemcao2048(int diemcao)
{
SQLiteDatabase database = getWritableDatabase();
database.execSQL("UPDATE Game2048 SET diemcao ='" +diemcao +"' WHERE hang='hang1'");
database.close();
}
public String getDiemHT2048(Context context)
{
Cursor cursor = new Database(context).getData("SELECT *FROM Game2048");
cursor.move(2);
return cursor.getString(5);
}
public void setDiemHT2048(int diemcao)
{
SQLiteDatabase database = getWritableDatabase();
database.execSQL("UPDATE Game2048 SET diemcao ='" +diemcao +"' WHERE hang='hang2'");
database.close();
}
public void setQuatrinh(int matrix[][])
{
SQLiteDatabase database = getWritableDatabase();
database.execSQL("UPDATE Game2048 SET cot1 ='" +matrix[1][1] +"' WHERE hang='hang1'");
database.execSQL("UPDATE Game2048 SET cot2 ='" +matrix[1][2] +"' WHERE hang='hang1'");
database.execSQL("UPDATE Game2048 SET cot3 ='" +matrix[1][3] +"' WHERE hang='hang1'");
database.execSQL("UPDATE Game2048 SET cot4 ='" +matrix[1][4] +"' WHERE hang='hang1'");
database.execSQL("UPDATE Game2048 SET cot1 ='" +matrix[2][1] +"' WHERE hang='hang2'");
database.execSQL("UPDATE Game2048 SET cot2 ='" +matrix[2][2] +"' WHERE hang='hang2'");
database.execSQL("UPDATE Game2048 SET cot3 ='" +matrix[2][3] +"' WHERE hang='hang2'");
database.execSQL("UPDATE Game2048 SET cot4 ='" +matrix[2][4] +"' WHERE hang='hang2'");
database.execSQL("UPDATE Game2048 SET cot1 ='" +matrix[3][1] +"' WHERE hang='hang3'");
database.execSQL("UPDATE Game2048 SET cot2 ='" +matrix[3][2] +"' WHERE hang='hang3'");
database.execSQL("UPDATE Game2048 SET cot3 ='" +matrix[3][3] +"' WHERE hang='hang3'");
database.execSQL("UPDATE Game2048 SET cot4 ='" +matrix[3][4] +"' WHERE hang='hang3'");
database.execSQL("UPDATE Game2048 SET cot1 ='" +matrix[4][1] +"' WHERE hang='hang4'");
database.execSQL("UPDATE Game2048 SET cot2 ='" +matrix[4][2] +"' WHERE hang='hang4'");
database.execSQL("UPDATE Game2048 SET cot3 ='" +matrix[4][3] +"' WHERE hang='hang4'");
database.execSQL("UPDATE Game2048 SET cot4 ='" +matrix[4][4] +"' WHERE hang='hang4'");
}
public int[][] getQuatrinh(Context context){
int a[][]= new int[5][5];
Cursor cursor = new Database(context).getData("SELECT *FROM Game2048");
for(int i=1;i<5;i++)
{
cursor.moveToPosition(i-1);
for(int j=1;j<5;j++) a[i][j] = Integer.valueOf(cursor.getString(j));
}
return a;
}
}
MainActivity.java – Màn hình bắt đầu trò chơi
package com.example.game2048;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.app.*;
import android.content.Intent;
import android.view.*;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
private Button playgame, choitiep;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
try{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Bạn có muốn thoát!!").setPositiveButton("Có", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startActivity(startMain);
finish();
}
})
.setNegativeButton("Không", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
}).show();
}catch (Exception e)
{
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
anhxa();
batxukienclick();
}
public void batxukienclick()
{
playgame.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, play2048.class);
intent.putExtra("playgame", 1);
startActivity(intent);
}
});
choitiep.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, play2048.class);
intent.putExtra("playgame", 3);
startActivity(intent);
}
});
}
public void anhxa()
{
playgame = (Button)findViewById(R.id.playgame2048);
choitiep = (Button)findViewById(R.id.choitiep);
}
}
play2048.java – Màn hình trò chơi
package com.example.game2048;
import androidx.appcompat.app.AppCompatActivity;
import android.app.*;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.*;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Random;
public class play2048 extends Activity {
private ImageView box11, box12, box13, box14;
private ImageView box21, box22, box23, box24;
private ImageView box31, box32, box33, box34;
private ImageView box41, box42, box43, box44;
Intent context;
private TextView text11, text12, text13, text14;
private TextView text21, text22, text23, text24;
private TextView text31, text32, text33, text34;
private TextView text41, text42, text43, text44;
private LinearLayout khungman;
private int scores=0;
Button quaylai, reset;
private int matrix [][], luumatrix[][];
private TextView diemso, diemcao;
private Database database;
@Override
public void onStop() {
LuuQuatrinh();
super.onStop();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
try{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Bạn có muốn thoát!!").setPositiveButton("Có", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LuuQuatrinh();
Intent startMain = new Intent(play2048.this, MainActivity.class);
startMain.addCategory(Intent.CATEGORY_HOME);
startActivity(startMain);
finish();
}
})
.setNegativeButton("Không", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
}).show();
}catch (Exception e)
{
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_play2048);
anhxa();
context = getIntent();
try{
if(context.getIntExtra("playgame",0) == 3)choitiep();
else khoitao();
}catch (Exception e){
khoitao();
}
final GestureDetector gestureDetector = new GestureDetector(this, new CuChiManHinh());
khungman.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetector.onTouchEvent(event);
return true;
}
});
quaylai.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
trove1buoc();
}
});
reset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RESETGAME();
}
});
}
public void LuuQuatrinh()
{
database = new Database(this);
database.setQuatrinh(matrix);
if(Integer.valueOf(database.getDiemcao2048(this)) < scores)
{
database.setDiemcao2048(scores);
}
database.setDiemHT2048(scores);
database.close();
}
public void RESETGAME()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Bạn có muốn chơi lại!!").setPositiveButton("Có", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
khoitao();
}
})
.setNegativeButton("Không", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
}).show();
}
public void choitiep()
{
database = new Database(this);
diemcao.setText(database.getDiemcao2048(this));
scores = Integer .valueOf(database.getDiemHT2048(this));
matrix = database.getQuatrinh(this);
database.close();
setLuumatrix();
setBOX();
}
public void khoitao()
{
database = new Database(this);
if(Integer.valueOf(database.getDiemcao2048(this)) < scores)
{
database.setDiemcao2048(scores);
}
diemcao.setText(database.getDiemcao2048(this));
database.close();
scores=0;
for(int i=0;i<25;i++) matrix [i/5][i%5]=0;
randdomnumber();
randdomnumber();
setLuumatrix();
setBOX();
}
void anhxa()
{
matrix = new int[5][5];
luumatrix = new int[5][5];
diemso = (TextView) findViewById(R.id.diemso);
diemcao = (TextView) findViewById(R.id.diemcao);
khungman = (LinearLayout) findViewById(R.id.khungchoi);
box11 = (ImageView) findViewById(R.id.box11);
box12 = (ImageView) findViewById(R.id.box12);
box13 = (ImageView) findViewById(R.id.box13);
box14 = (ImageView) findViewById(R.id.box14);
box21 = (ImageView) findViewById(R.id.box21);
box22 = (ImageView) findViewById(R.id.box22);
box23 = (ImageView) findViewById(R.id.box23);
box24 = (ImageView) findViewById(R.id.box24);
box31 = (ImageView) findViewById(R.id.box31);
box32 = (ImageView) findViewById(R.id.box32);
box33 = (ImageView) findViewById(R.id.box33);
box34 = (ImageView) findViewById(R.id.box34);
box41 = (ImageView) findViewById(R.id.box41);
box42 = (ImageView) findViewById(R.id.box42);
box43 = (ImageView) findViewById(R.id.box43);
box44 = (ImageView) findViewById(R.id.box44);
text11 = (TextView) findViewById(R.id.text11);
text12 = (TextView) findViewById(R.id.text12);
text13 = (TextView) findViewById(R.id.text13);
text14 = (TextView) findViewById(R.id.text14);
text21 = (TextView) findViewById(R.id.text21);
text22 = (TextView) findViewById(R.id.text22);
text23 = (TextView) findViewById(R.id.text23);
text24 = (TextView) findViewById(R.id.text24);
text31 = (TextView) findViewById(R.id.text31);
text32 = (TextView) findViewById(R.id.text32);
text33 = (TextView) findViewById(R.id.text33);
text34 = (TextView) findViewById(R.id.text34);
text41 = (TextView) findViewById(R.id.text41);
text42 = (TextView) findViewById(R.id.text42);
text43 = (TextView) findViewById(R.id.text43);
text44 = (TextView) findViewById(R.id.text44);
quaylai = (Button) findViewById(R.id.quaylai);
reset = (Button)findViewById(R.id.reset);
}
public void trove1buoc()
{
boolean check = true;
for(int i=1;i<25;i++)
{
if( matrix[i/5][i%5] != luumatrix[i/5][i%5])
{
check = false; break;
}
}
if (check==true)
{
Toast.makeText(this,"Không thể quay lại", Toast.LENGTH_SHORT).show();
return;
}
for(int i=1;i<25;i++) matrix[i/5][i%5] = luumatrix[i/5][i%5];
setBOX();
}
public void setBOX()
{
diemso.setText(String.valueOf(scores));
box11.setImageResource(getBackground(matrix[1][1]));
box12.setImageResource(getBackground(matrix[1][2]));
box13.setImageResource(getBackground(matrix[1][3]));
box14.setImageResource(getBackground(matrix[1][4]));
box21.setImageResource(getBackground(matrix[2][1]));
box22.setImageResource(getBackground(matrix[2][2]));
box23.setImageResource(getBackground(matrix[2][3]));
box24.setImageResource(getBackground(matrix[2][4]));
box31.setImageResource(getBackground(matrix[3][1]));
box32.setImageResource(getBackground(matrix[3][2]));
box33.setImageResource(getBackground(matrix[3][3]));
box34.setImageResource(getBackground(matrix[3][4]));
box41.setImageResource(getBackground(matrix[4][1]));
box42.setImageResource(getBackground(matrix[4][2]));
box43.setImageResource(getBackground(matrix[4][3]));
box44.setImageResource(getBackground(matrix[4][4]));
String matrixS[][]=new String[5][5];
for(int i=0;i<25;i++)
{
if(matrix[i/5][i%5]==0) matrixS[i/5][i%5]="";
else matrixS[i/5][i%5] = String.valueOf(matrix[i/5][i%5]);
}
setSizetext();
text11.setText(matrixS[1][1]);
text12.setText(matrixS[1][2]);
text13.setText(matrixS[1][3]);
text14.setText(matrixS[1][4]);
text21.setText(matrixS[2][1]);
text22.setText(matrixS[2][2]);
text23.setText(matrixS[2][3]);
text24.setText(matrixS[2][4]);
text31.setText(matrixS[3][1]);
text32.setText(matrixS[3][2]);
text33.setText(matrixS[3][3]);
text34.setText(matrixS[3][4]);
text41.setText(matrixS[4][1]);
text42.setText(matrixS[4][2]);
text43.setText(matrixS[4][3]);
text44.setText(matrixS[4][4]);
}
public void setSizetext()
{
if(matrix[1][1] <= 512) text11.setTextSize(35);
else text11.setTextSize(25);
if(matrix[2][1] <=512) text21.setTextSize(35);
else text21.setTextSize(25);
if(matrix[3][1] <= 512) text31.setTextSize(35);
else text31.setTextSize(25);
if(matrix[4][1] <= 512) text41.setTextSize(35);
else text41.setTextSize(25);
if(matrix[1][2] <= 512) text12.setTextSize(35);
else text12.setTextSize(25);
if(matrix[2][2] <= 512) text22.setTextSize(35);
else text22.setTextSize(25);
if(matrix[3][2] <= 512) text32.setTextSize(35);
else text32.setTextSize(25);
if(matrix[4][2] <= 512) text42.setTextSize(35);
else text42.setTextSize(25);
if(matrix[1][3] <= 512) text13.setTextSize(35);
else text13.setTextSize(25);
if(matrix[2][3] <= 512) text23.setTextSize(35);
else text23.setTextSize(25);
if(matrix[3][3] <= 512) text33.setTextSize(35);
else text33.setTextSize(25);
if(matrix[4][3] <= 512) text43.setTextSize(35);
else text43.setTextSize(25);
if(matrix[1][4] <= 512) text14.setTextSize(35);
else text14.setTextSize(25);
if(matrix[2][4] <= 512) text24.setTextSize(35);
else text24.setTextSize(25);
if(matrix[3][4] <= 512) text34.setTextSize(35);
else text34.setTextSize(25);
if(matrix[4][4] <= 512) text44.setTextSize(35);
else text44.setTextSize(25);
}
public int getBackground(int n)
{
if(n==0) return R.drawable.box0;
switch (n%2048)
{
case 2: return R.drawable.box2;
case 4: return R.drawable.box4;
case 8: return R.drawable.box8;
case 16: return R.drawable.box16;
case 32: return R.drawable.box32;
case 64: return R.drawable.box64;
case 128: return R.drawable.box128;
case 256: return R.drawable.box256;
case 512: return R.drawable.box512;
case 1024: return R.drawable.box1024;
case 0: return R.drawable.box2048;
}
return 0;
}
class CuChiManHinh extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean check = false;
setLuumatrix();
if(e1.getX() - e2.getX() > 100 && Math.abs(e1.getY() - e2.getY()) < Math.abs(e1.getX() - e2.getX()) && Math.abs(velocityX) > 100){
for(int i=1;i<5;i++){
for(int j=1;j<4;j++)
{
if(matrix[i][j]!=0)
{
for(int k=j+1; k<5;k++)
{
if(matrix[i][k]==matrix[i][j])
{
check = true;
matrix[i][j]+=matrix[i][k];
scores+=matrix[i][j];
matrix[i][k]=0;j=k;break;
}else if(matrix[i][k]!=0) break;
}
}
}
for(int j=1;j<4;j++)
{
if(matrix[i][j] == 0)
{
for(int k=j+1; k<5;k++)
{
if(matrix[i][k]!=0)
{
check = true;
matrix[i][j]=matrix[i][k];
matrix[i][k]=0; break;
}
}
}
}
}
}else if(e2.getX() - e1.getX() > 100 && Math.abs(e1.getY() - e2.getY()) < Math.abs(e1.getX() - e2.getX()) && Math.abs(velocityX) > 100)
{
for(int i=1;i<5;i++){
for(int j=4;j>1;j--){
if( matrix[i][j]!=0)
{
for(int k=j-1; k>0;k--)
{
if(matrix[i][k]==matrix[i][j])
{
check =true;
matrix[i][j]+=matrix[i][k];
scores+=matrix[i][j];
matrix[i][k]=0; j = k; break;
}else if(matrix[i][k]!=0) break;
}
}
}
for(int j=4;j>1;j--)
{
if(matrix[i][j] == 0)
{
for(int k=j-1; k>0;k--)
{
if(matrix[i][k]!=0)
{
check = true;
matrix[i][j]=matrix[i][k];
matrix[i][k]=0; break;
}
}
}
}
}
}
//vuot len
else if(e1.getY() - e2.getY() > 100 && Math.abs(e1.getX() - e2.getX()) < Math.abs(e1.getY() - e2.getY()) && Math.abs(velocityY) > 100){
for(int i=1;i<5;i++)
{
for(int j=1;j<4;j++){
if(matrix[j][i]!=0)
{
for(int k=j+1;k<5;k++)
{
if(matrix[k][i]==matrix[j][i])
{
check=true;
matrix[j][i] += matrix[k][i];
scores+=matrix[j][i];
matrix[k][i]=0; j=k; break;
}if(matrix[k][i]!=0) break;
}
}
}
for(int j=1;j<4;j++)
{
if(matrix[j][i] == 0)
{
for(int k=j+1;k<5;k++)
{
if(matrix[k][i]!=0)
{
check = true;
matrix[j][i] = matrix[k][i];
matrix[k][i]=0; break;
}
}
}
}
}
}
//vuot xuong
else if(e2.getY() - e1.getY() > 100 && Math.abs(e1.getX() - e2.getX()) < Math.abs(e1.getY() - e2.getY()) && Math.abs(velocityY) > 100)
{
for(int i=1;i<5;i++)
{
for(int j=4;j>1;j--)
{
if(matrix[j][i] != 0)
{
for(int k=j-1;k>0;k--)
{
if(matrix[k][i]==matrix[j][i])
{
check=true;
matrix[j][i]+= matrix[k][i];
scores+=matrix[j][i];
matrix[k][i]=0; j=k; break;
}else if(matrix[k][i] != 0) break;
}
}
}
for(int j=4;j>1;j--)
{
if(matrix[j][i] == 0)
{
for(int k=j-1;k>0;k--)
{
if(matrix[k][i]!=0)
{
check = true;
matrix[j][i] = matrix[k][i];
matrix[k][i]=0; break;
}
}
}
}
}
}
if(check==true)randdomnumber();
gameove();
setBOX();
return super.onFling(e1, e2, velocityX, velocityY);
}
}
public void randdomnumber()
{
Random random = new Random();
while(true)
{
int i=random.nextInt(4)+1, j=random.nextInt(4)+1;
if(matrix[i][j]==0)
{
if(random.nextInt(11) < 10
) matrix[i][j]=2;
else matrix[i][j]=4;
break;
}
}
}
public void setLuumatrix(){
for(int i=1;i<25;i++) luumatrix[i/5][i%5] = matrix[i/5][i%5];
}
public void gameove()
{
for(int i=1;i<5;i++)
for(int j=1;j<5;j++)
if(matrix[i][j] == 0)
return;
boolean check = false;
for(int i=1;i<5;i++)
{
for(int j=1;j<4;j++)
{
if(matrix[i][j] == matrix[i][j+1]) check=true;
if(matrix[j][i]== matrix[j+1][i]) check = true;
}
}
if(check==false)
{
final Dialog dialog = new Dialog(this);
dialog.setCancelable(false);
dialog.setContentView(R.layout.game_over);
dialog.show();
final Button menu = (Button) dialog.findViewById(R.id.menu);
Button Again = (Button) dialog.findViewById(R.id.Again) ;
TextView diemso = (TextView) dialog.findViewById(R.id.diemso);
TextView diemcao = (TextView) dialog.findViewById(R.id.diemcao);
diemso.setText("New "+String.valueOf(scores));
Database database;
database = new Database(this);
if(Integer.valueOf(database.getDiemcao2048(this)) < scores){
database.setDiemcao2048(scores);
}
database.close();
database = new Database(this);
diemcao.setText("Best "+database.getDiemcao2048(this));
database.close();
menu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(play2048.this, MainActivity.class));
}
});
Again.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
khoitao();
dialog.cancel();
}
});
}
}
}
Các file giao diện XML
activity_main.xml – Giao diện bắt đầu trò chơi
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#123"
android:gravity="center"
tools:context=".MainActivity">
<ImageView
android:layout_marginBottom="30dp"
android:layout_width="250dp"
android:layout_height="250dp"
android:src="@drawable/menugamehaikhongbontam"/>
<Button
android:textSize="18dp"
android:textColor="#ddd"
android:id="@+id/choitiep"
android:layout_margin="8dp"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:background="@drawable/backgroungbuttonmenu"
android:text="Chơi tiếp"/>
<Button
android:textSize="18dp"
android:textColor="#ddd"
android:id="@+id/playgame2048"
android:layout_margin="8dp"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:background="@drawable/backgroungbuttonmenu"
android:text="TRÒ CHƠI MỚI"/>
</LinearLayout>
activity_play2048.xml – Giao diện màn hình trò chơi
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:gravity="center"
android:background="#123"
android:weightSum="100"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".play2048">
<LinearLayout
android:paddingTop="70dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:weightSum="10"
android:layout_weight="30">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="match_parent">
<TextView
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2048"
android:textSize="50dp"
android:textStyle="bold"
android:textColor="#ddd"/>
</LinearLayout>
<LinearLayout
android:padding="10dp"
android:layout_width="0dp"
android:layout_weight="6"
android:orientation="vertical"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="60dp"
android:orientation="vertical"
android:weightSum="2"
android:background="@drawable/boxscores">
<LinearLayout
android:gravity="center|bottom"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:textColor="#ccc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Điếm số"/>
</LinearLayout>
<LinearLayout
android:gravity="center|top"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:id="@+id/diemso"
android:textColor="#fff"
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="60dp"
android:orientation="vertical"
android:weightSum="2"
android:background="@drawable/boxscores">
<LinearLayout
android:gravity="center|bottom"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:textColor="#ccc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Điếm cao"/>
</LinearLayout>
<LinearLayout
android:gravity="center|top"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:id="@+id/diemcao"
android:textColor="#fff"
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1204"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_marginRight="4dp"
android:gravity="right"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:padding="5dp"
android:layout_marginRight="15dp"
android:background="@drawable/newgame"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/quaylai"
android:background="@drawable/quaylai1"
android:layout_gravity="left"
android:layout_width="30dp"
android:layout_height="30dp" />
</RelativeLayout>
<LinearLayout
android:padding="5dp"
android:background="@drawable/newgame"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/reset"
android:background="@drawable/reset"
android:layout_gravity="left"
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/khungchoi"
android:layout_margin="10dp"
android:padding="3dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000"
android:orientation="vertical"
android:weightSum="4"
android:layout_weight="50">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:weightSum="4"
android:layout_weight="1">
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box11"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box2"/>
<TextView
android:textStyle="bold"
android:id="@+id/text11"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="2"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box12"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box4"/>
<TextView
android:textStyle="bold"
android:text="4"
android:id="@+id/text12"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box13"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box8"/>
<TextView
android:textStyle="bold"
android:id="@+id/text13"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="8"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box14"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box16"/>
<TextView
android:textStyle="bold"
android:text="16"
android:id="@+id/text14"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:weightSum="4"
android:layout_weight="1">
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box21"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box32"/>
<TextView
android:textStyle="bold"
android:text="32"
android:id="@+id/text21"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box22"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box0"/>
<TextView
android:textStyle="bold"
android:id="@+id/text22"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box23"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box64"/>
<TextView
android:textStyle="bold"
android:text="64"
android:id="@+id/text23"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box24"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box128"/>
<TextView
android:textStyle="bold"
android:text="128"
android:id="@+id/text24"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:weightSum="4"
android:layout_weight="1">
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box31"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box256"/>
<TextView
android:textStyle="bold"
android:text="256"
android:id="@+id/text31"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box32"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box512"/>
<TextView
android:textStyle="bold"
android:text="512"
android:id="@+id/text32"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box33"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box1024"/>
<TextView
android:textStyle="bold"
android:text="1024"
android:id="@+id/text33"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box34"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box2048"/>
<TextView
android:textStyle="bold"
android:id="@+id/text34"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:weightSum="4"
android:layout_weight="1">
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box41"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box0"/>
<TextView
android:textStyle="bold"
android:id="@+id/text41"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box42"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box0"/>
<TextView
android:textStyle="bold"
android:id="@+id/text42"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box43"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box0"/>
<TextView
android:textStyle="bold"
android:id="@+id/text43"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="3dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<ImageView
android:id="@+id/box44"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/box0"/>
<TextView
android:textStyle="bold"
android:id="@+id/text44"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#fff"
android:textSize="35dp"/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="20">
</LinearLayout>
</LinearLayout>
game_over.xml – Giao diện Dialog trò chơi kết thúc
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content"
android:background="@drawable/buttonnotich"
tools:context=".MainActivity">
<TextView
android:layout_margin="25dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="35dp"
android:textStyle="bold"
android:textColor="#444"
android:fontFamily="@font/aclonica"
android:text="GAME OVER"/>
<TextView
android:id="@+id/diemso"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30dp"
android:textStyle="bold"
android:fontFamily="@font/aclonica"
android:text="New 120"/>
<TextView
android:id="@+id/diemcao"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30dp"
android:textStyle="bold"
android:fontFamily="@font/aclonica"
android:text="Best 120"/>
<LinearLayout
android:layout_marginTop="30dp"
android:layout_marginBottom="30dp"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:gravity="center"
android:id="@+id/Again"
android:textStyle="bold"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Chơi lại"/>
<Button
android:id="@+id/menu"
android:textStyle="bold"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="VỀ MENU"/>
</LinearLayout>
</LinearLayout>
XÊM THÊM Lập trình Ứng dụng Máy tính bỏ túi trên Android Studio Xây dựng game Freaking Math trên Android – Lập trình android Lập trình tỏ tình người yêu trên Graphics C/C++ – I LOVE YOU Lập trình Đồng Hồ Thời Gian & Bấm Giờ Trên Graphics C/C++