IDEAを使用して、Javaオブジェクト指向のゲーム「ForgiveHatBattle」を作成します

アチーブメント表示

ここに写真の説明を挿入

制作のアイデア

ステップ1:クラス(オブジェクト)を発見する

人物-小丑: Buffoon
子弹-帽子:Missile
墙体:Wall
爆炸物:Explode

ステップ2:属性を発見する

小丑:宽和高,位置(x,y),移动速度
帽子:宽和高,位置(x,y),移动速度
墙体:宽和高,位置(x,y)
爆炸物:宽和高,位置(x,y)

ステップ3:方法を見つける

小丑:移动、攻击、人物撞边界
子弹:移动、子弹撞墙、子弹撞边界
爆炸物:消失

難易度分析

フォームの作成方法

public class GameClient extends Frame

Frameクラスを継承してJavaフォームを実装する

public class Frame extends Window implements MenuContainer

Frameクラスは、WindowクラスとMenuContainerインターフェイスを継承します

写真をフォームにロードする方法

ステップ1:一般的に使用されるツールクラスであるCommonUtilsを作成し、画像リソースをJavaオブジェクトに変換するための新しいgetImageメソッドを作成します

public class CommonUtils {
    
    
    /**
     * 读取图片资源, 转变为Java对象 Image
     * @param imgPath  图片路径
     * @return Image对象
     */
    public static Image getImage(String imgPath) {
    
    
        ImageIcon imageIcon = new ImageIcon(imgPath);
        return imageIcon.getImage();
    }
}

手順2:getImageメソッドを呼び出して、オブジェクトイメージを追加します

public class GameClient extends Frame {
    
    
    Image bg_image = CommonUtils.getImage("images/bg.png");
    Image explode = CommonUtils.getImage("images/explode.png");
    Image missile = CommonUtils.getImage("images/missile.png");
    Image wall_h = CommonUtils.getImage("images/wall-h.png");
    Image wall_v = CommonUtils.getImage("images/wall-v.png");
    Image buffoon = CommonUtils.getImage("images/body/s-left.png");

ステップ3:Framedのpaintメソッドを書き直して、画像をロードするフォームを実装します

@Override
    public void paint(Graphics g){
    
    
        //画背景图
        g.drawImage(bg_image,0,0,1100,700,this);
        //画小丑
        g.drawImage(buffoon,300,200,80,80,this);
        //画爆炸物
        g.drawImage(explode,800,400,90,90,this);
        //画原谅帽
        g.drawImage(missile,300,300,60,60,this);
        //画横着的墙体
        g.drawImage(wall_h,400,300,100,20,this);
        //画竖着的墙体
        g.drawImage(wall_v,400,300,20,100,this);

GraphicsクラスのdrawImageメソッドは、Imageクラスのパラメーター、フォームのxパラメーター、フォームのyパラメーター、Imageクラスの幅、Imageクラスの長さ、およびオブザーバー(より多くの画像が変換されたときに通知されるオブジェクト)を提供する必要があります。

オブジェクト移動の実装

ターゲットマップの方向は通常、「北上、下から南、左西、右東」のルールによって決定されます。移動の8つの方向は通常、北、北東、東、南東、南、南西、西、北西を指します。したがって、移動方向を定義するときは、上、左、下、右、右上、右下、左上、左下を使用して示します

LinJiabinによるデザイン

小丑:移动  move<Orientation类传递方向参数>
'left向左'   :x = x - this.speed;
'right向右'  :x = x + this.speed;
'down向下'   :y = y + this.speed;
'up向上'     :y = y - this.speed;
'ur东北方向'  : x = x + this.speed;
                y = y - this.speed;
'ul西北方向'  : x = x - this.speed;
                y = y - this.speed;
'dr东南方向'  : x = x + this.speed;
                y = y + this.speed;
'dl西南方向'  : x = x - this.speed;
                y = y + this.speed;

フォームクロージングの実現

    public void start() {
    
    
        //窗体添加侦听方法
        this.addWindowListener(new WindowAdapter() {
    
    
            @Override
            public void windowClosing(WindowEvent e) {
    
    
                super.windowClosing(e);
                //退出游戏
                System.exit(0);
            }
        });

WindowAdapterクラス
1。ウィンドウイベントを受信する抽象アダプタークラス。このクラスのメソッドは空です。このクラスの目的は、リスナーオブジェクトの作成を容易にすることです。
2.このクラスを拡張してWindowEventリスナーを作成し、必要なイベントのメソッドをオーバーライドします。(WindowListenerインターフェイスを実装する場合は、インターフェイスですべてのメソッドを定義する必要があります。この抽象クラスはすべてのメソッドをnullとして定義するため、関心のあるイベントのメソッドのみを定義する必要があります。3。
拡張クラスを使用してリスナーオブジェクトを作成します。 、次に、ウィンドウのaddWindowListenerメソッドを使用して、リスナーをウィンドウに登録します。ウィンドウの状態が、開く、閉じる、アクティブ化または非アクティブ化、アイコン化または非アイコン化によって変更されると、リスナーオブジェクトの関連するメソッドが呼び出されます。 、そしてWindowEventをメソッドに渡します
。windowAdapterリスナー

キーイベントトリガーの実現

 this.addKeyListener(new KeyAdapter() {
    
    
             //键盘按下的时候出发
            @Override
            public void keyPressed(KeyEvent e) {
    
    
                super.keyPressed(e);
            }
            //键盘松开
            @Override
            public void keyReleased(KeyEvent e) {
    
    
                //获取被按下的键对应的数值,如,a:67,b:68
                int keyCode = e.getKeyCode();
                switch (keyCode){
    
    
                    case KeyEvent.VK_UP:
                        System.out.println("向上走!!!");
                        buffoon.setDir("UP");
                        break;
                    case KeyEvent.VK_DOWN:
                        System.out.println("向下走");
                        buffoon.setDir("DOWN");
                        break;
                    case KeyEvent.VK_RIGHT:
                        System.out.println("向右走");
                        buffoon.setDir("RIGHT");
                        break;
                    case KeyEvent.VK_LEFT:
                        System.out.println("向左走!!");
                        buffoon.setDir("LEFT");
                        break;
                }
                buffoon.move(buffoon.getDir());
            }
        });

キーストロークの要点

ポイント1: 'new KeyAdapter()'新しいキーイベントリスナーを作成し、addKeyListener()を介してリスナーをメインフォームに登録します。
ポイント2:KeyAdapterメソッド、つまりKeyTyped(type)、KeyPresdded(を押す)を書き換えます。次)、KeyReleased(リリース済み)。ここでは、KeyPressedイベントのみをリッスンし、このメソッドを書き直して、キャラクターの方向状態の変更を実現し
ます。3番目のポイント:KeyEvent e.getKeyCodeは、押されたキーに対応するキー値を返します。KeyEventのkeyvalueプロパティを参照してください。Java8オンラインAPI

オブジェクトの作成Buffoon.move()メソッド

    public void move(String dir){
    
    
        switch (dir){
    
    
            case "UP":
                this.y -= this.speed;
                setDir("STOP");
                break;
            case "DOWN":
                this.y += this.speed;
                setDir("STOP");
                break;
            case "RIGHT":
                this.x += this.speed;
                setDir("STOP");
                break;
            case "LEFT":
                this.x -= this.speed;
                setDir("STOP");
                break;
        }

キーイベントが監視されるたびに、moveメソッドが呼び出され、buffoonオブジェクトの動きが実現されます。

キーイベントが監視されるたびにmoveメソッドを呼び出します

オブジェクトの動きの原理

オブジェクトの動画はアニメーションとも呼ばれます。一連の連続したアニメーション画像をフレームごとに画面に表示し、次のフレームを短い間隔で表示します。これは、人間の目の「視覚の持続性」を使用して繰り返されます。 'この現象は、写真のオブジェクトが動いているように主観的に感じます。
FPS(Frames Per Second)は、1秒あたりのフレーム数です。1フレームは静的ポートレートで、ムービーの再生速度は24FPSです。フレームが多いほど、表示される動きはスムーズになります。一般的に、ぎくしゃくした動きを避けるために必要な最小値は30FPSです。FPSバイドゥ百科事典

アニメーションの動くポータースレッド

スレッドとは何ですか?
スレッドは、オペレーティングシステムが操作スケジューリングを実行できる最小単位です。これはプロセスに含まれ、プロセスの実際のオペレーティングユニットです。スレッドとは、プロセス内の単一の順次制御フローを指します。プロセス内で複数のスレッドを同時に実行でき、各スレッドは異なるタスクを並行して実行します。

/**
 * 定义一个重新绘制画面的线程,相当于招一个工人专门去从事这项工作
 */
public class RePaintThread implements Runnable{
    
    
    @Override
    //线程操作的全都在run方法中
    public void run() {
    
    
        while (true){
    
    
            //每50毫秒 执行一次
            try {
    
    
                Thread.sleep(20);
                //重新绘制图像
                gameClient.repaint();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }

ポイント1:Runnableインターフェイス
パブリッククラスRePaintThreadはRunnable
を実装しますインターフェイスRunnableを実装するオブジェクトでスレッドを作成する場合、スレッドを開始すると、オブジェクトのrunメソッドが独立して実行されるスレッドで呼び出されます。
ポイント2:Runメソッドをオーバーライドするrunメソッド
の一般的な契約は次のとおりです。任意のアクションを実行できます。
画像を
再描画しますgameClient.repaint();
キーポイント3:Thread.sleep-スレッドの繰り返し実行間の時間間隔1.「While(
true)」を使用して無限ループを構築します
2.無限ループでrepaint()を実行して形状メソッドを再描画します
3。スレッド中断例外(InterruptedException)は、現在中断されているスレッドの兆候の1つです。この例外が発生した場合、その処理方法がわからない場合は、上向きにスローする必要があります。
キャッチ句

おすすめ

転載: blog.csdn.net/qq_42760141/article/details/109599610