AS3.0 if/else if evaluation behaviour for velocity control - actionscript-3

Sorry if this is obvious to others, but I can't get my head around something in ActionScript 3.0 (huge n00b btw)
I have this code for controlling velocity:
public function keyDownHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
vx = -5;
}
else if (event.keyCode == Keyboard.RIGHT)
{
vx = 5;
}
else if (event.keyCode == Keyboard.UP)
{
vy = -5
}
else if (event.keyCode == Keyboard.DOWN)
{
vy = 5;
}
}
When run, if I hold both LEFT and UP the Sprite moves Diagonally, but the fact that the two last conditionals (Keyboard.UP & Keyboard.DOWN) are elseifs should prevent them from being evaluated at all shouldnt it?
Is anyone able to shed some light on the behaviour?

When you press both buttons flash fires two independent events for each button. If you want to skip this case, you can make state flags (leftPressed, rightPressed, etc) for each button, change state in key handler and call the check motion method according to current states of each button.

If you don't want diagonal movement, set the velocity components to zero first like this:
public function keyDownHandler(event:KeyboardEvent):void
{
vx = vy = 0; ////
if (event.keyCode == Keyboard.LEFT)
{
vx = -5;
}
else if (event.keyCode == Keyboard.RIGHT)
{
vx = 5;
}
else if (event.keyCode == Keyboard.UP)
{
vy = -5
}
else if (event.keyCode == Keyboard.DOWN)
{
vy = 5;
}
}

Related

as3 - player moves through objects

So I'm making a collision detection when player touches an object. When it touches the object, you move and stop when colliding, but for example, if I press the D key to go right, and I press the A key and let go, then the player starts moving through the object.
This is my player moving code.
public function onKeyDown(event: KeyboardEvent): void
{
if (event.keyCode == Keyboard.D)
{
isRight = true;
}
if (event.keyCode == Keyboard.A)
{
isLeft = true;
}
if (event.keyCode == Keyboard.W)
{
isUp = true;
}
if (event.keyCode == Keyboard.S)
{
isDown = true;
}
}
private function onKeyUp(event: KeyboardEvent): void
{
if (event.keyCode == Keyboard.A || event.keyCode == Keyboard.D)
{
vx = 0;
}
else if (event.keyCode == Keyboard.S || event.keyCode == Keyboard.W)
{
vy = 0;
}
}
public function onEnterFrame(event: Event): void
{
if (isRight)
{
vx = 5;
x += vx;
}
if (isLeft)
{
vx = 5;
x -= vy;
}
if (isUp)
{
vx = 5;
y -= vy;
}
if (isDown)
{
vx = 5;
y += vy;
}
//collision detection
if (player.collisionArea.hitTestObject(wall0))
{
player.x -= vx;
player.y -= vy;
}
}
Your issue, is that vx is always 5. So one direction you subtract 5 from the x, the other direction you add it.
Yet in your collision if statement, you are always subtracting it from the player's x (which if moving left, would keep moving the player left until it's past the object it's colliding with).
Also, in your isLeft check, you are subtracting the vy value, but I imagine you want to actually subtract the vx value. On that same note, in your isUp/isDown checks, your set the vx var to 5, but it seems like you should be setting the vy.
As it's unclear what x and y affect in context to the player, it's hard to give you an exact code example.
Most likely, you just need to move the player to the wall edge, and choose the side based off the direction of the player:
//collision detection
if (player.collisionArea.hitTestObject(wall0))
{
//if the player x is colliding
if(player.x + player.width > wall0.x && player.x < wall0.x + wall0.width){
player.x = isRight ? wall0.x - player.width : wall0.x + wall0.width;
}else if(player.y + player.height > wall0.y && player.y < wall0.y + wall0.height){
player.y = isDown ? wall0.y - player.height : wall0.y + wall0.height;
}
}

as3 how to make movement smoother?

I have a WASD key movement for keydown. I want it to play an animation always when walking and always move when key is pressed.
The issue is, if I press multiple keys at once, it stops moving or stops the animation. Making it look stiff and unsmooth.
private function onKeyDown(event: KeyboardEvent): void
{
if (event.keyCode == Keyboard.A)
{
vx = -5;
play();
}
else if (event.keyCode == Keyboard.D)
{
vx = 5;
play();
}
else if (event.keyCode == Keyboard.W)
{
vy = -5;
play();
}
else if (event.keyCode == Keyboard.S)
{
vy = 5;
play();
}
}
code you are using right now means if keyboard is pressed, onKeyDown will be triggered and check if it key A or D or W or S is pressed and it only handles one of them because of else if
try change your code like this
private function onKeyDown(event: KeyboardEvent): void
{
if (event.keyCode == Keyboard.A)
{
vx = -5;
play();
}
if (event.keyCode == Keyboard.D)
{
vx = 5;
play();
}
if (event.keyCode == Keyboard.W)
{
vy = -5;
play();
}
if (event.keyCode == Keyboard.S)
{
vy = 5;
play();
}
}
if this doesn't solve your problem, maybe it is something on your play() function

AS3 - Skip not Move

I'm making a frogger game in AS3 and when you press up, down, left and right, you "skip" a certain amount of space instead of gradually moving there like in most platformers now. How would I be able to do this?
Currently he moves up left, down and right on their respective keys. But he gradually moves there, not skipping the amount of space like in the real frogger.
Any ideas on how I could do this?
Code:
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
function keyDownHandler(event:KeyboardEvent):void{
if (event.keyCode == Keyboard.UP){
trace("frogger up");
player.y -= 5;
}
if(event.keyCode == Keyboard.DOWN){
trace("frogger down");
player.y += 5;
}
if(event.keyCode == Keyboard.LEFT){
trace("frogger left");
player.x -= 5;
}
if(event.keyCode == Keyboard.RIGHT){
trace("frogger right");
player.x += 5;
}
}
One way to do is to increase the X and Y with a certain amount like as Marty said in the comment, with 50.. or you could create two variables, let's name them xPosition & yPosition.
When holding down the keys, you would just increase/decrease these variables by 1, and then call a positioning function which would calculate the new position of the player depending on the xPosition and yPosition 's values and of course the grid sizes.
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
var xPosition:int = 0;
var yPosition:int = 0;
var gridWidth:int = 32;
var gridHeight:int = 32;
function keyDownHandler(event:KeyboardEvent):void{
if (event.keyCode == Keyboard.UP){
yPosition--;
repositionPlayer();
}
if(event.keyCode == Keyboard.DOWN){
yPosition++;
repositionPlayer();
}
if(event.keyCode == Keyboard.LEFT){
xPosition--;
repositionPlayer();
}
if(event.keyCode == Keyboard.RIGHT){
xPosition++;
repositionPlayer();
}
}
function repositionPlayer():void{
player.x = gridWidth*xPosition;
player.y = gridHeight*yPosition;
}
This gives you a big advantage in case you want to change the grid size.

fluidly dealing with multiple keypresses in ActionScript3

I'm currently building an engine for a platformer game at the moment, but I've noticed that ActionScript3 is having difficulty in keeping fluid when multiple keypresses are in use. For example;
function onKeyDown(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.UP || event.keyCode == Keyboard.W || event.keyCode == Keyboard.SPACE) {
if (isTouchingGround()) {
isJumping = true;
yv = -100;
}
} else if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.D) {
if (xv == 0) {
player.gotoAndPlay(275);
}
} else if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.A) {
if (xv == 0) {
xv = -24;
} else if (xv != -120) {
xv-=2;
}
} else if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.D) {
if (xv == 0) {
xv = 24;
} else if (xv != 120) {
xv+=2;
}
}
}
So, as listed above, using the UP (or W, or Space) key triggers the player to jump (seperate onframe event handler handles gravity etc). Using the RIGHT (or D..) key triggers increases the player acceleration, which is again applied to the player in a seperate onframe event handler.
Everything works fine by itself - but the problem arises when multiple keystrokes are used. If a player starts to move to the right, and hits jump, he will cease accelerating. At the same time, he will not decelerate, as instructed in the Keyboard.UP method. Instead, he will maintain constant at his current rate, until the RIGHT key is hit again.
In short, it is as though Actionscript begins ignoring both the keyboard.down and keyboard.up methods for the RIGHT or LEFT movement keys, until they are no longer being pressed. This obviously causes for some very rigid gameplay - is there any solution anyone would be willing to share with me on this?
Your problem lies in the fact that your if conditionals are followed by if else conditionals. Drop the else and just have the if conditionals. Basically if the user holds down space then none of the other if conditionals are going to be tested since space is being held down and it's the first if statement. So just drop the else off of the if's. Just remove the if else conditionals that are testing keystrokes, not the conditionals inside of the if statements that deal with keystrokes.
Here is what your code should look like:
function onKeyDown(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.UP || event.keyCode == Keyboard.W || event.keyCode == Keyboard.SPACE) {
if (isTouchingGround()) {
isJumping = true;
yv = -100;
}
}
if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.D) {
if (xv == 0) {
player.gotoAndPlay(275);
}
}
if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.A) {
if (xv == 0) {
xv = -24;
} else if (xv != -120) {
xv-=2;
}
}
if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.D) {
if (xv == 0) {
xv = 24;
} else if (xv != 120) {
xv+=2;
}
}
}
Something else you may notice is that when the UP key and RIGHT key are both being held down, the computer seems to freeze keyboard input, however when the W key and D key are being held down you can still press other keys and the computer will register their input. The answer to that question is here.
Update:
For the fluid part, instead of triggering something when a keystroke takes place, it is better to have a boolean variable such as keyUP or UP that holds a true if the key is down or false when the key is up. Then have a function onEnterFrame(event:Event):void {} that performs an action when keyUP is true. Like so:
import flash.events.*;
public class keyEvents extends MovieClip {
private var keyRIGHT:Boolean = false;
public function keyEvents():void
{
this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
this.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
function onKeyDown(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.RIGHT) {
this.keyRIGHT = true;
}
}
function onKeyUp(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.RIGHT) {
this.keyRIGHT = false;
}
}
function onEnterFrame(event:Event):void
{
if(this.keyRIGHT) {
// This code is executed while the RIGHT arrow key is down.
}
}
}
If the above code does not work I think that your problem lies with your keyboard, not that it's broken or anything but the way it was made might be messing things up.
Let me know if this didn't help and I'll continue trying.

[AS3]Collision with walls using hitTestObject

So I am currently trying to do a game which is almost like a maze.
The problem is with the wall collision, once the character hits a wall, I can't get him out anymore, he gets "stuck" no matter what direction I try to take him after the collision.
One of the solutions I was thinking would be to whenever the character hits the wall, to "back him up", so that there is no more collision detected. However, when I do that, he goes through the wall in a strange way.
Here is my code so you guys can have an idea of what I'm doing:
function keyPressed(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
leftArrow = true;
if(char.hitTestObject(test))
{
leftHit= true;
} else {
leftHit = false;
}
}
if (event.keyCode == Keyboard.RIGHT)
{
rightArrow = true;
if(char.hitTestObject(test))
{
rightHit= true;
} else {
rightHit = false;
}
}
}
function keyReleased(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
leftArrow = false;
}
if (event.keyCode == Keyboard.RIGHT)
{
rightArrow = false;
}
}
function walking(event:Event):void {
if (rightArrow) {
if(rightHit)
char.x -= speed;
else
char.x += speed;
}
if (leftArrow) {
if(leftHit)
char.x += speed;
else
char.x -= speed;
}
}
A big part of this code I actually got from another person asking the same question. Even doing what was suggested in the other topic, the problem still remains.
Thank you very much for any help!
As requested, here is my solution:
if (rightArrow) {
if (!test.hitTestPoint(MovieClip(root).char.x+speed, MovieClip(root).char.y, true))
{
MovieClip(root).char.x += speed;
x = x-speed; //moving the background
}
}
if (leftArrow) {
if (!test.hitTestPoint(MovieClip(root).char.x-speed, MovieClip(root).char.y, true))
{
MovieClip(root).char.x -= speed;
x = x+speed; //moving the background
}
}
if (upArrow) {
if (!test.hitTestPoint(MovieClip(root).char.x, MovieClip(root).char.y-speed, true))
{
MovieClip(root).char.y -= speed;
y = y+speed; //moving the background
}
}
if (downArrow) {
if (!test.hitTestPoint(MovieClip(root).char.x, MovieClip(root).char.y+speed, true))
{
MovieClip(root).char.y += speed;
y = y-speed; //moving the background
}
}
It's been a while so some of this stuff I really don't remember, but from what I can see, I check if adding the speed of my character will make it become collided with the wall. If that happens, I do not move the character even if I do seemingly have enough space. I think that is pretty much it.
Hope it helps.