欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)經(jīng)典游戲超級(jí)瑪麗的示例代碼

 更新時(shí)間:2022年02月21日 08:59:36   作者:小虛竹and掘金  
在你的童年記憶里,是否有一個(gè)蹦跳、頂蘑菇的小人?本文將用java語(yǔ)言實(shí)現(xiàn)經(jīng)典游戲《超級(jí)瑪麗》,文中采用了swing技術(shù)進(jìn)行了界面化處理,需要的可以參考一下

前言

在你的童年記憶里,是否有一個(gè)蹦跳、頂蘑菇的小人?

如果你回憶起了它,你定然會(huì)覺(jué)得現(xiàn)在它幼稚、無(wú)聊,畫(huà)面不漂亮,游戲不精彩……但請(qǐng)你記住:這才是真正的游戲,它給了你無(wú)限的歡樂(lè)!

馬里奧是靠吃蘑菇成長(zhǎng),聞名世界的超級(jí)巨星。特征是大鼻子、頭戴帽子、身穿背帶工作服、還留著胡子。

如此經(jīng)典的游戲,你怎么能錯(cuò)過(guò),快來(lái)玩玩吧。

《超級(jí)瑪麗》游戲是用java語(yǔ)言實(shí)現(xiàn),采用了swing技術(shù)進(jìn)行了界面化處理,設(shè)計(jì)思路用了面向?qū)ο笏枷搿?/p>

主要需求

游戲劇情模擬超級(jí)瑪麗,用swing來(lái)做界面化處理,學(xué)會(huì)利用面向?qū)ο蟮乃枷雽?shí)現(xiàn)這個(gè)游戲

主要設(shè)計(jì)

1、游戲背景的設(shè)計(jì)

2、地圖的顯示

3、臺(tái)階的顯示

4、游戲物品的顯示

5、超級(jí)瑪麗的設(shè)計(jì),左右移動(dòng)能力、跳動(dòng)能力

6、小怪的設(shè)計(jì),包含出現(xiàn)的地點(diǎn)、殺傷功能、跳動(dòng)能力

7、游戲的分?jǐn)?shù)系統(tǒng)設(shè)計(jì)

8、地圖變動(dòng)功能

9、射擊功能

10、游戲采用多線(xiàn)程技術(shù)

11、背景音樂(lè)設(shè)計(jì)

功能截圖

游戲開(kāi)始:

超級(jí)瑪麗跳動(dòng)

換地圖

過(guò)了這一關(guān)

代碼實(shí)現(xiàn)

游戲主界面

public class MyFrame extends JFrame implements KeyListener,Runnable {
    //用于存儲(chǔ)所有的背景
    private List<BackGround> allBg = new ArrayList<>();
    //用于存儲(chǔ)當(dāng)前的背景
    private BackGround nowBg = new BackGround();
    //用于雙緩存
    private Image offScreenImage = null;
    //馬里奧對(duì)象
    private Mario mario = new Mario();
    //定義一個(gè)線(xiàn)程對(duì)象,用于實(shí)現(xiàn)馬里奧的運(yùn)動(dòng)
    private Thread thread = new Thread(this);

    public MyFrame() {
        //設(shè)置窗口的大小為800 * 600
        this.setSize(800,600);
        //設(shè)置窗口居中顯示
        this.setLocationRelativeTo(null);
        //設(shè)置窗口的可見(jiàn)性
        this.setVisible(true);
        //設(shè)置點(diǎn)擊窗口上的關(guān)閉鍵,結(jié)束程序
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //設(shè)置窗口大小不可變
        this.setResizable(false);
        //向窗口對(duì)象添加鍵盤(pán)監(jiān)聽(tīng)器
        this.addKeyListener(this);
        //設(shè)置窗口名稱(chēng)
        this.setTitle("超級(jí)瑪麗");
        //初始化圖片
        StaticValue.init();
        //初始化馬里奧
        mario = new Mario(10,355);
        //創(chuàng)建全部的場(chǎng)景
        for (int i = 1;i <= 3;i++) {
            allBg.add(new BackGround(i, i == 3 ? true : false));
        }
        //將第一個(gè)場(chǎng)景設(shè)置為當(dāng)前場(chǎng)景
        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);

        //添加分?jǐn)?shù)
        Color c = graphics.getColor();
        graphics.setColor(Color.BLACK);
        graphics.setFont(new Font("黑體",Font.BOLD,25));
        graphics.drawString("當(dāng)前的分?jǐn)?shù)為: " + 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) {

    }
    //當(dāng)鍵盤(pán)按下按鍵時(shí)調(diào)用
    @Override
    public void keyPressed(KeyEvent e) {
        //向右移動(dòng)
        if (e.getKeyCode() == 39) {
            mario.rightMove();
        }
        //向左移動(dòng)
        if (e.getKeyCode() == 37) {
            mario.leftMove();
        }
        //跳躍
        if (e.getKeyCode() == 38) {
            mario.jump();
        }
    }
    //當(dāng)鍵盤(pán)松開(kāi)按鍵時(shí)調(diào)用
    @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);
                }

                //判斷游戲是否結(jié)束
                if (mario.isOK()) {
                    JOptionPane.showMessageDialog(this,"恭喜你!成功通關(guān)了");
                    System.exit(0);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

馬里奧

public class Mario implements Runnable{
    //用于表示橫縱坐標(biāo)
    private int x;
    private int y;
    //用于表示當(dāng)前的狀態(tài)
    private String status;
    //用于顯示當(dāng)前狀態(tài)對(duì)應(yīng)的圖像
    private BufferedImage show = null;
    //定義一個(gè)BackGround對(duì)象,用來(lái)獲取障礙物的信息
    private BackGround backGround = new BackGround();
    //用來(lái)實(shí)現(xiàn)馬里奧的動(dòng)作
    private Thread thread = null;
    //馬里奧的移動(dòng)速度
    private int xSpeed;
    //馬里奧的跳躍速度
    private int ySpeed;
    //定義一個(gè)索引
    private int index;
    //表示馬里奧上升的時(shí)間
    private int upTime = 0;
    //用于判斷馬里奧是否走到了城堡的門(mén)口
    private boolean isOK;
    //用于判斷馬里奧是否死亡
    private boolean isDeath = false;
    //表示分?jǐn)?shù)
    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;
    }

    //馬里奧向左移動(dòng)
    public void leftMove() {
        //改變速度
        xSpeed = -5;
        //判斷馬里奧是否碰到旗子
        if (backGround.isReach()) {
            xSpeed = 0;
        }

        //判斷馬里奧是否處于空中
        if (status.indexOf("jump") != -1) {
            status = "jump--left";
        }else {
            status = "move--left";
        }
    }

    //馬里奧向右移動(dòng)
    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;
            //判斷馬里奧是否到達(dá)旗桿位置
            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 {
                //遍歷當(dāng)前場(chǎng)景里所有的障礙物
                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;
                    }

                    //判斷是否跳起來(lái)頂?shù)酱u塊
                    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();
                    }
                }

                //進(jìn)行馬里奧跳躍的操作
                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;
                }
            }
            //判斷當(dāng)前是否是移動(dòng)狀態(tài)
            if (status.contains("move")) {
                index = index == 0 ? 1 : 0;
            }
            //判斷是否向左移動(dòng)
            if ("move--left".equals(status)) {
                show = StaticValue.run_L.get(index);
            }
            //判斷是否向右移動(dòng)
            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{
    //存儲(chǔ)當(dāng)前坐標(biāo)
    private int x;
    private int y;
    //存儲(chǔ)敵人類(lèi)型
    private int type;
    //判斷敵人運(yùn)動(dòng)的方向
    private boolean face_to = true;
    //用于顯示敵人的當(dāng)前圖像
    private BufferedImage show;
    //定義一個(gè)背景對(duì)象
    private BackGround bg;
    //食人花運(yùn)動(dòng)的極限范圍
    private int max_up = 0;
    private int max_down = 0;
    //定義線(xiàn)程對(duì)象
    private Thread thread = new Thread(this);
    //定義當(dāng)前的圖片的狀態(tài)
    private int image_type = 0;

    //蘑菇敵人的構(gòu)造函數(shù)
    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();
    }
    //食人花敵人的構(gòu)造函數(shù)
    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);
            }

            //定義兩個(gè)布爾變量
            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;

                //食人花是否到達(dá)極限位置
                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();
            }

        }
    }
}

總結(jié)

通過(guò)此次的《超級(jí)瑪麗》游戲?qū)崿F(xiàn),讓我對(duì)JAVA的相關(guān)知識(shí)有了進(jìn)一步的了解,對(duì)java這門(mén)語(yǔ)言也有了比以前更深刻的認(rèn)識(shí)。

java的一些基本語(yǔ)法,比如數(shù)據(jù)類(lèi)型、運(yùn)算符、程序流程控制和數(shù)組等,理解更加透徹。java最核心的核心就是面向?qū)ο笏枷耄瑢?duì)于這一個(gè)概念,終于悟到了一些。

以上就是Java實(shí)現(xiàn)經(jīng)典游戲超級(jí)瑪麗的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Java超級(jí)瑪麗游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談IDEA2018打包可執(zhí)行jar包的流程

    淺談IDEA2018打包可執(zhí)行jar包的流程

    這篇文章主要介紹了淺談IDEA2018打包可執(zhí)行jar包的流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 使用RabbitMQ實(shí)現(xiàn)延時(shí)消息自動(dòng)取消的案例詳解

    使用RabbitMQ實(shí)現(xiàn)延時(shí)消息自動(dòng)取消的案例詳解

    這篇文章主要介紹了使用RabbitMQ實(shí)現(xiàn)延時(shí)消息自動(dòng)取消的簡(jiǎn)單案例,案例代碼包括導(dǎo)包的過(guò)程和相關(guān)配置文件,本文結(jié)合代碼給大家講解的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • 一篇文章弄懂Mybatis中#和$的區(qū)別

    一篇文章弄懂Mybatis中#和$的區(qū)別

    mybatis為我們提供了兩種支持動(dòng)態(tài)sql的語(yǔ)法#{}以及${},兩者都是動(dòng)態(tài)的向sql語(yǔ)句中傳入需要的參數(shù),下面這篇文章主要給大家介紹了如何通過(guò)一篇文章弄懂Mybatis中#和$區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • mybatis中mapper-locations的作用

    mybatis中mapper-locations的作用

    這篇文章主要介紹了mybatis中mapper-locations的具體作用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • SpringBoot中自定義參數(shù)綁定步驟詳解

    SpringBoot中自定義參數(shù)綁定步驟詳解

    這篇文章主要介紹了SpringBoot中自定義參數(shù)綁定步驟詳解,非常不錯(cuò),具有參考借鑒價(jià)值 ,需要的朋友可以參考下
    2018-02-02
  • java.net.UnknownHostException異常的一般原因及解決步驟

    java.net.UnknownHostException異常的一般原因及解決步驟

    關(guān)于java.net.UnknownHostException大家也許都比較熟悉,這篇文章主要給大家介紹了關(guān)于java.net.UnknownHostException異常的一般原因及解決步驟,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • java基于控制臺(tái)的學(xué)生學(xué)籍管理系統(tǒng)

    java基于控制臺(tái)的學(xué)生學(xué)籍管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java基于控制臺(tái)的學(xué)生學(xué)籍管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • SpringBoot如何監(jiān)控Redis中某個(gè)Key的變化(自定義監(jiān)聽(tīng)器)

    SpringBoot如何監(jiān)控Redis中某個(gè)Key的變化(自定義監(jiān)聽(tīng)器)

    這篇文章主要介紹了SpringBoot如何監(jiān)控Redis中某個(gè)Key的變化(自定義監(jiān)聽(tīng)器),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • ES模糊查詢(xún)失效的坑以及解決方案

    ES模糊查詢(xún)失效的坑以及解決方案

    ES的查詢(xún)?cè)硎前捶衷~建立索引,根據(jù)要保存的內(nèi)容先分詞,然后按照分詞的結(jié)果建立索引,這篇文章主要給大家介紹了關(guān)于ES模糊查詢(xún)失效的坑及解決方案的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • JXLS根據(jù)模板導(dǎo)出Excel實(shí)例教程

    JXLS根據(jù)模板導(dǎo)出Excel實(shí)例教程

    這篇文章主要為大家詳細(xì)介紹了JXLS根據(jù)模板導(dǎo)出Excel實(shí)例教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12

最新評(píng)論