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

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

ただいまの
回答率

87.36%

JavaScript初心者 ゲームプログラミングが起動しません

解決済

回答 2

投稿

  • 評価
  • クリップ 2
  • VIEW 1,508

score 7

前提・実現したいこと

当方JavaScript初心者です。
JavaScriptの入門書を購入しました。
本に書いてある通りに、ソースを写してゲームを作りました。しかし、作動しません。

写し間違えは99%ありえないと思ってます。確認作業は何度もやりました。

もしかしたら、本に書いてあるソースが間違っているのでは?と思い、ここで質問させてもらっています。どなたか原因を教えてください。

※ゲームの説明については本から引用します。
「...Canvasを使ったゲームとして、SnakeBite風のゲームを紹介しましょう。上下左右キーで蛇を操作し、餌を食べさせます。餌を食べるたびに体が伸びていきます。四方の壁にぶつかるか自分にぶつかるとゲームオーバーです。ただ、これだけのゲームだけですが、思いのほか夢中で遊んでしまうことでしょう...」

田中賢一郎『ゲームを作りながら楽しく学べる HTML5+CSS+JavaScript プログラミング』(株式会社インプレスR&D、2013年)

発生している問題・エラーメッセージ

ゲームプログラミングが起動しない。(ブラウザで背景のみ表示される)

該当のソースコード

<!DOCTYPE html>
<html>
<head>
<title>SnakeBite</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<script type="text/javascript">
var W, H, S = 20;
var snake = [], foods = [];
var keyCode = 0;
var point = 0;
var timer = NaN;
var ctx;

// Pointオブジェクト
function Point(x, y){
this.x = x;
this.y = y;
}

//初期化関数
function init(){
var canvas = document.getElementById("field");
W = canvas.width / S;
H = canvas.height / S;
ctx = canvas.getContext("2d");
ctx.font = "20px sans-serif";

//蛇の初期化
snake.push(new Point(W / 2, H / 2));

//餌の初期化
for(var i = 0; i < 10; i++){
addFood();
}

timer = setInterval("tick()", 200);
window.onkeydown = keydown;
}

//餌の追加
function addFood(){
while(true){
var x = Math.floor(Math.random() * W);
var y = Math.floor(Math.random() * H);

if(isHit(foods, x, y) || isHit(snake, x, y)){
continue;
}

foods.push(new Point(x, y));
break;
}
}

//衝突判定
function isHit(data, x, y){
for(var i = 0; i < data.length; i++){
if(data[i].x == x && data[i].y == y){
return true;
}
}
return false;
}

function moveFood(x, y){
foods = foods.filter(function (p) {
return (p.x != x || p.y != y);
});
addFood();
}

function tick(){
var x = snake[0].x;
var y = snake[0].y;

switch(keyCode){
case 37: x--; break; //左
case 38: y--; break; //上
case 39: x++; break; //右
case 40: y++; break; //下
default: paint(); return;
}

//自分 or 壁に衝突?
if(isHit(snake, x, y) || x < 0 || x >= W || y < 0 || y >= H)

clearInterval(timer);
paint();
return;
}

//頭を先頭に追加
snake.unshift(new Point(x, y));

if(isHit(foods, x, y)){
point += 10;  //餌を食べた
moveFood(x, y);
} else {
snake.pop();  //食べてない→しっぽを削除
}

paint();
}

function paint(){
ctx.clearRect(0, 0, W * S, H * S);
ctx.fillStyle = "rgb(256,0,0)";
ctx.fillText(point, S, S * 2);
ctx.fillStyle = "rgb(0,0,255)";

foods.forEach(function (p) {
ctx.fillText("+", p.x * S, (p.y + 1) * S);
});
snake.forEach(function (p) {
ctx.fillText("*", p.x * S, (p.y + 1) * S);
});
}

function keydown(event){
keyCode = event.keyCode;
}
</script>
</head>

<body onload="init()">
<canvas id="field" width="400" height="400" style="background:#cccccc">
</canvas>
</body>
</html>

試したこと

メモ帳に打ち込んだものを印刷して、本と照らし合わせながら、間違っていないか2回確認しました。

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • defghi1977

    2018/01/15 20:04

    開発者ツール(F12キーで起動)のコンソールに表示されているであろうエラーメッセージを追記して下さい.

    キャンセル

  • bebe

    2018/01/15 20:08

    なにも表示されていないです。×マークにマウスを当てたら「0個のエラー」と出ました。

    キャンセル

  • defghi1977

    2018/01/15 20:10

    調べてみたら, あなた偉い!一箇所しか間違ってない. 机上確認でよくここまで

    キャンセル

回答 2

checkベストアンサー

+1

ご提示のコードに一箇所記述ミスがあります. 

//自分 or 壁に衝突?
if(isHit(snake, x, y) || x < 0 || x >= W || y < 0 || y >= H)

clearInterval(timer);
paint();
return;
}

の部分のif文に{が一個足りません.

//自分 or 壁に衝突?
if(isHit(snake, x, y) || x < 0 || x >= W || y < 0 || y >= H){//←この部分

clearInterval(timer);
paint();
return;
}

とすることでゲームが動作することを確認しました.


プログラミングを行う場合, 開発者ツール利用の有無でその効率に雲泥の差が出ます. 上記のコードにおいても問題がある部分を一発で指摘してくれます. 

ある程度コードを記述することに慣れてきたら, 是非開発者ツールの使い方(最低限エラーの出力)について調べてみて下さい. 

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/01/15 20:36

    回答ありがとうございます。

    おかげさまで無事作動しました!

    実は、入門書にも開発者ツールの使い方について記述があったのですが、訳が分からなかったので読み飛ばしていました。今回の件で懲りました。使い方を勉強しようと思います。

    本当に助かりました。今日は眠れそうです。

    キャンセル

+1

コメントには開発者ツールでエラーは表示されていないと書かれていますが、こちらの環境で見ると以下のエラーが発生しています。

SyntaxError: expected expression, got '}'

単純に、閉じ括弧に対応した開き括弧が足りないのでおかしくなっているようですね。

問題は、「//自分 or 壁に衝突?」のコメントの次の行にあります。

    誤:if(isHit(snake, x, y) || x < 0 || x >= W || y < 0 || y >= H)
    正:if(isHit(snake, x, y) || x < 0 || x >= W || y < 0 || y >= H) {

このような問題を発見するために、インデントを入れるようにしましょう。

またエラーメッセージを読んで、そのエラーが発生している位置から問題を推測しましょう。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/01/15 20:41

    回答ありがとうございます。無事作動しました。

    なるほど、ミスを発見するためにインデントするのですね。初めて知りました。
    入門書のほうを見てみると確かにされていました。今までは気にも留めてませんでした。とても参考になりました。

    ありがとうございました。

    キャンセル

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

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

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