超级玛丽源码及素材
游戏效果截图
源码:
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();
}
}
素材:
有需要可私聊.
2022.1.23.13:23