【Android 2d 游戏开发(2)】——2048

来源:互联网 发布:unity3d arduino 编辑:程序博客网 时间:2024/05/18 22:14

实现效果 :

开始界面
游戏界面
结束界面

代码结构:

这里写图片描述

完整代码:

MainActivity:

package com.next.next2048;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.Window;import android.view.WindowManager;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        //全屏        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);        setContentView(new GameView(this));    }}

Tile:
package com.next.next2048;

/**
* Created by Next on 2016/3/17 0017.
*/
public class Tile {
private int number;
private int x,y;
public Tile(int x,int y,int number){
this.x = x;
this.y = y;
this.number = number;
}

public int getY() {    return y;}public void setY(int y) {    this.y = y;}public int getX() {    return x;}public void setX(int x) {    this.x = x;}public int getNumber() {    return number;}public void setNumber(int number) {    this.number = number;}

}
GameView:

package com.next.next2048;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.view.MotionEvent;import android.view.View;import java.util.ArrayList;import java.util.Random;/** * Created by Next on 2016/3/17 0017. */public class GameView extends View {    enum GameState {        Menu,        Playing,        Over    }    GameState gameState = GameState.Menu;    public static final int MAX_X = 4;    public static final int MAX_Y = 4;    int tWidth;//tile宽度    int scrW;//屏幕宽    int scrH;//屏幕高    int offsetX;//偏移x    int offsetY;//偏移y,用于调整游戏区域在屏幕中的位置    Paint paint;    Tile[][] tiles;//Tile集合    Random random;    ArrayList<Tile> zeroList;    float downX, downY, upX, upY;    public GameView(Context context) {        super(context);        scrW = ((MainActivity) context).getWindowManager().getDefaultDisplay().getWidth();        scrH = ((MainActivity) context).getWindowManager().getDefaultDisplay().getHeight();        offsetX = 30;        offsetY = (scrH - scrW) / 2;//使棋盘位于屏幕中央        tWidth = (scrW - offsetX * 2) / MAX_X;        paint = new Paint();        tiles = new Tile[MAX_X][MAX_Y];        setKeepScreenOn(true);//保持屏幕常亮        random = new Random();        zeroList = new ArrayList<Tile>();    }    private void newGame() {        for (int x = 0; x < MAX_X; x++) {            for (int y = 0; y < MAX_Y; y++) {                tiles[x][y] = new Tile(x, y, 0);            }        }        newTile();        newTile();    }    private void newTile() {        zeroList.removeAll(zeroList);        for (int x = 0; x < MAX_X; x++) {            for (int y = 0; y < MAX_Y; y++) {                if (tiles[x][y].getNumber() == 0) {                    zeroList.add(tiles[x][y]);                }            }        }        int size = zeroList.size();        if (size > 0) {            //出现4的概率是20%,出现2的概率是80%            if (random.nextInt(5) == 0) {                zeroList.get(random.nextInt(size)).setNumber(4);            } else {                zeroList.get(random.nextInt(size)).setNumber(2);            }        } else {            return;        }    }    @Override    protected void onDraw(Canvas canvas) {        switch (gameState) {            case Menu:                menuDraw(canvas);                break;            case Playing:                playingDraw(canvas);                break;            case Over:                overDraw(canvas);                break;            default:                break;        }    }    private void menuDraw(Canvas canvas) {        canvas.drawColor(Color.WHITE);        paint.setColor(Color.BLACK);        paint.setTextAlign(Paint.Align.CENTER);        paint.setTextSize(tWidth / 2);        canvas.drawText("2048", scrW / 2, scrH / 4, paint);        canvas.drawText("Touch me", scrW / 2, scrH / 2, paint);    }    private void playingDraw(Canvas canvas) {        canvas.drawColor(Color.WHITE);        //画主游戏区域        paint.setColor(Color.BLACK);        paint.setStrokeWidth(10);        for (int x = 0; x < MAX_X + 1; x++) {            canvas.drawLine(offsetX + x * tWidth, offsetY, offsetX + x * tWidth, offsetY + tWidth * MAX_Y, paint);        }        for (int y = 0; y < MAX_Y + 1; y++) {            canvas.drawLine(offsetX, offsetY + y * tWidth, offsetX + MAX_X * tWidth, offsetY + y * tWidth, paint);        }        for (int x = 0; x < MAX_X; x++) {            for (int y = 0; y < MAX_Y; y++) {                if (tiles[x][y].getNumber() != 0) {                    switch (tiles[x][y].getNumber()){                        case 2:                            paint.setColor(0xffff6666);                            break;                        case 4:                            paint.setColor(0xffff9900);                            break;                        case 8:                            paint.setColor(0xff99CC33);                            break;                        case 16:                            paint.setColor(0xff33CC99);                            break;                        case 32:                            paint.setColor(0xff666699);                            break;                        case 64:                            paint.setColor(0xff339933);                            break;                        case 128:                            paint.setColor(0xff0099CC);                            break;                        case 256:                            paint.setColor(0xff660033);                            break;                        case 512:                            paint.setColor(0xff006633);                            break;                        case 1024:                            paint.setColor(0xff660099);                            break;                        case 2048:                            paint.setColor(0xffff0033);                            break;                        case 4096:                            paint.setColor(0xff333333);                            break;                        case 8192:                            paint.setColor(0xff000000);                            break;                        default:                            paint.setColor(0xff000000);                            break;                    }                    canvas.drawText(tiles[x][y].getNumber() + "", offsetX + x * tWidth + tWidth / 2, offsetY + y * tWidth + tWidth * 3 / 4, paint);                }            }        }    }    private void overDraw(Canvas canvas) {        int max = 0;        for (int x = 0; x < MAX_X; x++) {            for (int y = 0; y < MAX_Y; y++) {                if (tiles[x][y].getNumber() > max) {                    max = tiles[x][y].getNumber();                }            }        }        canvas.drawColor(Color.WHITE);        paint.setColor(Color.BLACK);        paint.setTextAlign(Paint.Align.CENTER);        paint.setTextSize(tWidth / 2);        canvas.drawText("Top:" + max, scrW / 2, scrH / 4, paint);        canvas.drawText("Try again", scrW / 2, scrH / 2, paint);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (gameState) {            case Menu:                menuLogic(event);                break;            case Playing:                playingLoic(event);                break;            case Over:                overLogic(event);                break;        }        return true;    }    private void menuLogic(MotionEvent event) {        if (event.getX() > 0) {            gameState = GameState.Playing;            newGame();            invalidate();        }    }    private void playingLoic(MotionEvent event) {        if (event.getAction() == MotionEvent.ACTION_DOWN) {            downX = event.getX();            downY = event.getY();        } else if (event.getAction() == MotionEvent.ACTION_UP) {            upX = event.getX();            upY = event.getY();            float moveX = upX - downX;            float moveY = upY - downY;            if (Math.abs(moveX) > Math.abs(moveY)) {                if (moveX > 50) {                    //右滑                    //合并                    boolean isMove = false;//判断是否有tile移动                    for (int y = 0; y < MAX_Y; y++) {                        for (int x = MAX_X - 1; x >= 0; x--) {                            if (tiles[x][y].getNumber() == 0) {                                continue;                            }                            for (int x0 = x - 1; x0 >= 0; x0--) {                                if (tiles[x0][y].getNumber() == 0) {                                    continue;                                } else if (tiles[x][y].getNumber() == tiles[x0][y].getNumber()) {                                    tiles[x][y].setNumber(tiles[x][y].getNumber() * 2);                                    tiles[x0][y].setNumber(0);                                    isMove = true;                                    break;                                } else {                                    break;                                }                            }                        }                    }                    //移动                    for (int y = 0; y < MAX_Y; y++) {                        for (int x = MAX_X - 1; x >= 0; x--) {                            if (tiles[x][y].getNumber() != 0) {                                continue;                            }                            for (int x0 = x - 1; x0 >= 0; x0--) {                                if (tiles[x0][y].getNumber() == 0) {                                    continue;                                } else {                                    tiles[x][y].setNumber(tiles[x0][y].getNumber());                                    tiles[x0][y].setNumber(0);                                    isMove = true;                                    break;                                }                            }                        }                    }                    //有tile移动才添加新的tile                    if (isMove) {                        newTile();                        invalidate();                        judgeOver();                    }                } else if (moveX < -50) {                    //左滑                    //合并                    boolean isMove = false;                    for (int y = 0; y < MAX_Y; y++) {                        for (int x = 0; x < MAX_X; x++) {                            if (tiles[x][y].getNumber() == 0) {                                continue;                            }                            for (int x0 = x + 1; x0 < MAX_X; x0++) {                                if (tiles[x0][y].getNumber() == 0) {                                    continue;                                } else if (tiles[x][y].getNumber() == tiles[x0][y].getNumber()) {                                    tiles[x][y].setNumber(tiles[x][y].getNumber() * 2);                                    tiles[x0][y].setNumber(0);                                    isMove = true;                                    break;                                } else {                                    break;                                }                            }                        }                    }                    //移动                    for (int y = 0; y < MAX_Y; y++) {                        for (int x = 0; x < MAX_X; x++) {                            if (tiles[x][y].getNumber() != 0) {                                continue;                            }                            for (int x0 = x + 1; x0 < MAX_X; x0++) {                                if (tiles[x0][y].getNumber() == 0) {                                    continue;                                } else {                                    tiles[x][y].setNumber(tiles[x0][y].getNumber());                                    tiles[x0][y].setNumber(0);                                    isMove = true;                                    break;                                }                            }                        }                    }                    if (isMove) {                        newTile();                        invalidate();                        judgeOver();                    }                }            } else {                if (moveY > 50) {                    //下滑                    //合并                    boolean isMove = false;                    for (int x = 0; x < MAX_X; x++) {                        for (int y = MAX_Y - 1; y >= 0; y--) {                            if (tiles[x][y].getNumber() == 0) {                                continue;                            }                            for (int y0 = y - 1; y0 >= 0; y0--) {                                if (tiles[x][y0].getNumber() == 0) {                                    continue;                                } else if (tiles[x][y].getNumber() == tiles[x][y0].getNumber()) {                                    tiles[x][y].setNumber(tiles[x][y].getNumber() * 2);                                    tiles[x][y0].setNumber(0);                                    isMove = true;                                    break;                                } else {                                    break;                                }                            }                        }                    }                    //移动                    for (int x = 0; x < MAX_X; x++) {                        for (int y = MAX_Y - 1; y >= 0; y--) {                            if (tiles[x][y].getNumber() != 0) {                                continue;                            }                            for (int y0 = y - 1; y0 >= 0; y0--) {                                if (tiles[x][y0].getNumber() == 0) {                                    continue;                                } else {                                    tiles[x][y].setNumber(tiles[x][y0].getNumber());                                    tiles[x][y0].setNumber(0);                                    isMove = true;                                    break;                                }                            }                        }                    }                    if (isMove) {                        newTile();                        invalidate();                        judgeOver();                    }                } else if (moveY < -50) {                    //上滑                    //合并                    boolean isMove = false;                    for (int x = 0; x < MAX_X; x++) {                        for (int y = 0; y < MAX_Y; y++) {                            if (tiles[x][y].getNumber() == 0) {                                continue;                            }                            for (int y0 = y + 1; y0 < MAX_Y; y0++) {                                if (tiles[x][y0].getNumber() == 0) {                                    continue;                                } else if (tiles[x][y].getNumber() == tiles[x][y0].getNumber()) {                                    tiles[x][y].setNumber(tiles[x][y].getNumber() * 2);                                    tiles[x][y0].setNumber(0);                                    isMove = true;                                    break;                                } else {                                    break;                                }                            }                        }                    }                    //移动                    for (int x = 0; x < MAX_X; x++) {                        for (int y = 0; y < MAX_Y; y++) {                            if (tiles[x][y].getNumber() != 0) {                                continue;                            }                            for (int y0 = y + 1; y0 < MAX_Y; y0++) {                                if (tiles[x][y0].getNumber() == 0) {                                    continue;                                } else {                                    tiles[x][y].setNumber(tiles[x][y0].getNumber());                                    tiles[x][y0].setNumber(0);                                    isMove = true;                                    break;                                }                            }                        }                    }                    if (isMove) {                        newTile();                        invalidate();                        judgeOver();                    }                }            }        }    }    private void overLogic(MotionEvent event) {        if (event.getX() > 0) {            newGame();            gameState = GameState.Playing;        }    }    private void judgeOver() {        //右滑        //合并        for (int y = 0; y < MAX_Y; y++) {            for (int x = MAX_X - 1; x >= 0; x--) {                if (tiles[x][y].getNumber() == 0) {                    continue;                }                for (int x0 = x - 1; x0 >= 0; x0--) {                    if (tiles[x0][y].getNumber() == 0) {                        continue;                    } else if (tiles[x][y].getNumber() == tiles[x0][y].getNumber()) {                        return;                    } else {                        break;                    }                }            }        }        //移动        for (int y = 0; y < MAX_Y; y++) {            for (int x = MAX_X - 1; x >= 0; x--) {                if (tiles[x][y].getNumber() != 0) {                    continue;                }                for (int x0 = x - 1; x0 >= 0; x0--) {                    if (tiles[x0][y].getNumber() == 0) {                        continue;                    } else {                        return;                    }                }            }        }        //左滑        //合并        for (int y = 0; y < MAX_Y; y++) {            for (int x = 0; x < MAX_X; x++) {                if (tiles[x][y].getNumber() == 0) {                    continue;                }                for (int x0 = x + 1; x0 < MAX_X; x0++) {                    if (tiles[x0][y].getNumber() == 0) {                        continue;                    } else if (tiles[x][y].getNumber() == tiles[x0][y].getNumber()) {                        return;                    } else {                        break;                    }                }            }        }        //移动        for (int y = 0; y < MAX_Y; y++) {            for (int x = 0; x < MAX_X; x++) {                if (tiles[x][y].getNumber() != 0) {                    continue;                }                for (int x0 = x + 1; x0 < MAX_X; x0++) {                    if (tiles[x0][y].getNumber() == 0) {                        continue;                    } else {                        return;                    }                }            }        }        //下滑        //合并        for (int x = 0; x < MAX_X; x++) {            for (int y = MAX_Y - 1; y >= 0; y--) {                if (tiles[x][y].getNumber() == 0) {                    continue;                }                for (int y0 = y - 1; y0 >= 0; y0--) {                    if (tiles[x][y0].getNumber() == 0) {                        continue;                    } else if (tiles[x][y].getNumber() == tiles[x][y0].getNumber()) {                        return;                    } else {                        break;                    }                }            }        }        //移动        for (int x = 0; x < MAX_X; x++) {            for (int y = MAX_Y - 1; y >= 0; y--) {                if (tiles[x][y].getNumber() != 0) {                    continue;                }                for (int y0 = y - 1; y0 >= 0; y0--) {                    if (tiles[x][y0].getNumber() == 0) {                        continue;                    } else {                        return;                    }                }            }        }        //上滑        //合并        for (int x = 0; x < MAX_X; x++) {            for (int y = 0; y < MAX_Y; y++) {                if (tiles[x][y].getNumber() == 0) {                    continue;                }                for (int y0 = y + 1; y0 < MAX_Y; y0++) {                    if (tiles[x][y0].getNumber() == 0) {                        continue;                    } else if (tiles[x][y].getNumber() == tiles[x][y0].getNumber()) {                        return;                    } else {                        break;                    }                }            }        }        //移动        for (int x = 0; x < MAX_X; x++) {            for (int y = 0; y < MAX_Y; y++) {                if (tiles[x][y].getNumber() != 0) {                    continue;                }                for (int y0 = y + 1; y0 < MAX_Y; y0++) {                    if (tiles[x][y0].getNumber() == 0) {                        continue;                    } else {                        return;                    }                }            }        }        gameState = GameState.Over;        invalidate();    }}

说两句:

这次跟上次的五子棋用的一样的游戏框架,应该很容易理解游戏的主题逻辑,当然最重要的是游戏算法,我实现的算法可能有些麻烦,但还算达到了效果,欢迎提意见。

关于主体算法:

我分了两个步骤:1.合并。2.移动
哎呀,不写了,有兴趣的人自己看代码吧,好像也没多少人看我写这个东西。。。囧

下次写个能动的游戏,就贪吃蛇吧,感觉自己帅的人请加我的公众微信号:xinshouit 更新会在里面通知

0 0
原创粉丝点击