Game control question


(Nate ) #1

Hey guys so this is what I am currently doing for my main player control:

Input.define('MOVEMENT', Key.W, Key.A, Key.S, Key.D);
			
		//player controls
		if ( Input.check(Key.A) && !Input.check(Key.D) && !Input.check(Key.S) && !Input.check(Key.W))
		{
			xSpeed -= power;
			pressed = true;
			playerSprite.play("left");
			direction = 1;
		}
		if (Input.check(Key.D) && !Input.check(Key.A) && !Input.check(Key.S) && !Input.check(Key.W))
		{
			xSpeed += power;
			pressed = true;
			playerSprite.play("right");
			direction = 2;
		}
		if (Input.check(Key.W) && !Input.check(Key.S) && !Input.check(Key.A) && !Input.check(Key.D))
		{
			ySpeed -= power;
			pressed = true;
			playerSprite.play("up");
			direction = 3;	
		}
		if (Input.check(Key.S) && !Input.check(Key.W) && !Input.check(Key.A) && !Input.check(Key.D))
		{
			ySpeed += power;
			pressed = true;
			playerSprite.play("down");
			direction = 4;
		}
		//end of control code
		
	
		
	if (Input.pressed('MOVEMENT') || (Input.released('MOVEMENT') && pressed))
	{
		playSound();
	}

Basically all of the added stuff in each Input.check is making sure multiple keys are not being pressed to avoid the player from traveling diagonally. I would however like to be able to have the play say for example, press left, so the player is moving to the left, WHILE they are moving left for example, they press the up key, however since the left key was pressed first they continue to move left, HOWEVER when they release the left key and they are still pressing the up key, they will now travel up.

The way I have it now is great because I don’t want the player to move diagonally, however the player must take their finger off of a key before they can press another. I have gotten used to it, but the few friends I had test my game complained about this right off the bat.

What do you guys think?

Thank you!


(Bora Kasap) #2

Thats good. I got what you wanna do. It looks like there is no shorter way than yours. So… Keep going :slight_smile:


(Nate ) #3

Okay thanks! But so how would I make it do what I am trying to achieve?

EDIT:

I would like it so that for example, I am moving to the left so my finger is on the left key or A. While my finger is on the A key I press W for up, my character does not move up until my finger releases the the A key.


(Bora Kasap) #4

Ah got it, then don’t use

Input.check(Key.W)

I think you should use

Input.lastKey(Key.W)

(Jacob Albano) #5

Input.lastKey is not a function.


(Nate ) #6

Okay so uhm, Jacob what do you think? :smiley:


(Zachary Lewis) #7

I think a boolean should be enough to get what you need done.

Here’s some (untested) code.

// Define controls.
Input.define("UP", Key.W);
Input.define("DOWN", Key.S);
Input.define("LEFT", Key.A);
Input.define("RIGHT", Key.D);

/** Should the player move vertically? */
public var shouldMoveVertically;

public function movementLoop()
{
	// Held input
	var xm:int = 0;
	var ym:int = 0;

	// Pressed input
	var xp:int = 0;
	var yp:int = 0;

	// Create input sums.
	if (Input.check("LEFT")) xm--;
	if (Input.check("RIGHT")) xm++;
	if (Input.check("UP")) ym--;
	if (Input.check("DOWN")) ym++;

	// Now that the input sums are calculated,
	// they can be used to easily determine
	// player input and movement.
	//
	// If both xm and ym are 0, there was no
	// input. Otherwise, the values correspond
	// to movement along the corresponding axes.
	//
	// This system cancels out movement if both
	// left and right or both up and down are
	// pressed.

	if (xm != 0 || ym != 0)
	{
		// If any input was detected, play
		// sound effects for movement.
		playSound();

		if (xm != 0 && ym != 0)
		{
			// The player is holding two
			// different directions at once.

			// Was a key pressed to cause this?
			// If so, remember what was pressed.
			if (Input.pressed("LEFT")) xp--;
			if (Input.pressed("RIGHT")) xp++;
			if (Input.pressed("UP")) yp--;
			if (Input.pressed("DOWN")) yp++;

			// Favor horizontal movement.
			if (xp == 0)
			{
				if (yp != 0)
				{
					shouldMoveVertically = true;
				}
			}
			else
			{
				shouldMoveVertically = false;
			}

			// Cancel one of the two inputs.
			if (shouldMoveVertically)
			{
				xm = 0;
			}
			else
			{
				ym = 0;
			}
		}
		
		// Add power based on input sums.
		xSpeed += xm * power;
		ySpeed += ym * power;

		// Update the sprite and direction.
		updateSpriteDirection(xm, ym);
	}
}

(Nate ) #8

Thanks Zach!

I plugged this in, in place of my movement code and now up and down seem to be working but left and right are not! Any ideas?


(Zachary Lewis) #9

There’s probably a problem with the code. :wink:


(JP Mortiboys) #10

I’d approach it like this:

The player is either moving or not moving. Initialliy, he is not moving.

If the player is not moving, and a movement key is pressed, move in that direction (in the unlikely event that more than one movement key is pressed on the same frame, it doesn’t matter which key we process as long as we only process one).

If the player is moving, we’re only interested if a movement key is released. After a movement key is released, we check the keys that are down to get the new direction.r


// Elsewhere, main config or init or something
Input.define("up", Key.UP, Key.W);
Input.define("down", Key.DOWN, Key.S);
Input.define("right", Key.RIGHT, Key.D);
Input.define("left", Key.LEFT, Key.A);
Input.define("movement", Input.keys("up").concat(Input.keys("down")).concat(Input.keys("right")).concat(Input.keys("left")));

// In the player class

var mx:int = 0, my:int = 0; // Direction we're moving in

private function setDirection():void {
  if (Input.check("up")) {
    mx = 0; my = -1; return;
  }
  if (Input.check("down")) {
    mx = 0; my = 1; return;
  }

  if (Input.check("left")) {
    mx = -1; my = 0; return;
  }
  if (Input.check("right")) {
    mx = 1; my = 0; return;
  }
}

override public function update():void {
  if (mx == 0 && my == 0) {
    if (Input.pressed("movement")) {
      setDirection();
    }
  }
  else {
    if (Input.released("movement")) {
      setDirection();
    }
  }

  // Move in the specified direction
  moveBy(mx * speed, my * speed);
}

Here’s one interesting idea for you though: if the player is moving up and presses the “left” key, he keeps moving up, that’s fine - but wouldn’t it be cool for him to then shoot left rather than up?


(Nate ) #11

Thanks Zach and Raptor!

I just plugged in your code Raptor and nothing is happening I am not sure if I implemented it incorrectly or if there might be something up with it here.

EDIT:

Okay so one of the issues was I did not put my power variable into the moveBy, I did that, now the character will move in one direction then stop moving.

EDIT: EDIT:

Zach I got your code working! It turns out there was an issue with some of my older control code that was hiding deep within my update method! I made a new project that just had a main, world, player and your control code and everything is fine! Thanks guys for the input!

On another note, Raptor can you explain what the concat does in your code? It intrigues me ever so. Is it some kind of concatenation?


(Zachary Lewis) #12

Input.keys() returns a Vector.<int> of all of the keys in the definition. Vector.concat() takes a Vector and appends it to the end of the calling Vector.

Essentially what the code is doing is taking the individual key definitions (Key.UP, Key.W, Key.DOWN, et cetera) and putting them into one big list instead of writing them all out again.

This allows you to, for example, change the key for “up” in one place and have that change carry through.