2012-10-06 40 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