質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.59%

敵キャラを表示させたいです

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,325

score 16

私はまだまだプログラムの初心者です。
どなたかご教授頂ければ幸いです。

リンク内容

何かゲームを作りながら学ぼうと思い、上記リンク先の方の記事を参考にさせて頂きながら「その5の敵キャラを作る」ところでつまづいております。
画像の様にコンソールエラーが出ており解決に至っておりません。

何か間違えていたり、記述が不足、間違っていましたらご教授を宜しくお願いいたします。
また、質問方法やその他の事でも気づいた事が御座いましたらご指摘のほど、宜しくお願いいたします。

イメージ説明

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>shoot</title>
    <script src="commo.js"></script>
    <script src="character.js"></script>
    <script src="main.js"></script>
    <style>canvas {border: 1px solid skyblue;}</style>
</head>
<body>
    <canvas id="screen"></canvas>
    <p id="info"></p>

</body>
</html>
//main.js

//- global--------------------------------------------------
//html で記述したcanvasとpタグのinfoを参照するための変数screenCanvasとinfo
//run= ゲームの処理を継続するかどうかのフラグ(真偽値を格納)
//fps= ゲームの更新速度を表すFPS(1000㍉秒=1秒)
//mouse= マウスカーソルの座標を格納する
//ctx= canvas2d コンテキスト格納用
//fire= ショットを発射するのかしないのかを真偽値で保持
//counter= シーンを管理するために使用
var screenCanvas, info;
var run = true;
var fps = 1000 / 30; //1秒に約30回更新されるゲーム
var mouse = new Point(); //変数mouseにはcommo.jsで記述したPointクラスを利用してマウスカーソルの座標1を格納するためのインスタンスを作っておく
var ctx;
var fire = false;
var counter = 0;

// -const -----------------------------------------------------
var CHARA_COLOR = 'rgba(0, 0, 255, 0.75)';
var CHARA_SHOT_COLOR = 'rgba(0, 255, 0, 0.75)';
var CHARA_SHOT_MAX_COUNT = 10; //画面上に出せるショット数の最大値の設定
var ENEMY_COLOR = 'rgba(255, 0, 0, 0.75)';
var ENEMY_MAX_COUNT = 10;

//- main ----------------------------------------------------
window.onload = function () {

    //スクリーンの初期化
    screenCanvas = document.getElementById('screen');
    screenCanvas.width = 256; //横幅を256ピクセルに変更
    screenCanvas.height = 256; //縦幅を256ピクセルに変更

    //2dコンテキスト
    ctx = screenCanvas.getContext('2d');

    //イベントの登録
    //イベントの登録には addEventListener を使う
    //マウスカーソルの位置を検知するための関数一つとキー入力を検知するための関数2つを登録
    screenCanvas.addEventListener('mousemove', mouseMove, true);
    screenCanvas.addEventListener('mousedown', mouseDown, true);
    window.addEventListener('keydown', keyDown, true);

    //エレメント関連
    //変数 info にはHTML内のpタグへの参照を入れる
    //このpタグの中身を動的に書き換えてコンソール出力の様な感じで使用
    info = document.getElementById('info');

    //自機初期化
    var chara = new Character();
    chara.init(10); //init メソッドによって自機キャラクターサイズを10へ設定

    //自機ショットの初期化
    var charaShot = new Array(CHARA_SHOT_MAX_COUNT);
    for (var i = 0; i < CHARA_SHOT_MAX_COUNT; i++) {
        charaShot[i] = new CharacterShot();
    }

    //敵機初期化
    var enemy = new Array(ENEMY_MAX_COUNT);
    for (i = 0; i < ENEMY_MAX_COUNT; i++) {
        enemy[i] = new Enemy();
    }


    //ループ処理(レンダリング処理)を呼び出す
    (function () {
        //HTML を更新
        info.innerHTML = mouse.x + ':' + mouse.y;

        // fireフラグの値により分岐
        if (fire) {
            // すべての自機ショットを調査する
            for (i = 0; i < CHARA_SHOT_MAX_COUNT; i++) {
                // 自機ショットが既に発射されているかチェック
                if (!charaShot[i].alive) {
                    // 自機ショットを新規にセット
                    charaShot[i].set(chara.position, 3, 5);
                    // ループを抜ける
                    break;
                };
            };
            // フラグを降ろしておく
            fire = false;
        };

        // screen クリア
        ctx.clearRect(0, 0, screenCanvas.width, screenCanvas.height);

        //自機パスの設定を開始
        ctx.beginPath();

        //自機の位置を決定
        chara.position.x = mouse.x;
        chara.position.y = mouse.y;

        //自機を描くパスを設定
        ctx.arc(chara.position.x, chara.position.y, chara.size, 0, Math.PI * 2, false);

        //自機の色を設定する
        ctx.fillStyle = CHARA_COLOR;

        //自機を描く
        ctx.fill();

        //自機ショットのパスの設定を開始
        ctx.beginPath();
        // すべての自機ショットを調査する
        for (i = 0; i < CHARA_SHOT_MAX_COUNT; i++) {
            // 自機ショットが既に発射されているかチェック
            if (charaShot[i].alive) {
                // 自機ショットを動かす
                charaShot[i].move();

                // 自機ショットを描くパスを設定
                ctx.arc(
                    charaShot[i].position.x,
                    charaShot[i].position.y,
                    charaShot[i].size,
                    0, Math.PI * 2, false
                );

                // パスをいったん閉じる
                ctx.closePath();
            }
        }

        // 自機ショットの色を設定する
        ctx.fillStyle = CHARA_SHOT_COLOR;

        // 自機ショットを描く
        ctx.fill();

        // エネミーの出現管理---------------------------
        if (counter % 100 === 0) {
            for (i = 0; i < ENEMY_MAX_COUNT; i++) {
                if (!enemy[i].alive) {
                    j = (counter % 200) / 100;
                    var enemySize = 15;
                    p.x = -enemySize + (screenCanvas.width + enemySize * 2) * j
                    p.y = screenCanvas.height / 2;

                    enemy[i].set(p, enemySize, j);
                    break;
                }
            }
        }


        //フラグにより再帰呼び出し
        /**
         * setTimeoutを用いて無名関数自体を再帰的に呼び出す
         * mouse の中身は後述するイベント処理用の関数で更新するので
         * ここではループ処理の中には特に値を設定する処理は入れていない
         */
        if (run) {
            setTimeout(arguments.callee, fps);
        }

    })(); //ここまでが無名関数
}; //ここまでが window.onload関数

// - event --------------------------------------------
/**
 * マウスカーソルの位置を拾うためのmouseMove
 * @param {mouseMove} event 
 */
function mouseMove(event) {
    //マウスカーソル座標の更新
    mouse.x = event.clientX - screenCanvas.offsetLeft;
    mouse.y = event.clientY - screenCanvas.offsetTop;
};
//マウスがクリックされた際の処理
function mouseDown(event) {
    //フラグを立てる
    fire = true;
};
/**
 * キーの入力を拾うためのkeyDown
 * @param {keyDown} event 
 */
function keyDown(event) {
    //キーコードを取得
    var ck = event.keyCode;
    //Escキーが押されていたらフラグを降ろす
    if (ck === 27) {
        run === false;
        console.log('Escキーが押されたので処理を中断します');
    }
};
//character.js

//-自機のcharacterクラス作成-----------------------------------
function Character() {
    this.position = new Point();
    this.size = 0;
};

//自機のサイズ指定を init メソッドで行う
Character.prototype.init = function (size) {
    this.size = size;
};

//-自機の弾を扱う CharacterShotoクラスの作成-------------------
function CharacterShot() {
    this.position = new Point();
    this.size = 0;
    this.speed = 0;
    this.alive = false;
}
//set メソッドは引数を3つほど受け取りそれと共に自機ショットを初期化
//引数にはショットの初期位置とサイズ、スピード与えます
//このメソッドが呼び出されることで this.alive=true も自動で呼び出され生存フラグが立つ
CharacterShot.prototype.set = function (p, size, speed) {
    //座標をセット
    this.position.x = p.x;
    this.position.y = p.y;

    //サイズ、スピードをセット
    this.size = size;
    this.speed = speed;

    //生存フラグを立てる
    this.alive = true;
};
// moveメソッドはショットの動きに関する処理を持つ
//自機は画面下から画面上に向かってショットを打つので座標では y軸は数字が小さくなる(左上が座標0、0のため)

CharacterShot.prototype.move = function () {
    // 座標を真上にspeed分だけ移動させる
    this.position.y -= this.speed;

    //一定以上の座標に到達していたら生存フラグを降ろす
    if (this.position.y < -this.size) {
        this.alive = false;
    }
};
//-敵機の characterクラス作成-------------------------
function Enemy() {
    this.position = new Point();
    this.size = 0;
    this.type = 0;
    this.param = 0;
    this.alive = false;
}

Enemy.prototype.set = function (p, size, type) {
    //座標をセット
    this.position.x = p.x;
    this.position.y = p.y;

    //サイズ、タイプをセット
    this.size = size;
    this.type = type;

    //パラメーターをリセット
    this.param = 0;

    //生存フラグを立てる
    this.alive = true;
};

Enemy.prototype.move = function () {
    //パラメーターをインクリメント
    this.param++;
    switch (this.type) {
        case 0:
            //x 報告へまっすぐ進む
            this.position.x += 2;
            //すくりーんの右端より奥へ到達したら生存フラグを降ろす
            if (this.position.x > this.size + screenCanvas.width) {
                this.alive = false
            }
            break;
        case 1:
            this.position.x -= 2;
            if (this.position.x < -this.size) {
                this.alive = false;
            }
            break;
    }
};
//common.js

//xとyの二つの座標情報を格納するためのクラス
function Point(){
    this.x = 0;
    this.y =0;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2019/01/15 13:59

    コードの提示の仕方が結構めちゃくちゃになっています。
    質問は編集できるので、質問投稿画面の右側のプレビューを見ながら調整してください。
    エラー自体は未定義の変数を利用しようとしている、ということなので、そこは辿れそうに思います。

    キャンセル

  • shunsena

    2019/01/15 14:06

    コードを複数挿入する際に失敗しておりましたので修正致しました。
    プレビューを見ながら投稿する様に以後、気をつけます。
    ご指摘ありがとう御座います。

    キャンセル

回答 3

checkベストアンサー

+3

リンク先のソースを見ましょう。

・リンクを開く
・F12を押してディベロッパーツールを開く
・Sourcesをクリックして main.jsをクリックする

そうするとソースの全部が見れます。

既に解答されている方もいますが、問題となっているpの宣言箇所も見れます。

イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/15 14:36

    解決致しました。
    また、それだけでなくここまで記事のコードを見てどこにコードを記述するかわからず、文章やコードの役割を考えながら作っていたのですが、デベロッパーツールでファイル毎のコードを見る事ができるという初歩的な事に気づいておりませんでした。
    今回の質問の内容だけでなく、自分が気づけていなかった事まで推測して頂き、回答頂けたため、ベストアンサーに選ばせて頂きました。
    今後の学習に於いても非常に助けになりました。
    本当にありがとう御座いました。

    キャンセル

  • 2019/01/15 14:39

    私も記事を読んでどこのコードを切り取って話してるんだこいつはって思ったのでサイトが悪いです()
    ディベロッパーツールはコードを見るだけではなくて、デバック機能もあるので、
    使いこなすとどこが今実行されているんだろうとか、ブレークポイントを貼ってここに到達するのはいつだろうというのも見れるので
    画面系開発するときには必需品です。使いこなせると強いですよ。

    キャンセル

+2

リンク先のソースと見比べただけですが、
先頭で変数を宣言しているのが抜けてますね。

リンク先のソースでは、先頭でi,j,pが下記のように宣言されていました。

// - main ---------------------------------------------------------------------
window.onload = function(){
    // 汎用変数
    var i, j;
    var p = new Point();

    // スクリーンの初期化
     ・
     ・
     ・

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/15 14:29

    解決いたしました。
    ご返答頂きありがとう御座います。

    キャンセル

+1

とうとつにpを参照していますが、pがどこにも宣言されていないからでは?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/15 14:11

    ご返答ありがとう御座います。
    リンク先のサイト通りに記述を行い、pが未定義な事には気づいたのですが自分がどこで間違えているのか、どこをどの様に修正すれば良いのかが現状解決できておりません。
    差し支えなければご教授願えないでしょうか?

    キャンセル

  • 2019/01/15 14:14 編集

    なぜその箇所でpを参照しようとしたかソースを見るしかないですね
    よくよく元のサイトを確認してください。
    ソース量がおおくなっているので細かく検証はきびしいです
    (どこかのライブラリでpをグローバル変数として宣言していて
    マウス位置かなにかを示しているのかなぁ・・・とは想像しますが)

    キャンセル

  • 2019/01/15 14:38

    ご返答ありがとう御座います。
    他の方の回答で私が記事の部分しかコードを記述しておらず不完全な状態でプログラムを実行していた事に気づきました。
    お忙しい中、ご返答頂きありがとう御座いました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る