一级标题超级玛丽java实现
话不多说,先上图;
下面直接上代码
背景类
BackGround类
package com.sxt;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class BackGround {
//当前场景要显示的图像
private BufferedImage bgImage = null;
//记录当前是第几个场景
private int sort;
//判断是否是最后一个场景
private boolean flag;
private List<Obstacle> obstacleList=new ArrayList<>();
private List<Enemy>enemyList=new ArrayList<>();
private BufferedImage gan=null;
private BufferedImage tower=null;
private boolean isReach=false;
private boolean isBase=false;
public BackGround() {
}
public BackGround(int sort,boolean flag) {
this.sort = sort;
this.flag = flag;
if (flag) {
bgImage = StaticValue.bg2;
}else {
bgImage = StaticValue.bg;
}
if(sort==1){
for(int i=0;i<27;i++){
obstacleList.add(new Obstacle(i*30,420,1,this));
}
for(int j=0;j<=120;j+=30){
for(int i=0;i<27;i++){
obstacleList.add(new Obstacle(i*30,570-j,2,this));
}
}
for(int i=120;i<=150;i+=30){
obstacleList.add(new Obstacle(i,300,7,this));
}
for(int i=300;i<=570;i+=30){
if(i==360||i==390||i==480||i==510||i==540){
obstacleList.add(new Obstacle(i,300,7,this));
}else{
obstacleList.add(new Obstacle(i,300,0,this));
}
}
for(int i=420;i<=450;i+=30){
obstacleList.add(new Obstacle(i,240,7,this));
}
for(int i=360;i<=600;i+=25){
if(i==360){
obstacleList.add(new Obstacle(620,i,3,this));
obstacleList.add(new Obstacle(645,i,4,this));
}else{
obstacleList.add(new Obstacle(620,i,5,this));
obstacleList.add(new Obstacle(645,i,6,this));
}
}
enemyList.add(new Enemy(580,385,true,1,this));
enemyList.add(new Enemy(635,420,true,2,328,428,this));
}
if(sort==2){
for(int i=0;i<27;i++){
obstacleList.add(new Obstacle(i*30,420,1,this));
}
for(int j=0;j<=120;j+=30){
for(int i=0;i<27;i++){
obstacleList.add(new Obstacle(i*30,570-j,2,this));
}
}
for(int i=360;i<=600;i+=25){
if(i==360){
obstacleList.add(new Obstacle(60,i,3,this));
obstacleList.add(new Obstacle(85,i,4,this));
}else{
obstacleList.add(new Obstacle(60,i,5,this));
obstacleList.add(new Obstacle(85,i,6,this));
}
}
for(int i=330;i<=600;i+=25){
if(i==330){
obstacleList.add(new Obstacle(620,i,3,this));
obstacleList.add(new Obstacle(645,i,4,this));
}else{
obstacleList.add(new Obstacle(620,i,5,this));
obstacleList.add(new Obstacle(645,i,6,this));
}
}
obstacleList.add(new Obstacle(300,330,0,this));
for(int i=270;i<=330;i+=30){
if(i==270||i==330){
obstacleList.add(new Obstacle(i,360,0,this));
}else{
obstacleList.add(new Obstacle(i,360,7,this));
}
}
for(int i=240;i<=360;i+=30){
if(i==240||i==360){
obstacleList.add(new Obstacle(i,390,0,this));
}else{
obstacleList.add(new Obstacle(i,390,7,this));
}
}
obstacleList.add(new Obstacle(240,300,0,this));
for(int i=360;i<=540;i+=60){
obstacleList.add(new Obstacle(i,270,7,this));
}
enemyList.add(new Enemy(75,420,true,2,328,418,this));
enemyList.add(new Enemy(635,420,true,2,298,388,this));
enemyList.add(new Enemy(200,385,true,1,this));
enemyList.add(new Enemy(500,385,true,1,this));
}
if(sort==3){
for(int i=0;i<27;i++){
obstacleList.add(new Obstacle(i*30,420,1,this));
}
for(int j=0;j<=120;j+=30){
for(int i=0;i<27;i++){
obstacleList.add(new Obstacle(i*30,570-j,2,this));
}
}
int temp=290;
for(int i=390;i>=270;i-=30) {
for (int j = temp; j <= 410; j += 30) {
obstacleList.add(new Obstacle(j, i, 7, this));
}
temp += 30;
}
temp=60;
for(int i=390;i>=360;i-=30){
for(int j=temp;j<=90;j+=30){
obstacleList.add(new Obstacle(j,i,7,this));
}
temp+=30;
}
gan=StaticValue.gan;
tower=StaticValue.tower;
obstacleList.add(new Obstacle(515,220,8,this));
enemyList.add(new Enemy(150,385,true,1,this));
}
}
public BufferedImage getBgImage() {
return bgImage;
}
public int getSort() {
return sort;
}
public boolean isFlag() {
return flag;
}
public List<Obstacle> getObstacleList() {
return obstacleList;
}
public BufferedImage getGan() {
return gan;
}
public BufferedImage getTower() {
return tower;
}
public boolean isReach() {
return isReach;
}
public void setReach(boolean reach) {
isReach = reach;
}
public boolean isBase() {
return isBase;
}
public void setBase(boolean base) {
isBase = base;
}
public List<Enemy> getEnemyList() {
return enemyList;
}
}
敌人类
package com.sxt;
import java.awt.image.BufferedImage;
public class Enemy implements Runnable{
private int x, 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.bg=bg;
this.type=type;
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.bg=bg;
this.type=type;
this.max_up=max_up;
this.max_down=max_down;
show=StaticValue.mogu.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();
}
}
}
}
马里奥类
Mario
package com.sxt;
import java.awt.image.BufferedImage;
public class Mario implements Runnable{
private int x;
public int y;
private String status;
private BufferedImage show=null;
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 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 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 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;
}
}
Music类
实现背景音乐
package com.sxt;
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")+"/SuperMairo/src/Music/music.wav";
BufferedInputStream name=new BufferedInputStream(new FileInputStream(str));
player =new Player(name);
player.play();
}
}
MyFrame
package com.sxt;
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.lang.reflect.GenericArrayType;
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);
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 (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.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();
}
}
}
}
Obstacle障碍物实现
package com.sxt;
import java.awt.image.BufferedImage;
public class Obstacle implements Runnable{
private int x;
private int y;
private int type;
private BufferedImage show =null;
private BackGround bg=null;
private Thread thread=new Thread(this);
public Obstacle(int x,int y,int type,BackGround bg){
this.x=x;
this.y=y;
this.type=type;
this.bg=bg;
show=StaticValue.obstacle.get(type);
if(type==8){
thread.start();
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getType() {
return type;
}
public BufferedImage getShow() {
return show;
}
@Override
public void run() {
while(true){
if(this.bg.isReach()){
if(this.y<374){
this.y+=5;
}else{
this.bg.setBase(true);
}
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
StaticValue
package com.sxt;
import javax.imageio.ImageIO;
import java.awt.*;
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 = System.getProperty("user.dir") + "/SuperMairo/src/images/";
//初始化方法
public static void init() {
try {
//加载背景图片
bg = ImageIO.read(new File(path + "bg.png"));
bg2 = ImageIO.read(new File(path + "bg2.png"));
//加载马里奥向左站立
stand_L = ImageIO.read(new File(path + "s_mario_stand_L.png"));
//加载马里奥向右站立
stand_R = ImageIO.read(new File(path + "s_mario_stand_R.png"));
//加载城堡
tower = ImageIO.read(new File(path + "tower.png"));
//加载旗杆
gan = ImageIO.read(new File(path + "gan.png"));
//加载马里奥向左跳跃
jump_L = ImageIO.read(new File(path + "s_mario_jump1_L.png"));
//加载马里奥向右跳跃
jump_R = ImageIO.read(new File(path + "s_mario_jump1_R.png"));
} catch (IOException e) {
e.printStackTrace();
}
//加载马里奥向左跑
for (int i = 1;i <= 2;i++) {
try {
run_L.add(ImageIO.read(new File(path + "s_mario_run"+ i +"_L.png")));
} catch (IOException e) {
e.printStackTrace();
}
}
//加载马里奥向右跑
for (int i = 1;i <= 2;i++) {
try {
run_R.add(ImageIO.read(new File(path + "s_mario_run"+ i +"_R.png")));
} catch (IOException e) {
e.printStackTrace();
}
}
try {
//加载障碍物
obstacle.add(ImageIO.read(new File(path + "brick.png")));
obstacle.add(ImageIO.read(new File(path + "soil_up.png")));
obstacle.add(ImageIO.read(new File(path + "soil_base.png")));
} catch (IOException e) {
e.printStackTrace();
}
//加载水管
for (int i = 1;i <= 4;i++) {
try {
obstacle.add(ImageIO.read(new File(path + "pipe"+ i +".png")));
} catch (IOException e) {
e.printStackTrace();
}
}
//加载不可破坏的砖块和旗子
try {
obstacle.add(ImageIO.read(new File(path + "brick2.png")));
obstacle.add(ImageIO.read(new File(path + "flag.png")));
} catch (IOException e) {
e.printStackTrace();
}
//加载蘑菇敌人
for (int i = 1;i <= 3;i++) {
try {
mogu.add(ImageIO.read(new File(path + "fungus"+i+".png")));
} catch (IOException e) {
e.printStackTrace();
}
}
//加载食人花敌人
for (int i = 1;i <= 2;i++) {
try {
flower.add(ImageIO.read(new File(path + "flower1."+i+".png")));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这是所需背景图片
背景音乐不加可以直接把音乐类删除,只是运行时没有背景音乐。
想加背景音乐可以
按以下步骤
导入所需包,文件这个上传不了。
参考视频