⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 russiangamedisplayable.java

📁 手机游戏
💻 JAVA
字号:
package russiangame;

import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.GameCanvas;

/**
 * <p>Title: 俄罗斯方块</p>
 *
 * <p>Description: 俄罗斯方块游戏</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: Star Group</p>
 *
 * @author: Part of this programe comes from a open-source project in the Web(www.hyweb.net).
 *          Our group makes some remakeble improvement to it.
 * @version 1.0
 */
public class RussianGameDisplayable extends GameCanvas implements Runnable,
        CommandListener {
    private UIController controller;
    private Command startCommand;
    private Command exitCommand;
    private Command pauseCommand;

    protected int nState; //游戏状态
    protected GameBlock block; //当前下坠物
    protected GameMap map; //游戏地图

    protected Thread thread; //游戏重画线程

    protected int nCount; //游戏速度计数
    protected int nSpeed; //游戏当前速度

    protected final int GAME_INIT = 0; //游戏初始状态
    protected final int GAME_RUN = 1; //游戏运行状态
    protected final int GAME_SUSPEND = 3; //挂起状态
    protected final int GAME_OVER = 4; //游戏结束状态
    protected final int GAME_NEXT_ROUND = 5; //游戏过关状态

    private static int mainWidth; //屏幕宽度
    private static int mainHeight; //屏幕高度

    /**游戏区域左上角x坐标
     */
    public static int GAMEAREA_X;

    /**游戏区域左上角y坐标
     */
    public static int GAMEAREA_Y;

    /**小砖块边长
     */
    public static int BRICK_WIDTH;

    /**背景颜色
     */
    public static final int BACKGROUND = 0x00000000;

    private Graphics graphics;

    public RussianGameDisplayable(UIController controller) {
        super(false);
        try {
            jbInit();
        } catch (Exception e) {
            e.printStackTrace();
        }

        this.controller = controller;
        this.graphics = this.getGraphics();

        map = new GameMap();
        block = new GameBlock(map);

        startCommand = new Command("开始", Command.OK, 1);
        pauseCommand = new Command("暂停", Command.OK, 1);
        exitCommand = new Command("退出", Command.EXIT, 0);
        this.addCommand(pauseCommand);
        this.addCommand(exitCommand);
        this.setCommandListener(this);

        //启动应用程序
        thread = new Thread(this);
        thread.start();

    }

    private void jbInit() throws Exception {
        mainWidth = getWidth();
        mainHeight = getHeight();

        //取min为长与宽中更小的值
        //确保游戏域能够被16整除
        int min = (mainWidth <= mainHeight) ? mainWidth : mainHeight;
        for (; min >= 0; min--) {
            if (min % GameMap.MAP_ROW == 0) {
                break;
            }
        }

        //小砖块边长(厚度)
        BRICK_WIDTH = min / GameMap.MAP_ROW;
        GAMEAREA_X = (mainWidth - min) / 2;
        GAMEAREA_Y = (mainHeight - min) / 2;

        this.nState = this.GAME_INIT; //游戏处于INIT状态
    }

    /**清屏,重绘 全屏背景 和 游戏背景
     * @param g
     */
    public static void Clear(Graphics g) {
        //设置全屏背景
        g.setColor(0xffffff);
        g.fillRect(0, 0, mainWidth, mainHeight);

        //设置游戏区域背景
        g.setColor(BACKGROUND);
        g.fillRect(GAMEAREA_X, GAMEAREA_Y, GameMap.MAP_ROW * BRICK_WIDTH, GameMap.MAP_ROW * BRICK_WIDTH);
    }

    public void run() {
        while (true) {
            try {
                //每50ms重画一次
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.keyPressedState();
            this.paintCanvas(this.graphics);
        }
    }

    /**
     * 响应键盘事件的回调函数, 除了down请求以外, 其他移动及转向都需要由击键一次,而不是根据状态
     */
    protected synchronized void keyPressed(int keyCode) {
        int action = getGameAction(keyCode);
        if(nState == GAME_RUN){
            switch(action){
            case Canvas.LEFT://左移
                if (this.block.checkMove(GameBlock.MOVE_LEFT)) {
                    block.move(GameBlock.MOVE_LEFT);
                }
                break;
            case Canvas.RIGHT://右移
                if (this.block.checkMove(GameBlock.MOVE_RIGHT)) {
                    block.move(GameBlock.MOVE_RIGHT);
                }
                break;
            case Canvas.UP://下坠物形状变化
            case Canvas.FIRE://下坠物变化
                if (this.block.checkRot()) {
                    block.rotBlock();
                }
                break;
            default:
                break;
            }
        }
    }

    /**
     * 主动查询按键状态
     */
    public synchronized void keyPressedState() {
        //主动查询状态
        int keyState = getKeyStates();

        if ((keyState & DOWN_PRESSED) != 0 && nState == GAME_RUN) {
            if (this.block.checkDown()) {
                block.down();
            }
        }
    }

    /**
     *  画布重画事件,替代Canvas中的paint()事件, 根据不同的游戏状态(nState)画出游戏画面
     *  本方法由thread每次重新启动, 最后执行flushGraphics()重画缓冲区
     */
    public synchronized void paintCanvas(Graphics g) {
        switch(nState){
        case GAME_INIT://游戏第一次启动
            //画出游戏逻辑地图(容器部分)
            g.setColor(BACKGROUND);
            g.fillRect(0, 0, mainWidth, mainHeight);
            map.init();
            map.paint(g);

            //根据产生的砖块类型(随机数),逻辑上初始化下坠物
            block.init();

            //图形上绘制当前和下一个下坠物
            block.drawBlock(g);
            block.drawNextBlock(g);

            //设置游戏速度和下一步游戏状态
            this.nCount = 0;
            this.nSpeed = 10-map.getLevel()*2;
            nState = GAME_RUN;
            break;

        case GAME_RUN:
            this.nCount++;
            if (this.nCount >= this.nSpeed) {
                //每停顿nSpeed次检查下降一次,随着nSpeed的变小,下降的速度会越来越大
                if (block.checkDown()) {
                    //是否能够下降(自动)
                    block.down();
                    //清除旧图形,画出新下坠物,同时将当前坐标另存为旧值
                    block.paint(g);
                } else {
                    //不再能够下降(消行 / Game over)
                    //画出图形,设置坐标
                    int y = block.getYBrick();

                    //不再下降,而是直接重新画出下坠物
                    block.paint(g);

                    //根据下坠物位置画出当前 逻辑地图数据
                    block.fixBlock();

                    //检查从y开始一下4行是否有消去行为
                    if (map.check(g, y)) {
                        map.repaintMap(g);
                    }

                    //根据产生的砖块类型(随机数),重新在 逻辑上 初始化下坠物
                    block.init();

                    //判断是否游戏结束
                    if (block.getYBrick() < 0) {
                        nState = GAME_OVER;
                    }

                    block.drawBlock(g);
                    block.drawNextBlock(g);
                }
                this.nCount = 0;

            } else {
                block.paint(g);
            }

            if(map.getScore() >= map.getLevelScroe(map.getLevel())){
                if(map.getLevel() > map.getMaxLevel())
                    nState = GAME_OVER;
                else
                    nState = GAME_NEXT_ROUND;
            }
            break;

        case GAME_NEXT_ROUND:
            StringBuffer str = new StringBuffer("Level"+" "+(map.getLevel()+1));
            Splash nr = new Splash(this.controller,str);
            controller.setNextRoundSplash(nr);
            controller.handleEvent(UIController.EventID.EVENT_NEXTROUND);
            nState = GAME_INIT;
            break;

        case GAME_OVER://游戏结束
            g.setColor(255, 255, 255);
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(BACKGROUND);
            g.fillRect(this.GAMEAREA_X, this.GAMEAREA_Y,
                       GameMap.MAP_ROW * this.BRICK_WIDTH, GameMap.MAP_ROW * this.BRICK_WIDTH);
            g.setColor(255, 0, 0);
            g.setFont(Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD,
                                   Font.SIZE_LARGE));
            g.drawString("Game Over", this.GAMEAREA_X + (GameMap.MAP_ROW / 2)* this.BRICK_WIDTH,
                         this.GAMEAREA_Y + (GameMap.MAP_ROW / 4)* this.BRICK_WIDTH,
                         Graphics.BASELINE | Graphics.HCENTER);

            this.removeCommand(this.pauseCommand);
            this.addCommand(startCommand);
            break;

        default:
            break;
        }
        //在缓冲区重画
        this.flushGraphics();
    }

    public void commandAction(Command command, Displayable displayable) {
        if (command == startCommand) {
            if (this.nState == GAME_OVER)
                nState = GAME_INIT;
            else
                nState = GAME_RUN;

            this.removeCommand(this.startCommand);
            this.addCommand(pauseCommand);

        } else if (command == pauseCommand) {
            nState = GAME_SUSPEND;

            this.removeCommand(this.pauseCommand);
            this.addCommand(startCommand);

        } else if (command == exitCommand) {
            controller.handleEvent(UIController.EventID.EVENT_EXIT);
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -