0

変数の実際の値がユーザーによって更新されたときに、JavaScript変数によってHTML5キャンバスに表示される値を「再書き込み」する簡単な方法があるかどうか疑問に思っていますか?

たとえば、HTML5キャンバスとJavaScriptを使用して、ユーザーに基本的なウェールズ語を教える非常にシンプルなゲームを作成しています。

現在、2つの配列があります。1つは1〜10の数字の10個の.png画像を含み、もう1つは1〜10の数字のウェールズ語の10個の文字列を含みます。

ユーザーがページを表示すると、キャンバスに「ゲーム開始」ボタンが表示されます。このボタンをクリックすると、画像配列からランダムな要素が1つ、単語配列からランダムな要素が1つ、目盛りと十字の画像が描画されます。 。

画像と単語が同じ数字を表す場合、ユーザーはチェックマークをクリックする必要があります。そうでない場合、ユーザーは十字をクリックする必要があります。ユーザーが正しい選択を行った場合-値が5増加した(0から開始)currentScore変数があり、間違った選択を行った場合、currentScoreの値は同じままです。

ブラウザでページを表示してゲームをプレイするときに、画像と単語が数字を表すときにチェックマークをクリックすると、コンソールでcurrentScoreの値が5増加していることがわかりますが、currentScoreの値はキャンバスに表示されるものは同じままです。同様に、一致しないときに十字をクリックすると、コンソールではスコアが増加しますが、キャンバスでは増加しません。

したがって、コードの背後にあるロジックは正しく、それは機能します。実際の値が更新されるたびに、currentScoreに表示される値をキャンバス上で更新する方法がわかりません。

これを行うために使用している関数は次のとおりです。

function drawLevelOneElements(){
            /*First, clear the canvas */ 
            context.clearRect(0, 0, myGameCanvas.width, myGameCanvas.height);
            /*This line clears all of the elements that were previously drawn on the canvas. */
            /*Then redraw the game elements */
            drawGameElements(); 

            /*Create an array of words for numbers 1-10 */
            var wordsArray = new Array();
            wordsArray[0] = "Un";
            wordsArray[1] = "Dau";
            wordsArray[2] = "Tri";
            wordsArray[3] = "Pedwar";
            wordsArray[4] = "Pump";
            wordsArray[5] = "Chwech";
            wordsArray[6] = "Saith";
            wordsArray[7] = "Wyth";
            wordsArray[8] = "Naw";
            wordsArray[9] = "Deg";

            /*Use Math.random() to generate a random number between 1 & 10 to draw the word and image to the canvas */
            var drawnImage = Math.floor(Math.random()*10);
            var drawnWord = Math.floor(Math.random()*10);

            /*Draw an image and a word to the canvas just to test that they're being drawn */
            context.drawImage(imageArray[drawnImage], 100, 30, 30, 30);
            context.strokeText(wordsArray[drawnWord], 500, 60);

            /*Now draw the tick and cross to the canvas */
            context.font = "30pt Calibri"; /*Set text font and size */
            context.drawImage(tick, 250, 200, 50, 50);
            context.drawImage(cross, 350, 200, 50, 50);

            /*Add an event listener to the page to listen for a click on the tick or the cross, if the user clicks
                the right one to indicate whether the image and word relate to the same number or not, increase the
                user's score*/
            myGameCanvas.addEventListener('click', function(e){
                console.log('click: ' + e.pageX + '/' + e.pageY);
                var mouseX = e.pageX - this.offsetLeft;
                var mouseY = e.pageY - this.offsetTop;
                /*If the tick is clicked, check whether or not the image and word represent the same number, if they do,
                    increase the score, if not, leave the score as it is*/
                if((mouseX > 250 && mouseX < 300) && (mouseY > 200 && mouseY < 250) && (drawnImage == drawnWord)){ 
                    currentScore = currentScore + 5;
                    console.log('Current Score = ' + currentScore);
                } else if((mouseX > 250 && mouseX < 300) && (mouseY > 200 && mouseY < 250) && (drawnImage != drawnWord)){
                    currentScore = currentScore; 
                    console.log('Current Score = ' + currentScore);

                /*If the cross is clicked, check whether or not the image and word represent the same number, if they 
                    don't, increase the score, otherwise, leave the score as it is*/
                } else if((mouseX > 350 && mouseX < 400) && (mouseY > 200 && mouseY < 250) && (drawnImage != drawnWord)){
                    currentScore = currentScore + 5;
                    console.log('Current Score = ' + currentScore);
                } else if ((mouseX > 350 && mouseX < 400) && (mouseY > 200 && mouseY < 250) && (drawnImage == drawnWord)){
                    currentScore = currentScore; 
                    console.log('Current Score = '+ currentScore); 
                } else {
                    console.log('The click was not on either the tick or the cross.');
                }
            }, false);

これを行うのにあまりにも多くのコードが必要になるとは思いませんでしたが、それを行う方法を理解することはできません。どんな助けでも大歓迎です。ありがとう!

*編集*

あなたが提案したようにコードを追加しましたが、キャンバスに表示されるスコアはまだ何らかの理由で更新されていません...

if((mouseX > 250 && mouseX < 300) && (mouseY > 200 && mouseY < 250) && (drawnImage == drawnWord)){ 
                    currentScore = currentScore + 5;
                    context.clearRect(currentScorePositionX, currentScorePositionY, 20, 20); /*Clear the old score from the canvas */
                    context.strokeText(currentScore, 650, 15); /*Now write the new score to the canvas */
                    console.log('Current Score = ' + currentScore);
                } else if((mouseX > 250 && mouseX < 300) && (mouseY > 200 && mouseY < 250) && (drawnImage != drawnWord)){
                    currentScore = currentScore; 
                    console.log('Current Score = ' + currentScore);

助言がありますか?

4

4 に答える 4

1

思いもよらなかったかもしれませんが、canvas 要素は透明で、互いに重ねることができるということです。このようにして、GUI のみのキャンバスとアクション キャンバスを作成し、それらを別々に保つことができます。CSSに自信がなく、例が必要な場合は、絶対配置でこれが機能します。

于 2012-05-10T23:13:38.490 に答える
0

Ed Kirkの発言に基づいて、スコア変数が頻繁に(たとえば、初心者の場合は50ミリ秒)それ自体と比較することで、スコア変数がいつ変更されたかを検出できます。

例:

var myScore = 0;
var myOldScore = myScore;

setInterval(function() { 
    if(myScore != myOldScore) {
        myOldScore = myScore;
        // the variable has changed, write it to the canvas
    }
}, 50); // will execute every 50 milliseconds
于 2012-05-10T13:28:34.973 に答える
0

キャンバスの表示を更新するには、キャンバスの一部または全部をクリアして再描画する必要があります。drawLevelOneElements() の最初の行ですでにこれを行っています-画面全体をクリアします。セクションだけをクリアするには、次のことができます。

context.clearRect(x, y, scoreDigitWidth, scoreDigitHeight);

x と y はスコア桁の座標で、scoreDigitWidth と scoreDigitHeight は幅と高さです。次に、context.drawImage() を使用して、このクリアされた領域を埋めることができます。フレームを継続的に更新するループを使用してプロセスを開始するか、更新する必要がない場合は、次の行の後に実行することができます。

currentScore = currentScore;

つまり、新しいスコアを知っているときです。

通常、キャンバス上で変更されたものすべてではなく、変更されたものだけをクリアして再描画する方が適切です。パフォーマンスについては、こちらの記事を参照してください。http://www.html5rocks.com/en/tutorials/canvas/performance/ .

非常に単純なアニメーションのように見えます。キャンバスの代わりに html 要素 (div、imgs など) を使用する方がよいかもしれません。これにより、キャンバス要素をサポートしていないブラウザー (つまり IE8) を使用するユーザーが引き続き使用できるようになります。 <。

于 2012-05-10T13:24:53.697 に答える