> 文档中心 > JAVA 实现《超级玛丽》游戏

JAVA 实现《超级玛丽》游戏


前言

在你的童年记忆里,是否有一个蹦跳、顶蘑菇的小人?

如果你回忆起了它,你定然会觉得现在它幼稚、无聊,画面不漂亮,游戏不精彩……但请你记住:这才是真正的游戏,它给了你无限的欢乐!

马里奥是靠吃蘑菇成长,闻名世界的超级巨星。特征是大鼻子、头戴帽子、身穿背带工作服、还留着胡子。

如此经典的游戏,你怎么能错过,快来玩玩吧。

《超级玛丽》游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想。

主要需求

游戏剧情模拟超级玛丽,用swing来做界面化处理,学会利用面向对象的思想实现这个游戏

主要设计

1、游戏背景的设计

2、地图的显示

3、台阶的显示

4、游戏物品的显示

5、超级玛丽的设计,左右移动能力、跳动能力

6、小怪的设计,包含出现的地点、杀伤功能、跳动能力

7、游戏的分数系统设计

8、地图变动功能

9、射击功能

10、游戏采用多线程技术

11、背景音乐设计

功能截图

游戏开始:

JAVA 实现《超级玛丽》游戏

超级玛丽跳动

JAVA 实现《超级玛丽》游戏

换地图

JAVA 实现《超级玛丽》游戏

过了这一关

JAVA 实现《超级玛丽》游戏

代码实现

游戏主界面

public class MyFrame extends JFrame implements KeyListener,Runnable {    //用于存储所有的背景    private List<BackGround> allBg = new ArrayList<>();    //用于存储当前的背景    private BackGround nowBg = new BackGround();    //用于双缓存    private Image offScreenImage = null;    //马里奥对象    private Mario mario = new Mario();    //定义一个线程对象,用于实现马里奥的运动    private Thread thread = new Thread(this);    public MyFrame() { //设置窗口的大小为800 * 600 this.setSize(800,600); //设置窗口居中显示 this.setLocationRelativeTo(null); //设置窗口的可见性 this.setVisible(true); //设置点击窗口上的关闭键,结束程序 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗口大小不可变 this.setResizable(false); //向窗口对象添加键盘监听器 this.addKeyListener(this); //设置窗口名称 this.setTitle("超级玛丽"); //初始化图片 StaticValue.init(); //初始化马里奥 mario = new Mario(10,355); //创建全部的场景 for (int i = 1;i <= 3;i++) {     allBg.add(new BackGround(i, i == 3 ? true : false)); } //将第一个场景设置为当前场景 nowBg = allBg.get(0); mario.setBackGround(nowBg); //绘制图像 repaint(); thread.start(); try {     new Music(); } catch (FileNotFoundException e) {     e.printStackTrace(); } catch (Exception e) {      }    }    @Override    public void paint(Graphics g) { if (offScreenImage == null) {     offScreenImage = createImage(800,600); } Graphics graphics = offScreenImage.getGraphics(); graphics.fillRect(0,0,800,600); //绘制背景 graphics.drawImage(nowBg.getBgImage(),0,0,this); //绘制敌人 for (Enemy e : nowBg.getEnemyList()) {     graphics.drawImage(e.getShow(),e.getX(),e.getY(),this); } //绘制障碍物 for (Obstacle ob : nowBg.getObstacleList()) {     graphics.drawImage(ob.getShow(),ob.getX(),ob.getY(),this); } //绘制城堡 graphics.drawImage(nowBg.getTower(),620,270,this); //绘制旗杆 graphics.drawImage(nowBg.getGan(),500,220,this); //绘制马里奥 graphics.drawImage(mario.getShow(),mario.getX(),mario.getY(),this); //添加分数 Color c = graphics.getColor(); graphics.setColor(Color.BLACK); graphics.setFont(new Font("黑体",Font.BOLD,25)); graphics.drawString("当前的分数为: " + mario.getScore(),300,100); graphics.setColor(c); //将图像绘制到窗口中 g.drawImage(offScreenImage,0,0,this);    }    public static void main(String[] args) { MyFrame myFrame = new MyFrame();    }    @Override    public void keyTyped(KeyEvent e) {    }    //当键盘按下按键时调用    @Override    public void keyPressed(KeyEvent e) { //向右移动 if (e.getKeyCode() == 39) {     mario.rightMove(); } //向左移动 if (e.getKeyCode() == 37) {     mario.leftMove(); } //跳跃 if (e.getKeyCode() == 38) {     mario.jump(); }    }    //当键盘松开按键时调用    @Override    public void keyReleased(KeyEvent e) { //想左停止 if (e.getKeyCode() == 37) {     mario.leftStop(); } //向右停止 if (e.getKeyCode() == 39) {     mario.rightStop(); }    }    @Override    public void run() { while (true) {     repaint();     try {  Thread.sleep(50);  if (mario.getX() >= 775) {      nowBg = allBg.get(nowBg.getSort());      mario.setBackGround(nowBg);      mario.setX(10);      mario.setY(355);  }  //判断马里奥是否死亡  if (mario.isDeath()) {      JOptionPane.showMessageDialog(this,"马里奥死亡!!!");      System.exit(0);  }  //判断游戏是否结束  if (mario.isOK()) {      JOptionPane.showMessageDialog(this,"恭喜你!成功通关了");      System.exit(0);  }     } catch (InterruptedException e) {  e.printStackTrace();     } }    }}

马里奥

public class Mario implements Runnable{    //用于表示横纵坐标    private int x;    private int y;    //用于表示当前的状态    private String status;    //用于显示当前状态对应的图像    private BufferedImage show = null;    //定义一个BackGround对象,用来获取障碍物的信息    private BackGround backGround = new BackGround();    //用来实现马里奥的动作    private Thread thread = null;    //马里奥的移动速度    private int xSpeed;    //马里奥的跳跃速度    private int ySpeed;    //定义一个索引    private int index;    //表示马里奥上升的时间    private int upTime = 0;    //用于判断马里奥是否走到了城堡的门口    private boolean isOK;    //用于判断马里奥是否死亡    private boolean isDeath = false;    //表示分数    private int score = 0;    public Mario() {    }    public Mario (int x,int y) { this.x = x; this.y = y; show = StaticValue.stand_R; this.status = "stand--right"; thread = new Thread(this); thread.start();    }    //马里奥的死亡方法    public void death() { isDeath = true;    }    //马里奥向左移动    public void leftMove() { //改变速度 xSpeed = -5; //判断马里奥是否碰到旗子 if (backGround.isReach()) {     xSpeed = 0; } //判断马里奥是否处于空中 if (status.indexOf("jump") != -1) {     status = "jump--left"; }else {     status = "move--left"; }    }    //马里奥向右移动    public void rightMove() { xSpeed = 5; //判断马里奥是否碰到旗子 if (backGround.isReach()) {     xSpeed = 0; } if (status.indexOf("jump") != -1) {     status = "jump--right"; }else {     status = "move--right"; }    }    //马里奥向左停止    public void leftStop() { xSpeed = 0; if (status.indexOf("jump") != -1) {     status = "jump--left"; }else {     status = "stop--left"; }    }    //马里奥向右停止    public void rightStop() { xSpeed = 0; if (status.indexOf("jump") != -1) {     status = "jump--right"; }else {     status = "stop--right"; }    }    //马里奥跳跃    public void jump() { if (status.indexOf("jump") == -1) {     if (status.indexOf("left") != -1) {  status = "jump--left";     }else {  status = "jump--right";     }     ySpeed = -10;     upTime = 7; } //判断马里奥是否碰到旗子 if (backGround.isReach()) {     ySpeed = 0; }    }    //马里奥下落    public void fall() { if (status.indexOf("left") != -1) {     status = "jump--left"; }else {     status = "jump--right"; } ySpeed = 10;    }    @Override    public void run() { while (true) {     //判断是否处于障碍物上     boolean onObstacle = false;     //判断是否可以往右走     boolean canRight = true;     //判断是否可以往左走     boolean canLeft = true;     //判断马里奥是否到达旗杆位置     if (backGround.isFlag() && this.x >= 500) {  this.backGround.setReach(true);  //判断旗子是否下落完成  if (this.backGround.isBase()) {      status = "move--right";      if (x < 690) {   x += 5;      }else {   isOK = true;      }  }else {      if (y < 395) {   xSpeed = 0;   this.y += 5;   status = "jump--right";      }      if (y > 395) {   this.y = 395;   status = "stop--right";      }  }     }else {  //遍历当前场景里所有的障碍物  for (int i = 0; i < backGround.getObstacleList().size(); i++) {      Obstacle ob = backGround.getObstacleList().get(i);      //判断马里奥是否位于障碍物上      if (ob.getY() == this.y + 25 && (ob.getX() > this.x - 30 && ob.getX() < this.x + 25)) {   onObstacle = true;      }      //判断是否跳起来顶到砖块      if ((ob.getY() >= this.y - 30 && ob.getY() <= this.y - 20) && (ob.getX() > this.x - 30 && ob.getX() < this.x + 25)) {   if (ob.getType() == 0) {backGround.getObstacleList().remove(ob);score += 1;   }   upTime = 0;      }      //判断是否可以往右走      if (ob.getX() == this.x + 25 && (ob.getY() > this.y - 30 && ob.getY() < this.y + 25)) {   canRight = false;      }      //判断是否可以往左走      if (ob.getX() == this.x - 30 && (ob.getY() > this.y - 30 && ob.getY() < this.y + 25)) {   canLeft = false;      }  }  //判断马里奥是否碰到敌人死亡或者踩死蘑菇敌人  for (int i = 0;i < backGround.getEnemyList().size();i++) {      Enemy e = backGround.getEnemyList().get(i);      if (e.getY() == this.y + 20 && (e.getX() - 25 <= this.x && e.getX() + 35 >= this.x)) {   if (e.getType() == 1) {e.death();score += 2;upTime = 3;ySpeed = -10;   }else if (e.getType() == 2) {//马里奥死亡death();   }      }      if ((e.getX() + 35 > this.x && e.getX() - 25 < this.x) && (e.getY() + 35 > this.y && e.getY() - 20 < this.y)) {   //马里奥死亡   death();      }  }  //进行马里奥跳跃的操作  if (onObstacle && upTime == 0) {      if (status.indexOf("left") != -1) {   if (xSpeed != 0) {status = "move--left";   } else {status = "stop--left";   }      } else {   if (xSpeed != 0) {status = "move--right";   } else {status = "stop--right";   }      }  } else {      if (upTime != 0) {   upTime--;      } else {   fall();      }      y += ySpeed;  }     }     if ((canLeft && xSpeed < 0) || (canRight && xSpeed > 0)) {  x += xSpeed;  //判断马里奥是否到了最左边  if (x < 0) {      x = 0;  }     }     //判断当前是否是移动状态     if (status.contains("move")) {  index = index == 0 ? 1 : 0;     }     //判断是否向左移动     if ("move--left".equals(status)) {  show = StaticValue.run_L.get(index);     }     //判断是否向右移动     if ("move--right".equals(status)) {  show = StaticValue.run_R.get(index);     }     //判断是否向左停止     if ("stop--left".equals(status)) {  show = StaticValue.stand_L;     }     //判断是否向右停止     if ("stop--right".equals(status)) {  show = StaticValue.stand_R;     }     //判断是否向左跳跃     if ("jump--left".equals(status)) {  show = StaticValue.jump_L;     }     //判断是否向右跳跃     if ("jump--right".equals(status)) {  show = StaticValue.jump_R;     }     try {  Thread.sleep(50);     } catch (InterruptedException e) {  e.printStackTrace();     } }    }    public int getX() { return x;    }    public void setX(int x) { this.x = x;    }    public int getY() { return y;    }    public void setY(int y) { this.y = y;    }    public BufferedImage getShow() { return show;    }    public void setShow(BufferedImage show) { this.show = show;    }    public void setBackGround(BackGround backGround) { this.backGround = backGround;    }    public boolean isOK() { return isOK;    }    public boolean isDeath() { return isDeath;    }    public int getScore() { return score;    }}

小怪

public class Enemy implements Runnable{    //存储当前坐标    private int x;    private int y;    //存储敌人类型    private int type;    //判断敌人运动的方向    private boolean face_to = true;    //用于显示敌人的当前图像    private BufferedImage show;    //定义一个背景对象    private BackGround bg;    //食人花运动的极限范围    private int max_up = 0;    private int max_down = 0;    //定义线程对象    private Thread thread = new Thread(this);    //定义当前的图片的状态    private int image_type = 0;    //蘑菇敌人的构造函数    public Enemy(int x,int y,boolean face_to,int type,BackGround bg) { this.x = x; this.y = y; this.face_to = face_to; this.type = type; this.bg = bg; show = StaticValue.mogu.get(0); thread.start();    }    //食人花敌人的构造函数    public Enemy(int x,int y,boolean face_to,int type,int max_up,int max_down,BackGround bg) { this.x = x; this.y = y; this.face_to = face_to; this.type = type; this.max_up = max_up; this.max_down = max_down; this.bg = bg; show = StaticValue.flower.get(0); thread.start();    }    //死亡方法    public void death() { show = StaticValue.mogu.get(2); this.bg.getEnemyList().remove(this);    }    public int getX() { return x;    }    public int getY() { return y;    }    public BufferedImage getShow() { return show;    }    public int getType() { return type;    }    @Override    public void run() { while (true) {     //判断是否是蘑菇敌人     if (type == 1) {  if (face_to) {      this.x -= 2;  }else {      this.x += 2;  }  image_type = image_type == 1 ? 0 : 1;  show = StaticValue.mogu.get(image_type);     }     //定义两个布尔变量     boolean canLeft = true;     boolean canRight = true;     for (int i = 0;i < bg.getObstacleList().size();i++) {  Obstacle ob1 = bg.getObstacleList().get(i);  //判断是否可以右走  if (ob1.getX() == this.x + 36 && (ob1.getY() + 65 > this.y && ob1.getY() - 35 < this.y)) {      canRight = false;  }  //判断是否可以左走  if (ob1.getX() == this.x - 36 && (ob1.getY() + 65 > this.y && ob1.getY() - 35 < this.y)) {      canLeft = false;  }     }     if (face_to && !canLeft || this.x == 0) {  face_to = false;     }     else if ((!face_to) && (!canRight) || this.x == 764) {  face_to = true;     }     //判断是否是食人花敌人     if (type == 2) {  if (face_to) {      this.y -= 2;  }else {      this.y += 2;  }  image_type = image_type == 1 ? 0 : 1;  //食人花是否到达极限位置  if (face_to && (this.y == max_up)) {      face_to = false;  }  if ((!face_to) && (this.y == max_down)) {      face_to = true;  }  show = StaticValue.flower.get(image_type);     }     try {  Thread.sleep(50);     } catch (InterruptedException e) {  e.printStackTrace();     } }    }}

总结

通过此次的《超级玛丽》游戏实现,让我对JAVA的相关知识有了进一步的了解,对java这门语言也有了比以前更深刻的认识。

java的一些基本语法,比如数据类型、运算符、程序流程控制和数组等,理解更加透彻。java最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。

源码获取

源码下载地址:传送门------->

点赞,关注博主后,私聊博主免费获取

今天是持续写作的第 18 / 100 天。
可以关注我,点赞我、评论我、收藏我啦。