游戏效果截图
源码:
Class1:demon.java
public class demon { public static void main(String[] args){ new MyFrame(); } }
Class2:MyFrame.java
import javazoom.jl.decoder.JavaLayerException; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; 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); boolean isOk =false; public MyFrame(){ //Login login = new Login("lining"); //设置窗口的大小 this.setSize(800,600); //设置窗口居中显示 this.setLocationRelativeTo(null); //设置窗口的可见性 this.setVisible(true); //设置点击窗口上的关闭键,结束程序 this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); //设置窗口大小不变 this.setResizable(false); //向窗口对象添加键盘监听器 this.addKeyListener((KeyListener) this); //设置窗口名称 this.setTitle("SuperMario"); //初始化图片 StaticValue.init(); //初始化马里奥 mario = new Mario(10,365); //创建全部的场景 for(int i=1;i<=3;i++){ allBg.add(new BackGround(i,i==3?true:false)); } //将第一个场景设置为当前场景 nowBg = allBg.get(0); mario.setBackGround(nowBg); JOptionPane.showMessageDialog(this,"靓仔你好,请开始你的表演"); //绘制图像 repaint(); thread.start(); try { new Music(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (JavaLayerException e) { e.printStackTrace(); } } @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.getBaImage(),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(),600,130,this); //绘制旗杆 graphics.drawImage(nowBg.getGan(),500,220,this); //绘制马里奥 graphics.drawImage(mario.getShow(), mario.getX(), mario.getY(), this); //绘制分数 Color c = graphics.getColor(); graphics.setColor(Color.red); graphics.setFont(new Font("宋体",Font.BOLD,40)); graphics.drawString("当前的分数为"+mario.getScore(),300,100); graphics.setColor(Color.yellow); //将图像绘制到窗口中 g.drawImage(offScreenImage,0,0,this); } @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(365); } //判断马里奥是否死亡 if(mario.isDeath()) { JOptionPane.showMessageDialog(this,"不好意思,靓仔你挂了"); System.exit(0); } //判断游戏是否结束了 if(mario.isOK()) { JOptionPane.showMessageDialog(this,"恭喜靓仔通关了"); System.exit(0); } } catch (InterruptedException e) { e.printStackTrace(); } } } }
Class3:Mario.java
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage; 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--left"; if(x<690) { x+=5; } else { isOK =true; } } else { if(y<385) { xSpeed = 0; this.y += 5; status = "jump--right"; } if(y>385) { xSpeed = 0; this.y += 5; 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; } }
Class4:Enemy.java
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage; public class Enemy implements Runnable{ //储存当前坐标 private int x; private int y; //储存敌人类型 private int type; //判断敌人运动的方向 private boolean fact_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 fact_to, int type, BackGround bg) { this.x = x; this.y = y; this.fact_to = fact_to; this.type = type; this.bg = bg; show = StaticValue.mogu.get(0); thread.start(); } //食人花敌人的构造函数 public Enemy(int x, int y, boolean fact_to, int type, int max_up, int max_down, BackGround bg) { this.x = x; this.y = y; this.fact_to = fact_to; this.type = type; this.max_down = max_down; this.max_up = max_up; this.bg = bg; show = StaticValue.flower.get(0); thread.start(); } //死亡方法 public void death() { show = StaticValue.mogu.get(2);//蘑菇敌人死亡时的图片 this.bg.getEnemyList().remove(this); } @Override public void run() { while(true) { //判断是否是蘑菇敌人 if (type == 1) { if (fact_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(fact_to&&!canLeft || this.x==0) { fact_to=false; } else if(!(fact_to)&&!(canRight) || this.x==764) { fact_to = true; } //判断是否是食人花敌人 if(type == 2) { if(fact_to) { this.y -= 2; } else { this.y += 2; } image_type = image_type == 1 ? 0 : 1; //食人花是否到达极限位置 if(fact_to && (this.y == max_up)){ fact_to = false; } if((!fact_to)&&(this.y == max_down)){ fact_to = true; } show = StaticValue.flower.get(image_type); } try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } } public int getX() { return x; } public int getY() { return y; } public BufferedImage getShow() { return show; } public int getType() { return type; } }
Class5:StaticValue
import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class StaticValue { //背景 public static BufferedImage bg=null; public static BufferedImage bg2=null; //马里奥向左跳跃 public static BufferedImage jump_L=null; //马里奥向右跳跃 public static BufferedImage jump_R=null; //马里奥向左站立 public static BufferedImage stand_L=null; //马里奥向右站立 public static BufferedImage stand_R=null; //城堡 public static BufferedImage tower=null; //旗杆 public static BufferedImage gan=null; //障碍物 public static List<BufferedImage> obstacle = new ArrayList<>(); //马里奥向左跑 public static List<BufferedImage> run_L = new ArrayList<>(); //马里奥向右跑 public static List<BufferedImage> run_R = new ArrayList<>(); //蘑菇敌人 public static List<BufferedImage> mogu = new ArrayList<>(); //食人花敌人 public static List<BufferedImage> flower = new ArrayList<>(); //路径的前缀,方便后续使用 public static String path ="data"; //初始化方法 public static void init(){ try { //加载背景图片 bg = ImageIO.read(new File("data/bg.png")); bg2 = ImageIO.read(new File("data/bg.png")); //加载马里奥向左站立 stand_L = ImageIO.read(new File("data/32.png")); //加载马里奥向右站立 stand_R = ImageIO.read(new File("data/32.png")); //加载城堡 tower = ImageIO.read(new File("data/chengbao.png")); //加载旗杆 gan = ImageIO.read(new File("data/gan.png")); //加载马里奥向左跳跃 jump_L = ImageIO.read(new File("data/s_mario_run1_L.png")); //加载马里奥向右跳跃 jump_R = ImageIO.read(new File("data/s_mario_run1_L.png")); } catch (IOException e) { e.printStackTrace(); } //加载马里奥左跑 for(int i=1;i<3;i++){ try { run_L.add(ImageIO.read(new File("data/s_mario_run"+i+"_L.png"))); } catch (IOException e) { e.printStackTrace(); } } //加载马里奥右跑 for(int i=1;i<3;i++){ try { run_R.add(ImageIO.read(new File("data/s_mario_run"+i+"_L.png"))); } catch (IOException e) { e.printStackTrace(); } } //加载障碍物 try { obstacle.add(ImageIO.read(new File("data/no_no_stone.png"))); obstacle.add(ImageIO.read(new File("data/soli_up.png"))); obstacle.add(ImageIO.read(new File("data/soli_base.png"))); } catch (IOException e) { e.printStackTrace(); } //加载水管 for(int i=1;i<=4;i++){ try { obstacle.add(ImageIO.read(new File("data/guan"+i+".png"))); } catch (IOException e) { e.printStackTrace(); } } //加载不可破坏的砖块和旗子 try { obstacle.add(ImageIO.read(new File("data/stonezhuan.png"))); obstacle.add(ImageIO.read(new File("data/flag.png"))); } catch (IOException e) { e.printStackTrace(); } //加载蘑菇敌人 for(int i=1;i<=3;i++){ try { mogu.add(ImageIO.read(new File("data/mogu"+i+".png"))); } catch (IOException e) { e.printStackTrace(); } } //加载食人花敌人 for(int i=1;i<=2;i++){ try { flower.add(ImageIO.read(new File("data/flower"+i+".png"))); } catch (IOException e) { e.printStackTrace(); } } } }
Class6:Music.java
import javazoom.jl.decoder.JavaLayerException; import javazoom.jl.player.Player; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; public class Music { public Music() throws FileNotFoundException, JavaLayerException { Player player; String str = System.getProperty("user.dir")+"/src/Music/mus.mp3"; BufferedInputStream name = new BufferedInputStream(new FileInputStream(str)); player = new Player(name); player.play(); } }
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/291108.html