ylluminarious Posted September 15, 2014 Share Posted September 15, 2014 In my game, I need some buttons that will work on mobile devices (buttons that you can press and/or hold in the game). I saw this example (note that the version of Phaser being used here is old, however, it still works) and was able to temporarily have some working buttons. Here's the source code for that example. However, one thing bothered me about this example's code for the creation of these virtual gamepad buttons: the buttons' code wasn't DRY (Don't Repeat Yourself). You can see how these buttons keep getting created in the same fashion here over and over again: // 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;});Because they were created in such a non-DRY and, what I feel to be, inefficient way, I decided that my buttons should have a gamepad button class that they all inherit from. Unfortunately, I've been running into lots of problems trying to make this button class work. I have an example here that models what I'm trying to do in my game. (Here's the source code for my example) // 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; }As you can see, the arrow keys work fine for moving the sprite, but the mobile buttons do not work well; they only move the sprite for a frame, and then it stops moving again. I'm not sure why the keys work, yet the mobile buttons don't. The problem seems to be that the code in the class is not being run the way that I am thinking it should run (i.e., it seems like all of the code concerning the `onInputOver`, `onInputDown`, and `onInputUp` events is not being correctly run and the class is only paying attention to the method to run when a button is pressed). Can anyone figure out what the problem is with my button class? Link to comment Share on other sites More sharing options...
ylluminarious Posted September 16, 2014 Author Share Posted September 16, 2014 Btw, here's this question on Stack Overflow: http://stackoverflow.com/questions/25870037/problems-with-a-class-for-virtual-controls-in-the-phaser-framework Link to comment Share on other sites More sharing options...
ylluminarious Posted September 17, 2014 Author Share Posted September 17, 2014 Ok, someone came up with a solution to this on Stack Overflow: Your problem is that the onInputDown of Phaser.Button only fires once each time the button is pressed.What you need to do is set an isDown property on the button something like this: button.events.onInputDown.add(function () { button.isDown = true;});button.events.onInputUp.add(function () { button.isDown = false;});And the in your update method check for that property: function update () { stopMoving(); if (leftKey.isDown || leftButton.isDown) { moveLeft(); } // Other stuff in the update method} Link to comment Share on other sites More sharing options...
Recommended Posts