2012-05-10 13 views
0

HTML5キャンバスのJavaScript変数に表示される値を簡単に再書き込みする方法があるのでしょうか?変数の値がユーザーによって更新されましたか?変数の値が更新されたときにJavaScript変数をHTML5キャンバスに書き直します

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

現在、私は2つの配列を持っています:1つは10の.pngの画像を含み、もう1つは1~10のウェールズ語の10の文字列です。

ユーザーがページを見ると、キャンバスには「クリックしてゲーム」ボタンが表示されます。このボタンをクリックすると、イメージ配列から1つのランダム要素とwords配列から1つのランダム要素が描画されます。ダニと十字架。

イメージと単語が同じ番号を表す場合、ユーザーはティックをクリックする必要があります。ティックをクリックしないと、ユーザーは十字形をクリックします。ユーザーが適切な選択を行った場合、currentScore変数の値が5(0から始まる)増加し、誤った選択を行った場合、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); 

は、私はそれがこれを行うには、あまりにも多くのコードを必要とするだろうと思っていないだろうが、私はちょうど行う方法を動作することはできませんそれ。どんな助けでも大歓迎です。ありがとう!

* EDIT *

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

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); 

助言がありますか?

答えて

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 <です。

+0

context.drawImage()ではなく、最初にcontext.strokeText()を使用してスコアを書き込んでいますので、この矩形をクリアした後に再度strokeTextを使用して新しいスコアを書き込むことはできますか? – someone2088

+0

はい、あなたのフォントが異なる文字で異なる幅を使用するかどうかを注意する必要があります。 1を0に置き換えると、次の桁と重複する可能性があります。そのため、最初または適切な方法で適切な間隔で各桁を別々に描画し、スコア文字列全体をクリアしてから再描画することをお勧めします。 –

+0

また、キャンバスを使用することが不可欠であるか、標準のhtml div要素とimg要素を使用する方が良い方法かどうかを検討したいと思います。 –

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 
+0

私が持っている問題は、スコア変数が変更されたかどうかを検出していないことです。ティックやクロスをクリックするたびに、Firebugコンソールに更新された値が表示されるためです。私の問題は、キャンバス上で更新された値を示しています... – someone2088

+0

これは更新のためのより良い方法です、それは長期的にはより信頼性が高く、スクリーン更新の過度な実行やパフォーマンスの低下を防ぎます。あなたのスコアが2msごとに変わり始めるとすぐに停止するようになります。 –

0

私は私の機能にいくつかの変更を加えた、そして今follwingコードを持っていました:

/*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; 
        var scorePositionX = currentScorePositionX; 
        var scorePositionY = currentScorePositionY; 
        context.clearRect(scorePositionX, scorePositionY, 30, 30); /*Clear the old score from the canvas */ 
        context.strokeText(currentScore, 650, 50); /*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); 

       /*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; 
        context.clearRect(currentScorePositionX, currentScorePositionY, 20, 20); /*Clear the old score from the canvas */ 
        context.strokeText(currentScore, 500, 50); /*Now write the new score to the canvas */ 
        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); 

これは、現在のスコアを表示し、更新されましたユーザが正確にティックやクロスを選択するたびに、スコアを前の図を削除して新しいスコアをその場所に書き込むのではなく、毎回キャンバスに新しいスコアを描画するときに、にpであるので、古いスコアと新しいスコアの両方が同じ場所に表示されます。これはちょっと混乱し、読みにくいものです。

また、スコアのサイズは&で、私が意図した場所ではありません。前に述べたようにスコアバーに表示されることを意図していましたが、スコアバーの下に表示されます。キャンバスのメインの「表示」セクションに表示されます。また、フォントは異なります。数字は通常の文字、つまり5,10などでは表示されませんが、フォントは大きく、数字の真ん中に空白が入り、「バブル」と似ています。フォントは、私が 'スコアバー'に表示したテキストのサイズの少なくとも2倍の大きさでもあります。

私がここで間違っていることを誰かが指摘できますか?どうもありがとう!

+0

これは新しい質問で尋ねられるべきです。 –

+0

@danpあなたは言った "あなたには起こり得なかったことは、キャンバスの要素が透明になり、お互いの上に積み重ねられることです。この方法では、GUIのみのキャンバスとアクションキャンバスを持つことができます。それらを別々にしておいてください。絶対的なポジショニングは、あなたがCSSに自信がなく、例を欲しがっているならば、この作業を行います。 例がありますか? – Someone2088

1

あなたには何も起こり得なかったことは、キャンバス要素が透明であり、互いの上に積み重ねられているということです。このようにして、GUIのみのキャンバスとアクションキャンバスを用意し、それらを別々に保つことができます。あなたがcssに自信がないなら、絶対的なポジショニングはこの仕事をし、例を欲しがります。

関連する問題