超级玛丽--Java课程设计

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

超级玛丽--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所示:
图1
1.3程序类图
系统的整体类图的框架如图2所示。

首先是窗体类。

他需要调用到Mario和BackGround类中的方法。

以便动态的显示Mario类和BackGround。

而BackGround里面又包含了Enemy和Obstruction。

Enemy,Obstruction和Mario类又调用静态类StaticValue的方法,用以显示真实的图片。

而StaticValue则是一个静态类,将存储在硬盘的图片资源加载进入内存以便其他模块调用。

图2
2详细设计
2.1 MyFrame实现
2.1.1窗体对象的序列图
窗体对象继承了JFrame类并且实现了Runnable接口。

作为窗体对象,它首先显示窗体,绘制背景。

然后启动线程。

在run方法里面动态得绘制窗体中需要显示的Mario
的图片,障碍物的图片,敌人的图片。

该窗体的run方法是一个死循环,每次执行一个循环调用sleep方法睡眠50毫秒。

序列图如图3所示。

图3
2.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();
}
@Override
public 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);
}
/**
*/
@Override
public 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的生命加10
if(70 == e.getKeyCode())
{
this.mario.setLife(this.mario.getLife() + 10);
}
}
else
{
if(e.getKeyCode() == 32)
{
this.isStart = true;
this.nowBg.enemysStartMove();
}
}
}
/**
*/
@Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == 39)
{
this.mario.rightStop();
}
if(e.getKeyCode() == 37)
{
this.mario.leftStop();
}
}
/**
*/
@Override
public void keyTyped(KeyEvent e)
{
// TODO Auto-generated method stub }
@Override
public 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;//标识用户是否通关。

isClear为true时代表用户通关了
public boolean isClear() {
return isClear;
}
private boolean isDead = false;//标识Mario是否死亡
public Mario(int x, int y)
{
this.x = x;
this.y = y;
this.status = "rignht--standing";
this.showImage = null;
this.score = 0;
this.life = 3;
t = new Thread(this);
t.start();
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setBg(BackGround bg)
{
this.bg = bg;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public BufferedImage getShowImage()
{
return showImage;
}
//Mario向左移动
public void leftMove()
{
if(this.status.indexOf("jumping") != -1) {
this.status = "left--jumping";
}
else
{
this.status = "left--moving";
}
if(this.x < 5)
{
this.x = 5;
}
else
{
this.xmove = -5;
}
}
//Mario向右移动
public void rightMove()
{
if(this.status.indexOf("jumping") != -1) {
this.status = "right--jumping";
}
else
{
this.status = "right--moving";
}
this.xmove = 5;
}
//Mario左停止
public void leftStop()
{
if(this.status.indexOf("jumping") != -1) {
this.status = "left--jumping";
}
else
{
this.status = "left--standing";
}
this.xmove = 0;
}
//Mario右停止
public void rightStop()
{
if(this.status.indexOf("jumping") != -1) {
this.status = "right--jumping";
}
else
{
this.status = "right--standing";
}
this.xmove = 0;
}
//Mario跳跃
public void jump()
{
if(this.status.indexOf("jumping") == -1) {
if(this.status.indexOf("left") != -1)
{
this.status = "left--jumping";
}
else
{
this.status = "right--jumping";
}
ymove = -10;
uptime = 36;
}
}
//Mario下落
public void down()
{
if(this.status.indexOf("left") != -1)
{
this.status = "left--jumping";
}
else
{
this.status = "right--jumping";
}
ymove = 10;
}
private void reSet()
{
this.x = 0;
this.y = 480;
}
@Override
public void run()
{
while (true)
{
this.sleep();//线程睡眠
this.changeMarioImage();//修改Mario显示图片
//如果游戏结束了
if(this.bg.isFlag() && this.x >= 520)
{
this.gameOver();
}
else//游戏进行中
{
this.determinexy(); //判断Mario的x和y坐标来决定Mario的状态
this.deterMarioWithObstruction();//通过Mario和障碍物的相对位置修改Mario自身的状态
this.marioTouchEnemys();//Mario和敌人碰撞后的结果
}
}
}
public int getLife() {
return life;
}
void dead()
{
--this.life;
if(0 == this.life)
{
this.isDead = true;//如果生命数为0,Mario死亡
}
else
{
this.bg.reset();
this.reSet();
}
}
public boolean isDead()
{
return isDead;
}
public void setDead(boolean isDead) {
this.isDead = isDead;
}
//线程睡眠
private void sleep()
{
try
{
Thread.sleep(30);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public int getScore() {
return score;
}
//判断Mario的x和y坐标来决定Mario的状态
private void determinexy()
{
if(y > 600)
{
this.dead();//如果Mario到达屏幕的底部,那么Mario死亡}
if(this.x < 0)
{。

相关文档
最新文档