سؤال

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.

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

The problem here is that you're waiting for the character to go out of bounds, then moving the map instead. But the flag has already been tripped, and now the character movement is static no matter what direction you go in, because you're already out of bounds.

You could instead detect when a character is going to cross the boundary and prevent it by moving the map instead:

//UP
if(this.isUpKey){

// save the x and y offset to prevent needless recalculation
var xOffset = this.speed * Math.cos(this.characterRotation),
    yOffset = this.speed * Math.sin(this.characterRotation);

    //Character movement
    if( boundaryCheck(xOffset, yOffset) ){
        this.drawX = this.drawX + xOffset;
        this.drawY = this.drawY + yOffset;
    }
    else{
        mapPositionX = mapPositionX - xOffset
        mapPositionY = mapPositionY - yOffset;
    }

then boundaryCheck takes the x and y delta's and figures out if they're still in bounds. If the character will still be in bounds, return true and the character will move, otherwise the map will move.

function boundaryCheck(xOffset, yOffset){
// variables set and other stuff done...
    if(this.drawX + xOffset > paddingLeft && this.drawX + xOffset < paddingRight && this.drawY + yOffset > paddingTop && this.drawY + yOffset < paddingBottom){
       return true;
    }
    else{
        console.debug("Out Of Boundary!");
        return false;
    }

};

This way you don't have to figure out whether an out of bounds character is moving toward the boundary or not. Instead, you pre-determine where the character is going, and adjust accordingly, always keeping him in boundaries.

Without full code this isn't testable, of course, but I think it should work with what you've given.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top