Link to home
Start Free TrialLog in
Avatar of ErnstJacobs
ErnstJacobsFlag for Germany

asked on

actionscript - smooth movement

I want my figure to move smoothly, so far so good. The movement is pretty slick, but there's one problem. When you're moving to the right, and then change direction say left, it takes a moment to realize it needs to go left. So it stops moving for a second and then goes left.

I've added the CS4 file so it's easier to understand what I mean.
Just press the right arrow key, and then the left arrow key, you'll see what I mean :)

Please help

edit: omg I forgot to put the file up :') It's added now dimension-switch-CS4.fla
Avatar of dgofman
dgofman
Flag of United States of America image

If you really wants to smooth do not use Timer, move by one pixel and increase a FrameRate

import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;

//variables global
var stageVar:Stage = stage;

//variables player
var player:MovieClip = player;
var plr_action:String = "NONE"
var plr_direction:String = "NONE";
var plr_inAir:Boolean = true;

//variables movement
var velocityX:Number = 0;
var velocityY:Number = 0;
var velocityXMax:Number = 1;
var velocityYMax:Number = 1;
var acceleration:Number = 0.5;
var friction:Number = 0.79;

//variables level
var wall:MovieClip = wall;
var wall2:MovieClip = wall2;
var lvl_bottom:uint = 350;
var lvl_top:uint = 10;
var lvl_left:uint = 10;
var lvl_gravity:Boolean = true;

//initiate
player.x = 15;
player.y = 150; //350
stageVar.frameRate = 200;

//Events
stageVar.addEventListener(KeyboardEvent.KEY_DOWN, keyPressedDown);
stageVar.addEventListener(KeyboardEvent.KEY_UP, keyPressedUp);
stageVar.addEventListener(Event.ENTER_FRAME, onTick);

//functions
function onTick(e:Event) {
      playerMove();
      playerActions();
      getGravity();
}

function getGravity() {
      if(plr_inAir) {
            if(lvl_gravity == true) {
                  velocityY -= 1.5;
            }
            if(lvl_gravity == false) {
                  velocityY += 1.5;
            }
            velocityY *= friction;
            player.y -= velocityY;
            playerCollide();
      }
} //getGravity

function playerActions() {
      if(plr_action == "GRAVITY") {
            if(lvl_gravity == true) {
                  lvl_gravity = false;
                  plr_inAir = true;
                  player.y -= 1;
            }
            else {
                  lvl_gravity = true;
                  plr_inAir = true;
                  player.y += 1;
            }
            plr_action = "NONE";
      }
} //playerActions

function playerCollide() {
      if(player.hitTestObject(wall)) {
            plr_inAir = false;
            velocityY = 0;
      }
      if(player.hitTestObject(wall2)) {
            plr_inAir = false;
            velocityY = 0;
      }
} //playerCollide

function playerMove() {
      if(plr_direction == "LEFT") {
            if (velocityX < velocityXMax) {
                  velocityX += acceleration;
            }
      }
      if(plr_direction == "RIGHT") {
            if (velocityX > -velocityXMax) {
                  velocityX -= acceleration;
            }
      }
      
      // friction
      velocityX *= friction;
      velocityY *= friction;
      
      // update position
      player.x -= velocityX;

      if(player.x <= lvl_left) {
            player.x += 1;
            velocityX = 0;
      }
} //movePlayer

function keyPressedDown(e:KeyboardEvent) {
      var key:uint = e.keyCode;
      //trace(e.keyCode);
      if(key == 37) {
            plr_direction = "LEFT";
      }
      if(key == 39) {
            plr_direction = "RIGHT";
      }
      if(key == 38) {
            plr_direction = "UP";
      }       
      if(key == 71) {
            plr_action = "GRAVITY";
      }
} //keyPressedDown

function keyPressedUp(event:KeyboardEvent):void {
      plr_direction = "NONE";
}
Avatar of ErnstJacobs

ASKER

Thank you for your reply, however it still doesnt respond as it should. It just runs everything faster. Not that that's a problem since I'll slow the rest down, but it is still not changing direction immediatly when you go from right to left.
Why? As soon as I am pressing the arrows keys your box changing direction
When you press right, so you'll go right. Then press left and release right.
So first press left and then release right, then you'll get that problem. You always have to let go first.
ASKER CERTIFIED SOLUTION
Avatar of dgofman
dgofman
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Perfect! It works great now.

Just one more thing, I've got the button G as gravity switch. Right now I've got it as a seperate function, which I want to keep if possible. But at this moment if you move right, and then press G it stops moving right.

How should I resolve this problem?
I don't see G button it's working for me. Can you pass again your updated FLA file?
Sure thing, but it has changed a lot, it now has background, different size, working walls and a little menu.
When you enter the menu, press N for new game, then to start game press N again.

Wow that's a first... I'm getting
"The extension of one or more files in the archive is not in the list of allowed extensions: bin/SymDepend.cache"

So I'll post the code below.

The G(RAVITY) is located under playerActions()
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;
import flash.text.TextField;

//variables global
var options:String;
var menu:MovieClip = menu;
var startGame:Boolean = false;
var stageVar:Stage = stage;
var backGround:MovieClip = backGround;
var lastKeyCodePressed:uint;
var mainText:TextField = menu.main_text as TextField;
var helpText:TextField = menu.help_text as TextField;

//variables player
var player:MovieClip = player;
var plr_action:String = "NONE"
var plr_direction:String = "NONE";
var plr_inAir:Boolean = true;

//variables movement
var velocityY:Number = 0;
var velocityYMax:Number = 5;
var velocityYMaxReverse:Number = -5;
var acceleration:Number = 0.5;
var friction:Number = 0.89;

//variables level
var lvl_bottom:uint = 350;
var lvl_top:uint = 10;
var lvl_left:uint = 10;
var lvl_gravity:Boolean = true;

//arrays
var hwalls:Array = new Array(h_wall1, h_wall2, h_wall3, h_wall4, h_wall5, h_wall6, h_wall7, h_wall8, h_wall9, h_wall10, h_wall11, h_wall12, h_wall13, h_wall14);
var vwalls:Array = new Array(v_wall1);

/*
for(var a = 0; a < 15; a++) {
	trace(hwalls[a] = );
}
*/

//initiate
mainText.text = "Dimension Switch";
helpText.visible = false;
stageVar.frameRate = 200;

//Events
stageVar.addEventListener(KeyboardEvent.KEY_DOWN, keyPressedDown);
stageVar.addEventListener(KeyboardEvent.KEY_UP, keyPressedUp);
stageVar.addEventListener(Event.ENTER_FRAME, onTick);


//functions
function onTick(e:Event) {
	menuActions();
	if(options == "startgame") {
		playerMove();
		playerActions();
		playerCollide();
		getGravity();
		plr_action = "NONE"
	}	
}

function reset() {
	//reset variables
	player.x = 15;
	player.y = 150;
	
	plr_inAir = true;
	lvl_gravity = true;
	
	menu.visible = false;
	helpText.visible = false;
	options = "none";
}

function menuActions() {
	if(plr_action == "NEW") {
		reset();
	}
	if(plr_action == "START") {
		options = "startgame"
	}
	if(plr_action == "HELP") {
		helpText.visible = true;
	}
	if(plr_action == "QUIT") {
		menu.visible = true
	}
	if(plr_action == "EXIT") {
		fscommand("quit", "");
	}
}

function getGravity() {
	if(plr_inAir) {
		if(lvl_gravity == true) {
			velocityY -= 0.9;
		}
		if(lvl_gravity == false) {
			velocityY += 0.9;
		}
		velocityY *= friction;
		player.y -= velocityY;
		
	}
} //getGravity

function playerActions() {
	if(plr_action == "GRAVITY") {
		if(lvl_gravity) {
			lvl_gravity = false;
			plr_inAir = true;
			player.y -= 10;
		}
		else {
			lvl_gravity = true;
			plr_inAir = true;
			player.y += 10;
		}
		plr_action = "NONE";
	}
} //playerActions

function playerCollide() {
	for(var i = 0; i < hwalls.length; i++) {
		if(player.hitTestObject(hwalls[i])) {
			plr_inAir = false;
			velocityY = 0;
		}
	}
	for(var c = 0; c < vwalls.length; c++) {
		if(player.hitTestObject(vwalls[c])) {
			player.x -= 2;
		}
	}
} //playerCollide

function playerMove() {
	if(plr_direction == "LEFT") {
		player.x -= 2;
	}
	if(plr_direction == "RIGHT") {
		player.x += 2;
	}
	
	velocityY *= friction;
	moveLevel();
	
	if(player.x <= lvl_left) {
		player.x += 2;
	}
} //movePlayer

function moveLevel() {	
	if(player.x > 1250) {
		backGround.x -= 1250;
		player.x = 0;
	}
}

function keyPressedDown(e:KeyboardEvent) {
	var key:uint = e.keyCode;
	lastKeyCodePressed = e.keyCode;
	
	//trace(e.keyCode);
	if(key == 78) {
		if(plr_action == "NEW") {
			plr_action = "START";
		}
		if(plr_action != "NEW" && plr_action != "START") {
			plr_action = "NEW"
		}
	}
	if(key == 72) {
		plr_action = "HELP";
	}
	if(key == 81) {
		if(menu.visible) {
			plr_action = "EXIT";
			trace(plr_action);
		}
		if(!menu.visible) {
			plr_action = "QUIT";
			trace(plr_action);
		}
	}
	
	if(key == 37) {
		plr_direction = "LEFT";
	}
	if(key == 39) {
		plr_direction = "RIGHT";
	}
	if(key == 71) {
		plr_action = "GRAVITY";
	}
} //keyPressedDown

function keyPressedUp(e:KeyboardEvent):void {
	if(lastKeyCodePressed == e.keyCode){
    	//trace("UP="+e.keyCode);
    	plr_direction = "NONE";
    }
} //keyPressedUp


/*
[OLD]
function playerMove() {
	if(plr_direction == "LEFT") {
		if (velocityX < velocityXMax) {
			velocityX += acceleration;
		}
	}
	if(plr_direction == "RIGHT") {
		if (velocityX > velocityXMaxReverse) {
			velocityX -= acceleration;
		}
	}
	
	// friction
	velocityX *= friction;
	velocityY *= friction;
	
	// update position 
	player.x -= velocityX;
	moveLevel();
	
	if(player.x <= lvl_left) {
		player.x += 1;
		velocityX = 0;
	}
} //movePlayer
*/

Open in new window

I can help you only tonight, I will be busy whole day. If u will find an answer early please let me know
I haven't solved it yet, I tried a couple of things since I know what the problem is but I haven't figure it out yet.

in the keyPressedDown code I say plr_direction = "NONE";

That is so that the box does not move right or left when you let go of the key.
But, when you keep right pressed and then press G, and you release G again, it sees that as the trigger to set plr_direction to "NONE". And there's the problem
Please can you upload your FLA I don;'t have with your old version h_wall1(s)
It may be you cannot get "G" key from keydown function.
In this case you need to disable shortcuts here is details

http://www.lawriecape.co.uk/theblog/index.php/archives/113
Any way I helped to resolve your original problem

"actionscript - smooth movement"

Please accept my workaround #36974012 and open a new ticket.

Please do not forget to upload your currrent version of FLA

Good luck!