2012-10-06 44 views
0

我的問題是有關在HTML畫布繪製函數中沒有畫出。 我嘗試使用Canvas繪製「交易卡」來創建遊戲。 所以我決定寫一個函數來獲取所有必要的信息來繪製不同的卡片。 對於一張卡片 - 沒問題。但如果我嘗試在第一張卡的頂部繪製另一張卡,則可以通過第二張卡看到第一張卡上的圖像。圖片背景(畫布)

這裏的源代碼:

function RoundRect(x,y,scale,lvl,mage,headline,text,HP,MP,AtckP,DefP,MDefP){ 
      //Kartenumriss zeichnen 
      context.strokeStyle="rgb(0,0,0)"; 
      context.fillStyle="rgb(180,180,180)"; 
      context.lineWidth=2*scale; 
      context.beginPath(); 
      context.moveTo(x+10*scale,y+0*scale); 
      context.lineTo(x+90*scale,y+0*scale); 
      context.arcTo(x+100*scale,y+0*scale,x+100*scale,y+10*scale,10*scale); 
      context.lineTo(x+100*scale,y+110*scale); 
      context.arcTo(x+100*scale,y+120*scale,x+90*scale,y+120*scale,10*scale); 
      context.lineTo(x+10*scale,y+120*scale); 
      context.arcTo(x+0*scale,y+120*scale,x+0*scale,y+110*scale,10*scale); 
      context.lineTo(x+0*scale,y+10*scale); 
      context.arcTo(x+0*scale,y+0*scale,x+10*scale,y+0*scale,10*scale); 
      context.fill(); 
      context.stroke(); 
      //innerer Kartenumriss zeichnen 
      context.strokeStyle="rgb(0,0,0)"; 
      context.lineWidth=2*scale; 
      context.beginPath(); 
      context.moveTo(x+20*scale,y+10*scale) 
      context.lineTo(x+80*scale,y+10*scale); 
      context.arcTo(x+80*scale,y+20*scale,x+90*scale,y+20*scale,10*scale); 
      context.lineTo(x+90*scale,y+100*scale); 
      context.arcTo(x+80*scale,y+100*scale,x+80*scale,y+110*scale,10*scale); 
      context.lineTo(x+20*scale,y+110*scale); 
      context.arcTo(x+20*scale,y+100*scale,x+10*scale,y+100*scale,10*scale); 
      context.lineTo(x+10*scale,y+20*scale); 
      context.arcTo(x+20*scale,y+20*scale,x+20*scale,y+10*scale,10*scale); 
      context.lineCap="square"; 
      context.stroke(); 
      //Textfeld zeichnen 
      context.strokeStyle="rgb(0,0,0)"; 
      context.fillStyle="rgb(0,0,0)"; 
      context.lineWidth=2*scale; 
      context.beginPath(); 
      context.moveTo(x+90*scale,y+65*scale); 
      context.lineTo(x+90*scale,y+100*scale); 
      context.arcTo(x+80*scale,y+100*scale,x+80*scale,y+110*scale,10*scale); 
      context.lineTo(x+20*scale,y+110*scale); 
      context.arcTo(x+20*scale,y+100*scale,x+10*scale,y+100*scale,10*scale); 
      context.lineTo(x+10*scale,y+65*scale); 
      context.arcTo(x+20*scale,y+65*scale,x+20*scale,y+75*scale,10*scale); 
      context.lineTo(x+80*scale,y+75*scale) 
      context.arcTo(x+80*scale,y+65*scale,x+90*scale,y+65*scale,10*scale) 
      context.lineCap="square"; 
      context.fill(); 
      context.stroke(); 
      //lvl zeichnen 
      shift=0; 
      for(var greystar=0;greystar<=4; greystar++){ 
       context.strokeStyle="rgb(100,100,100)"; 
       context.fillStyle="rgb(100,100,100)"; 
       context.beginPath(); 
       context.moveTo(shift+x+23.33*scale,y+112*scale); 
       context.lineTo(shift+x+25.33*scale,y+118.66*scale); 
       context.lineTo(shift+x+20*scale,y+114.53*scale); 
       context.lineTo(shift+x+26.66*scale,y+114.53*scale); 
       context.lineTo(shift+x+21.26*scale,y+118.66*scale); 
       context.lineTo(shift+x+23.33*scale,y+112*scale); 
       context.fill(); 
       shift+=13.5*scale; 
      } 
      shift=0; 
      while(lvl>0){ 
       context.strokeStyle="yellow"; 
       context.fillStyle="yellow"; 
       context.beginPath(); 
       context.moveTo(shift+x+23.33*scale,y+112*scale); 
       context.lineTo(shift+x+25.33*scale,y+118.66*scale); 
       context.lineTo(shift+x+20*scale,y+114.53*scale); 
       context.lineTo(shift+x+26.66*scale,y+114.53*scale); 
       context.lineTo(shift+x+21.26*scale,y+118.66*scale); 
       context.lineTo(shift+x+23.33*scale,y+112*scale); 
       context.fill(); 
       shift+=13.5*scale; 
       lvl--; 
      } 
      //Bild einbinden 
      var chucknorris = new Image(); 
      chucknorris.onload = function() { 
       context.drawImage(chucknorris,x+18*scale,y+18*scale,64*scale,49*scale); 
      }; 
      chucknorris.src="pics/chucknorris.png"; 
      //Symbole einbinden 
      //life 
      var life = new Image(); 
      life.onload = function() { 
       context.drawImage(life,x+87*scale,y+11*scale,7*scale,7*scale); 
      }; 
      life.src="pics/heart_small.png"; 
      //magic 
      var magic = new Image(); 
      magic.onload = function() { 
       context.drawImage(magic,x+6*scale,y+11*scale,7*scale,7*scale); 
      }; 
      magic.src="pics/magic_small.png"; 
      if(mage==true){ 
       //wand 
       var wand = new Image(); 
       wand.onload = function() { 
        context.drawImage(wand,x+6*scale,y+102*scale,7*scale,7*scale); 
       }; 
       wand.src="pics/wand_small.png"; 
      } 
      else{ 
       //sword 
       var sword = new Image(); 
       sword.onload = function() { 
        context.drawImage(sword,x+6*scale,y+102*scale,7*scale,7*scale); 
       }; 
       sword.src="pics/sword_crossed_small.png"; 
      } 
      //shield 
      var shield = new Image(); 
      shield.onload = function() { 
       context.drawImage(shield,x+85*scale,y+102*scale,7*scale,7*scale); 
      }; 
      shield.src="pics/shield_small.png"; 
      //magic_shield 
      var magic_shield = new Image(); 
      magic_shield.onload = function() { 
       context.drawImage(magic_shield,x+91*scale,y+102*scale,7*scale,7*scale); 
      }; 
      magic_shield.src="pics/magic_shield_small.png"; 
      //Text einfügen 
      context.font = 'bold '+4*scale+'px Calibri'; 
      context.fillStyle = 'rgb(255,255,255)'; 
      context.fillText(headline,x+20*scale, y+80*scale); 
      context.font = 'normal '+3*scale+'px Calibri'; 
      context.fillStyle = 'rgb(255,255,255)'; 
      wrapText(context, text, x+20*scale, y+85*scale, maxWidth, lineHeight, scale); 
      //HP anzeigen 
      context.font = 'bold 20pt Calibri'; 
      context.fillStyle = 'rgb(255,0,0)'; 
      var textmetric = context.measureText(HP); 
      var textwidth = textmetric.width/2; 
      context.fillText(HP,x-textwidth+90.25*scale, y+10*scale); 
      //MP anzeigen 
      context.fillStyle = 'rgb(0,0,255)'; 
      textmetric = context.measureText(MP); 
      textwidth = textmetric.width/2; 
      context.fillText(MP,x-textwidth+9.5*scale, y+10*scale); 
      //AtckP anzeigen 
      context.fillStyle = 'rgb(0,0,0)'; 
      textmetric = context.measureText(AtckP); 
      textwidth = textmetric.width/2; 
      context.fillText(AtckP,x-textwidth+9.5*scale, y+115*scale); 
      //DefP und MDefP anzeigen 
      context.fillStyle = 'rgb(0,0,0)'; 
      var DefAll = DefP+'/'+MDefP; 
      textmetric = context.measureText(DefAll); 
      textwidth = textmetric.width; 
      context.fillText(DefAll,x-textwidth+98*scale, y+115*scale); 
     }; 

我認爲重要的部分是「圖片報//​​ einbinden」和「//文字einfügen」之間,但我不知道這一點。

的功能在測試代碼以後像這樣使用:

RoundRect(0,0,4,5,false,'Chuck Norris','Wenn Chuck Norris spricht, hört Gott zu!!! Chuck Norris` Tränen können Krebs heilen. Nur schade dass er niemals weint!!! Chuck Norris geht manchmal Blut spenden. Nur nie sein eigenes. Und wenn doch, dann mit ner Knarre und nem Eimer!!!','100','0','120','20','60'); 
RoundRect(100,120,4,2,false,'Chuck Norris Vers 0.3','Wenn Chuck Norris spricht, hört Gott zu!!! Chuck Norris` Tränen können Krebs heilen. Nur schade dass er niemals weint!!! Chuck Norris geht manchmal Blut spenden. Nur nie sein eigenes. Und wenn doch, dann mit ner Knarre und nem Eimer!!!','50','100','60','10','30'); 

下面的結果:

Result

我希望有一個人誰可以幫助我。預先感謝您(< - 希望Google-Tranlator就在這裏 - 聽起來對我來說是錯誤的...)。

編輯: 我想出了一部分問題,但我仍然需要一個解決方案: 我試着在代碼中設置一些「alert()」。結果是interessting:首先,從第一張卡的背景畫出。然後是第二張牌的背景。之後,第一張卡片的圖像被繪製,然後其他卡片從第二張卡片中拉出。因此繪製了其他所有繪製的圖像。 所以問題是如何告訴Canvas立即繪製圖像,或者至少在函數內繪製圖像。

回答

1

你做好一切後繪製的圖像,因爲它們是在Image.onLoad的回調繪製的()。

這意味着該函數將首先渲染第一張卡片的背景,爲您的Image.onLoad事件註冊一個偵聽器,然後返回,以便您可以進行seconde調用,它將渲染背景並註冊另一個監聽新的Image.onLoad事件。然後第一個偵聽器在加載第一個圖像時觸發,所以它將繪製圖片,最後一個偵聽器將被觸發。因此你的結果。

至於解決此問題的方法,可以在繪製任何卡之前加載圖像,然後直接在函數中繪製圖像,避免等待加載,或者使您的設計成爲異步驗證。你可以在這裏得到有關異步編程的信息:http://www.html5rocks.com/en/tutorials/async/deferred/?redirect_from_locale=why

編輯:第二個解決方案可以幫助第一個解決方案(它對應於enzhflep的答案)。本文重新推薦使用jquery來處理異步事件,如加載多個圖像。但是,如果你不需要jQuery,你也可以編寫一個小的JavaScript對象,它可以註冊要加載的圖像,並在加載所有圖像時觸發偵聽器。 This ressource似乎提供了特定的對象。

+0

謝謝你。我會無論如何讀這篇文章。但是我想首先測試enhzflep的解決方案^^ – Sandro

0

不是問題。你的英語很好。 (你提到的翻譯是有點奇怪「謝謝,你在前進)

正如你似乎開始鑑定,該問題是由於它需要加載圖像的時間..

每次你畫一張卡片,你就加載它的每一張圖片。一旦每個圖像被加載,它的onload處理器就會觸發並將其繪製到畫布上。現在,問題在於有時第一張卡片的圖像在繪製第二張卡片時仍然在加載。這意味着第二張卡的部分已經在卡1的圖像加載之前被繪製。當他們最終加載時,它們被繪製在card2之上。

你可以通過在頁面的init函數中加載圖像來解決這個問題。

下面是我用了一個解決方案:

var canvas, context; 

var chucknorris = new Image(); 
var life = new Image(); 
var magic = new Image(); 
var wand = new Image(); 
var sword = new Image(); 
var shield = new Image(); 
var magic_shield = new Image(); 

function myInit() 
{ 
    chucknorris.src="img/girl.png"; //"pics/chucknorris.png"; 
    life.src="img/heartSmall.jpg"; //"pics/heart_small.png"; 
    magic.src="img/magicSmall.jpg"; //"pics/magic_small.png"; 
    wand.src="img/magicSmall.jpg"; //"pics/wand_small.png"; 
    sword.src="img/magicSmall.jpg"; //"pics/sword_crossed_small.png"; 
    shield.src="img/close.png"; //pics/shield_small.png"; 
    magic_shield.src="img/magicSmall.jpg"; //"pics/magic_shield_small.png"; 

    canvas = document.createElement('canvas'); 
    canvas.setAttribute('width', '400'); 
    canvas.setAttribute('height', '800'); 
    context = canvas.getContext('2d'); 
    document.body.appendChild(canvas); 

    RoundRect(0,0,2,5,false,'Chuck Norris','Wenn Chuck Norris spricht, hört Gott zu!!! Chuck Norris` Tränen können Krebs heilen. Nur schade dass er niemals weint!!! Chuck Norris geht manchmal Blut spenden. Nur nie sein eigenes. Und wenn doch, dann mit ner Knarre und nem Eimer!!!','100','0','120','20','60'); 

    RoundRect(128,0,2,5,false,'Pussy Galore','She loves Austin Powers','100','0','120','20','60'); 
} 



function RoundRect(x,y,scale,lvl,mage,headline,text,HP,MP,AtckP,DefP,MDefP) 
{ 
    var mImages 

    //Kartenumriss zeichnen 
    context.globalCompositeOperation = "src-over"; 

    context.strokeStyle="rgb(0,0,0)"; 
    context.fillStyle="rgb(180,180,180)"; 
    context.lineWidth=2*scale; 
    context.beginPath(); 
    context.moveTo(x+10*scale,y+0*scale); 
    context.lineTo(x+90*scale,y+0*scale); 
    context.arcTo(x+100*scale,y+0*scale,x+100*scale,y+10*scale,10*scale); 
    context.lineTo(x+100*scale,y+110*scale); 
    context.arcTo(x+100*scale,y+120*scale,x+90*scale,y+120*scale,10*scale); 
    context.lineTo(x+10*scale,y+120*scale); 
    context.arcTo(x+0*scale,y+120*scale,x+0*scale,y+110*scale,10*scale); 
    context.lineTo(x+0*scale,y+10*scale); 
    context.arcTo(x+0*scale,y+0*scale,x+10*scale,y+0*scale,10*scale); 
    context.fill(); 
    context.stroke(); 
    //innerer Kartenumriss zeichnen 
    context.strokeStyle="rgb(0,0,0)"; 
    context.lineWidth=2*scale; 
    context.beginPath(); 
    context.moveTo(x+20*scale,y+10*scale) 
    context.lineTo(x+80*scale,y+10*scale); 
    context.arcTo(x+80*scale,y+20*scale,x+90*scale,y+20*scale,10*scale); 
    context.lineTo(x+90*scale,y+100*scale); 
    context.arcTo(x+80*scale,y+100*scale,x+80*scale,y+110*scale,10*scale); 
    context.lineTo(x+20*scale,y+110*scale); 
    context.arcTo(x+20*scale,y+100*scale,x+10*scale,y+100*scale,10*scale); 
    context.lineTo(x+10*scale,y+20*scale); 
    context.arcTo(x+20*scale,y+20*scale,x+20*scale,y+10*scale,10*scale); 
    context.lineCap="square"; 
    context.stroke(); 
    //Textfeld zeichnen 
    context.strokeStyle="rgb(0,0,0)"; 
    context.fillStyle="rgb(0,0,0)"; 
    context.lineWidth=2*scale; 
    context.beginPath(); 
    context.moveTo(x+90*scale,y+65*scale); 
    context.lineTo(x+90*scale,y+100*scale); 
    context.arcTo(x+80*scale,y+100*scale,x+80*scale,y+110*scale,10*scale); 
    context.lineTo(x+20*scale,y+110*scale); 
    context.arcTo(x+20*scale,y+100*scale,x+10*scale,y+100*scale,10*scale); 
    context.lineTo(x+10*scale,y+65*scale); 
    context.arcTo(x+20*scale,y+65*scale,x+20*scale,y+75*scale,10*scale); 
    context.lineTo(x+80*scale,y+75*scale) 
    context.arcTo(x+80*scale,y+65*scale,x+90*scale,y+65*scale,10*scale) 
    context.lineCap="square"; 
    context.fill(); 
    context.stroke(); 
    //lvl zeichnen 
    shift=0; 
    for(var greystar=0;greystar<=4; greystar++) 
    { 
     context.strokeStyle="rgb(100,100,100)"; 
     context.fillStyle="rgb(100,100,100)"; 
     context.beginPath(); 
     context.moveTo(shift+x+23.33*scale,y+112*scale); 
     context.lineTo(shift+x+25.33*scale,y+118.66*scale); 
     context.lineTo(shift+x+20*scale,y+114.53*scale); 
     context.lineTo(shift+x+26.66*scale,y+114.53*scale); 
     context.lineTo(shift+x+21.26*scale,y+118.66*scale); 
     context.lineTo(shift+x+23.33*scale,y+112*scale); 
     context.fill(); 
     shift+=13.5*scale; 
    } 
    shift=0; 
    while(lvl>0) 
    { 
     context.strokeStyle="yellow"; 
     context.fillStyle="yellow"; 
     context.beginPath(); 
     context.moveTo(shift+x+23.33*scale,y+112*scale); 
     context.lineTo(shift+x+25.33*scale,y+118.66*scale); 
     context.lineTo(shift+x+20*scale,y+114.53*scale); 
     context.lineTo(shift+x+26.66*scale,y+114.53*scale); 
     context.lineTo(shift+x+21.26*scale,y+118.66*scale); 
     context.lineTo(shift+x+23.33*scale,y+112*scale); 
     context.fill(); 
     shift+=13.5*scale; 
     lvl--; 
    } 
    //Bild einbinden 
    context.drawImage(chucknorris,x+18*scale,y+18*scale,64*scale,49*scale); 

    //Symbole einbinden 
    //life 
    context.drawImage(life,x+87*scale,y+11*scale,7*scale,7*scale); 

    //magic 
     context.drawImage(magic,x+6*scale,y+11*scale,7*scale,7*scale); 
    if(mage==true) 
    { 
     context.drawImage(wand,x+6*scale,y+102*scale,7*scale,7*scale); 
    } 
    else{ 
      context.drawImage(sword,x+6*scale,y+102*scale,7*scale,7*scale); 
    } 
    //shield 
     context.drawImage(shield,x+85*scale,y+102*scale,7*scale,7*scale); 

     //magic_shield 
// magic_shield.onload = function() { 
     context.drawImage(magic_shield,x+91*scale,y+102*scale,7*scale,7*scale); 
// }; 

    //Text einfügen 
    context.font = 'bold '+4*scale+'px Calibri'; 
    context.fillStyle = 'rgb(255,255,255)'; 
    context.fillText(headline,x+20*scale, y+80*scale); 
    context.font = 'normal '+3*scale+'px Calibri'; 
    context.fillStyle = 'rgb(255,255,255)'; 
    wrapText(context, text, x+20*scale, y+85*scale, maxWidth, lineHeight, scale); 
    //HP anzeigen 
    context.font = 'bold 20pt Calibri'; 
    context.fillStyle = 'rgb(255,0,0)'; 
    var textmetric = context.measureText(HP); 
    var textwidth = textmetric.width/2; 
    context.fillText(HP,x-textwidth+90.25*scale, y+10*scale); 
    //MP anzeigen 
    context.fillStyle = 'rgb(0,0,255)'; 
    textmetric = context.measureText(MP); 
    textwidth = textmetric.width/2; 
    context.fillText(MP,x-textwidth+9.5*scale, y+10*scale); 
    //AtckP anzeigen 
    context.fillStyle = 'rgb(0,0,0)'; 
    textmetric = context.measureText(AtckP); 
    textwidth = textmetric.width/2; 
    context.fillText(AtckP,x-textwidth+9.5*scale, y+115*scale); 
    //DefP und MDefP anzeigen 
    context.fillStyle = 'rgb(0,0,0)'; 
    var DefAll = DefP+'/'+MDefP; 
    textmetric = context.measureText(DefAll); 
    textwidth = textmetric.width; 
    context.fillText(DefAll,x-textwidth+98*scale, y+115*scale); 
}; 
+0

如果你的連接速度足夠快以便在需要繪製圖像之前加載圖像,這應該可以工作。也許你應該在調用RoundRect之前檢查是否加載了所有圖像。 – TonioElGringo

+0

謝謝。我會試試這個,並在稍後發佈結果。 @TonioElGringo:你會如何檢查? – Sandro

+0

@TonioElGringo - 這是一個很好的觀點。感謝您提供我忽略的清晰度!從本地主機加載資源總是會比通過電線或空氣更快:) – enhzflep