ホームページ  >  記事  >  Java  >  Java で Snake War ミニゲームを実装する方法

Java で Snake War ミニゲームを実装する方法

WBOY
WBOY転載
2023-04-26 08:55:061737ブラウズ

1. 開発環境とゲーム表示

Snake War の設計と実験のプロセスは、Window 10 システムと開発ツール IntelliJ IDEA Community Edition 2020.3.2 (jdk-15) で実行する必要があります。 ) コードの作成、コンパイル、デバッグ、テストなどを完了します。ヘビの頭、体、背景画像など、プログラムに必要なコンポーネントはすべて、画像ソフトウェア Adob​​e Photoshop 2020 を使用して作成されています。

1.1 ゲームメインインターフェース

Java で Snake War ミニゲームを実装する方法

1.2 モバイルインターフェース

Java で Snake War ミニゲームを実装する方法

##1.3 報酬インターフェース

1. ゲームが 50 ポイントに到達:

Java で Snake War ミニゲームを実装する方法

2. ゲームが 100 ポイントに到達:

Java で Snake War ミニゲームを実装する方法##1.4 F 加速機能インターフェイス

F を押すと速度が 100 に増加します。

Java で Snake War ミニゲームを実装する方法1.5 Death インターフェイス

Java で Snake War ミニゲームを実装する方法2. 要件分析

スネーク ゲームは小さなパズルですゲームは、人々の日常のレジャー、エンターテイメント、その他のシナリオで使用できます。このゲーム設計には、1 次元配列、Swing の共通コンポーネント、GUI でのイベント処理 (イベント リスナー、キーボード リスナー)、クラスのカプセル化と継承、静的変数、パッケージ化クラス、乱数などの知識が含まれます。

特定の要件は次のように要約されます:

1. 初期化インターフェイスのサイズは 800×800 で、ゲーム インターフェイスは画面の中央に維持され、ウィンドウは「Snake」という単語がある;

2. ゲーム インターフェイスには、ゲーム スコアとスネークの現在の速度を求めるために必要なプロンプト テキストが必要です。開始インターフェイスには操作プロンプトのテキスト (スペース ゲームをタップしてゲームを開始/一時停止し、F を押し続けると加速) が表示され、テキストの色は美しくなければなりません;

3. ヘビの位置を初期化します。プログラム (パネルの左側付近)、ヘビの方向 (デフォルトは右)、ヘビの長さ (デフォルトは 3)、および食べ物の位置を初期化します。 4. ゲームの開始と一時停止の実装: スペース バーを使用してゲームの開始と一時停止を制御します。一時停止;

5. ヘビの移動機能の実現: W、S、A、D または&uar;、↓、←、→ でヘビの移動方向を上下左右に制御します。 Game;

6. ヘビの頭がアクティビティの周囲に触れたとき:スネークヘッドがインターフェースの右端(左)に触れると、対称の左(右)端から出現し、同様にスネークヘッドがインターフェースの上端(下)端に触れると、対称の左(右)端から出現します。対称性の下端 (上端);

7. ヘビの餌を食べる機能の実現: ゲーム中、ヘビの頭が餌に触れると、ヘビは餌を食べます。このとき、ヘビの長さは 1 増加し、速度は 10 増加し、スコアは 10 増加し、餌の位置は更新されます (ランダムな位置);

8. スネーク加速機能の実装: 「F」キーを押し続けると、スネークが加速し、速度値が 100 に達します。「F」キーを放すと、スネークはデフォルトの速度 10 に戻ります。

#9. ヘビの死の判定: ヘビの頭がヘビの体に触れると、ヘビは死にます。ゲームは終了し、インターフェイスの中央近くに次のメッセージが表示されます。「あなたの小さなヘビは死にました。スペースを押してやり直してください!」 ";

10. ゲームの報酬メカニズムの実装: スコアが 10 の場合、ゲームは「Good !」をプロンプトし、スコアが 50 の場合、ゲームは「Good !!!」をプロンプトします。 100 の場合、ゲームは「完璧!!!」と表示します。スコアが 200 に達すると、ゲームは「止められない!!!」と表示します。上記のプロンプト ワードはすべてスネーク ヘッドにあります。

# #基本動作表は以下のとおりです:

3. システム設計

3.1 システム全体の機能設計

Java で Snake War ミニゲームを実装する方法This Snakeプログラムには一般に、スネークの移動機能、スネークのアクティブ加速機能、ゲームルール判定機能、メインインターフェイス制御機能、貪欲なスネークが食べ物を食べる機能が含まれています。このうち、ヘビの移動機能には、移動方向のキー制御とヘビの自動移動が含まれ、ゲームルール判定機能には、ヘビの死亡判定、ゲームの開始と一時停止の判定、および場外ルールが含まれます。主なインターフェース制御機能には、ヘビの初期化と餌の初期化が含まれ、貪欲なヘビが餌を食べる機能には、ヘビの体の成長、ヘビの速度の増加、ポイントの増加、餌の更新位置が含まれます。具体的な機能構成図は以下のとおりです。

3.2 全体的なシステム処理設計

Snake プログラムに入るときは、まずスペースバーが押されたかどうかを判断し、スペースバーが押された場合はゲームが開始されます。ゲーム開始後、キー入力の有無を判定し、キー入力があればキー設定に応じてヘビの移動方向を変更または加速し、キー操作がなければヘビはそのまま移動を続けます。本来の方向性。ヘビの移動中に、ヘビがエサを食べたかどうかが判断され、エサを食べた場合、ゲームのスコアが 10 増加し、それに応じてヘビの移動速度も増加します。ヘビが死んだかどうかを判定し、ヘビが死んだ場合はゲーム終了、ヘビが死んでいない場合は引き続きスペース入力があるかどうかを判定し、スペース入力があった場合はゲームを一時停止します。キーを判断し続け、キーに応じてヘビの動作状態を変更し、ヘビが死んでゲームが終了するまでゲームを継続します。

Java で Snake War ミニゲームを実装する方法

4. 機能設計

4.1 スネークの移動と加速関数の設計

スネークの移動機能は主に選択に依存しますステートメントとキーボード モニターはW、S、A、D または ↑、↓、←、→ を使用して、ヘビの移動方向を上下左右に制御してゲームをプレイします。 F キーを押すと、ヘビが加速します。

Java で Snake War ミニゲームを実装する方法

4.2 貪欲なヘビの餌を食べる加速と死の判定関数の設計

貪欲なヘビの餌を食べることと死の判定のプロセスでは、次のことが行われます。パラメータ:

  • Timer クラスのパラメータ: int 型の time. timer.setDelay(time) メソッドがプログラム内で呼び出され、タイマー (時間が小さいほど、ヘビの動きは速くなります) ;

  • ヘビが死んだかどうかを記録するパラメータ: ブール型の isDied (true はヘビが死ぬことを意味し、false はヘビが生きていることを意味します) )、デフォルトは false;

  • ヘビの長さ: int 型の長さ (最初は 3);

  • 整数パラメータ: スコアint 型 (最初は 0) で、食べるたびにプログラムのループによって制御されます 食べ物は 10 ポイントを追加します;

  • ヘビの頭の座標:snakeX[0] とsnakeY int 型の [0]、スネーク頭の水平座標と垂直座標をそれぞれ保存します;

  • スネーク本体の座標: int 型のsnakeX[i] およびsnakeY[i] []、ヘビの体の各セクションの水平座標と垂直座標 (i≠0) をそれぞれ格納します;

  • 食べ物の座標: int 型 foodX、foodY、水平座標と垂直座標を格納しますfoodX と foodY は、Random クラスの nextInt() メソッドを使用して生成された乱数であるため、食べ物の座標はランダムです。

上記のパラメータを以下で使用する場合の詳細については説明しません。

4.2.1 貪欲なヘビの餌を食べる加速関数の設計

ヘビの頭のsnakeX[0]とsnakeY[0]の座標がfoodXとsnakeY[0]の座標と等しい場合それぞれ foodY の場合、スコアは 10 追加され、ヘビの体の長さが 1 増加し、タイマー パラメーターの時間が 10 減少します。これにより、ヘビが食物を食べた後に追加のポイントが完了し、ヘビの体が長くなり、機能が加速されます。 。この機能の処理設計図は以下のとおりです。

Java で Snake War ミニゲームを実装する方法

4.2.2 ヘビ死亡判定関数の設計

貪欲なヘビが自分自身を食べると、ヘビは死、つまり、ヘビの頭の座標snakeX[0]とsnakeY[0]が、それぞれヘビ​​の体の座標snakeX[i]とsnakeY[i]に等しい場合、ヘビは死にます。この時点では死んだ=!亡くなった。

Java で Snake War ミニゲームを実装する方法

4.3 スネークのアクティブ加速機能の設計

スネークのアクティブ加速機能は、ゲーム中に F キーを押し続けると、スネークが動きます。速度が上がり、押して放すとヘビの速度は初期値に戻ります。これは主に GUI のキーボード リスナーによって実現され、キーボード リスナーの 2 つのメソッド keyPressed() と key release() がそれぞれ実装され、F キーを押す操作と F キーを離す操作を監視します。次に、パラメータ time を使用し、プログラム内で timer.setDelay(time) メソッド (timer は Timer クラスのオブジェクト) を呼び出して time の値を変更し、タイマーの頻度を変更することで、次の効果を実現します。ヘビのスピードを上げる。

Java で Snake War ミニゲームを実装する方法

4.4 スネーク報酬メカニズム関数の設計

スネーク報酬メカニズム関数は、主に選択構造とpaintComponent(Graphics g) メソッドを使用します。 ブラシ ツールこれを達成するために使用されます。ゲームが特定のスコアに達すると、プログラムはブラシ ツールの g.drawString("XXX",snakeX[0],snakeY[0]) メソッドを呼び出し、スネーク ヘッドの位置にプロンプ​​ト テキストを描画します。

Java で Snake War ミニゲームを実装する方法

5. プロジェクトの構造とプロジェクトの実装

5.1 プロジェクトの構造とクラス間の関係

Java で Snake War ミニゲームを実装する方法

Java で Snake War ミニゲームを実装する方法

5.2 完全なプロジェクト ソース コード

5.2.1 画像クラス

このクラスは静的クラスであり、主に Snake コンポーネントの画像オブジェクトを格納します。

package snakegame;

import javax.swing.*;
import java.net.URL;

//Images类用于封装图片路径以及获取图片(使用静态对象便于用类名直接访问)
public class Images {
    //将图片的路径封装成一个对象
    public static URL bodyURL=Images.class.getResource("/snake_images/body.jpg");
    public static URL backURL=Images.class.getResource("/snake_images/back.jpg");
    public static URL snakeDownURL=Images.class.getResource("/snake_images/snakeDown.jpg");
    public static URL snakeLeftURL=Images.class.getResource("/snake_images/snakeLeft.jpg");
    public static URL snakeRightURL=Images.class.getResource("/snake_images/snakeRight.jpg");
    public static URL snakeUpURL=Images.class.getResource("/snake_images/snakeUp.png");
    public static URL foodURL=Images.class.getResource("/snake_images/food.jpg");
    //将图片封装为程序中的对象
    public static ImageIcon bodyImg=new ImageIcon(bodyURL);
    public static ImageIcon backImg=new ImageIcon(backURL);
    public static ImageIcon snakeDownImg=new ImageIcon(snakeDownURL);
    public static ImageIcon snakeUpImg=new ImageIcon(snakeUpURL);
    public static ImageIcon snakeRightImg=new ImageIcon(snakeRightURL);
    public static ImageIcon snakeLeftImg=new ImageIcon(snakeLeftURL);
    public static ImageIcon foodImg=new ImageIcon(foodURL);
}

5.2.2 HighestScore

このクラスは、史上最高スコア関数を実装します。

package snakegame;

import org.w3c.dom.Text;

import java.io.*;

//该类用于给游戏添加历史最高分功能
public class HighestScore {
    static int score = 0;//最高分的存储

    public void highest() throws IOException {
        //得分为最高分时存储
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(String.valueOf(Text.class.getResourceAsStream("贪吃蛇大作战/score.txt"))));
        if (GamePanel.score > score) {
            score = GamePanel.score;
            String s1 = String.valueOf(score);
            bos.write(s1.getBytes());
        }
        bos.close();
    }

    //用于游戏开始时从文件读取最高分的值
    public void readHighest() throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(String.valueOf(Text.class.getResourceAsStream("贪吃蛇大作战/score.txt"))));
        byte[] bys = new byte[1024];
        int len;
        while ((len = bis.read(bys)) != -1) {
            System.out.print(new String(bys, 0, len));//测试用
            String s2 = new String(bys, 0, len);
            score = Integer.valueOf(s2);
        }
        bis.close();
    }
}

5.2.3 GamePanel クラス

このクラスは、Snake ゲーム パネルを描画し、ゲームの特定のロジック関数を実装するために使用されます。

package snakegame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.Random;

//贪吃蛇游戏面板的绘制
public class GamePanel extends JPanel {
    Timer timer;
    int time=100;
    static int score;//记录游戏分数
    //蛇属性部分
    boolean isDied;
    int length;//设置蛇长
    String direction;//蛇头朝向
    //分别储存蛇身的X,Y坐标
    int[] snakeX=new int[300];
    int[] snakeY=new int[300];
    //判断游戏是否开始
    boolean isStart=false;
    int foodX,foodY;//食物的X,Y坐标
    //贪吃蛇初始化方法
    public void init(){
        length=3;
        snakeX[0]=175;
        snakeY[0]=275;
        snakeX[1]=150;
        snakeY[1]=275;
        snakeX[2]=125;
        snakeY[2]=275;
        foodX=300;
        foodY=400;
        score=0;
        isDied=false;//蛇默认状态为活着
        direction="R";//U,D,L,R分别表示蛇头朝向上,下,左,右
    }

    //构造方法
    public GamePanel() throws IOException {
        init();

        if(GamePanel.score>HighestScore.score){
            new HighestScore().highest();
        }
        //焦点定位到当前面板
        this.setFocusable(true);
        //监听器的实现部分
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                super.keyPressed(e);
                int keyCode = e.getKeyCode();
                //按下空格以开始游戏,以及方向键的控制
                if (keyCode == KeyEvent.VK_SPACE) {
                    if(isDied){
                        init();
                    }else {
                        isStart = !isStart;
                        repaint();//重绘
                    }
                } else if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_W) {
                    direction = "U";
                } else if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) {
                    direction = "D";
                } else if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) {
                    direction = "L";
                } else if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) {
                    direction = "R";
                }
            }
        });
        //贪吃蛇加速功能的实现
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode=e.getKeyCode();
                if(keyCode==KeyEvent.VK_F){
                    time=10;
                    timer.setDelay(time);//按下F时加速
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
                int keyCode=e.getKeyCode();
                if(keyCode==KeyEvent.VK_F){
                    time=100;
                    timer.setDelay(time);//松开F键减速恢复默认速度
                }
            }
        });
        //对定时器进行初始化,并实现监听器
            timer = new Timer(time, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    //当游戏处于开始状态且蛇活着时蛇活动,且后一节身子到前一节身子的位置上(每一节身子为25乘25像素)
                    if (isStart && isDied == false) {
                        //蛇身运动部分
                        for (int i = length - 1; i > 0; i--) {
                            snakeX[i] = snakeX[i - 1];
                            snakeY[i] = snakeY[i - 1];
                        }
                        //蛇头运动部分
                        if ("D".equals(direction)) {
                            snakeY[0] += 25;
                        }
                        if ("U".equals(direction)) {
                            snakeY[0] -= 25;
                        }
                        if ("L".equals(direction)) {
                            snakeX[0] -= 25;
                        }
                        if ("R".equals(direction)) {
                            snakeX[0] += 25;
                        }
                        //防止超出边界
                        if (snakeX[0] > 750) {
                            snakeX[0] = 25;
                        }
                        if (snakeX[0] < 25) {
                            snakeX[0] = 750;
                        }
                        if (snakeY[0] < 100) {
                            snakeY[0] = 725;
                        }
                        if (snakeY[0] > 725) {
                            snakeY[0] = 100;
                        }
                        //吃食物的动作,吃食物加10分且蛇身变长,蛇的速度提升10
                        if ((snakeX[0] == foodX && snakeY[0] == foodY)) {
                            length++;//蛇身长度加1
                            foodX = (new Random().nextInt(30) + 1) * 25;//随机生成X坐标[25,750]
                            foodY = (new Random().nextInt(26) + 4) * 25;//随机生成Y坐标[100,725]
                            score += 10;//吃一次食物积分加10
                            try {
                                new HighestScore().highest();
                            } catch (IOException ioException) {
                                ioException.printStackTrace();
                            }
                            if(time>10)
                                timer.setDelay(time-=10);//吃一次食物速度增加10
                        }
                        //蛇的死亡机制判定
                        for (int i = 1; i < length; i++) {
                            if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
                                isDied = !isDied;
                            }
                        }
                        repaint();
                    }
                }
            });
            timer.start();//定时器启动
    }

    //绘制面板部分
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        //填充背景颜色
        this.setBackground(new Color(164, 219, 246));
        //绘制初始蛇头的图片(默认右方朝向)
        Images.backImg.paintIcon(this,g,10,10);
        //调整画笔的颜色并绘制一个矩形面板
        g.setColor(new Color(219,226,219));
        g.fillRect(10,70,770,685);
        //蛇头的绘制;上下左右不同情况
        if("L".equals(direction)){
            Images.snakeLeftImg.paintIcon(this,g,snakeX[0],snakeY[0]);
        }
        if("R".equals(direction)){
            Images.snakeRightImg.paintIcon(this,g,snakeX[0],snakeY[0]);
        }
        if("U".equals(direction)){
            Images.snakeUpImg.paintIcon(this,g,snakeX[0],snakeY[0]);
        }
        if("D".equals(direction)){
            Images.snakeDownImg.paintIcon(this,g,snakeX[0],snakeY[0]);
        }
        //蛇身的绘制
        for(int i=1;i<length;i++) {
            Images.bodyImg.paintIcon(this, g, snakeX[i], snakeY[i]);
        }
        //食物绘制
       Images.foodImg.paintIcon(this,g,foodX,foodY);
        //游戏的文字提示语
        if(!isStart&&!isDied){
            g.setColor(new Color(12, 191, 222));
            g.setFont(new Font("楷体",Font.BOLD,40));
            g.drawString("轻按空格以开始/暂停游戏!",150,330);
            g.setColor(new Color(246, 2, 31));
            g.setFont(new Font("宋体",Font.CENTER_BASELINE,30));
            g.drawString("按住F以加速",300,380);
        }
        //游戏的得分显示
        g.setColor(new Color(248, 4, 74));
        g.setFont(new Font("楷体",Font.BOLD,30));
        g.drawString("得分:"+score,420,90);
        //游戏的最高分展示模块
        try {
            new HighestScore().readHighest();
        } catch (IOException e) {
            e.printStackTrace();
        }
        g.setColor(new Color(183, 25, 238));
        g.setFont(new Font("楷体",Font.BOLD,30));
        g.drawString("历史最高分:"+HighestScore.score,10,90);
        //蛇的速度提示
        g.setColor(new Color(248, 136, 36));
        g.setFont(new Font("楷体",Font.BOLD,30));
        g.drawString("当前速度:"+String.valueOf(110-time),550,90);
        //游戏的奖励鼓励机制
        if(score==10){
            g.setColor(new Color(127, 232, 20));
            g.setFont(new Font("微软雅黑",Font.BOLD,50));
            g.drawString("Good!",snakeX[0],snakeY[0]);
        }
        else if(score==50){
            g.setColor(new Color(17, 231, 250));
            g.setFont(new Font("微软雅黑",Font.BOLD,50));
            g.drawString("Good!!!",snakeX[0],snakeY[0]);
        }else if(score==100){
            g.setColor(new Color(248, 196, 6));
            g.setFont(new Font("微软雅黑",Font.BOLD,50));
            g.drawString("Perfect!!!",snakeX[0],snakeY[0]);
        }else if(score==200){
            g.setColor(new Color(248, 245, 26));
            g.setFont(new Font("微软雅黑",Font.BOLD,50));
            g.drawString("无人能挡!!!",snakeX[0],snakeY[0]);
        }
        //小蛇死亡时面板的绘制
        if(isDied){
            g.setColor(new Color(6, 115, 248));
            g.setFont(new Font("微软雅黑",Font.BOLD,30));
            g.drawString("你的小蛇已经死亡,按下空格重新开始!",170,330);
        }
    }
}

5.2.4 クラスの開始

ページの全体的なレイアウトとプログラムの入り口。

rree

以上がJava で Snake War ミニゲームを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。