Я работаю над стрелком сверху вниз, и в основном персонаж начинается в середине экрана, внутри прямоугольника (Безопасная зона). Персонаж не статичен, сцена есть. Он может ходить, внутри безопасной зоны. Как только персонаж выходит из этой зоны, статика переключается ... персонаж статичен, и сцена движется вокруг него.

Единственная проблема в том, что я не могу вернуться в безопасную зону, позволяя моей статике снова переключаться.

Так что я навсегда застрял за пределами зоны. Все, что я делаю, это проверяю, находится ли позиция моего персонажа «в пределах» определенного значения (то есть прямоугольника), если он отсутствует - тогда мои KeyControls влияют на карту, а не на персонажа.

Так что это мой пограничный (Safe Zone) контролер:

//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!");
    }

И это мой 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));
        }

Мой персонаж всегда сталкивается с моей мышью (вращается). Таким образом, каждый раз, когда пользователь нажимает W или Up - персонаж всегда будет двигаться в направлении положения мыши.

Есть идеи, как мне вернуться в зону?

----- Обновить -----

Я думаю, мне нужно как-то проверить, все ли еще я смотрю за пределы безопасной зоны - если нет, то поменять статику.

2
Oliver Jones 23 Янв 2013 в 03:10

2 ответа

Лучший ответ

Просто разделите две вещи: карту и вид.

Карта - это ваш уровень, вы держите там объекты с координатами. Вид - это часть карты, которую вы видите на экране. Вид имеет 4 свойства: x, y, widht и height, где widht и height, скорее всего, соответствует размеру вашего холста.

Если ваша игра начинается с просмотра точки на карте (0,0) в центре экрана, тогда ваши координаты вида (x, y) должны быть (-view.width / 2, -view.height / 2).

Как нарисовать вашего персонажа и объекты в представлении?

Во-первых, нарисуйте только то, что находится в прямоугольнике вида. Обведите все объекты и проверьте,

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

(вы, вероятно, должны также учитывать границы объектов).

Если объект находится в области просмотра, нарисуйте его в позиции (object.x - view.x, object.y - view.y). И это все о рисовании вещей.

Перемещение персонажа и просмотр области вместе с ним.

Теперь, когда ваш персонаж сталкивается с границей, например (сталкивается с правой границей)

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

Затем переместите представление вправо, увеличив view.x с некоторым значением (это может быть character.width / 2).

- ОБНОВЛЕНИЕ -

Я вижу, что вы не используете ООП в своей игре (на самом деле вы используете это, потому что все в JS является объектом, но вы не используете его специально).

ООП в JS многое объясняет, поэтому я постараюсь сделать его коротким.

Вы можете создавать объекты, такие как ваш персонаж, карта и вид, используя формат JSON.

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,
}

Это объекты, которые вы можете использовать в своих функциях следующим образом:

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);
    }
}

Это не лучший способ, но он все еще намного лучше, чем ваш прямо сейчас. Когда вы поймете, что такое ООП, вы сделаете это лучше для себя.

0
Rafał Łużyński 24 Янв 2013 в 12:54

Проблема в том, что вы ждете, когда персонаж выйдет за пределы, а затем перемещаете карту. Но флаг уже сработал, и теперь движение персонажа статично, независимо от того, в каком направлении вы идете, потому что вы уже вне границ.

Вместо этого вы можете определить, когда персонаж собирается пересечь границу, и предотвратить это, переместив карту:

//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;
    }

Затем boundaryCheck берет дельты x и y и выясняет, находятся ли они в границах. Если персонаж все еще будет в границах, return true и персонаж переместится, в противном случае карта переместится.

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;
    }

};

Таким образом, вам не нужно выяснять, движется ли персонаж за границей к границе или нет. Вместо этого вы заранее определяете, куда идет персонаж, и корректируете его, всегда удерживая его в границах.

Без полного кода это, конечно, не поддается тестированию, но я думаю, что оно должно работать с тем, что вы дали.

0
Jonathan F 23 Янв 2013 в 00:27