Как сделать так, чтобы изменение размера спрайта не останавливало обнаружение столкновений в Phaser?

Я разрабатываю небольшую игру на JavaScript с помощью Phaser, и у меня есть спрайт, который в определенные моменты меняет свой размер. Это делается с помощью метода sprite.body.setSize. Однако похоже, что спрайт перестает сталкиваться с объектами, с которыми он должен сталкиваться, когда он меняет размер. Я понимаю, почему он это делает, поскольку границы спрайта изменяются во время изменения размера, но я боюсь, что мой пользователь может воспользоваться этой проблемой и пройти сквозь стены. Я не уверен, как заставить спрайт реагировать на столкновения, когда он находится в процессе изменения размера. Есть ли способ предотвратить это?

Редактировать по запросу Супамиу:

Вот быстрый пример того, что я пытаюсь сделать в своей игре. Кроме того, вот исходный код этого примера.

// Global constants
var GAME_WIDTH = 800;
var GAME_HEIGHT = 600;

var TEXT_X_POS = 150;
var TEXT_Y_POS = 50;

var PHASER_DUDE_WIDTH = 27;
var PHASER_DUDE_HEIGHT = 40;

var MASTER_WIDTH = 57;
var MASTER_HEIGHT = 77;

var SPRITE_X_POS = 200;
var SPRITE_Y_POS = 400;

var SPRITE_GRAVITY = 300;

var LEFT_VELOCITY = -300;
var RIGHT_VELOCITY = 300;
var JUMP_VELOCITY = -300;
var STOPPED = 0;

var WALL_X_POS = 500;
var WALL_Y_POS = 300;

// Global variables
var sprite;
var wall;
var cursors;

var game = new Phaser.Game(GAME_WIDTH, GAME_HEIGHT, Phaser.AUTO, "game", {preload: preload, create: create, update: update});

function preload () {
    game.load.image("master", "sprites/master.png");
    game.load.image("phaser dude", "sprites/phaser_dude.png");
    game.load.image("wall", "sprites/wall.png");
}

function create () {
    game.add.text(TEXT_X_POS, TEXT_Y_POS, "Use the cursor keys to jump and move", {fontSize: "16px", fill: "white"});

    sprite = game.add.sprite(SPRITE_X_POS, SPRITE_Y_POS, "master");
    game.physics.arcade.enable(sprite);
    sprite.body.collideWorldBounds = true;
    sprite.body.gravity.y = SPRITE_GRAVITY;

    wall = game.add.sprite(WALL_X_POS, WALL_Y_POS, "wall");
    game.physics.arcade.enable(wall);
    wall.body.immovable = true;

    cursors = game.input.keyboard.createCursorKeys();
}

function update () {
    game.physics.arcade.collide(sprite, wall);

    sprite.body.velocity.x = STOPPED;

    cursors.up.onDown.add(jump);
    if (cursors.left.isDown) {
        sprite.body.velocity.x = LEFT_VELOCITY
    }
    if (cursors.right.isDown) {
        sprite.body.velocity.x = RIGHT_VELOCITY;
    }

    if (sprite.isJumping && sprite.body.onFloor()) {
        sprite.isJumping = false;
        sprite.loadTexture("master");
        sprite.body.setSize(MASTER_WIDTH, MASTER_HEIGHT);
    }
}

function jump () {
    sprite.isJumping = true;
    sprite.body.velocity.y = JUMP_VELOCITY;

    sprite.loadTexture("phaser dude");
    sprite.body.setSize(PHASER_DUDE_WIDTH, PHASER_DUDE_HEIGHT);
}

Вы можете видеть, что если вы нажмете на левую сторону стены, когда спрайт изменит размер (и текстуру), он может пройти сквозь стену.


person GDP2    schedule 03.10.2014    source источник


Ответы (1)


если вы не хотите, чтобы пользователи использовали эту ошибку, заставьте их вернуться к началу стены, если они пытаются пройти через нее. нравится:

U - пользователь || стена

     ||
U    ||
     ||
     ||

Начало

||
|U|
||
||

О, U проходит сквозь стену!

  ||
U ||
  ||
  ||

U идет к началу стены.

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

РЕДАКТИРОВАТЬ:

есть еще два решения, установите систему стен с границами со значением 0 для подпрыгивания:

function create () {
    game.add.text(TEXT_X_POS, TEXT_Y_POS, "Use the cursor keys to jump and move", {fontSize: "16px", fill: "white"});

    sprite = game.add.sprite(SPRITE_X_POS, SPRITE_Y_POS, "master");
    game.physics.arcade.enable(sprite);
    sprite.body.collideWorldBounds = true;
    sprite.body.gravity.y = SPRITE_GRAVITY;

    wall = game.add.sprite(WALL_X_POS, WALL_Y_POS, "wall");
    game.physics.arcade.enable(wall);
    wall.body.immovable = true;
    //here is what i added
    wall.body.collideWorldBounds = true;
    wall.body.bounce.set(0);

    cursors = game.input.keyboard.createCursorKeys();
}

или сделать тело спрайта неподвижным, пока вы меняете его размер:

function update () {
    game.physics.arcade.collide(sprite, wall);

    sprite.body.velocity.x = STOPPED;

    cursors.up.onDown.add(jump);
    if (cursors.left.isDown) {
        sprite.body.velocity.x = LEFT_VELOCITY
    }
    if (cursors.right.isDown) {
        sprite.body.velocity.x = RIGHT_VELOCITY;
    }
    if (sprite.isJumping && sprite.body.onFloor()) {
        sprite.isJumping = false;
        sprite.loadTexture("master");
        //Here is what i added
        sprite.body.velocity.x = STOPPED;
        sprite.body.setSize(MASTER_WIDTH, MASTER_HEIGHT);
    }
}
person Supamiu    schedule 06.10.2014
comment
Спасибо за ответ. Я попробовал первое предложенное вами решение (то есть, когда вы снова помещаете пользователя перед стеной, если он проходит через нее), но это выглядит странно, и я не уверен, хочу ли я его использовать. Вы знаете, как сделать так, чтобы пользователь не мог двигаться, пока вы меняете его размер? - person GDP2; 08.10.2014
comment
не могли бы вы отредактировать свой пост, чтобы добавить код, в котором вы меняете размер пользователя? - person Supamiu; 09.10.2014
comment
Я отредактировал свой пост, так что есть реальный пример моей проблемы, и вы можете увидеть код, который я использую для изменения размера моего пользователя. - person GDP2; 11.10.2014
comment
Эти два решения работают на вас? Я спрашиваю об этом, потому что мне кажется, что они не работают на меня. Извините, я ненавижу здесь беспокоиться, но я все же предпочел бы иметь лучшее решение, чем решение номер 1 (вытаскивание пользователя за пределы стены, когда они перекрываются). - person GDP2; 15.10.2014
comment
Я не мог проверить эти решения, но они должны работать, второе - останавливает игрока перед установкой его размера, я не знаю, как это не сработает: s. Попробуйте добавить console.log("Player stopped");just после кода, где вы должны его остановить. Возможно, тебе стоит поискать свое решение ‹a href=examples.phaser.io› здесь ‹/a› - person Supamiu; 15.10.2014
comment
Я думаю, что второе решение не работает, потому что, даже если оно говорит игроку остановиться, ничто не удерживает игрока от повторного запуска; все, что им нужно сделать, это нажать клавишу, и скорость вернется к норме. Кроме того, спасибо, что отправили меня на examples.phaser.io, но я уже проверял там решения. - person GDP2; 17.10.2014