piobug

Issues with selecting and moving sprites one at the time to click location

Recommended Posts

Hi all,

I have two sprites ( sprite A and sprite B ) that I want to select and move around the screen one at the time, like this:

  • click on sprite A to select it, sprite B should be then deselcted
  • click anywhere in the world to move sprite A to where the mouse clicked
  • double click on a sprite A to cast spell 1
  • double click on sprite B to cast spell 2

Issues I have are:

  1.  Issue: If sprite A is already selected, and I single click on sprite B to select it, then sprite A moves to location of sprite B. Intended: no sprite moves, sprite B is selected and sprite A is deselected
  2. Issue: If a sprite is already selected, and I single click on it, the sprite is deselected (and the other is selected). Intended: the sprite remains selected 
  3. Issue: Double clicking on the world (outside any sprite) cause a selected sprite to move two steps towards where clicked. Intended: Double clicking on the world should be ignored 
  4. Issue: Single clicking anywhere but the center of a selected sprite makes it move a bit towards where clicked. Intended: single clicking on a selected sprite should be ignored
  5. Issue: The two sprite overlap. Intended: collision and separation

What I'm doing wrong

Thanks!

Code

var playState = {
	
create: function() {
	this.mouseClicks = 0;
	this.mouseClicksStarted = false;
	this.createPlayers();

	this.myEvent = game.input.onDown.add(this.movePlayer, this);
	this.playerGroup.forEach(function(player) {
		player.events.onInputDown.add(this.countClicks,this); //param 1: sprite, param2: pointer
	}, this); 

},

update: function() {
	game.physics.arcade.collide(this.playerGroup);
},

countClicks: function(player, pointer) {

	this.mouseClicks ++;
	this.player.canMove = false;

	if (this.mouseClicksStarted) {

			return;
	}

	this.mouseClicksStarted = true;		

	//call function after x seconds
	setTimeout(function() { 
	
		if(this.mouseClicks > 1) {

			if(player.role == "thrower") {
				console.log("double: casting thrower spell")
			} else {
				console.log("double: casting catcher spell")
			}
		
			//One click	
		} else {

			this.selectPlayer(player);
		}

		this.mouseClicksStarted = false;
		this.mouseClicks = 0;

	 }.bind(this), 250);
	
},

selectPlayer: function(player) {

	this.playerGroup.forEach(function(player) {

			if(player.isSelected) {
				player.isSelected = false;
				player.tint = 0xffffff;

			} else {

				player.isSelected = true;
				player.tint = 0xff0000;
			}
		}, this);
},

createPlayers: function() {
		this.playerGroup = game.add.group();

		this.player = new Player(this.game, 'player', 'thrower', true);
		this.game.add.existing(this.player);
		this.playerGroup.add(this.player);
		this.player.reset(game.world.randomX, game.world.randomY);

		this.player2 = new Player(this.game, 'catcher', 'catcher', false);
		this.game.add.existing(this.player2);
		this.playerGroup.add(this.player2);
		this.player2.reset(game.world.randomX, game.world.randomY);
},

movePlayer: function  (pointer) {    
	
	this.playerGroup.forEach(function(player) {

	if(player.isSelected) {
		if (this.tween && this.tween.isRunning)    {        
			this.tween.stop();    
		}    
		var duration = (game.physics.arcade.distanceToPointer(player, pointer) / 400) * 1000;    
		this.tween = game.add.tween(player).to({ x: pointer.x, y: pointer.y }, duration, "Sine.easeInOut", true);
		
		game.add.tween(player.scale).to({x: 1, y: .8}, duration).to({x: 1, y: 1}, 1000, Phaser.Easing.Elastic.Out).start();

    	player.rotation = game.physics.arcade.angleToPointer(player);

		}

	}, this); 
},

};

Player

var Player = function (game, sprite, role, isSelected) {
  //save passed variables so they can be accessed later
  this.role = role;
  this.isSelected = isSelected;

  this.max_energy = 100;
  this.currentEnergyLevel = 0;


  Phaser.Sprite.call(this, game, game.width/2, game.height-150, sprite);
  this.anchor.setTo(0.5, 0.5);
  this.scale.setTo(1);

  game.physics.enable(this, Phaser.Physics.ARCADE);
  this.body.collideWorldBounds = true;
  this.body.bounce.setTo(0.9, 0.9);
  //this.body.immovable = true;

  this.playerKillParticles = game.add.emitter(0,0,15);
  this.playerKillParticles.makeParticles('playerParticle', 2);
  this.playerKillParticles.setYSpeed(-100,0);
  this.playerKillParticles.setXSpeed(-100,100);

  this.inputEnabled = true;   
  this.input.useHandCursor = true;
  //this.input.priorityID = 1;

};

Player.prototype = Object.create(Phaser.Sprite.prototype);
Player.prototype.constructor = Player;

Player.prototype.setRole = function(role) {
    this.role = role;
};

Thanks!

Share this post


Link to post
Share on other sites

This is how I solved issue2:

selectPlayer: function(player) {

	//If the sprite I'm clicking on is not selected
	if(!player.isSelected) {
		//then deselect all sprites
		this.playerGroup.setAll('isSelected', false);
		//and select the sprite I'm clicking on
		player.isSelected = true;
	}
},

 

Share this post


Link to post
Share on other sites

Solved all other issues.

Issue 5 was due the fact that using tweens to move sprites ignores collisions. Solving issue 4 made solving issue 5 not necessary.

The main trick was to use an invisoble sprite as background to capture clicks rather than the event game.input.onDown.add(this.movePlayer, this);

Here's the play.js code to move sprites around the screen with clicks.

var playState = {
	

create: function() {
	this.mouseClicks = 0;
	this.mouseClicksStarted = false;

	this.createBackgroundSprite();	
	this.playerGroup = game.add.group();
	this.createCatcher();
	this.createThrower();

 	//passes: param 1: sprite, param2: pointer
	this.backgroundSprite.events.onInputDown.add(this.countClicks,this);
	this.playerGroup.forEach(function(player) {
		player.events.onInputDown.add(this.countClicks,this);
	}, this); 

},


countClicks: function(sprite, pointer) {

	this.mouseClicks ++;

	if (this.mouseClicksStarted) {
		return;
	}

	this.mouseClicksStarted = true;		

	//call function after x seconds
	setTimeout(function() { 
		
		//If we double clicked 
		if(this.mouseClicks > 1) {

			//on a sprite that's part of the player's group
			if(this.playerGroup.children.indexOf(sprite) > -1) {
				this.selectPlayer(sprite);
				this.castSpell(sprite);
			}

		//If we single clicked	
		} else {
			//on the background
			if(sprite == this.backgroundSprite) {
				this.movePlayer(pointer);
			} else {
				this.selectPlayer(sprite);
			}
		}

		this.mouseClicksStarted = false;
		this.mouseClicks = 0;

	}.bind(this), 250);
	
},

castSpell: function(sprite) {

	switch(sprite.role) {
    case "thrower":
		console.log("double: casting thrower spell");
        break;
    case "catcher":
		console.log("double: casting catcher spell");
        break;
	}
},

selectPlayer: function(player) {

	//If the sprite I'm clicking on is not selected
	if(!player.isSelected) {
		//then deselect all sprites
		this.playerGroup.setAll('isSelected', false);
		//and select the sprite I'm clicking on
		player.isSelected = true;
		this.selectPlayerEffect();
		}
},

selectPlayerEffect: function() {
	this.playerGroup.forEach(function(player) {

		if(player.isSelected) {
			player.tint = 0xff0000;
		} else {
			player.tint = 0xffffff;
		}
 	}, this);

},
	

createThrower: function() {

		this.player = new Player(this.game, 'player', 'thrower', true);
		this.game.add.existing(this.player);
		this.playerGroup.add(this.player);
		this.player.reset(game.world.randomX, game.world.randomY);

},

createCatcher: function() {
		
		this.player2 = new Player(this.game, 'catcher', 'catcher', false);
		//this.player2 = new Player(this.game, 'catcherSheet', 'catcher', false);
		this.game.add.existing(this.player2);
		this.playerGroup.add(this.player2);
		this.player2.reset(game.world.randomX, game.world.randomY);
		//this.player2.animations.play('idle');

},


movePlayer: function  (pointer) {   
	this.playerGroup.forEach(function(player) {

	if(player.isSelected) {
		if (this.tween && this.tween.isRunning)    {        
			this.tween.stop();    
		}    
		var duration = (game.physics.arcade.distanceToPointer(player, pointer) / 400) * 1000;    
		this.tween = game.add.tween(player).to({ x: pointer.x, y: pointer.y }, duration, "Sine.easeInOut", true);
		
		game.add.tween(player.scale).to({x: 1, y: .8}, duration).to({x: 1, y: 1}, 1000, Phaser.Easing.Elastic.Out).start();
    	player.rotation = game.physics.arcade.angleToPointer(player);

		}

	}, this); 
},


//create invisible sprite to capture clicks outside of sprites
createBackgroundSprite: function() {
	this.backgroundSprite = game.add.sprite(0, 0);
	this.backgroundSprite.fixedToCamera = true;
	this.backgroundSprite.scale.setTo(game.width, game.height);
	this.backgroundSprite.inputEnabled = true;
}

};

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.