[JavaScript] なぜかうまくいかない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
dic
記事: 657
登録日時: 13年前
住所: 宮崎県
連絡を取る:

[JavaScript] なぜかうまくいかない

#1

投稿記事 by dic » 7年前

ほんの通りにソースコードを打ち込んでいるのですが、
エラーがでてしまい、原因がわかりません。

snakeBite 風のゲームだぞうですが、エラーメッセージが英語でわかりません。
エラーメッセージは
Uncaught TypeError: Failed to execute 'fillText' on
'CanvasRenderingContext2D' : 3 arguments required, buf only 2 preset.
です。109行目が悪いようですが、タイプミスはしてないし、わかりません。
以下がソースコード(長文)になります。

コード:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>SnakeBite</title>
    <meta heep-equiv="X-UA-Compatilbe" 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 / 8;
            H = canvas.height / 8;
            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, y, 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, y, 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.ekyCode;
             }
        
        </script>
</head>
<body onload="init()">
    <canvas id="field" width="400" height="400" style="background:#cccccc">
    </canvas>

</body>
</html>

dic
記事: 657
登録日時: 13年前
住所: 宮崎県
連絡を取る:

Re: [JavaScript] なぜかうまくいかない

#2

投稿記事 by dic » 7年前

インデントをきれいにしたところ
ミスっているところがありました。
再度、ソースコードを載せます。

しかし、こんどは91行目の return; がエラーで
Uncaught SyntaxError: Illegal return statement
となってしまい。

うまく動作しません。

ここの return はどのように修正すればいいのでしょうか?
本の通りにやっているので、わかりません。

コード:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>SnakeBite</title>
    <meta heep-equiv="X-UA-Compatilbe" 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 / 8;
            H = canvas.height / 8;
            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, y, 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, y, 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.ekyCode;
        }
        
        </script>
</head>
<body onload="init()">
    <canvas id="field" width="400" height="400" style="background:#cccccc">
    </canvas>

</body>
</html>

たいちう
記事: 418
登録日時: 13年前

Re: [JavaScript] なぜかうまくいかない

#3

投稿記事 by たいちう » 7年前

91行目は関数の内部ではないのでエラーになっています。
88行目の条件を満たすときに、95-104行目を実行したくないのならば、
その部分をelseにするとか。

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: [JavaScript] なぜかうまくいかない

#4

投稿記事 by YuO » 7年前

dic さんが書きました:エラーメッセージが英語でわかりません。
エラーメッセージは
Uncaught TypeError: Failed to execute 'fillText' on
'CanvasRenderingContext2D' : 3 arguments required, buf only 2 preset.
ref)
Google 翻訳 :キャッチされない例外TypeError:必要な3つの引数が、唯一の2プリセット:「CanvasRenderingContext2D'on'にfillText'を実行できませんでした。
Bing 翻訳 : キャッチ TypeError: は 'CanvasRenderingContext2D' の 'filltext' を描かないようにを実行に失敗しました: 必要な 3 つの引数 buf だけ 2 プリセット。
エキサイト 翻訳 : 捕えられていないTypeError:'CanvasRenderingContext2D'の'fillText'を実行するために失敗する:3回の議論がbufほんの2プリセット必要とした。
この翻訳に関しては、Google 翻訳が一番精度がよい感じです。

個人的な訳) キャッチされない例外 TypeError : 'CanvasrenderingContext2D'の'fillText'メソッドの実行に失敗した。 : 3つの引数が必要だが、2つしか設定されなかった。
dic さんが書きました:109行目が悪いようですが、タイプミスはしてないし、わかりません。
本当にそうでしょうか。109行目は
dic さんが書きました:

コード:

                 ctx.fillText( point. S, S * 2 );
ですが、そもそも、CanvasRenderingContext2D.fillTextは、
  1. 描画するテキスト
  2. 描画するx座標
  3. 描画するy座標
  4. 描画する最大幅(省略可能)
の4つの引数からなっており、最後の1つのみが省略可能です。
ところが、上記の109行目は、「point. S」と「S * 2」の2つの引数しか指定していません。
fillTextの引数としては不足しています。
dic さんが書きました:しかし、こんどは91行目の return; がエラーで
Uncaught SyntaxError: Illegal return statement
となってしまい。
この91行目周辺は、
dic さんが書きました: // 自分 or 壁に衝突?
if( isHit(snake,x,y) || x < 0 || x>= W || y < 0 || y >= H ) {
clearInterval(timer);
paint();
return;
}
ですが、return文は「関数から戻る」ものとしか規格に書かれていません。
ref) 13.10 The return Statement
しかし、今回のreturn文はifにぶら下がるblockの中とはいえ、関数内ではなくscriptの直下にあります。
JavaScirptはECMAScriptの方言なので、HTML5の規格をみてみましたが、scriptの中を関数であるかのように扱うという記述は、私には見付けられませんでした。
ref) script 要素 - スクリプティング - HTML要素 - HTML5 タグリファレンス - HTML5.JP (規格ではないので手抜きですが)
エラーメッセージは「不正なreturn文」と言っているのですから、実行系がscript直下のreturn文を許していないのでしょう。
例えば、script直下の内容を関数化するなどして、確実にreturn可能な状態にするのは方法だと思います。

dic
記事: 657
登録日時: 13年前
住所: 宮崎県
連絡を取る:

Re: [JavaScript] なぜかうまくいかない

#5

投稿記事 by dic » 7年前

>>YuO様 >>たいちう様
解説をありがとうございます。
目を凝らしてみた結果、 fillText( point. S, S * 2 ); となっており
fillText( point, S, S * 2 );になっておりませんでした。
. と , を見落としていました。

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

以下、他の部分もタイプミスがあったので、全文ソースコードを載せて解決とさせていただきます。

コード:

<!DOCTYPE html>

<html>
<head>
    <title>SnakeBite</title>
    <meta heep-equiv="X-UA-Compatilbe" 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, y, 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, y, y)) {
                point += 10; // 餌を食べた
                moveFood(x,y);
            } else {
                snake.pop(); // 食べていないー>しっぽを削除
            }
            
            paint();

        }

        function paint() {
            ctx.clearRect(0, 0, W * S, H * S);
            ctx.fillStyle = "red";
            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>

閉鎖

“C言語何でも質問掲示板” へ戻る