Java实现超级玛丽

创建MyFrame类

import com.laoma.obj.*;
import com.laoma.util.BackGround;
import com.laoma.util.Start;
import com.laoma.util.StaticValue;
import jdk.jshell.Snippet;
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 Start s = new Start();
    //用于双缓存
    private Image offScreenImage = null;
    //马里奥对象
    private Mario mario = new Mario();
    //实现马里奥线程
    private Thread thread = new Thread(this);

    public MyFrame() {
        //设置标题
        this.setTitle("老马麻里奥");
        //设置窗口大小
        this.setSize(800, 600);
        //设置窗口居中显示
        this.setLocationRelativeTo(null);
        //设置窗口关闭
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置窗口大小不可变
        this.setResizable(false);
        //添加键盘监听
        this.addKeyListener(this);
        //让窗口显示
        this.setVisible(true);
        //初始化图片
        StaticValue.init();
        //初始化马里奥
        mario = new Mario(10, 355, getHeight(), getWidth());
        //创建全部场景
        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) {
//            throw new RuntimeException(e);
//        } catch (JavaLayerException e) {
//            throw new RuntimeException(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(s.getsImage(), 0, 0, this);*/
        //绘制背景
        graphics.drawImage(nowBg.getBgImage(), 0, 0, this);
        //绘制敌人
        for (Enemy e : nowBg.getEnemyList()) {
            graphics.drawImage(e.getShow(), e.getX(), e.getY(), this);
        }
        //绘制道具
        for (DaoJu daoJu : nowBg.getDjlist()) {
            graphics.drawImage(daoJu.getShow(), daoJu.getX(), daoJu.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);
        //绘制马里奥
        if (!mario.isBig()) {
            graphics.drawImage(mario.getShow(), mario.getX(), mario.getY(), 25, 25, this);
        } else {
            graphics.drawImage(mario.getShow(), mario.getX(), mario.getY() - 15, 28, 40, this);
        }
        //绘制火球
        for (HuoQiu huoQiu : nowBg.getHuoQius()) {
            graphics.drawImage(huoQiu.getShow(), huoQiu.getX(), huoQiu.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();
        }
        //发射火球
        if (e.getKeyCode() == 32) {
            mario.fire();
        }
        //向右奔跑
        if (e.isShiftDown() && e.getKeyCode() == 39) {
            mario.rightSpeed();
        }
        //向左奔跑
        if (e.isShiftDown() && e.getKeyCode() == 37) {
    }
        /*//暂停
        if (e.isAltDown()) {
                JOptionPane.showMessageDialog(this, "暂停");
        }*/
    }

    //松开键盘调用
    @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(395);
                }
                //判断马里奥是否死亡
                if (mario.isDeath()) {
                    JOptionPane.showMessageDialog(this, "马里奥死了");
                    System.exit(0);
                }
                //判断游戏是否结束
                if (mario.isOk()) {
                    JOptionPane.showMessageDialog(this, "恭喜,通关!");
                    System.exit(0);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

创建背景Background类

import com.laoma.obj.DaoJu;
import com.laoma.obj.Enemy;
import com.laoma.obj.HuoQiu;
import com.laoma.obj.Obstacle;

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 List<DaoJu> djlist = new ArrayList<>();
    //用于存放火球
    private List<HuoQiu> huoQius = new ArrayList<>();
    //判断马里奥是否到达旗杆位置
    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, 2, this));
            }
            for (int j = 0; j <= 120; j += 30) {
                for (int i = 0; i < 27; i++) {
                    obstacleList.add(new Obstacle(i * 30, 570 - j, 1, this));
                }
            }
            //绘制 砖块
            for (int i = 120; i <= 150; i += 30) {
                obstacleList.add(new Obstacle(i, 300, 3, 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, 3, this));
                } else {
                    obstacleList.add(new Obstacle(i, 300, 0, this));
                }
            }
            for (int i = 420; i <= 450; i += 30) {
                obstacleList.add(new Obstacle(i, 240, 3, this));
            }
            obstacleList.add(new Obstacle(210, 300, 3, this));
            //绘制水管
            for (int i = 360; i <= 600; i += 25) {
                if (i == 360) {
                    obstacleList.add(new Obstacle(620, i, 5, this));
                    obstacleList.add(new Obstacle(645, i, 6, this));
                } else {
                    obstacleList.add(new Obstacle(620, i, 7, this));
                    obstacleList.add(new Obstacle(645, i, 8, this));
                }
            }
            //绘制道具方块
            obstacleList.add(new Obstacle(180, 300, 9, this));
            //绘制蘑菇敌人
            enemyList.add(new Enemy(580, 385, 1, true, this));
            //绘制食人花敌人
            enemyList.add(new Enemy(635, 420, 2, true, this, 328, 428));
            //绘制乌龟敌人
            enemyList.add(new Enemy(280, 385, 3, true, this));
        }
        //判断是否为第二关
        if (sort == 2) {
            for (int i = 0; i <= 27; i++) {
                obstacleList.add(new Obstacle(i * 30, 420, 2, this));
            }
            for (int j = 0; j <= 120; j += 30) {
                for (int i = 0; i < 27; i++) {
                    obstacleList.add(new Obstacle(i * 30, 570 - j, 1, this));
                }
            }
            //绘制第一根水管
            for (int i = 360; i <= 600; i += 25) {
                if (i == 360) {
                    obstacleList.add(new Obstacle(60, i, 5, this));
                    obstacleList.add(new Obstacle(85, i, 6, this));
                } else {
                    obstacleList.add(new Obstacle(60, i, 7, this));
                    obstacleList.add(new Obstacle(85, i, 8, this));
                }
            }
            //绘制第二根水管
            for (int i = 330; i <= 600; i += 25) {
                if (i == 330) {
                    obstacleList.add(new Obstacle(620, i, 5, this));
                    obstacleList.add(new Obstacle(645, i, 6, this));
                } else {
                    obstacleList.add(new Obstacle(620, i, 7, this));
                    obstacleList.add(new Obstacle(645, i, 8, 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, 3, 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, 3, this));
                }
            }
            obstacleList.add(new Obstacle(240, 300, 0, this));
            for (int i = 360; i <= 540; i += 60) {
                obstacleList.add(new Obstacle(i, 270, 3, this));
            }
            //绘制道具方块
            obstacleList.add(new Obstacle(210, 300, 9, this));
            //绘制第二关第一个蘑菇敌人
            enemyList.add(new Enemy(200, 385, 1, true, this));
            //绘制第二关第二个蘑菇敌人
            enemyList.add(new Enemy(500, 385, 1, true, this));
            //绘制第二关第一个食人花敌人
            enemyList.add(new Enemy(75, 420, 2, true, this, 328, 428));
            //绘制第二关第二个食人花敌人
            enemyList.add(new Enemy(635, 420, 2, true, this, 298, 388));
            //第二关乌龟敌人
            enemyList.add(new Enemy(580, 385, 3, true, this));
        }
        //判断是否为第三关
        if (sort == 3) {
            for (int i = 0; i <= 27; i++) {
                obstacleList.add(new Obstacle(i * 30, 420, 2, this));
            }
            for (int j = 0; j <= 120; j += 30) {
                for (int i = 0; i < 27; i++) {
                    obstacleList.add(new Obstacle(i * 30, 570 - j, 1, 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, 3, 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, 3, this));
                }
                temp += 30;
            }
            //绘制旗杆
            gan = StaticValue.gan;
            //绘制城堡
            tower = StaticValue.tower;
            //把旗子添加到旗杆上
            obstacleList.add(new Obstacle(515, 220, 4, this));
            //绘制第三关蘑菇敌人
            enemyList.add(new Enemy(150, 385, 1, true, 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;
    }
    
    public List<DaoJu> getDjlist() {
        return djlist;
    }
    public List<HuoQiu> getHuoQius() {
        return huoQius;
    }

   
}

创建敌人类Enemy类

import com.laoma.util.BackGround;
import com.laoma.util.StaticValue;

import java.awt.*;
import java.awt.image.BufferedImage;

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() {
    }

    //蘑菇敌人
    public Enemy(int x, int y, int type, boolean face_to, BackGround bg) {
        this.x = x;
        this.y = y;
        this.type = type;
        this.face_to = face_to;
        this.bg = bg;
        show = StaticValue.mogu.get(0);
        thread.start();
    }

    //食人花敌人
    public Enemy(int x, int y, int type, boolean face_to, BackGround bg, int max_up, int max_down) {
        this.x = x;
        this.y = y;
        this.type = type;
        this.face_to = face_to;
        this.bg = bg;
        this.max_up = max_up;
        this.max_down = max_down;
        show = StaticValue.flower.get(0);
        thread.start();
    }

    //死亡方法
    public void death() {
        if (this.getType() == 1) {
            show = StaticValue.mogu.get(2);
            this.bg.getEnemyList().remove(this);
        } else if (this.getType() == 3) {
            //this.bg.getEnemyList().remove(this);
            show = StaticValue.shell.get(0);
            type = 4;
        } else if (this.getType() == 4) {
            this.bg.getEnemyList().remove(this);
        }
    }

    @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);
            } else if (type == 3) {
                //判断乌龟
                if (face_to) {
                    this.x -= 2;
                    show = StaticValue.toise_L.get(image_type);
                } else {
                    this.x += 2;
                    show = StaticValue.toise_R.get(image_type);
                }
                image_type = image_type == 1 ? 0 : 1;
            } else if (type == 4) {
                //判断龟壳
                if (face_to) {
                    this.x -= 5;
                } else {
                    this.x += 5;
                }
                image_type = image_type == 1 ? 0 : 1;
                show = StaticValue.shell.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)) {
                    canLeft = false;
                }
                //判断是否可以向右走
                if (ob1.getX() == this.x + 36 && (ob1.getY() + 65 > this.y && ob1.getY() - 35 < this.y)) {
                    canRight = 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) {
                throw new RuntimeException(e);
            }
        }
    }
    public Rectangle getRec(){
        return new Rectangle(this.x,this.y,35,35);
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    public int getType() {
        return type;
    }
    
    public BufferedImage getShow() {
        return show;
    }
    
}

创建道具类DaoJu类

import com.laoma.util.BackGround;
import com.laoma.util.StaticValue;

import java.awt.image.BufferedImage;

public class DaoJu implements Runnable {
    //位置
    private int x;

    private int y;
    //显示当前图片状态
    private BufferedImage show;
    //类型
    private int type;
    //定义一个背景图像
    private BackGround bg;
    //图片状态
    private int image_type=0;
    //定义一个线程
    private Thread thread = new Thread(this);

    public DaoJu() {
    }

    public DaoJu(int x, int y, int type,BackGround bg) {
        this.x = x;
        this.y = y;
        this.type = type;
        this.bg = bg;
        show = StaticValue.mg.get(0);
        thread.start();
    }

    //吃掉道具
    public void eat() {
        this.bg.getDjlist().remove(this);
    }

    @Override
    public void run() {
        while (true) {
            //判断道具类型0
            if (type == 0) {
                image_type = image_type == 1 ? 1 : 0;
                show = StaticValue.mg.get(image_type);
            } else if (type == 1) {
                show = StaticValue.xh;
            } else if (type == 2) {
                image_type = image_type == 1 ? 1 : 0;
                show = StaticValue.jinBi.get(image_type);
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public BufferedImage getShow() {
        return show;
    }
    
    public int getType() {
        return type;
    }
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值