简体   繁体   中英

canvas scrolling with collision detecting

I'm new in html5+canvas and i can't find more information about my problem and i decided ask here...

I need help with scrolling large map - 2800x1500px in canvas 400x300px and collision detecting on "invisible area" which is outside of canvas.

like this:
http://i.stack.imgur.com/NI59z.png

Few functions from my code

function Map()
{
    this.img = new Image();
    this.img.src = "img/map.jpg"; //map picture on main canvas
    this.gimg = new Image();

    //map with opacity on "ghost" canvas for collision detecting
    this.gimg.src = "img/gmap.png";
    this.draw = function(ctx,gctx)
    {
        ctx.drawImage(this.img,-offset.x,-offset.y);    
        gctx.drawImage(this.gimg,-offset.x,-offset.y);  
    }
}
function init()
{
    var gameLoop = setInterval(function() {
        draw(ctx,gctx);

    }, 1000/fps);
}
function draw(ctx,gctx)
{
    ctx.save();
    gctx.save();
    ctx.clearRect(-offset.x,-offset.y,2800,1500);
    gctx.clearRect(-offset.x,-offset.y,2800,1500);  
    map.draw(ctx,gctx); 
    ctx.translate(offset.x,offset.y); //scrolling canvas
    gctx.translate(offset.x,offset.y); //scrolling ghost canvas
    ctx.restore();
    gctx.restore();
}

//collision detecting function
function hitTest(obj,gctx)
{
    var imageData = gctx.getImageData(obj.x,obj.y,1,1);
    if( imageData.data[3]==255)
    {
        return true;
    }
    else return false;
}

for scrolling map i use that example:
http://jsfiddle.net/hKrrY/

my project:
http://game.com.hostinghood.com/

You cant do your collision that way with objects not in the viewable area. The image isn't being rendered onto the canvas in that portion so it will always have a 0 opacity.

There are two ways you can do it. One would be to render your collision map on a separate in-memory canvas that is the same width and height of the collision map, and then compare the coordinates for your enemy on the active active canvas to the area on your collision map. That would probably be the easiest way for you to do it after looking at your code.

The second approach would be to use a tilemap. You would basically have a 2d array where each element represents an area lets say 32x32, if its a 1 its collide-able, if its a 0 you can pass through. This would involve translating the enemies position to the area on the array to check.

I've done it both ways, the best in terms of memory utilization is the tilemap approach.

Here is a great tutorial explaining the tilemap approach

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM