本篇文章用到了GesTureDetector,TextView,
1024是一款前段時間比較火的游戲,在游戲中你要通過左右上下移動方塊,等值方塊會在碰撞中合并,游戲目標盡可能得到更大的數值,
1. ui設計
2. 代碼實作
首先我們要設計一個ui,
筆者采用的是TextView,因為它可以方便的得到和設定面值,我采用的4*4,這里就不貼ui代碼了
其次代碼實作,
我們可以用GestureDetector判斷用戶是上下,左右滑動,
筆者設定了一個工具類meach用來管理每個方塊的,一個meach示例對應一個TextView,筆者有個想法或許可以讓meach繼承TextView,并重寫,應該可以方便一點,
/**
* meach物件表示游戲中一個單元格與TextView配合使用,
* @number number表示方塊的面值
* @state state表示方塊是否有值,true則表示存在
*/
class meach
{
private int number;
private boolean state;
public meach(int number,boolean state)
{
this.number=number;
this.state=state;
}
public void settate(boolean b)
{
this.state=b;
}
public void setNumber(int n)
{
this.number=n;
}
public int getNumber()
{
return number;
}
public boolean getstate() {
return state;
}
}
設定亂數,在用戶每次滑動后要隨機給棋盤上生成一個方塊,
/**
* 設定亂數,當界面無空位時回傳原陣列
* @return meach[][] 回傳物件數值
*/
public static meach[][] setnewnumber() {
Random r = new Random();
//!!!判斷若棋盤上無位置
for(int i=0;i<=3;i++)
{
for(int j=0;j<=3;j++)
{
if(e[i][j].getstate()==false)
{
i=4;
break;
}
else if( i==3 && j==3)
{
//處理棋盤上無位置,回傳原陣列不設定
return e;
}
}
}
//設定亂數
do
{
i = r.nextInt(4);
j = r.nextInt(4);
}
while (e[i][j].getstate());
e[i][j].settate(true);
e[i][j].setNumber(2);
return e;
}
更新TextView的值
/**
* 函式用于設定新View
*/
public static boolean setnewview(TextView[][] tv) {
for(int i=0;i<=3;i++)
{
for(int j=0;j<=3;j++)
{
if(e[i][j].getstate())
tv[i][j].setText(e[i][j].getNumber()+"");
else
{
tv[i][j].setText(" ");
}
}
}
return true;
}
演算法實作,當用戶滑動時我們要分別遍歷行或列,讀取有數值的方塊,將其移動至滑動方向,若有相鄰兩TextView的text相同則合并,
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float x=e1.getX()-e2.getX();
float y=e1.getY()-e2.getY();
float x1=Math.abs(x);
float y1=Math.abs(y);
//向右劃
if( x1>y1 && x<0)
{
/**
* meaches[] 為一行或一列中state為true的meach物件
* sub 為meaches[]的當前下標
* sube 為應將meachs[]中的物件應移動至的下標
*/
meach meaches[];
int sub;
//從第一行開始遍歷
for(int n=0;n<=3;n++)
{
//重置
sub=0;
//從右往左開始遍歷,得出一行中的含有State為true的下標存入numbers陣列;
meaches =new meach[4];
for(int m=3;m>=0;m--) {
if (e[n][m].getstate()==true)
{
meaches[sub] = e[n][m];
sub++;
}
}
//合并并移動
if(sub==1)
{
e[n][3].setNumber(meaches[0].getNumber());
meaches[0].settate(false);
e[n][3].settate(true);
}
int sube=3;
for(int i=0;i<sub-1;i++)
{
if(meaches[i].getstate()&& meaches[i].getNumber() == meaches[i+1].getNumber() )
{
e[n][sube].setNumber( meaches[i].getNumber() *2);
meaches[i].settate(false);
meaches[i+1].settate(false);
e[n][sube].settate(true);
sube--;
}
else if(i==sub-2) {
if (meaches[i].getstate()) {
e[n][sube].setNumber(meaches[i].getNumber());
e[n][sube-1].setNumber(meaches[i + 1].getNumber());
meaches[i].settate(false);
meaches[i+1].settate(false);
e[n][sube].settate(true);
e[n][sube-1].settate(true);
}
else
{
e[n][sube].setNumber(meaches[i+1].getNumber());
meaches[i+1].settate(false);
e[n][sube].settate(true);
}
}
else if(meaches[i].getstate()) {
e[n][sube].setNumber(meaches[i].getNumber());
meaches[i].settate(false);
e[n][sube].settate(true);
sube--;
}
}
}
//顯示View
setnewnumber();
setnewview(tv);
}
}
其他方向的判斷同理,
玩家應可以選擇重開以結束本局,并開始下一局
btnrm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//清理棋盤
for(int i=0;i<=3;i++)
{
for(int j=0;j<=3;j++)
{
e[i][j].settate(false);
}
}
setnewnumber();
setnewview(tv);
}
});
注意:
//activiy層面的點擊監聽器,將事件監聽交給gesture監聽器
@Override
public boolean onTouchEvent(MotionEvent event) {
return detector.onTouchEvent(event);
}
這里將事件監聽傳遞給了Gesture,Gesture的方法才能夠實行,否則執行只onTouchEvent,
這里是筆者寫的小demo在其中也完善了一些小細節,但還是有很多游戲應該有的內容沒有設計完成,后續有時間應該會更新,
102game
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/238694.html
標籤:其他
上一篇:96年的我用一年時間從年入13w到年入百萬的創業歷程
下一篇:求助
