Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

Reactでバトル画面を作成

前回マップ画面の作成とキャラクターの操作を実施してみました。
elsammit-beginnerblg.hatenablog.com

今回はバトル画面の作成を行ってみましたので、その報告です!!
※技術の備忘録は少なめ(というかほとんどない)です。



■環境

・ubuntu16.04(VirtualBox上)
・React:17.0.1
・react-router-dom:5.2.0

※react-router-domはマップ⇔バトル画面間の遷移のために利用

■完成結果

できたアプリはこちらのようになります。
f:id:Elsammit:20201229225120g:plain

それっぽくできたかな?と思っております!!

■コード紹介

コード全体はこちらのGithubに格納しておりますので、こちらをご参照ください。
https://github.com/Elsammit/RPGGame

バトル画面はこちらのコードを参考にしました。
ただ、参考はjavascriptであるためReact用に変更しました。
https://blog.ver001.com/javascript-keydown/

重要な部分としては、こちらになります。

    componentDidMount(){
        this.setState({xx:this.props.location.state.xx});
        this.setState({yy:this.props.location.state.yy});

        document.addEventListener(
            "keydown",
            this.handleKeyDown,
        );
        this.activeMenu(1);
    }

    componentWillUnmount() {
        document.removeEventListener(
          "keydown",
          this.handleKeyDown,
        );
        menu_id = 0;
    }

    handleKeyDown = (e: KeyboardEvent) => {
        switch (e.key) {
            case "Left": // IE/Edge specific value
            case "ArrowLeft":
                break;
            case "Right": // IE/Edge specific value
            case "ArrowRight":
                break;
            case "Up": // IE/Edge specific value
            case "ArrowUp":
                if (menu_id <= 1) {
                    this.activeMenu(5);
                } else {
                    this.activeMenu(menu_id - 1);
                }
                break;
            case "Down": // IE/Edge specific value
            case "ArrowDown":
                if (menu_id >= 5) {
                    this.activeMenu(1);
                } else {
                    this.activeMenu(menu_id + 1);
                }
                break;
            case "Enter":
                this.doCommand(menu_id);
                break;
            default:
                console.log("key Error");
                break;
            }
      };

    activeMenu = (id) =>{
	    if (menu_id === id) {
		    this.doCommand(id);
	    } else {
		    if (menu_id !== 0) {
			    document.getElementById('menu' + menu_id).className = 'menu';
		    }
		    document.getElementById('menu' + id).className = 'menu menu-active';
		    menu_id = id;
	    }
    }
    
    //コマンドの実行
    doCommand = (command_id) => {
	    switch (command_id) {
		    case 1: //たたかう
			    this.DoAttack();
                break;
              case 2: //まほう
			    document.getElementById('message').innerHTML = '<span class="message">残念!  まほうを覚えていない!</span>';
                break;
		    case 3: //ぼうぎょ
			    document.getElementById('message').innerHTML = '<span class="message">AAAは みをまもっている!</span>';
			    break;
		    case 4: //どうぐ
			    document.getElementById('message').innerHTML = '<span class="message">しかし なにももっていなかった。</span>';
			    break;
		    case 5: //にげる
                document.getElementById('message').innerHTML = '<span class="message">AAAたちは戦闘から逃げた!!</span>';
                setTimeout(this.DoEscape, 2000);
                break;
		    default:
			    break;
	    }
    }

やっていることは、
componentDidMount関数にてキーイベント登録。
さらに、キーボードの矢印キーを押下すると、
handleKeyDownイベントがコールされ、選択されているカーソール位置を変更します。
カーソール位置を変更するための関数は、
activeMenu関数にて実施しています。

後はエンターキーを押下した時に、
たたかう、まほう、ぼうぎょ、どうぐ、にげる
に合わせた処理を実行しております。

今回は時間の関係で、
たたかう、にげる
のみ実装してみました!!

攻撃時のダメージ計算はこちらの通り、
こうげき-ぼうぎょ
で差分をHPから差し引いております。

    DoAttack = () =>{
        var usrparam = this.state.usrparam.slice();
        var enemyparam = this.state.enemyparam.slice();
        var damege = usrparam[2] - enemyparam[3];
        console.log("usr:"+usrparam[2]+" enemy:"+enemyparam[3]+"damege:"+damege);
        document.getElementById('message').innerHTML = '<span class="message">AAAの こうげき!  '+ damege + 'のダメージ</span>';
        if(enemyparam[0]-damege <=0){
            setTimeout(this.KnockDown, 1000);
        }else{
            enemyparam[0] -= damege;
            this.setState({enemyparam:enemyparam});
            console.log("enemyHP:"+enemyparam[0]);
            setTimeout(this.DoAtkEnemy, 1000);
        }
    }

ユーザや敵のパラメータは、

    constructor (props) {
        super(props);
        this.state = {
            usrparam:[350,100,30,30,30,30,50],      // HP,MP,Atk,Def,SpAtk,SpDef,Speed,Lv
            enemyparam:[60,5,100,10,5,5,10,1],     // HP,MP,Atk,Def,SpAtk,SpDef,Speed,Lv
        };
    }

により、配列にて管理しております。

詳しい処理内容は、こちらに載っておりますのでご参考にしてください。
elsammit-beginnerblg.hatenablog.com
elsammit-beginnerblg.hatenablog.com

■最後に

ReactでRPGゲームを作ってみました。
結構簡単にバトル画面も作成することが出来ました。
このレベルでも1日かかってしまう。。もう少し早くアプリ作れるようになりたいな。