2012-02-17 59 views
2

我在將畫布從緩衝區畫布複製到頁面上的畫布時遇到了一些困難。到目前爲止,我已經構建了一個Render對象,一個Level對象,並且我有我的主遊戲循環(目前只是一個啓動函數)。如何將隱藏畫布上的內容複製到可見畫布上?

我能夠寫入Render對象的緩衝區畫布(如果我添加一個document.body.append()語句畫布成功地附加到具有必要內容的文檔),但我不能從緩衝畫布到我的主要畫布。見下文對我的代碼片段:

function Renderer(bufferWidth, bufferHeight) { 
    var c=document.createElement('canvas'); 
    var ctx=c.getContext('2d'); 
    c.width=bufferWidth; 
    c.height=bufferHeight; 

    this.getBufferContext = function() { return ctx; }; 
    this.getBufferElement = function() { return c; }; 

    this.drawToCanvas = function(canvasCtx) { 
     canvasCtx.drawImage(c,0,0); 
    }; 
} 


var c = document.getElementById('mycanvas'); 
var ctx = c.getContext('2d'); 

var render = new Renderer(c.width, c.height); 
var level1 = new Level('images/imagequality.png'); 

level1.Draw(render.getBufferContext()); 
render.drawToCanvas(ctx); 

注意,渲染是在一個單獨的文件,並在我的HTML頁面中使用script標籤加載。

如前所述,drawToCanvas()函數似乎沒有成功將數據從一個畫布複製到另一個畫布。追加我的源畫布確認它包含預期的數據。

編輯:我在下面列出了我的關卡代碼。

function Level(mapname) { 
    var map=new Image(); 
    map.src=mapname; 

    this.Draw = function(renderer) { 
     map.onload = function() { renderer.drawImage(map,0,0); }; 
    }; 
} 

回答

3

我有好消息,而且我有壞消息。

好消息是,你在這裏展示的代碼工作100% 這裏是演示:http://jsbin.com/upatij/edit#javascript,html,live

壞消息:這意味着,作爲我的存根等級代碼完全在你的框架您的等級代碼裏面的東西被打破... :-(

存根等級:

function Level() { 
    this.Draw = function(xxctx) { 
    for (var i = 0; i < 30; i++) { 
     xxctx.moveTo(10 + (i * 40 % 300), 10 + (parseInt(i/6, 10) * 40)); 
     xxctx.lineTo(40 + (i * 40 % 300), 40 + (parseInt(i/6, 10) * 40)); 
     xxctx.moveTo(40 + (i * 40 % 300), 10 + (parseInt(i/6, 10) * 40)); 
     xxctx.lineTo(10 + (i * 40 % 300), 40 + (parseInt(i/6, 10) * 40)); 
    } 
    xxctx.stroke(); 
    }; 
} 

好運-CK

後,你看到你的級別代碼:

的問題是同步的,您的使用類在這裏都躲在從你的問題,通過欺騙性的命名,如您Level.Draw,是不是平局功能在所有...讓我解開它你:

var c = document.getElementById('mycanvas'); 
var ctx = c.getContext('2d'); 

// var render = new Renderer(c.width, c.height); 
var Renderer_c = document.createElement('canvas'); 
var Renderer_ctx = Renderer_c.getContext('2d'); 
document.body.appendChild(Renderer_c); //added to show 
Renderer_c.width = c.width; 
Renderer_c.height = c.height; 

// var level1 = new Level('images/imagequality.png'); 
var map = new Image(); 
document.body.appendChild(map); //add to show 
map.src = 'http://th06.deviantart.net/fs71/150/i/2011/255/9/5/omnom_upside_down_by_earnurm-d49pjnl.png'; 

console.log('at ' + 1); 
// level1.Draw(render.getBufferContext()); 
map.onload = function() { 
    console.log('at ' + 3); 
    //this happens async: 
    alert('drawing now!'); 
    Renderer_ctx.drawImage(map,0,0); 
}; 

console.log('at ' + 2); 
// render.drawToCanvas(ctx); 
ctx.drawImage(Renderer_c, 0, 0); 

如果您運行的代碼,你會看到,在處onload叫一切已經執行的那一刻,你會發現如何控制檯將顯示爲:

at 1 
at 2 
at 3 

,因此,此刻當執行alert('drawing now!'); ...

// render.drawToCanvas(ctx); 
ctx.drawImage(Renderer_c, 0, 0); 

將已經跑了......基本上你Draw()功能實際上是一個異步的「加載」。不幸的是,你目前的概念化不起作用。你Draw()功能需要是一個異步一個這樣的:

function Level(mapname) { 
    var map=new Image(); 
    document.body.appendChild(map); //add to show 
    map.src=mapname; 

    this.asyncDraw = function(renderer, onComplete) { 
     map.onload = function() { 
      renderer.drawImage(map,0,0); 
      onComplete(); 
     }; 
    }; 
} 

和功能,那麼應該被稱爲像這樣在你的榜樣:

level1.asyncDraw(render.getBufferContext(), function() { 
    render.drawToCanvas(ctx); 
}); 

我也許應該去上說,這種類型的異步性使得HTML5遊戲編程有點棘手,因爲您必須拋出「加載...」微調器,並在加載所有「資源」之前不要進入渲染循環。在所有的實踐中,你都需要「準備就緒」的概念。 Load(fOnReady)Draw(ctx),而不是僅僅asyncDraw(ctx, fOnReady) ...

更新jsbin是在這裏:http://jsbin.com/upatij/2/edit

希望這有助於-ck

+0

感謝您的反饋。如果您有興趣,我已將我的關卡代碼附加到原始文件。在那裏沒有什麼特別的事情發生......到目前爲止,它只是向提供的畫布上下文(渲染器)繪製單個圖像。 FWIW我在我的HTML頁面中的body.onload函數中調用了函數launch()中的繪圖代碼(創建上下文,渲染器,級別等)。 – RavB 2012-02-17 21:17:15

相關問題