09 智慧桥/ 艾摩君

来源:互联网 发布:js曲线饼图插件 编辑:程序博客网 时间:2024/06/05 17:19

1. 前言

最近, 实在是闲的淡疼, 所以 没事的时候, 想起了以前的这个游戏[fc, 智慧桥 or 艾摩君], 以前小的时候玩的时候感觉非常难啊, 然后 后来大概是高中高考之后自己郁闷的时候, 又回来完了完吧, 当时候是玩到了44关, 但是没有 玩完啊, 深表遗憾
说实话 这个游戏是挺好玩的, 就像一道一道的难题, 在解决难题之前, 总是要进行很多次的想到的尝试方案的执行, 然而 当你解决问题之后, 你会感觉到一股喜悦, 这样的喜悦会让你感觉生活充满了意义, 但是 同时也有一种哀伤, 毕竟陪伴自己的这段时间的这个难题, 对于自己来说不再是难题了, 以后基本上都不会再来思考这个难题了
就好比 同学聚会的时候, 聚会之前是充满喜悦的, 然后聚会之后, 当你一个人沉思的时候, 你总会有一种莫名其妙的伤感..
又或者是一部好看的电视剧 或者电影

好了, 最近 闲的淡疼时候, 就(ˇˍˇ) 想~做做游戏, 这次就拿这个开刀吧, 还是花费了一些时间的的, 不过也有一些收获的
第一 : 是在控制左右方向方面 [这一次的控制不是按一下键, 调用一下方法, 而是在按下键盘的时候设置标志位, 释放键盘灯的时候, 设置回标志位, 在标志位为true这段时间, 使用一个线程, 隔一段时间定时判断一下, 如果为true, 则调用一下方法]
第二 : 双缓冲问题, 先将需要绘制的数据绘制到一个Image缓存中, 然后 在绘制到屏幕上
第三 : 状态模式的时候, 之前曾经看过一次状态模式的场景, 这还是第一次真正的使用呢
这个, 并没有完成, 只是完成了简单的东西, 也就是完成了第一关需要的东西, 因为最近 不想花多的时间来完成剩余的东西了, 因为最近 还需要去看看其他的东西。

难点 : 各个元素绘制, 以及方向键和跳跃键的兼容, 以及判断是否能够移动元素的判断
这个涉及到多线程的是挺多的, 但是并没有太多涉及线程同步的地方


规则 : 捡到所有的boy, 并且进入门就过关 [某些元素可以攻击, 某些元素是否可以穿过]

元素介绍 :
elmo : 我们的主角, 用户控制的角色
boy : 哭闹的孩子, elmo需要收集到所有的boy, 才能够进入门, 进入下一个关卡
brick : 砖块, elmo可以站在上面, elmo可以攻击, elmo不能穿过, 不能独立存在于空中
floor : 地板砖, elmo可以站在上面, elmo不可以攻击, elmo不能穿过, 能独立存在于空中
rack : 岩石, elmo可以站在上面, elmo不可以攻击, elmo不能穿过, 能独立存在于空中
iron : 刚块, elmo可以站在上面, elmo不可以攻击, elmo不能穿过, 能独立存在
door : elmo收集完元素之后的目的地, 到达之后就可以进入下一个关卡

这里写图片描述

元素继承关系
这里写图片描述

2. 基本的数据结构介绍

2.1 Element : 所有元素的基类

/** * file name : Element.java * created at : 7:35:42 PM Oct 26, 2015 * created by 970655147 */package com.hx.elmo;// 元素public class Element {    // 坐标, 图片    protected int x;    protected int y;    protected Image img;    // 初始化    public Element() {    }    public Element(int x, int y) {        setXY(x, y);    }    // 绘制当前元素    public void paint(Graphics g) {        g.drawImage(img, x, y, Constants.GRID_WIDTH, Constants.GRID_HEIGHT, null);    }    // 驱动元素变化    public void move() {    }    // setter & getter    // ...    // for debug ...    public String toString() {        return this.getClass().getName();    }}

2.2 Elmo : 主角, 控制角色的各种操作

/** * file name : Elmo.java * created at : 7:32:53 PM Oct 26, 2015 * created by 970655147 */package com.hx.elmo;// 艾摩君public class Elmo extends Element {    // 水平方向上移动一次的偏移, 竖直方向上移动一次的偏移    private int moveHorizonOff = Constants.ELMO_MOVE_HORIZON_OFF;    private int moveVerticalOff = Constants.ELMO_MOVE_VERTICAL_OFF;    // panel    // 移动的方向, 主面板, elmo的当前图像 [向左 或右]    // 地图model, 是否向左, 是否向右, 是否向下, 是否在跳    // 是否工具, 是否成功    private int direction;    private MainPanel panel;    private Image[] imgs = Constants.elmoRight;    private Map map;    private long lastRunnable;    private boolean isLeft;    private boolean isRight;    private boolean isDown;    private boolean isJump;    private boolean isAtt;    private boolean isSuccess;    // 初始化    public Elmo() {    }    public Elmo(int x, int y, Map map) {        super(x, y);        this.map = map;        direction = Constants.RIGHT;        this.img = imgs[Constants.STAND];        isDown = false;        isJump = false;        isLeft = false;        isRight = false;        isAtt = false;        isSuccess = false;    }    // 移动相关    // 如果能够向左移动, 则向左移动, 并做移动之后需要做事情    public void left() {        if(canLeft(map)) {            setDirection(Constants.LEFT);            setX(this.x - moveHorizonOff);            moveHorizonOff = Constants.ELMO_MOVE_HORIZON_OFF;            doStuffAfterMove(map);        }    }    // 如果能够右移动, 则向右移动, 并做移动之后需要做事情    public void right() {        if(canRight(map)) {            setDirection(Constants.RIGHT);            setX(this.x + moveHorizonOff);            moveHorizonOff = Constants.ELMO_MOVE_HORIZON_OFF;            doStuffAfterMove(map);        }    }    // 下操作    public void down() {        if(canDown(map)) {            isDown = true;            setImage(imgs[Constants.DOWN]);        }    }    // 下的逆操作    public void undown() {        isDown = false;        setImage(imgs[Constants.STAND]);    }    // 跳跃    public void jump() {        if(canJump(map)) {            isJump = true;            panel.putTask(new JumpRunnable(this, map));            doStuffAfterMove(map);        }    }    // 落下    private void gravity(int upOff) {        setY(this.y + upOff);    }    // 攻击旁边的元素    public void attack() {        if(canAttack(map)) {            isAtt = true;            doAttack(map);            panel.putTask(new AttackRunnable(this, map));        }    }    // setter & getter    public void setImage(Image img) {        this.img = img;    }    public void setPanel(MainPanel panel) {        this.panel = panel;    }    public void setX(int otherX) {        this.x = Tools.formatX(otherX);    }    public void setY(int otherY) {        this.y = Tools.formatY(otherY);    }    public void setAtt(boolean isAtt) {        this.isAtt = isAtt;    }    public void setDirection(int direction) {        if(this.direction != direction) {            this.direction = direction;            if(this.direction == Constants.LEFT) {                this.imgs = Constants.elmoLeft;            } else {                this.imgs = Constants.elmoRight;            }        }    }    public void setLeft(boolean isLeft) {        this.isLeft = isLeft;    }    public void setRight(boolean isRight) {        this.isRight = isRight;    }    public boolean isJump() {        return isJump;    }    public void setJump(boolean isJump) {        this.isJump = isJump;    }    public boolean isLeft() {        return isLeft;    }    public boolean isRight() {        return isRight;    }    public boolean isSuccess() {        return isSuccess;    }    // 获取上一次按键到当前按键 的时间差    public boolean isLastRunnableOk() {        return true;    }    // 判断是否能够向左右走 [受限于环境]    // 获取左边的一个元素, 然后判断其是否crossable        // 如果 当前x为其左边的元素的x相同, 设置当前移动的位移为0, 返回true        // 如果 当前再向左移动一步之后x会小于左边元素的x, 更新此次移动的位移为到达左边的元素的位置    private boolean canLeft(Map map) {        if(isDown) {            return false;        }        int row = Tools.getRowByY(this.y);        int col = Tools.getColByX(this.x);        Element leftEle = getLeftELe(map, row, col);        if(ifBeTurePreJudge(leftEle)) {            return true;        } else {            if(this.x == Tools.getXByCol(col)) {                moveHorizonOff = 0;                return true;            } else if(this.x - moveHorizonOff < Tools.getXByCol(col)) {                moveHorizonOff = this.x - Tools.getXByCol(col);                return true;            } else {                return true;            }        }    }    // 类似于canLeft [受限于环境]    private boolean canRight(Map map) {        if(isDown) {            return false;        }        int row = Tools.getRowByY(this.y);        int col = Tools.getColByX(this.x);        Element rightEle = getRightELe(map, row, col);        if(ifBeTurePreJudge(rightEle) ) {            return true;        } else {            if(this.x + Constants.GRID_WIDTH == Tools.getXByCol(col+1) ) {            moveHorizonOff = 0;            return true;            } else if(this.x + Constants.GRID_WIDTH + moveHorizonOff < Tools.getXByCol(col+1)) {                moveHorizonOff = Tools.getXByCol(col+1) - this.x - Constants.GRID_WIDTH;                return true;            // can't be there ...            } else {                return true;            }        }    }    // 是否可以向下操作 [受限于环境]    private boolean canDown(Map map) {        if(isJump) {            return false;        }        return true;    }    // 是否可以跳跃操作 [受限于环境]    private boolean canJump(Map map) {        if(isJump) {            return false;        }        return true;    }    // 是否可以攻击操作 [受限于环境]    private boolean canAttack(Map map) {        if(isAtt) {            return false;        }        return true;    }    // 是否可以向下掉落 [受限于环境]    // 与上面的canRight的区别在于移动到支持元素上面, 就不能在向下面移动了    private boolean canGravity(Map map) {        int row = Tools.getRowByY(this.y);        int col = Tools.getColByX(this.x);        Element downLeftEle = map.getEle(Tools.formatRow(row+1), col );        Element downRightEle = null;        if(x != Tools.getXByCol(col) ) {            downRightEle = map.getEle(Tools.formatRow(row+1), Tools.formatCol(col+1) );        }        if((downLeftEle == null) && (downRightEle == null) ) {            moveVerticalOff = Constants.ELMO_MOVE_VERTICAL_OFF;            return true;        } else {            if(!(downLeftEle instanceof Prop) && (! (downRightEle instanceof Prop)) ) {                moveVerticalOff = Constants.ELMO_MOVE_VERTICAL_OFF;                return true;            } else {                if( ((downLeftEle == null) || (! ((Prop) downLeftEle).isStandable())) &&  ((downRightEle == null) || (! ((Prop) downRightEle).isStandable())) ) {                    moveVerticalOff = Constants.ELMO_MOVE_VERTICAL_OFF;                    return true;                } else {                    if(this.y + Constants.GRID_HEIGHT == Tools.getYByRow(row+1) ) {                        return false;                    } else if(this.y + Constants.GRID_HEIGHT + moveVerticalOff < Tools.getYByRow(row+1)) {                        moveVerticalOff = Tools.getYByRow(row+1) - this.y - Constants.GRID_HEIGHT;                        return true;                    // can't be there ...                    } else {                        return true;                    }                }            }        }    }    // 获取当前元素"左边"的元素, 判断规则详见下面的注释    private Element getLeftELe(Map map, int row, int col) {        Element leftEle = null;        // 如果是和物品在同一水平线上,则判断左方向的物品            // 否则  判断脚的左方向上的物品        if(this.y == Tools.getYByRow(row) ) {            leftEle = map.getEle(row, Tools.formatCol(col-1) );        } else {            leftEle = map.getEle(Tools.formatRow(row+1), Tools.formatCol(col-1) );        }        return leftEle;    }    // 获取当前位置的右边的元素    private Element getRightELe(Map map, int row, int col) {        Element rightEle = null;        // 如果是和物品在同一水平线上,则判断右方向的物品            // 否则  判断脚的右下方向的物品        if(this.y == Tools.getYByRow(row) ) {            rightEle = map.getEle(row, Tools.formatCol(col+1) );        } else {            rightEle = map.getEle(Tools.formatRow(row+1), Tools.formatCol(col+1) );        }        return rightEle;    }    // canRight, canLeft 的公共判断部分    private boolean ifBeTurePreJudge(Element ele) {        if(ele == null) {            return true;        } else {            if(! (ele instanceof Prop) ) {                return true;            } else {                if(((Prop) ele).isCrossable() ) {                    return true;                } else {                    return false;                }            }        }    }    // 一些左右移动之后需要做的事情        // 1. 校验是否可落下, 可落下, 则落下        // 2. 校验是否可获取到boy        // 3. 校验是否到达门处, 是否完成任务    private void doStuffAfterMove(Map map) {        // ------------------ 1 ------------------        if(!isJump) {            if(canGravity(map)) {                panel.putTask(new GravityRunnable(this, map));            }        }        // ------------------ 2 ------------------        int row = Tools.getRowByY(this.y);        int col = Tools.getColByX(this.x);        Element ele = null;        ele = map.getEle(row, col);        if(ele instanceof Boy) {            map.propBeAttacked(ele);        }        // ------------------ 3 ------------------        if(ele instanceof Door) {            if(map.boysLeft() == 0) {                isSuccess = true;            }        }    }    // 攻击操作, 根据当前的方向 获取需要攻击的对象, 然后更新map中的model      private void doAttack(Map map) {        int row = Tools.getRowByY(this.y);        int col = Tools.getColByX(this.x);        Element tarEle = null;        if(this.y == Tools.getYByRow(row) ) {            if(imgs == Constants.elmoLeft) {                tarEle = map.getEle(row, Tools.formatCol(col-1) );            } else {                tarEle = map.getEle(row, Tools.formatCol(col+1) );            }        } else {            if(imgs == Constants.elmoLeft) {                tarEle = map.getEle(Tools.formatRow(row+1), Tools.formatCol(col-1) );            } else {                tarEle = map.getEle(Tools.formatRow(row+1), Tools.formatCol(col+1) );            }        }        if((tarEle != null) && (tarEle instanceof Prop) ) {            if(((Prop) tarEle).isAttackable() ) {                map.propBeAttacked(tarEle);            }        }    }    // 重写move方法 控制移动 [否则 移动不流畅]    public void move() {        if(isLeft) {            left();        }        if(isRight) {            right();        }    }    // 重写paint方法  更新控制艾摩君的大小    public void paint(Graphics g) {        g.drawImage(img, x, y, Constants.ELMO_WIDTH, Constants.ELMO_HEIGHT, null);    }    // elmo移动的时候, 创建一个, 添加到线程池中执行, 切换elmo的脚步 [STAND -> GO -> STAND]    static class MoveRunnable implements Runnable {        private Elmo elmo;        public MoveRunnable(Elmo elmo) {            this.elmo = elmo;        }        public void run() {            elmo.setImage(elmo.imgs[Constants.GO]);            Tools.sleep(Constants.ELMO_MOVE_CHANGE_PIC_INTERVAL);            elmo.setImage(elmo.imgs[Constants.STAND]);        }    }    // elmo跳跃的时候, 创建一个, 添加到线程池中执行, 先分成ELMO_JUMP_UP_TIMES 阶段来向上移动        // 然后  向下掉落    static class JumpRunnable implements Runnable {        private Elmo elmo;        private Map map;        public JumpRunnable(Elmo elmo, Map map) {            this.elmo = elmo;            this.map = map;        }        public void run() {            int upOff = elmo.moveVerticalOff / Constants.ELMO_JUMP_UP_TIMES;            elmo.setImage(elmo.imgs[Constants.GO]);            for(int i=0; i<Constants.ELMO_JUMP_UP_TIMES; i++) {                elmo.setY(elmo.y - upOff);                Tools.sleep(Constants.JUMP_CHANGE_PIC_INTERVAL);            }            new GravityRunnable(elmo, map).run();        }    }    // elmo向下掉落的时候, 创建一个, 添加到线程池中执行        // 如果  当前元素下面的元素不可standable, 则向下掉落    static class GravityRunnable implements Runnable {        private Elmo elmo;        private Map map;        public GravityRunnable(Elmo elmo, Map map) {            this.elmo = elmo;            this.map = map;        }        public void run() {            int upOff = elmo.moveVerticalOff / Constants.ELMO_JUMP_UP_TIMES;            elmo.setImage(elmo.imgs[Constants.GO]);            while(elmo.canGravity(map)) {                elmo.gravity(upOff);                Tools.sleep(Constants.JUMP_CHANGE_PIC_INTERVAL);            }            elmo.setImage(elmo.imgs[Constants.STAND]);            elmo.isJump = false;            elmo.moveVerticalOff = Constants.ELMO_MOVE_VERTICAL_OFF;        }    }    // elmo攻击的时候, 创建一个, 添加到线程池中执行        // 如果  更新显示的图片, 一段时间后更新回来    static class AttackRunnable implements Runnable {        private Elmo elmo;        private Map map;        public AttackRunnable(Elmo elmo, Map map) {            this.elmo = elmo;            this.map = map;        }        public void run() {            elmo.setImage(elmo.imgs[Constants.ATT]);            Tools.sleep(Constants.ELMO_ATTACK_CHANGE_PIC_INTERVAL);            elmo.setImage(elmo.imgs[Constants.STAND]);        }    }}

2.3 Enemy : 敌人[这里没有实现]

/** * file name : Enemy.java * created at : 7:39:06 PM Oct 26, 2015 * created by 970655147 */package com.hx.elmo;// 敌人public class Enemy extends Element {    // 初始化    public Enemy() {    }    public Enemy(int x, int y) {        super(x, y);    }}

2.3 Prop : 道具[所有的非elmo 以及非enemy的其他元素] [控制了影响elmo, enemy的性质]

/** * file name : Prop.java * created at : 2:17:30 PM Oct 27, 2015 * created by 970655147 */package com.hx.elmo;// 道具public class Prop extends Element {    // 是否可站立, 是否可攻击, 是否可穿过, 是否可以独立存在于高空    protected boolean standable;    protected boolean attackable;    protected boolean crossable;    protected boolean standaloneable;    // 初始化    public Prop() {    }    public Prop(int x, int y) {        super(x, y);        standable = true;        attackable = false;        crossable = false;        standaloneable = false;    }    // setter & getter    // 省略若干...}

2.4 Boy : elmo需要收集的boy, 注意更新的move方法 [由MainPanel.threadPool中的一条线程定时调用]

/** * file name : Boy.java * created at : 7:35:33 PM Oct 26, 2015 * created by 970655147 */package com.hx.elmo;// 哭闹的小孩..public class Boy extends Prop {    // 当前图片的索引    Image[] imgs = Constants.boys;    int idx = Tools.nextRandom(imgs.length);    // 初始化    public Boy() {    }    public Boy(int x, int y) {        super(x, y);        this.img = imgs[idx];        crossable = true;        standable = false;    }    // 累增idx, 并制造一个"循环"    private void incIdx() {        idx ++;        if(idx == imgs.length) {            idx = 0;        }    }    // 驱动boy的"移动"    public void move() {        incIdx();        img = imgs[idx];    }}

2.5 Brick : 砖头 [可被攻击][这里, 我们只介绍一个Brick元素]

/** * file name : Brice.java * created at : 2:22:35 PM Oct 27, 2015 * created by 970655147 */package com.hx.elmo;// 砖public class Brick extends Prop {    // 初始化    public Brick() {    }    public Brick(int x, int y) {        super(x, y);        this.attackable = true;        this.img = Constants.brick;    }}

2.6 MainPanel : 控制着状态的改变, 以及响应用户的操作

/** * file name : MainPanel.java * created at : 2:15:01 PM Oct 26, 2015 * created by 970655147 */package com.hx.elmo;// 主面板public class MainPanel extends JPanel {    // 全局变量    // 每一个元素宽度, 高度    private static int gridWidth = Constants.GRID_WIDTH;    private static int gridHeight = Constants.GRID_HEIGHT;    // 选择的位置, 是否绘制选中的文字 [用于闪烁选中的文字]    // 当前的状态, 是否游戏结束, 是否开始游戏    private Point selected;    private boolean isDrawSelected;    private State state;    private boolean isOver;    private boolean isStart;    // 业务数据    // 关卡id, 剩余的人数, map model, elmo    private int stageId = 1;    private int rest = 3;    private Map map;    private Elmo elmo;    // 其他数据    private ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(Constants.N_THREADS);    // 初始化    public MainPanel() {        state = State.START_UP;        isDrawSelected = true;        isOver = false;        isStart = false;        map = new Map(Tools.generateMap(Constants.STAGE_00) );        initElmo();    }    // 初始化elmo    private void initElmo() {        elmo = map.getElmo();        elmo.setPanel(this);    }    // 重写paint方法, 绘制panel        // 根据不同的状态, 执行不同的业务    public void paint(Graphics g) {        switch(state) {            case IN_GAME :                drawInGame(g);                break ;            case START_UP :                drawInStartUp(g);                break ;            case STAGE_INFO :                drawInStageInfo(g);                break ;                         default :                Log.err("error state : " + state.toString() );                break ;        }    }    // 重写update方法 [双缓冲, 先将g中的数据缓冲到一个Image中, 然后在将其绘制到屏幕]    public void update(Graphics g){                                         //覆盖update方法,截取默认的调用过程          Image buffer = createImage(this.getWidth(), this.getHeight());      //创建图形缓冲区          Graphics bufferGraphics = buffer.getGraphics();                     //获取图形缓冲区的图形上下文          paint(bufferGraphics);                                              //用paint方法中编写的绘图过程对图形缓冲区绘图          bufferGraphics.dispose();                                           //释放图形上下文资源          g.drawImage(buffer, 0, 0, this);                                    //将图形缓冲区绘制到屏幕上      }      // 绘制在开始状态    // 1. 必要的话初始化selected    // 2. 绘制背景    // 3. 绘制文字    // 4. 必要的话清空当前选择的文字 [闪烁控制]    // 5. 绘制选择图标    private void drawInStartUp(Graphics g) {        if(selected == null) {            selected = Constants.START_UP_START_POS;        }        drawStartUpBg(g);        g.setColor(Constants.START_UP_COLOR);        g.setFont(Constants.START_UP_FONT);        Tools.assert0(Constants.START_UPS_WORDS.length, Constants.START_UPS_WORDS_POS.length);        for(int i=0; i<Constants.START_UPS_WORDS.length; i++) {            drawString(g, Constants.START_UPS_WORDS, Constants.START_UPS_WORDS_POS, i);        }        if(!isDrawSelected) {            g.setColor(Constants.START_BG_COLOR);            int selectedWordIdx = 0;            if(selected == Constants.START_UP_START_POS) {                selectedWordIdx = 2;            } else {                selectedWordIdx = 3;            }            drawString(g, Constants.START_UPS_WORDS, Constants.START_UPS_WORDS_POS, selectedWordIdx);        }        g.drawImage(Constants.elmoRight[Constants.STAND], selected.x, selected.y, gridWidth, gridHeight, this);    }    // 绘制正在游戏的 的图像    // 1. 绘制背景图片    // 2. 绘制所有的元素    private void drawInGame(Graphics g) {        drawInGameBg(g);        Iterator<Element> eles = map.elements();        while(eles.hasNext() ) {            Element e = eles.next();            e.paint(g);        }    }    // 绘制关卡信息    // 1. 绘制背景    // 2. 绘制关卡数, 剩余的人数    private void drawInStageInfo(Graphics g) {        drawStageInfoBg(g);        g.setColor(Constants.STAGE_INFO_COLOR);        g.setFont(Constants.STAGE_INFO_FONT);        Tools.assert0(Constants.STAGE_INFO_WORDS.length, Constants.STAGE_INFO_WORDS_POS.length);        drawString(g, Constants.STAGE_INFO_WORDS[0] + "  " + getStageIdString(stageId), Constants.STAGE_INFO_WORDS_POS[0]);        drawString(g, Constants.STAGE_INFO_WORDS[1] + "  " + getStageIdString(rest), Constants.STAGE_INFO_WORDS_POS[1]);    }    // 绘制开始状态, 关卡信息, 游戏开始 的背景图片    private void drawStartUpBg(Graphics g) {        g.drawImage(Constants.startBg, 0, 0, Constants.FRAME_WIDTH, Constants.FRAME_HEIGHT, this);    }    private void drawInGameBg(Graphics g) {        g.drawImage(Constants.inGameBg, 0, 0, Constants.FRAME_WIDTH, Constants.FRAME_HEIGHT, this);    }    private void drawStageInfoBg(Graphics g) {        g.drawImage(Constants.stageInfoBg, 0, 0, Constants.FRAME_WIDTH, Constants.FRAME_HEIGHT, this);    }    // 键盘业务处理    // 对于开始界面的时候        // 点击选择键, 更新选择图标的位置        // 点击开始键, 绘制选择文字闪烁的情况, 并切换到关卡信息页面    public void dealKeyPressInStart(KeyEvent e) {        if(e.getKeyCode() == Constants.SELECT) {            if(selected == Constants.START_UP_START_POS) {                selected = Constants.START_UP_CONTINUE_POS;            } else {                selected = Constants.START_UP_START_POS;            }        } else if(e.getKeyCode() == Constants.START) {            if(! isStart) {                isStart = true;                selected = null;                threadPool.execute(new Runnable() {                    public void run() {                        for(int i=0; i<Constants.START_TWINKLE_TIMES; i++) {                            isDrawSelected = !isDrawSelected;                            repaint();                            Tools.sleep(Constants.START_TWINKLE_INTERVAL);                        }                        startRepaint();                        showStageInfo();                        startGame();                    }                });            }        }        repaint();    }    // 对于开始游戏界面        // 对于各个操作键的响应        // 如果成功了, 则更新stage    public void dealKeyPressInGame(KeyEvent e) {        if(e.getKeyCode() == Constants.GO_LEFT) {            elmo.setLeft(true);        } else if(e.getKeyCode() == Constants.GO_RIGHT) {            elmo.setRight(true);            elmo.right();        } else if(e.getKeyCode() == Constants.GO_DOWN) {            elmo.down();        } else if(e.getKeyCode() == Constants.GO_JUMP) {            elmo.jump();        } else if(e.getKeyCode() == Constants.GO_ATTACK) {            elmo.attack();        }        if(elmo.isSuccess() ) {            setStage(getNextStageMap(stageId) );        }    }    // 更新关卡    // 更新stageId, rest, 更新isOver 停止所有的线程, 等待所有的线程执行完成    // 更新map, 更新isOver    // 启动repaint线程, 绘制关卡信息, 启动游戏 [更新可移动元素, 更新移动elmo, 绘制elmo移动时候的步伐]    public void setStage(Integer[][] map) {        stageId ++;        rest ++;        isOver = true;        Tools.awaitTasksEnd(threadPool, Constants.DEFAULT_CHECK_THREADPOOL_INTERVAL);        this.map = new Map(map );        initElmo();        isOver = false;        threadPool.execute(new Runnable() {            public void run() {                startRepaint();                showStageInfo();                startGame();                                }        });    }    // 对于开始界面的时候        // doNothing    public void dealKeyReleaseStartUp(KeyEvent e) {    }    // 对于开始游戏界面        // 响应键盘的操作    public void dealKeyReleaseInGame(KeyEvent e) {        if(e.getKeyCode() == Constants.GO_LEFT) {            elmo.setLeft(false);        } else if(e.getKeyCode() == Constants.GO_RIGHT) {            elmo.setRight(false);        } else if(e.getKeyCode() == Constants.GO_DOWN) {            elmo.undown();        } else if(e.getKeyCode() == Constants.GO_ATTACK) {            elmo.setAtt(false);        }    }    // 启动定时重绘线程    public void startRepaint() {        threadPool.execute(new Runnable() {            public void run() {                while(! isOver) {                    Tools.sleep(Constants.REFRESH_INTERVAL);                    repaint();                }            }        });    }    // 显示关卡信息 [依赖于定时刷新线程]    private void showStageInfo() {        state(State.STAGE_INFO);        Tools.sleep(Constants.STAGE_INFO_INTERVAL);    }    // 开始游戏 [更新可移动元素, 更新移动elmo, 绘制elmo移动时候的步伐][依赖于定时刷新线程]    private void startGame() {        state(State.IN_GAME);        putTask(new Runnable() {            public void run() {                while(! isOver) {                    Iterator<Element> it = map.movableElements();                    while(it.hasNext() ) {                        it.next().move();                    }                    Tools.sleep(Constants.MOVABLE_ELE_REFRESH_INTERVAL);                }            }        });        putTask(new Runnable() {            public void run() {                while(! isOver) {                    Elmo elmo = map.getElmo();                    elmo.move();                    Tools.sleep(Constants.ELMO_MOVABLE_REFRESH_INTERVAL);                }            }        });        putTask(new Runnable() {            public void run() {                while(! isOver) {                    Elmo elmo = map.getElmo();                    if(!elmo.isJump() && (elmo.isLeft() || elmo.isRight()) ) {                        putTask(new MoveRunnable(elmo));                    }                    Tools.sleep(Constants.ELMO_MOVABLE_STEP_REFRESH_INTERVAL);                }            }        });    }    // 绘制给定的索引对应的字符串    private void drawString(Graphics g, String[] words, Point[] poses, int idx) {        drawString(g, words[idx], poses[idx]);    }    private void drawString(Graphics g, String word, Point pos) {        g.drawString(word, pos.x, pos.y);    }    // 获取stageId的字符串表示    // 此处的实现为 不足两位, 在前面填充0    private String getStageIdString(int stageId) {        if(stageId < 10) {            return "0" + String.valueOf(stageId);        }        return String.valueOf(stageId);    }    // 获取下一个关卡的地图    public Integer[][] getNextStageMap(int stageId) {        return Tools.generateMap(Constants.STAGE_01);    }    // 想线程池抛去一个任务    public void putTask(Runnable run) {        threadPool.execute(run);    }    // setter & getter    // 省略若干...}

2.7 State : 各个状态的枚举

/** * file name : State.java * created at : 2:31:26 PM Oct 26, 2015 * created by 970655147 */package com.hx.elmo;// 状态 [当前游戏的状态]public enum State {    // 三个状态 [开始状态, 显示关卡信息, 正在游戏状态]    START_UP("startUp"), STAGE_INFO("stageInfo"), IN_GAME("inGame");     // 名称    private String name;    // 初始化    private State() {        this(Constants.DEFAULT_STATE_NAME);    }    private State(String name) {        this.name = name;    }    // for debug ..    public String toString() {        return name;    }}

2.8 Map : 地图model, 控制着所有元素的存取 取出元素有两种方式, 一种是按照坐标, 另一种是从存储的List中存取

/** * file name : Map.java * created at : 5:02:16 PM Oct 26, 2015 * created by 970655147 */package com.hx.elmo;// 地图modelpublic class Map {    // 地图model    // 艾摩君, 孩子, 敌人, 其他元素, 门    private Integer[][] map;    private Element[][] eleMap;    private List<Element> elmos;    private List<Element> boys;    private List<Element> enemys;    private List<Element> props;    private List<Element> doors;    // 初始化    public Map() {    }    public Map(Integer[][] map) {        Tools.assert0(map.length, Constants.ROW_MAX);        Tools.assert0(map[0].length, Constants.COL_MAX);        this.map = map;        elmos = new ArrayList<>();        boys = new ArrayList<>();        enemys = new ArrayList<>();        props = new ArrayList<>(100);        doors = new ArrayList<>(1);        eleMap = new Element[map.length][map[0].length];        init(map, this);    }    // 初始化, 构造对象    // 根据map生成eleMap的model, 以及收集各种类型的元素    private void init(Integer[][] map, Map mapObj) {        for(int row=0; row<map.length; row++) {            for(int col=0; col<map[row].length; col++) {                Element curEle = null;                if(Tools.isEle(map[row][col], Constants.elmo) ) {                    curEle = new Elmo(Tools.getXByCol(col), Tools.getYByRow(row), this );                    elmos.add(curEle );                    curEle = null;                    map[row][col] = Constants.NULL;                } else if(Tools.isEle(map[row][col], Constants.boy) ) {                    curEle = new Boy(Tools.getXByCol(col), Tools.getYByRow(row) );                    boys.add(curEle);                } else if(Tools.isEnemy(map[row][col]) ) {                    curEle = new Enemy(Tools.getXByCol(col), Tools.getYByRow(row) );                    enemys.add(curEle );                    map[row][col] = Constants.NULL;                    curEle = null;                } else if(Tools.isProps(map[row][col]) ) {                    if(Tools.isEle(map[row][col], Constants.brick)) {                        curEle = new Brick(Tools.getXByCol(col), Tools.getYByRow(row) );                    } else if (Tools.isEle(map[row][col], Constants.floor)) {                        curEle = new Floor(Tools.getXByCol(col), Tools.getYByRow(row) );                    } else if (Tools.isEle(map[row][col], Constants.rack)) {                        curEle = new Rack(Tools.getXByCol(col), Tools.getYByRow(row) );                    } else if (Tools.isEle(map[row][col], Constants.iron)) {                        curEle = new Iron(Tools.getXByCol(col), Tools.getYByRow(row) );                    }                    props.add(curEle );                } else {                    if(map[row][col] != Constants.NULL) {                        curEle = new Door(Tools.getXByCol(col), Tools.getYByRow(row), Constants.idToImg.get(map[row][col]));                        doors.add(curEle );                    }                }                eleMap[row][col] = curEle;            }        }    }    // 返回所有元素的一个迭代器    // 最后获取elmo, 不然他就变成背景啦 [主要用于主面板重新绘制]    public Iterator<Element> elements() {        return new Iterator<Element>() {            Iterator<Element> boysIt = boys.iterator();            Iterator<Element> enemysIt = enemys.iterator();            Iterator<Element> propsIt = props.iterator();            Iterator<Element> doorIt = doors.iterator();            Iterator<Element> elmosIt = elmos.iterator();            Iterator<Element> curIt = boysIt;            public boolean hasNext() {                if(curIt.hasNext() ) {                    return true;                }                if(curIt == boysIt) {                    curIt = enemysIt;                    return hasNext();                } else if(curIt == enemysIt) {                    curIt = propsIt;                    return hasNext();                } else if(curIt == propsIt) {                    curIt = doorIt;                    return hasNext();                } else if(curIt == doorIt) {                    curIt = elmosIt;                    return hasNext();                }  else {                    return false;                }            }            public Element next() {                if(hasNext() ) {                    return curIt.next();                }                return null;            }            public void remove() {                throw new RuntimeException("unsupproted exception ...");            }        };    }    // 返回可移动元素的一个迭代器 [主要用于主面板, 定期调度这些元素的move方法, 比如 : 孩子需要哭, 敌人需要移动, 攻击等等]    public Iterator<Element> movableElements() {        return new Iterator<Element>() {            Iterator<Element> boysIt = boys.iterator();            Iterator<Element> enemysIt = enemys.iterator();            Iterator<Element> curIt = boysIt;            public boolean hasNext() {                if(curIt.hasNext() ) {                    return true;                }                if(curIt == boysIt) {                    curIt = enemysIt;                    return hasNext();                } else {                    return false;                }            }            public Element next() {                if(hasNext() ) {                    return curIt.next();                }                return null;            }            public void remove() {                throw new RuntimeException("unsupproted exception ...");            }        };    }    // 某个元素被攻击了          // 如果是道具, 则操作该位置的元素 [如果其之上的元素不能"腾空"的话, 将其移动下来]        // 如果是敌人, 多态    // 啊 这里不是可以在基类中封装一个beAttacked方法嘛...    public void propBeAttacked(Element prop) {        int row = Tools.getRowByY(prop.y);        int col = Tools.getColByX(prop.x);        int id = map[row][col];        if(Tools.isProps(id) ) {            map[row][col] = Constants.NULL;            eleMap[row][col] = null;            if(! props.remove(prop)) {                boys.remove(prop);            }            downIfNotStandaloneable(row, col);        } else if(Tools.isEnemy(id) ) {        }    }    // 获取剩余的小孩的个数    public int boysLeft() {        return boys.size();    }    // 如果当前位置上面的元素不能独立存在的话, 则将上面的元素, 移到当前位置, 并递归更新    private void downIfNotStandaloneable(int row, int col) {        Element above = eleMap[row-1][col];        if((above != null) && (above instanceof Prop) ) {            if(! ((Prop) above).isStandaloneable() ) {                map[row][col] = map[row-1][col];                eleMap[row][col] = eleMap[row-1][col];                eleMap[row][col].setXY(Tools.getXByCol(col), Tools.getYByRow(row) );                map[row-1][col] = Constants.NULL;                eleMap[row-1][col] = null;                downIfNotStandaloneable(row-1, col);            }        }    }    // setter & getter    // 省略若干...}

2.9 Tools : 常用的工具函数

/** * file name : Tools.java * created at : 2:37:02 PM Oct 26, 2015 * created by 970655147 */package com.hx.elmo;// 工具 常量,方法public class Tools {    // 工具常量    public static String CRLF = "\r\n";    public static Random ran = new Random();    // 工具方法    // 确保val 和expected相同, 否则 抛出异常    public static void assert0(int val, int expect) {        assert0(val, expect, true);    }    public static void assert0(int val, int expect, boolean isEquals) {        if(isEquals ^ (val == expect)) {            String symbol = null;            if(isEquals) {                symbol = "!=";            } else {                symbol = "==";            }            throw new RuntimeException("assert0Exception : " + val + " " + symbol + " " + expect);        }    }    public static <T> void assert0(T val, T expect) {        assert0(val, expect, true);    }    public static <T> void assert0(T val, T expect, boolean isEquals) {        if(isEquals ^ (val == expect)) {            throw new RuntimeException("assert0Exception : " + val + " != " + expect);        }    }    // 使当前线程休眠sleepMillus    public static void sleep(int sleepMillus) {        try {            Thread.sleep(sleepMillus);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    // 根据地图文件生成map    public static Integer[][] generateMap(String path) {        List<String> lines = null;        try {            lines = getContentWithList(new File(path));        } catch (IOException e) {            // TODO Auto-generated catch block        }        Tools.assert0(lines, null, false);        Iterator<String> it = lines.iterator();        Integer[][] res = new Integer[lines.size()][];        int idx = 0;        while(it.hasNext()) {            String[] splits = it.next().split("\\s+");            res[idx] = new Integer[splits.length];            for(int i=0; i<splits.length; i++) {                res[idx][i] = Integer.valueOf(splits[i]);            }            idx ++;        }        return res;    }    // 获取文件的所有的行, 存储在一个结果的List    public static List<String> getContentWithList(File file) throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)) );        List<String> lines = new LinkedList<>();        String line = null;        while((line = br.readLine()) != null) {            lines.add(line);        }        br.close();        return lines;    }    // 通过行列的数据, 获取坐标    public static int getXByCol(int col) {        return col * Constants.GRID_WIDTH;    }    public static int getYByRow(int row) {        return row * Constants.GRID_HEIGHT;    }    public static int getColByX(int x) {        return x / Constants.GRID_WIDTH;    }    public static int getRowByY(int y) {        return y / Constants.GRID_HEIGHT;    }    // 判断是否是给定的元素    public static boolean isEle(Integer id, Image img) {        return Constants.idToImg.get(id) == img;    }    public static boolean isEnemy(Integer id) {        return false;    }    public static boolean isProps(Integer id) {        return isEle(id, Constants.brick) || isEle(id, Constants.floor) || isEle(id, Constants.rack) || isEle(id, Constants.iron) || isEle(id, Constants.boy);    }    // 获取一个随机数    public static int nextRandom(int range) {        return ran.nextInt(range);    }    // 使坐标合法化 [求模]    public static int formatX(int x) {        if(x < 0 || x >= Constants.FRAME_WIDTH) {            x = (x + Constants.FRAME_WIDTH) % Constants.FRAME_WIDTH;        }        return x;    }    public static int formatY(int y) {        if(y < 0 || y >= Constants.FRAME_HEIGHT) {            y = (y + Constants.FRAME_HEIGHT) % Constants.FRAME_HEIGHT;        }        return y;    }    public static int formatRow(int row) {        if(row < 0 || row >= Constants.ROW_MAX) {            row = (row + Constants.ROW_MAX) % Constants.ROW_MAX;        }        return row;    }    public static int formatCol(int col) {        if(col < 0 || col >= Constants.COL_MAX) {            col = (col + Constants.COL_MAX) % Constants.COL_MAX;        }        return col;    }    // 等待 线程池中任务结束 [并不关闭线程池]    public static void awaitTasksEnd(ThreadPoolExecutor threadPool, int checkInterval) {        while (! threadPool.isShutdown() ) {            int acitveTaskCount = threadPool.getActiveCount();            if(acitveTaskCount == 0) {                break ;            } else {                Tools.sleep(checkInterval);            }        }    }}

2.10 Constants : 存放常量

/** * file name : Constants.java * created at : 2:27:39 PM Oct 26, 2015 * created by 970655147 */package com.hx.elmo;// 常量配置public class Constants {    // 游戏属性配置  [平常元素的宽高, 以及elmo的宽高]    public static int GRID_WIDTH = 40;    public static int GRID_HEIGHT = 36;    public static int ELMO_WIDTH = 36;    public static int ELMO_HEIGHT = 32;     // 主窗口的宽高, 最多的行数, 列数    public static int FRAME_WIDTH = 640;    public static int FRAME_HEIGHT = 500;     public static int ROW_MAX = 13;    public static int COL_MAX = 16;    // 控制配置        // 开始, 选择, 上下左右, 跳跃, 攻击     public static int START = KeyEvent.VK_1;    public static int SELECT = KeyEvent.VK_3;    public static int GO_UP = KeyEvent.VK_W;    public static int GO_RIGHT = KeyEvent.VK_D;    public static int GO_DOWN = KeyEvent.VK_S;    public static int GO_LEFT = KeyEvent.VK_A;    public static int GO_JUMP = KeyEvent.VK_K;    public static int GO_ATTACK = KeyEvent.VK_J;    // 方向    public static int RIGHT = 0;    public static int LEFT = 1;    // 各个需要的图片的路径, 以及Image对象, 以及数字到图片的映射[构建地图]    // 三张背景图 + 元素图 + 门 + elmo的左右两个方向的各自四张图, boy哭的四张图    public static String START_BG_BG = System.getProperty("user.dir") + "/src/com/hx/elmo/startUpBG.png";    public static String STAGE_INFO_BG = System.getProperty("user.dir") + "/src/com/hx/elmo/stageInfo.png";    public static String IN_GAME_BG = System.getProperty("user.dir") + "/src/com/hx/elmo/inGameBG.png";    public static String BRICK = System.getProperty("user.dir") + "/src/com/hx/elmo/brick.png";    public static String FLOOR = System.getProperty("user.dir") + "/src/com/hx/elmo/floor.png";    public static String RACK = System.getProperty("user.dir") + "/src/com/hx/elmo/rack.png";    public static String IRON = System.getProperty("user.dir") + "/src/com/hx/elmo/iron.png";    public static String LEFT_UP_DOOR = System.getProperty("user.dir") + "/src/com/hx/elmo/leftUpDoor.png";    public static String LEFT_DOWN_DOOR = System.getProperty("user.dir") + "/src/com/hx/elmo/leftDownDoor.png";    public static String RIGHT_UP_DOOR = System.getProperty("user.dir") + "/src/com/hx/elmo/rightUpDoor.png";    public static String RIGHT_DOWN_DOOR = System.getProperty("user.dir") + "/src/com/hx/elmo/rightDownDoor.png";    public static int STAND = 0;    public static int GO = 1;    public static int ATT = 2;    public static int SLEEP = 3;    public static int DOWN = 4;    public static String[] ELMO_LEFT = new String[] {        System.getProperty("user.dir") + "/src/com/hx/elmo/elmoStandLeft.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/elmoGoLeft.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/elmoAttLeft.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/elmoSleepLeft.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/elmoDownLeft.png"    };    public static String[] ELMO_RIGHT = new String[] {        System.getProperty("user.dir") + "/src/com/hx/elmo/elmoStandRight.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/elmoGoRight.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/elmoAttRight.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/elmoSleepRight.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/elmoDownRight.png"    };    public static String[] BOYS = new String[] {        System.getProperty("user.dir") + "/src/com/hx/elmo/boy_1.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/boy_2.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/boy_3.png",        System.getProperty("user.dir") + "/src/com/hx/elmo/boy_4.png"    };    // 默认配置的关卡0, 1, 默认的StageName Stage中使用, 背景颜色    public static String STAGE_00 = System.getProperty("user.dir") + "/src/com/hx/elmo/map00.txt";    public static String STAGE_01 = System.getProperty("user.dir") + "/src/com/hx/elmo/map01.txt";    public static String DEFAULT_STATE_NAME = "unknowName";    public static Color START_BG_COLOR = new Color(144, 208, 255);    // 各个id, 图片    public static int NULL = 0;    public static int RACK_ID = 1;    public static int FLOOR_ID = 2;    public static int ELMO_ID = 3;    public static int BRICK_ID = 4;    public static int BOY_ID = 5;    public static int IRON_ID = 6;    public static int LEFT_UP_DOOR_ID = 7;    public static int LEFT_DOWN_DOOR_ID = 8;    public static int RIGHT_UP_DOOR_ID = 9;    public static int RIGHT_DOWN_DOOR_ID = 10;    public static Image startBg;    public static Image stageInfoBg;    public static Image inGameBg;    public static Image brick;    public static Image floor;    public static Image rack;    public static Image iron;    public static Image leftUpDoor;    public static Image leftDownDoor;    public static Image rightUpDoor;    public static Image rightDownDoor;    public static Image elmo;    public static Image[] elmoLeft;    public static Image[] elmoRight;    public static Image boy;    public static Image[] boys;    public static java.util.Map<Integer, Image> idToImg;     // 初始化各个图片, 建立id 到图片的映射    static {        try {            startBg = ImageIO.read(new File(START_BG_BG) );            stageInfoBg = ImageIO.read(new File(STAGE_INFO_BG) );            inGameBg = ImageIO.read(new File(IN_GAME_BG) );            brick = ImageIO.read(new File(BRICK) );            floor = ImageIO.read(new File(FLOOR) );            rack = ImageIO.read(new File(RACK) );            iron = ImageIO.read(new File(IRON) );            leftUpDoor = ImageIO.read(new File(LEFT_UP_DOOR) );            leftDownDoor = ImageIO.read(new File(LEFT_DOWN_DOOR) );            rightUpDoor = ImageIO.read(new File(RIGHT_UP_DOOR) );            rightDownDoor = ImageIO.read(new File(RIGHT_DOWN_DOOR) );            boys = new Image[BOYS.length];            elmoLeft = new Image[ELMO_LEFT.length];            elmoRight = new Image[ELMO_RIGHT.length];            for(int i=0; i<ELMO_LEFT.length; i++) {                elmoLeft[i] = ImageIO.read(new File(ELMO_LEFT[i]) );                elmoRight[i] = ImageIO.read(new File(ELMO_RIGHT[i]) );            }            for(int i=0; i<BOYS.length; i++) {                boys[i] = ImageIO.read(new File(BOYS[i]) );            }            elmo = elmoLeft[0];            boy = boys[0];        } catch (IOException e) {            e.printStackTrace();        }        idToImg = new HashMap<>();        idToImg.put(RACK_ID, rack);        idToImg.put(FLOOR_ID, floor);        idToImg.put(ELMO_ID, elmo);        idToImg.put(BRICK_ID, brick);        idToImg.put(BOY_ID, boys[0]);        idToImg.put(IRON_ID, iron);        idToImg.put(LEFT_UP_DOOR_ID, leftUpDoor);        idToImg.put(LEFT_DOWN_DOOR_ID, leftDownDoor);        idToImg.put(RIGHT_UP_DOOR_ID, rightUpDoor);        idToImg.put(RIGHT_DOWN_DOOR_ID, rightDownDoor);    }    // 开始按钮的时候 选中文字的闪烁的次数, 每一次闪烁间隔的时间    // MainPanel中线程的个数, 显示stage信息的时候 停滞的时间    public static int START_TWINKLE_TIMES = 5;    public static int START_TWINKLE_INTERVAL = 200;    public static int N_THREADS = 10;    public static int STAGE_INFO_INTERVAL = 1000;    // 游戏画面重绘的周期, 可移动元素的重绘的时间周期[boy, enemy], elmo移动的时间周期 [这里和其他的可移动的元素是分开的]    // elmo绘制其脚步变化的周期 [在移动才更新图片], elmo移动的时候绘制跑的图片的时间长度    // elmo跳跃的时候 相邻的两个高度绘制的时间间隔, elmo水平移动的长度, elmo竖直方向上移动的长度    // elmo 跳跃一次分为多少个阶段绘制, elmo攻击的时候显示攻击图片的时间    // 过关的时候, 等待所有的线程停止的检查时间    public static int REFRESH_INTERVAL = 30;    public static int MOVABLE_ELE_REFRESH_INTERVAL = 100;    public static int ELMO_MOVABLE_REFRESH_INTERVAL = 40;    public static int ELMO_MOVABLE_STEP_REFRESH_INTERVAL = 400;    public static int ELMO_MOVE_CHANGE_PIC_INTERVAL = 200;    public static int JUMP_CHANGE_PIC_INTERVAL = 50;    public static final int ELMO_MOVE_HORIZON_OFF = 5;    public static final int ELMO_MOVE_VERTICAL_OFF = GRID_HEIGHT + 10;    public static final int ELMO_JUMP_UP_TIMES = 5;    public static int ELMO_ATTACK_CHANGE_PIC_INTERVAL = 1000;    public static int DEFAULT_CHECK_THREADPOOL_INTERVAL = 200;    // 开始界面需要绘制的数字, 以及其位置    public static Color START_UP_COLOR = Color.WHITE;    public static Font START_UP_FONT = new Font("宋体", Font.BOLD, 24);    public static String[] START_UPS_WORDS = new String[] {        "@  KONAMI  1990",        "PLAY  SELECT",        "START",        "CONTINUE"    };    public static Point[] START_UPS_WORDS_POS = new Point[] {        new Point(200, 230),        new Point(220, 280),        new Point(160, 310),        new Point(350, 310)    };    public static Point START_UP_START_POS = new Point(110, 280);    public static Point START_UP_CONTINUE_POS = new Point(300, 280);    // 显示关卡页面需要绘制的数字, 以及其位置    public static Color STAGE_INFO_COLOR = new Color(224, 80, 0);    public static Font STAGE_INFO_FONT = new Font("宋体", Font.BOLD, 24);    public static String[] STAGE_INFO_WORDS = new String[] {        "STAGE ",        "REST "    };    public static Point[] STAGE_INFO_WORDS_POS = new Point[] {        new Point(260, 230),        new Point(260, 280)    };}

3 下载链接 [包含图片, 源码] :

http://download.csdn.net/detail/u011039332/9221627

这里写图片描述

游戏截图 :

fc 原版截图
这里写图片描述

过关成功
这里写图片描述

过关失败
这里写图片描述

0 0
原创粉丝点击