我的网络应用程序的画布绘图

时间:2016-06-13 14:11:05

标签: javascript html5 canvas

我刚刚开始在我的网页游戏项目中使用Canvas并遇到了问题。

我使用此代码渲染游戏:

function render(f){
if(charoffset.x == null) charoffset.x = charpos.x*tilescale;
if(charoffset.y == null) charoffset.y = charpos.y*tilescale;

if(!tiles) tiles = [];
if(f){
    log("Welcome.","gold");

}
var canPassthrough = function (){
    if ((def.passable(this.type))&&(typeof this.type !== 'undefined')){
        return true;
    }
    else {
        return false;
    }
};
if(!f) lighting.update();
canvas.getContext("2d").clearRect(0,0,sq,sq);
for (var i = 0; i < map[charlvl].length; i++){
    if(!tiles[i]) tiles[i] = [];
    for (var j = 0; j < map[charlvl][i].length; j++){
        if(!tiles[i][j]) tiles[i][j] = placetile(i,j);
        drawtile(tiles[i][j]);
        placeitem(i,j);
    }
}
ui.overlay.text("casting shadows...");
//shadowcaster(20);
    var tex = document.createElement("img");
    tex.src = "../img/charplaceholder.png";
    var hero = canvas.getContext("2d");
    hero.globalAlpha = 1.0;
    if(charoffset.x>=map_scroll.x&&charoffset.y*tilescale>=map_scroll.y){
        var pos = {
            x: charoffset.x - map_scroll.x - tilescale,
            y: charoffset.y - map_scroll.y - tilescale
        };
        hero.drawImage(tex,pos.x,pos.y,tilescale,tilescale);
    }
function placetile(x,y){
    var obj = {};
    obj.type = map[charlvl][x][y].id;
    obj.canPassthrough = canPassthrough;
    obj.state = {explored: false, lit: false};
    obj.coords = {x:x,y:y};
    obj.offset = {x:x*tilescale,y:y*tilescale};
    return obj;
}
function drawtile(t){
    if(t.offset.x>=map_scroll.x&&t.offset.y>=map_scroll.y){
        var pos = {
            x: t.offset.x - map_scroll.x - tilescale,
            y: t.offset.y - map_scroll.y - tilescale
        };
        if(!t.state.explored&&!t.state.lit){
            return false;
        }
        else if(t.state.lit&&t.state.explored){

            var tex = document.createElement("img");
            var tile = canvas.getContext("2d");
            tex.src = def.css.tile(t.type);
            tile.globalAlpha = 1.0;
            tile.drawImage(tex,pos.x,pos.y,tilescale,tilescale);
            return true;
        }
        else if(t.state.explored&&!t.state.lit){
            var tex = document.createElement("img");
            var tile = canvas.getContext("2d");
            tex.src = def.css.tile(t.type);
            tile.globalAlpha = 0.25;
            tile.drawImage(tex,pos.x,pos.y,tilescale,tilescale);
            return true;
        }
    }
}
function placeitem(x,y){
    return;
    if (loot[charlvl][x][y]){
        for(var i=0;i<loot[charlvl][x][y].length;i++){
            var tile = document.createElement("div");
            var tileid = loot[charlvl][x][y][i].type;
            tile.className = def.css.item(tileid);
            tile.coords = {x:x,y:y};
            document.getElementById("x" + x + "y" + y).appendChild(tile);
        }
    }
}

if(f){
    camera.center(charpos.x,charpos.y);
    ui.overlay.text("loading the dungeon...");
    ui.overlay.hide();
}
}

函数render()由各种事件触发,例如角色移动,地图拖动,灯光更新等。

这是结果: enter image description here

我想在墙壁上添加插入阴影,这样可以清楚地看到那些是墙壁。我尝试过使用画布上下文阴影,并使用了这个: enter image description here 它应该为100,100绘制一个透明的矩形和阴影,大小为20,20,但是这会将阴影应用于每个绘制的图块。

我觉得我用错了。任何人都可以解释如何有效 使用canvas来达到预期的效果?

1 个答案:

答案 0 :(得分:3)

不要使用2D API阴影选项,它们非常慢(并且这是对它们有多糟糕的轻描淡写)。最好将阴影创建为图块集的一部分,并将ctx.globalAlpha设置为小于1并使用多种复合模式中的一种进行渲染。例如ctx.globalCompositeOperation = "multiply";overlaycolor-burnhard-lightsoft-light。您甚至可以使用组合来获得非常好的阴影效果。

将阴影作为图块集的一部分创建将提供更逼真的效果,因为阴影API仅适用于从平面上方浮动的平面对象投射的阴影,而不适用于从屏幕突出的可能具有倾斜边的3D对象在z方向。

如果您不希望将阴影作为图块集的一部分创建,请考虑使用屏幕外观画布通过阴影API选项在onload上创建阴影图块集。然后使用alpha和复合选项从那里渲染到画布