Search code examples
javascripthtmlpositioncollisionboundary

HTML5 Game - Walking Boundary Issue


I'm working on a top down shooter, and basically the character starts in the middle of the screen, inside a rect (Safe Zone). The character isn't static, the scene is. He can walk around, inside the safe zone. As soon as the character walks out of this zone, the statics switch over ... the character is static, and the scene is moving around him.

The only problem with this is that I can't walk back into the safe zone, allowing my statics to switch over again.

So I'm forever stuck outside the zone. All I'm doing is checking to see whether my character position is 'within' a certain value (which is the rect), if he's out - then my KeyControls then affect the Map, not the character.

So this is my boundary (Safe Zone) checker:

//Walking Window Boundaries
    var boundarySizeX = 400;
    var boundarySizeY = 200;

    ctxWalkBoundary.fillStyle = "grey";
    ctxWalkBoundary.fillRect(gameWidth/2 - boundarySizeX/2, gameHeight/2 - boundarySizeY/2, boundarySizeX, boundarySizeY);
    ctxWalkBoundary.clearRect((gameWidth/2 - boundarySizeX/2) + 2, (gameHeight/2 - boundarySizeY/2) + 2, (boundarySizeX) - 4, (boundarySizeY) -4 );

    var paddingLeft = (gameWidth - boundarySizeX) / 2;
    var paddingRight = gameWidth - ((gameWidth - boundarySizeX) / 2) - this.charWidth;
    var paddingTop = (gameHeight - boundarySizeY) / 2;
    var paddingBottom = gameHeight - ((gameHeight - boundarySizeY) / 2) - this.charHeight;

    var paddingY = (gameHeight - boundarySizeY) / 2;

    if(this.drawX > paddingLeft && this.drawX < paddingRight && this.drawY > paddingTop && this.drawY < paddingBottom){
        inBoundary = true;
    }
    else{
        inBoundary = false;
        console.debug("Out Of Boundary!");
    }

And this is my KeyChecker:

//UP
    if(this.isUpKey){

        //Character movement
        if(inBoundary){
            this.drawX = this.drawX + this.speed * Math.cos((this.characterRotation));
            this.drawY = this.drawY + this.speed * Math.sin((this.characterRotation));
        }
        else{
            mapPositionX = mapPositionX - this.speed * Math.cos((this.characterRotation));
            mapPositionY = mapPositionY - this.speed * Math.sin((this.characterRotation));
        }

My character always faces my mouse (rotates). So every time the user pressed W, or Up - the character will always walk towards the mouse position.

Any ideas how I can get back into the zone?

----- Update -----

I guess I need to somehow check if I'm still facing outside the safe zone - if not, then reverse he statics.


Solution

  • Just separate two things: map and view.

    Map is your level, you keep there objects with coordinates. View is part of map you see on screen. View has 4 properties: x, y, widht and height, where widht and height most likely is your canvas size.

    If your game start with view on map point (0,0) in the middle of screen, then your view (x,y) coordinates should be (-view.width/2, -view.height/2).

    How to draw your character and objects in a view?

    In first place, draw only thing that are in the view rectangle. So loop over all objects and check if

    object.x >= view.x && object.x <= view.x + view.width && object.y >= view.y && object.y <= view.y + view.height
    

    (you probably should take into account objects boundaries too).

    If object is in view area then draw it at position (object.x - view.x, object.y - view.y). And that's all about drawing things.

    Moving character and view area with him.

    Now when your character collides with boundary, in example (colliding with right border)

    character.x >= view.x + view.width
    

    then move view to the right by incrementing view.x with some value (that might be character.width/2).

    -- UPDATE --

    I see that you are not using OOP in your game (actually you are because everything in JS is an object, but you are not using it on purpose).

    OOP in JS is a lot of explaining, so I'll try to make it short.

    You can make objects like your Character, Map and View using JSON format.

    character = {
        x: 0,
        y: 0,
        xspeed: 0,
        yspeed: 0,
        speed: 0,
        radius: 20,
    }
    
    map = {
        objects: [
            {sprite: 'tree.jpg', x: 100, y: 50},
            {sprite: 'stone.jpg', x: 20, y: 30},
        ],
    }
    
    view = {
        width: canvas.width,
        height: canvas.height,
        x: -this.width/2,
        y: -this.height/2,
    }
    

    These are objects that you can use like in your functions like that:

    for (var i=0; i++, i<map.objects.length) {
        if (map_obj.x >= view.x && map_obj.x <= view.x + view.width && map_obj.y >= view.y && map_obj.y <= view.y + view.height) {
            var map_obj = map.objects[i];
            draw_sprite(map_obj.sprite, map_obj.x - view.x, map_obj.y - view.y);
        }
    }
    

    It's not the best way, but it's still much better than yours right now. When you understand what OOP is about you will make it better for your own.