Проблемы с классом для виртуальных элементов управления в фреймворке Phaser

В моей игре мне нужны кнопки, которые будут работать на мобильных устройствах (кнопки, которые вы можете нажимать и / или удерживать в игре). Я видел этот пример (обратите внимание, что используемая здесь версия Phaser устарела, однако она до сих пор работает) и смог временно иметь некоторые рабочие кнопки. Вот исходный код этого примера.

Однако в коде этого примера для создания этих виртуальных кнопок геймпада меня беспокоила одна вещь: код кнопок не был СУХИМ (Не повторяй себя). Вы можете видеть, как эти кнопки продолжают создаваться одним и тем же способом здесь снова и снова:

// create our virtual game controller buttons 
buttonjump = game.add.button(660, 340, 'buttonjump', null, this, 0, 1, 0, 1);  //game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame
buttonjump.anchor.setTo(0.5, 0.5);
buttonjump.fixedToCamera = true;  //our buttons should stay on the same place  
buttonjump.events.onInputOver.add(function(){jump=true;});
buttonjump.events.onInputOut.add(function(){jump=false;});
buttonjump.events.onInputDown.add(function(){jump=true;});
buttonjump.events.onInputUp.add(function(){jump=false;});

buttonfire = game.add.button(750, 340, 'buttonfire', null, this, 0, 1, 0, 1);
buttonfire.anchor.setTo(0.5, 0.5);
buttonfire.fixedToCamera = true;
buttonfire.events.onInputOver.add(function(){fire=true;});
buttonfire.events.onInputOut.add(function(){fire=false;});
buttonfire.events.onInputDown.add(function(){fire=true;});
buttonfire.events.onInputUp.add(function(){fire=false;});        

buttonleft = game.add.button(40, 312, 'buttonhorizontal', null, this, 0, 1, 0, 1);
buttonleft.anchor.setTo(0.5, 0.5);
buttonleft.fixedToCamera = true;
buttonleft.events.onInputOver.add(function(){left=true;});
buttonleft.events.onInputOut.add(function(){left=false;});
buttonleft.events.onInputDown.add(function(){left=true;});
buttonleft.events.onInputUp.add(function(){left=false;});

buttonbottomleft = game.add.button(48, 352, 'buttondiagonal', null, this, 6, 4, 6, 4);
buttonbottomleft.anchor.setTo(0.5, 0.5);
buttonbottomleft.fixedToCamera = true;
buttonbottomleft.events.onInputOver.add(function(){left=true;duck=true;});
buttonbottomleft.events.onInputOut.add(function(){left=false;duck=false;});
buttonbottomleft.events.onInputDown.add(function(){left=true;duck=true;});
buttonbottomleft.events.onInputUp.add(function(){left=false;duck=false;});

buttonright = game.add.button(136, 312, 'buttonhorizontal', null, this, 0, 1, 0, 1);
buttonright.anchor.setTo(0.5, 0.5);
buttonright.fixedToCamera = true;
buttonright.events.onInputOver.add(function(){right=true;});
buttonright.events.onInputOut.add(function(){right=false;});
buttonright.events.onInputDown.add(function(){right=true;});
buttonright.events.onInputUp.add(function(){right=false;});

buttonbottomright = game.add.button(128, 352, 'buttondiagonal', null, this, 7, 5, 7, 5);
buttonbottomright.anchor.setTo(0.5, 0.5);
buttonbottomright.fixedToCamera = true;
buttonbottomright.events.onInputOver.add(function(){right=true;duck=true;});
buttonbottomright.events.onInputOut.add(function(){right=false;duck=false;});
buttonbottomright.events.onInputDown.add(function(){right=true;duck=true;});
buttonbottomright.events.onInputUp.add(function(){right=false;duck=false;});

buttondown = game.add.button(88, 360, 'buttonvertical', null, this, 0, 1, 0, 1);
buttondown.anchor.setTo(0.5, 0.5);
buttondown.fixedToCamera = true;
buttondown.events.onInputOver.add(function(){duck=true;});
buttondown.events.onInputOut.add(function(){duck=false;});
buttondown.events.onInputDown.add(function(){duck=true;});
buttondown.events.onInputUp.add(function(){duck=false;});

Поскольку они были созданы не-DRY и, как мне кажется, неэффективным способом, я решил, что мои кнопки должны иметь класс кнопок геймпада, от которого все они наследуются. К сожалению, я столкнулся с множеством проблем, пытаясь заставить этот класс кнопок работать.

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

(Вот исходный код для моего примера)

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

var ORIGIN = 0;

var TEXT_X_POS = 50;
var TEXT_Y_POS = 100;
var TEXT_STYLE = { fontSize: "16px" };

var RIGHT_BUTTON_X_POS = 600;
var RIGHT_BUTTON_Y_POS = 400;

var LEFT_BUTTON_X_POS = 100;
var LEFT_BUTTON_Y_POS = 400;

var PHASER_DUDE_Y_POS = 300;
var PHASER_DUDE_GRAVITY = 300;
var PHASER_DUDE_RIGHT_VELOCITY = 100;
var PHASER_DUDE_LEFT_VELOCITY = -100;

var STOPPED = 0;

// Global variables
var background;

var rightButton;
var movingRight;
var rightButtonDown;

var leftButton;
var movingLeft;
var leftButtonDown;

var phaserDude;

var rightKey;
var leftKey;

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

// Mobile button class
var MobileButton = function (button, movingInADirection, isTheButtonDown, pressedMethod) {
    button.events.onInputOver.add(function () {
        if (isTheButtonDown === true) {
            movingInADirection = true;
        }
    });
    button.events.onInputDown.add(function () {
        isTheButtonDown = true;
        movingInADirection = true;
    });
    button.events.onInputUp.add(function () {
        movingInADirection = false;
    });
};

function preload () {
    game.load.image("background", "sprites/sky.png");
    game.load.image("left arrow", "sprites/left_arrow.png");
    game.load.image("right arrow", "sprites/right_arrow.png");
    game.load.image("phaser dude", "sprites/phaser_dude.png");
}

function create () {
    background = game.add.image(ORIGIN, ORIGIN, "background");

    game.add.text(TEXT_X_POS, TEXT_Y_POS, "Use the arrow keys or the arrow buttons below to move", TEXT_STYLE);

    rightButton = game.add.button(RIGHT_BUTTON_X_POS, RIGHT_BUTTON_Y_POS, "right arrow", moveRight);

    leftButtonDown = game.add.button(LEFT_BUTTON_X_POS, LEFT_BUTTON_Y_POS, "left arrow", moveLeft);

    phaserDude = game.add.sprite(game.world.centerX, PHASER_DUDE_Y_POS, "phaser dude");
    game.physics.arcade.enable(phaserDude);
    phaserDude.body.collideWorldBounds = true;
    phaserDude.body.gravity.y = PHASER_DUDE_GRAVITY;

    rightKey = game.input.keyboard.addKey(Phaser.Keyboard.RIGHT);
    leftKey = game.input.keyboard.addKey(Phaser.Keyboard.LEFT);
}

function update () {
    stopMoving();

    if (leftKey.isDown || movingLeft === true) {
        moveLeft();
    }
    if (rightKey.isDown || movingRight === true) {
        moveRight();
    }
}

function moveRight () {
    phaserDude.body.velocity.x = PHASER_DUDE_RIGHT_VELOCITY;
}

function moveLeft () {
    phaserDude.body.velocity.x = PHASER_DUDE_LEFT_VELOCITY;
}
function stopMoving () {
    phaserDude.body.velocity.x = STOPPED;
}

Как видите, клавиши со стрелками работают нормально для перемещения спрайта, но мобильные кнопки не работают; они перемещают спрайт только для кадра, а затем он снова перестает двигаться. Не знаю, почему клавиши работают, а мобильные кнопки - нет. Проблема, похоже, заключается в том, что код в классе не выполняется так, как я думаю, он должен работать (т. Е. Похоже, что весь код, относящийся к событиям onInputOver, onInputDown и onInputUp, запускается неправильно, и класс обращает внимание только на метод, запускаемый при нажатии кнопки). Может ли кто-нибудь понять, в чем проблема с моим классом кнопок?


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


Ответы (1)


Ваша проблема в том, что onInputDown Phaser.Button срабатывает только один раз при каждом нажатии кнопки.

Что вам нужно сделать, так это установить свойство isDown на кнопке примерно так:

button.events.onInputDown.add(function () {
    button.isDown = true;
});

button.events.onInputUp.add(function () {
    button.isDown = false;
});

И в вашем методе обновления проверьте это свойство:

function update () {
    stopMoving();

    if (leftKey.isDown || leftButton.isDown) {
        moveLeft();
    }
person imcg    schedule 16.09.2014
comment
Большое спасибо, это была палочка-выручалочка! - person GDP2; 17.09.2014