信息发布→ 登录 注册 退出

Java实现经典游戏超级玛丽的示例代码

发布时间:2026-01-11

点击量:
目录
  • 前言
  • 主要设计
  • 功能截图
  • 代码实现
    • 游戏主界面
    • 马里奥
    • 小怪
  • 总结

    前言

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

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

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

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

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

    主要需求

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

    主要设计

    1、游戏背景的设计

    2、地图的显示

    3、台阶的显示

    4、游戏物品的显示

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

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

    7、游戏的分数系统设计

    8、地图变动功能

    9、射击功能

    10、游戏采用多线程技术

    11、背景音乐设计

    功能截图

    游戏开始:

    超级玛丽跳动

    换地图

    过了这一关

    代码实现

    游戏主界面

    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最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。

    以上就是Java实现经典游戏超级玛丽的示例代码的详细内容,更多关于Java超级玛丽游戏的资料请关注其它相关文章!

    在线客服
    服务热线

    服务热线

    4008888355

    微信咨询
    二维码
    返回顶部
    ×二维码

    截屏,微信识别二维码

    打开微信

    微信号已复制,请打开微信添加咨询详情!