超级玛丽--Java课程设计
- 格式:doc
- 大小:3.58 MB
- 文档页数:70
超级玛丽--Java课程设计《面向对象程序设计》课程设计报告题目:超级玛丽软件的设计与实现院(系):信息科学与工程学院专业班级:计算机科学与技术1201班学生姓名:程伟学号:20121183011指导教师:吴奕20 14 年 12 月 29 日至20 15 年 1 月 9 日华中科技大学武昌分校制总体设计1天详细设计1.5天编制源程序实现3.5天测试与修改1天撰写课设报告2天六、主要参考资料[1] 张广彬. Java课程设计案例精编(第二版).北京:清华大学出版社, 2011.[2] 耿祥义. Java课程设计(第二版).北京:清华大学出版社, 2008.[3] 耿祥义.JAVA大学实用教程.北京:清华大学出版社,2009.[4] 邹林达.陈国君 Java2程序设计基础.北京:清华大学出版社,2010.[5] 邹林达.Java2程序设计基础实验指导.北京:清华大学,2010.目录1需求与总体设计 (2)1.1需求分析 (2)1.2程序功能图 (3)1.3程序类图 (3)2详细设计 (4)2.1 MyFrame实现 (4)2.1.1窗体对象的序列图 (4)2.1.2 Myframe详细类图 (5)2.2 Mario实现 (6)2.2.1 Mario对象的序列图 (6)2.2.2 Mario类图 (7)2.3 Enemy类的实现 (8)2.4 Obstruction类的实现 (9)2.5 BackGround类实现 (9)3编码实现 (10)3.1 MyFrame类的详细代码....... 错误!未定义书签。
3.2 BackGround类的详细代码.错误!未定义书签。
3.3 Mario类的详细代码........... 错误!未定义书签。
3.4 Enemy类的详细代码........... 错误!未定义书签。
3.5 Obstruction类的详细代码错误!未定义书签。
4系统测试 (60)4.1 游戏开始界面的测试 (60)4.2 游戏运行的测试 (60)4.3 排除错误的处理 (64)总结 (64)1需求与总体设计1.1需求分析提供一个友好的用户交互界面,简单明了容易操作。
并且游戏有一定的难度和娱乐性。
开发一个Mario类。
一个场景类,以及敌人类,障碍物类。
让超级玛丽能够在场景中完成各种动作。
并且有场景的切换等等功能。
游戏中设计了一些很有意思的陷阱,玩家一步小心掉入陷阱,超级玛丽就会死亡。
这样会给人意想不到的惊奇,达到娱乐大众,增加游戏难度的效果。
游戏的设计匠心独具,并且都经过了各种测试,除了为玩家增加一些意想不到的游戏陷阱以外,还必须保证玩家能够通关。
1.2程序功能图如图1所示:图11.3程序类图系统的整体类图的框架如图2所示。
首先是窗体类。
他需要调用到Mario和BackGround类中的方法。
以便动态的显示Mario类和BackGround。
而BackGround里面又包含了Enemy和Obstruction。
Enemy,Obstruction和Mario类又调用静态类StaticValue的方法,用以显示真实的图片。
而StaticValue则是一个静态类,将存储在硬盘的图片资源加载进入内存以便其他模块调用。
图22详细设计2.1 MyFrame实现2.1.1窗体对象的序列图窗体对象继承了JFrame类并且实现了Runnable接口。
作为窗体对象,它首先显示窗体,绘制背景。
然后启动线程。
在run方法里面动态得绘制窗体中需要显示的Mario的图片,障碍物的图片,敌人的图片。
该窗体的run方法是一个死循环,每次执行一个循环调用sleep方法睡眠50毫秒。
序列图如图3所示。
图32.1.2 Myframe详细类图private Mario mario;//Mario对象private boolean isStart = false;//标识游戏是否已经开始this.paintAllEnemys(g2);//绘制所有的敌人this.paintAllObstruction(g2);//绘制所有障碍物2.2 Mario实现2.2.1 Mario对象的序列图因为需要有一个专门的线程来实时监测Mario的移动状况,和障碍物和敌人的碰撞情况。
所以让Mario类继承了Runnable接口。
Mario先启动线程。
该线程的run方法也是一个死循环。
首先根据Mario的状态changeMarioImage方法修改Mario的显示图片。
再根据Mario的determinexy方法决定Mario的移动。
然后通过deterMarioWithObstruction方法检测Mario和障碍物之间的碰撞,在根据marioTouchEnemys方法检测Mario和敌人之间的碰撞。
然后调用sleep()方法让线程休息5毫秒。
如此结束一个循环。
序列图如图4所示。
2.2.2 Mario类图类图中:private int x;//Mario的x坐标private int y;//Mario的y坐标private int life;//Mario的生命BackGround bg = null;//Mario所在的背景private int uptime;//Mario的上升时间String status;//Mario的移动状态int score;//Mario的分数Thread t;//Mario的线程int xmove;//Mario的x移动距离int ymove;//Mario的y移动距离private boolean isClear = false;//标识用户是否通关。
isClear为true时代表用户通关了2.3 Enemy类的实现private int x;//敌人的x坐标private int y;//敌人的y坐标private int startX;//敌人的初始x坐标private int startY;//敌人的初始y坐标private boolean startIsLeftOrUp;//敌人初始的移动方向private int startImageType;//初始的显示图片private int type;//敌人的类型1代表蘑菇,2代表食人花,3代表乌龟private BufferedImage bufferedImage;private BackGround bg;//障碍物所在的背景private int imageType;//移动的极限范围详细类图如下:2.4 Obstruction类的实现private int x;//障碍物的x坐标private int y;//障碍物的y坐标private BufferedImage showImage = null;//障碍物的显示图片private int type;//障碍物的类型private int startType;//障碍物的初始类型private BackGround bg; //标识该障碍物在哪一个场景中详细类图如下:2.5 BackGround类实现private int sort;//背景的序列号private boolean flag;//标识是否是最后一张图片,flag为true时代表到了最后一张图片private boolean isOver = false;//标识游戏是否已经结束private boolean isDown = false;//标志是否降旗结束详细类图如下:3编码实现源代码import java.awt.image.BufferedImage;import java.util.ArrayList;import java.util.List;import java.awt.Graphics;import java.awt.Toolkit;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Iterator;import javax.swing.JFrame;import javax.swing.JOptionPane;import java.io.File;import javax.imageio.ImageIO;public class MyFrame extends JFrame implements KeyListener,Runnable {public static void main(String[] args){new MyFrame();}private List<BackGround> allBg = new ArrayList<BackGround>();//当前背景private BackGround nowBg = null;private Mario mario;//Mario对象private boolean isStart = false;//标识游戏是否已经开始public void setNowBg(BackGround nowBg) {this.nowBg = nowBg;}private Thread t;/***/public MyFrame(){this.setSize(900,600);this.setTitle("马里奥游戏");this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);int width = Toolkit.getDefaultToolkit().getScreenSize().width;int height = Toolkit.getDefaultToolkit().getScreenSize().height;this.setLocation((width - 900) / 2,(height - 600) / 2);this.addKeyListener(this);StaticValue.init();this.setVisible(true);//绘制出所有的背景for(int i = 1; i <= 4; i++){this.allBg.add(new BackGround(i, i == 4 ? true : false));}this.nowBg = this.allBg.get(0);this.mario = new Mario(0, 480);this.mario.setBg(nowBg);this.setResizable(false);t = new Thread(this);t.start();}@Overridepublic void paint(Graphics g){BufferedImage image = new BufferedImage(900, 600, BufferedImage.TYPE_4BYTE_ABGR);if(isStart){Graphics g2 = image.getGraphics();g2.drawImage(this.nowBg.getBgImage(), 0, 0, this);//绘制背景g2.drawString("生命:" + this.mario.getLife(), 800, 60);//显示生命数g2.drawString("分数:" + this.mario.getScore(), 60, 60);//显示生命数this.paintAllEnemys(g2);//绘制所有的敌人this.paintAllObstruction(g2);//绘制所有障碍物}else{Graphics g2 = image.getGraphics();g2.drawImage(StaticValue.startImage, 0, 0, this);//绘制游戏开始的图片}g.drawImage(image, 0, 0, this);}/***/@Overridepublic void keyPressed(KeyEvent e){//int k = e.getKeyCode();//获得键盘的ASCII码//System.out.println(k);if(this.isStart){if(e.getKeyCode() == 39){this.mario.rightMove();}if(e.getKeyCode() == 37){this.mario.leftMove();}if(e.getKeyCode() == 32){this.mario.jump();}//按下空格键,Mario的生命加10if(70 == e.getKeyCode()){this.mario.setLife(this.mario.getLife() + 10);}}else{if(e.getKeyCode() == 32){this.isStart = true;this.nowBg.enemysStartMove();}}}/***/@Overridepublic void keyReleased(KeyEvent e) {if(e.getKeyCode() == 39){this.mario.rightStop();}if(e.getKeyCode() == 37){this.mario.leftStop();}}/***/@Overridepublic void keyTyped(KeyEvent e){// TODO Auto-generated method stub }@Overridepublic void run(){while(true){this.repaint();if(840 == this.mario.getX()){this.intoNewBackGround();//进入下一张图片}if(this.mario.isClear()){JOptionPane.showMessageDialog(this, "恭喜您通关了,敬请期待新的关卡");System.exit(0);}if(this.mario.isDead()){this.gameOver();//游戏结束}this.sleep();}}//进入下一张图片private void intoNewBackGround(){this.nowBg = this.allBg.get(this.nowBg.getSort());this.mario.setBg(this.nowBg);this.mario.setX(0);this.mario.setY(480);this.mario.setUptime(0);this.nowBg.enemysStartMove();}//绘制所有的敌人private void paintAllEnemys(Graphics g2){Iterator<Enemy> iterEnemy = this.nowBg.getAllEnemy().iterator();while(iterEnemy.hasNext()){Enemy e = iterEnemy.next();g2.drawImage(e.getBufferedImage(), e.getX(), e.getY(), this);}}//绘制所有障碍物private void paintAllObstruction(Graphics g2){Iterator<Obstruction> iter = this.nowBg.getAllObstruction().iterator();while(iter.hasNext()){Obstruction ob = iter.next();g2.drawImage(ob.getShowImage(), ob.getX(), ob.getY(), this);}g2.drawImage(mario.getShowImage(), mario.getX(), mario.getY(), this);}private void sleep(){try{Thread.sleep(20);}catch (InterruptedException e){e.printStackTrace();}}//游戏结束private void gameOver(){JOptionPane.showMessageDialog(this, "马里奥死亡");this.mario.setDead(false);System.exit(0);}}class BackGround{private BufferedImage bgImage = null;private int sort;//背景的序列号private boolean flag;//标识是否是最后一张图片,flag为true时代表到了最后一张图片private List<Enemy> allEnemy = new ArrayList<Enemy>();//所有敌人的集合//所有障碍物的集合private List<Obstruction> allObstruction = new ArrayList<Obstruction>();//所有被移除的敌人的集合private List<Enemy> removeEnemy = new ArrayList<Enemy>();//所有被移除的障碍物的集合private List<Obstruction> removeObstruction = new ArrayList<Obstruction>();private boolean isOver = false;//标识游戏是否已经结束private boolean isDown = false;//标志是否降旗结束public boolean isDown() {return isDown;}public void setDown(boolean isDown) {this.isDown = isDown;}public boolean isOver() {return isOver;}public void setOver(boolean isOver) {this.isOver = isOver;}public boolean isFlag() {return flag;}public void setFlag(boolean flag) {this.flag = flag;}public int getSort() {return sort;}public void setSort(int sort) {this.sort = sort;}public BufferedImage getBgImage(){return bgImage;}public List<Obstruction> getAllObstruction(){return allObstruction;}public List<Obstruction> getRemoveObstruction() { return removeObstruction;}public List<Enemy> getAllEnemy() {return allEnemy;}public List<Enemy> getRemoveEnemy() {return removeEnemy;}/**** @param sort 背景的序列号* @param flag 标识是否是最后一张背景*/public BackGround(int sort, boolean flag) {this.sort = sort;this.flag = flag;if(flag){bgImage = StaticValue.endImage;}else{bgImage = StaticValue.bgImage;}switch(sort){case 1:this.creat1Map();break;case 2:this.creat2Map();break;case 3:this.creat3Map();break;case 4:this.creat4Map();break;}}public void reset(){this.allEnemy.addAll(removeEnemy);for(int i = 0; i < this.allEnemy.size(); ++i){this.allEnemy.get(i).reSet();}this.removeEnemy.clear();this.allObstruction.addAll(removeObstruction);for(int i = 0; i < this.allObstruction.size(); ++i) {this.allObstruction.get(i).reset();}this.removeObstruction.clear();}public void enemysStartMove(){for(int i =0; i < this.allEnemy.size(); ++i){this.allEnemy.get(i).starMove();}}//创建第一张图private void creat1Map(){for(int i = 0; i < 15; i++){//创建出所有地面this.allObstruction.add(new Obstruction(i * 60,540,9, this));}//创建出所有砖块,10代表问好,0代表木块this.allObstruction.add(new Obstruction(120,300,10, this));this.allObstruction.add(new Obstruction(60,300,10, this));this.allObstruction.add(new Obstruction(0,300,10, this));this.allObstruction.add(new Obstruction(300,360,0, this));this.allObstruction.add(new Obstruction(360,360,10, this));this.allObstruction.add(new Obstruction(420,360,0, this));this.allObstruction.add(new Obstruction(480,360,10, this));this.allObstruction.add(new Obstruction(540,360,0, this));this.allObstruction.add(new Obstruction(420,180,10, this));//创建水管this.allObstruction.add(new Obstruction(660,540,6, this));this.allObstruction.add(new Obstruction(720,540,7, this));this.allObstruction.add(new Obstruction(660,480,4, this));this.allObstruction.add(new Obstruction(720,480,5, this));//创建出所有的敌人,1代表三角菇,2代表食人花this.allEnemy.add(new Enemy(600, 480, true, 1, this));this.allEnemy.add(new Enemy(540, 300, true, 1, this));this.allEnemy.add(new Enemy(480, 300, true, 1, this));this.allEnemy.add(new Enemy(420, 300, true, 1, this));this.allEnemy.add(new Enemy(360, 300, true, 1, this));this.allEnemy.add(new Enemy(690, 540, true, 2, 540, 420, this)); }//创建第二张图private void creat2Map(){for(int i = 0; i < 15; i++){if(i != 10){this.allObstruction.add(new Obstruction(i * 60,540,9, this));}}//创建水管this.allObstruction.add(new Obstruction(60,540,6, this));this.allObstruction.add(new Obstruction(120,540,7, this));this.allObstruction.add(new Obstruction(60,480,6, this));this.allObstruction.add(new Obstruction(120,480,7, this));this.allObstruction.add(new Obstruction(60,420,4, this));this.allObstruction.add(new Obstruction(120,420,5, this));//创建水管this.allObstruction.add(new Obstruction(240,540,6, this));this.allObstruction.add(new Obstruction(300,540,7, this));this.allObstruction.add(new Obstruction(240,480,6, this));this.allObstruction.add(new Obstruction(300,480,7, this));this.allObstruction.add(new Obstruction(240,420,6, this));this.allObstruction.add(new Obstruction(300,420,7, this));this.allObstruction.add(new Obstruction(240,360,4, this));this.allObstruction.add(new Obstruction(300,360,5, this));//创建水管this.allObstruction.add(new Obstruction(720,540,6, this));this.allObstruction.add(new Obstruction(780,540,7, this));this.allObstruction.add(new Obstruction(720,480,6, this));this.allObstruction.add(new Obstruction(780,480,7, this));this.allObstruction.add(new Obstruction(720,420,6, this));this.allObstruction.add(new Obstruction(780,420,7, this));this.allObstruction.add(new Obstruction(720,360,4, this));this.allObstruction.add(new Obstruction(780,360,5, this));//创建砖块for(int i = 0; i < 6; ++i){this.allObstruction.add(new Obstruction(360 + i * 60,360,3, this));}//创建敌人this.allEnemy.add(new Enemy(90, 480, true, 2, 480, 360, this));//食人花this.allEnemy.add(new Enemy(270, 420, true, 2, 420, 300, this));//食人花this.allEnemy.add(new Enemy(750, 420, true, 2, 420, 300, this));//食人花}//创建第三张图private void creat3Map(){for(int i = 0; i < 15; i++){//创建出所有地面this.allObstruction.add(new Obstruction(i * 60,540,9, this));}//创建砖块this.allObstruction.add(new Obstruction(60, 360, 0, this));this.allObstruction.add(new Obstruction(120, 360, 0, this));this.allObstruction.add(new Obstruction(180, 360, 0, this));this.allObstruction.add(new Obstruction(360, 360, 10, this));this.allObstruction.add(new Obstruction(360, 180, 3, this));this.allObstruction.add(new Obstruction(420, 180, 3, this));this.allObstruction.add(new Obstruction(540, 360, 10, this));this.allObstruction.add(new Obstruction(540, 180, 10, this));this.allObstruction.add(new Obstruction(720, 360, 10, this));//创建敌人this.allEnemy.add(new Enemy(840, 480, true, 3, 4, this));this.allEnemy.add(new Enemy(540, 480, true, 3, this));this.allEnemy.add(new Enemy(840, 480, true, 1, this));this.allEnemy.add(new Enemy(780, 480, true, 1, this));this.allEnemy.add(new Enemy(720, 480, true, 1, this));this.allEnemy.add(new Enemy(660, 360, true, 1, this));this.allEnemy.add(new Enemy(600, 360, true, 1, this));}private void creat4Map(){for(int i = 0; i < 15; i++){//创建出所有地面this.allObstruction.add(new Obstruction(i * 60,540,9, this));}//绘制旗子this.allObstruction.add(new Obstruction(550, 190, 11, this));//绘制旗子下面的砖块this.allObstruction.add(new Obstruction(520,480,2, this));}}class Enemy implements Runnable{private int x;//敌人的x坐标private int y;//敌人的y坐标private int startX;//敌人的初始x坐标private int startY;//敌人的初始y坐标private boolean startIsLeftOrUp;//敌人初始的移动方向private int startImageType;//初始的显示图片private int type;//敌人的类型1代表蘑菇,2代表食人花,3代表乌龟private BufferedImage bufferedImage;private BackGround bg;//障碍物所在的背景//敌人的显示图片,不同的type代表不同的敌人显示图片,通过显示图片的切换,达到动态的效果private int imageType;//移动的极限范围private int upMax;private int downMax;private boolean isLeftOrUP;Thread t = new Thread(this);//普通敌人的构造方法,加入显示图片参数public Enemy(int x, int y, boolean isLeft, int type, int imageType, BackGround bg){this.x = x;this.y = y;this.startX = x;this.startY = y;this.isLeftOrUP = isLeft;this.startIsLeftOrUp = isLeft;this.type = type;this.bg = bg;this.imageType = imageType;this.startImageType = imageType;switch(type){case 1://蘑菇//取蘑菇的图片this.bufferedImage = StaticValue.allTriangleImage.get(0);break;case 3://乌龟this.bufferedImage = StaticValue.allTurtleImage.get(0);break;}t.start(); //启动线程t.suspend();//抑制线程启动}//普通敌人的构造方法public Enemy(int x, int y, boolean isLeft, int type, BackGround bg) {this.x = x;this.y = y;this.startX = x;this.startY = y;this.isLeftOrUP = isLeft;this.startIsLeftOrUp = isLeft;this.type = type;this.bg = bg;switch(type){case 1://蘑菇//取蘑菇的图片this.bufferedImage = StaticValue.allTriangleImage.get(0);break;case 3://乌龟this.bufferedImage = StaticValue.allTurtleImage.get(0);break;}t.start(); //启动线程t.suspend();//抑制线程启动}//食人花敌人的构造方法public Enemy(int x, int y, boolean isUp, int type, int upMax, int downMax, BackGround bg){this.x = x;this.y = y;this.startX = x;this.startY = y;this.isLeftOrUP = isUp;this.bg = bg;this.type = type;this.upMax = upMax;this.downMax = downMax;if(2 == type){//取食人花图片this.bufferedImage = StaticValue.allFlowerImage.get(0);}t.start();//启动线程t.suspend();//抑制线程启动}//当Mario死亡的时候重置敌人的方法public void reSet(){this.x = this.startX;this.y = this.startY;this.isLeftOrUP = this.startIsLeftOrUp;this.imageType = this.startImageType;switch(this.type){case 1:this.bufferedImage = StaticValue.allTriangleImage.get(0);break;case 2:this.bufferedImage = StaticValue.allFlowerImage.get(0);this.isLeftOrUP = true;break;case 3:this.bufferedImage = StaticValue.allTurtleImage.get(this.startImageType);break;}}//敌人死亡的方法public void dead(){switch(this.type){case 1://蘑菇//将显示图片改为敌人死亡的图片this.bufferedImage = StaticValue.allTriangleImage.get(2);this.bg.getAllEnemy().remove(this);this.bg.getRemoveEnemy().add(this);break;case 3://乌龟//将显示图片改为敌人死亡的图片this.imageType = 4;this.bufferedImage = StaticValue.allTurtleImage.get(imageType);break;}}public void run(){while(true){this.sleep();switch(this.type){case 1://蘑菇this.triangleMove();//蘑菇移动break;case 2://食人花this.flowerMove();//食人花移动break;case 3://乌龟this.turtleMove();//乌龟移动break;}}}public BufferedImage getBufferedImage() { return bufferedImage;}public int getStartX() {return startX;}public int getStartY() {return startY;}public int getX() {return x;}public int getY() {return y;}public int getType() {return type;}public void starMove(){this.t.resume();}//蘑菇移动private void triangleMove(){if(this.isLeftOrUP){this.x -= 2;}else{this.x += 2;}//改变imageType来让敌人的图片切换,达到动态的效果if(0 == this.imageType){this.imageType = 1;}else{this.imageType = 0;}//定义用来标记敌人是否可以向左或者向右移动的标记boolean canleft = true;boolean canright = true;boolean onLand = false;for(int i = 0; i < bg.getAllObstruction().size(); i++){Obstruction ob = bg.getAllObstruction().get(i);//敌人不能向右移动if(this.x == ob.getX() - 50 && ((this.y < ob.getY() + 50) && (this.y > ob.getY() - 50))){canright = false;}//敌人不能向左移动if(this.x == ob.getX() + 50 && ((this.y < ob.getY() + 50) && (this.y > ob.getY() - 50))){canleft = false;}if((this.y == ob.getY() - 60) && ((this.x < ob.getX() + 50) && (this.x > (ob.getX() - 50)))){onLand = true;}}if(!onLand){this.down();}//如果敌人正在向左移动,但是又不能向左移动了,那么改变敌人的移动方向if((this.isLeftOrUP && !canleft) || 0 == this.x){this.isLeftOrUP = false;}//如果敌人正在向右移动,但是又不能向右移动了,那么改变敌人的移动方向if((!this.isLeftOrUP && !canright) || 840 == this.x){this.isLeftOrUP = true;}//通过imageType获取在内存中真正的图片this.bufferedImage = StaticValue.allTriangleImage.get(this.imageType);}//食人花移动private void flowerMove(){if(this.isLeftOrUP){this.y -= 2;}else{this.y += 2;}//当食人花到达极限位置的时候,修改它移动的方向if(!this.isLeftOrUP && this.y == this.upMax){this.isLeftOrUP = true;}else if(this.isLeftOrUP && this.y == this.downMax){this.isLeftOrUP = false;}//改变imageType来让敌人的图片切换,达到动态的效果if(0 == this.imageType){this.imageType = 1;}else{this.imageType = 0;}//通过imageType获取在内存中真正的图片this.bufferedImage = StaticValue.allFlowerImage.get(this.imageType);}//乌龟移动private void turtleMove(){if(this.isLeftOrUP){if(4 == this.imageType){this.x -= 10;}else{this.x -= 2;}}else{if(4 == this.imageType){this.x += 10;}else{this.x += 2;}}this.changeTurtleImage();//改变乌龟的显示图片//定义用来标记敌人是否可以向左或者向右移动的标记boolean canleft = true;boolean canright = true;boolean onLand = false;for(int i = 0; i < bg.getAllObstruction().size(); i++){Obstruction ob = bg.getAllObstruction().get(i);//敌人不能向右移动if(this.x == ob.getX() - 50 && ((this.y < ob.getY() + 50) && (this.y > ob.getY() - 50))){canright = false;}//敌人不能向左移动if(this.x == ob.getX() + 50 && ((this.y < ob.getY() + 50) && (this.y > ob.getY() - 50))){canleft = false;}if((this.y == ob.getY() - 60) && ((this.x < ob.getX() + 50) && (this.x > (ob.getX() - 50)))){onLand = true;}}if(!onLand){this.down();}//如果敌人正在向左移动,但是又不能向左移动了,那么改变敌人的移动方向if((this.isLeftOrUP && !canleft) || this.x <= 0){this.isLeftOrUP = false;}//如果敌人正在向右移动,但是又不能向右移动了,那么改变敌人的移动方向if((!this.isLeftOrUP && !canright) || this.x >= 840){this.isLeftOrUP = true;}//通过imageType获取在内存中真正的图片this.bufferedImage = StaticValue.allTurtleImage.get(this.imageType);}//敌人下落private void down(){this.y += 5;}private void sleep(){try{Thread.sleep(20);}catch(Exception e){e.printStackTrace();}}//改变乌龟的显示图片private void changeTurtleImage(){if(4 == this.imageType){return;}if(this.isLeftOrUP)//如果是向左移动{//循环切换向左移动的两张图片if(0 == this.imageType){this.imageType = 1;}else{this.imageType = 0;}}else//如果是向右边移动{if(2 == this.imageType){this.imageType = 3;}else{this.imageType = 2;}}}}class Mario implements Runnable{private int x;//Mario的x坐标private int y;//Mario的y坐标private int moving = 1;private BufferedImage showImage = null;private int life;//Mario的生命BackGround bg = null;//Mario所在的背景private int uptime;//Mario的上升时间String status;//Mario的移动状态int score;//Mario的分数Thread t;//Mario的线程int xmove;//Mario的x移动距离int ymove;//Mario的y移动距离private boolean isClear = false;//标识用户是否通关。