Pressing run button does not increase speed unless pressed before - actionscript-3

The way I've done the run in my game is it detects you clicked the run button which is a Movieclip, then it set the increased walkspeeds. If you lift your finger, or move it off the button, it reverts it back the default walkspeed is.
So, the problem is the run button only works when pressed prior to the directional DPAD.
How do I fix this?
My movement class
package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TouchEvent;
import flash.net.dns.AAAARecord;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
public class Movement extends MovieClip
{
public function Movement(main:Game)
{
trace("SUCCESS | Constructed Movement Class");
addChild(Game.playerPosKeeper_mc);
Game.playerPosKeeper_mc.x = 384;
Game.playerPosKeeper_mc.y = 46;
addChild(main.up_dpad);
main.up_dpad.x = 55;
main.up_dpad.y = 336;
addChild(main.down_dpad);
main.down_dpad.x = 57;
main.down_dpad.y = 432;
addChild(main.left_dpad);
main.left_dpad.x = 19;
main.left_dpad.y = 372;
addChild(main.right_dpad);
main.right_dpad.x = 118;
main.right_dpad.y = 372;
addChild(main.menu_dpad);
main.menu_dpad.x = 61;
main.menu_dpad.y = 377;
addChild(main.run_dpad);
main.run_dpad.x = 684;
main.run_dpad.y = 369;
addChild(main.barrierRoof1_game);
main.barrierRoof1_game.x = 0;
main.barrierRoof1_game.y = 0;
addChild(main.barrierRoof2_game);
main.barrierRoof2_game.x = 0;
main.barrierRoof2_game.y = 470;
addChild(main.barrierRoof3_game);
main.barrierRoof3_game.x = 0;
main.barrierRoof3_game.y = 320;
addChild(main.barrierSide1_game);
main.barrierSide1_game.x = 0;
main.barrierSide1_game.y = 0;
addChild(main.barrierSide2_game);
main.barrierSide2_game.x = 790;
main.barrierSide2_game.y = 0;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
main.run_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBeginRUN);
main.run_dpad.addEventListener(TouchEvent.TOUCH_OUT, onTouchEndRUN);
main.run_dpad.addEventListener(TouchEvent.TOUCH_END, onTouchEndRUN);
function onTouchBeginRUN(e:TouchEvent):void
{
Game.upWalkspeed = -5;
Game.downWalkspeed = 5;
Game.leftWalkspeed = -5;
Game.rightWalkspeed = 5;
}
function onTouchEndRUN(e:TouchEvent):void
{
Game.upWalkspeed = -3;
Game.downWalkspeed = 3;
Game.leftWalkspeed = -3;
Game.rightWalkspeed = 3;
}
for each (var aButton:MovieClip in main.Buttons)
{
aButton.addEventListener(TouchEvent.TOUCH_BEGIN, onDown);
aButton.addEventListener(TouchEvent.TOUCH_OUT, onUp);
aButton.addEventListener(TouchEvent.TOUCH_END, onUp);
}
function onDown(e:TouchEvent):void
{
switch (e.currentTarget)
{
case main.up_dpad :
Game.goingUp = true;
Game.goingDown = false;
Game.goingLeft = false;
Game.goingRight = false;
main._Direction.x = 0;
main._Direction.y = Game.upWalkspeed;
if (Game.player1)
{
if (P1UAnim_mc != null)
{
}
else
{
var P1UAnim_mc:MovieClip = new mc_P1UAnim();
addChild(P1UAnim_mc);
}
}
else if (Game.player2)
{
if (P2UAnim_mc != null)
{
}
else
{
var P2UAnim_mc:MovieClip = new mc_P2UAnim();
addChild(P2UAnim_mc);
}
}
break;
case main.down_dpad :
Game.goingUp = false;
Game.goingDown = true;
Game.goingLeft = false;
Game.goingRight = false;
main._Direction.x = 0;
main._Direction.y = Game.downWalkspeed;
if (Game.player1)
{
if (P1DAnim_mc != null)
{
}
else
{
var P1DAnim_mc:MovieClip = new mc_P1DAnim();
addChild(P1DAnim_mc);
}
}
else if (Game.player2)
{
if (P2DAnim_mc != null)
{
}
else
{
var P2DAnim_mc:MovieClip = new mc_P2DAnim();
addChild(P2DAnim_mc);
}
}
break;
case main.left_dpad :
Game.goingUp = false;
Game.goingDown = false;
Game.goingLeft = true;
Game.goingRight = false;
main._Direction.x = Game.leftWalkspeed;
main._Direction.y = 0;
if (Game.player1)
{
if (P1LAnim_mc != null)
{
}
else
{
var P1LAnim_mc:MovieClip = new mc_P1LAnim();
addChild(P1LAnim_mc);
}
}
else if (Game.player2)
{
if (P2LAnim_mc != null)
{
}
else
{
var P2LAnim_mc:MovieClip = new mc_P2LAnim();
addChild(P2LAnim_mc);
}
}
break;
case main.right_dpad :
Game.goingUp = false;
Game.goingDown = false;
Game.goingLeft = false;
Game.goingRight = true;
main._Direction.x = Game.rightWalkspeed;
main._Direction.y = 0;
if (Game.player1)
{
if (P1RAnim_mc != null)
{
}
else
{
var P1RAnim_mc:MovieClip = new mc_P1RAnim();
addChild(P1RAnim_mc);
}
}
else if (Game.player2)
{
if (P2RAnim_mc != null)
{
}
else
{
var P2RAnim_mc:MovieClip = new mc_P2RAnim();
addChild(P2RAnim_mc);
}
}
break;
}
if (! Game.inMotion)
{
Game.inMotion = true;
addEventListener(Event.ENTER_FRAME, onFrame);
}
}
function onFrame(e:Event)
{
movePlayer(main._Direction.x, main._Direction.y);
}
function onUp(e:TouchEvent):void
{
removeEventListener(Event.ENTER_FRAME, onFrame);
Game.goingUp = false;
Game.goingDown = false;
Game.goingLeft = false;
Game.goingRight = false;
Game.inMotion = false;
main._Direction.x = 0;
main._Direction.y = 0;
}
function movePlayer(movementX:Number, movementY:Number):void
{
var originalX:Number = Game.playerPosKeeper_mc.x;
var originalY:Number = Game.playerPosKeeper_mc.y;
Game.playerPosKeeper_mc.x += movementX;
if (checkCollision())
{
Game.playerPosKeeper_mc.x = originalX;
}
Game.playerPosKeeper_mc.y += movementY;
if (checkCollision())
{
Game.playerPosKeeper_mc.y = originalY;
}
}
function checkCollision():Boolean
{
for each (var StageCollisions:MovieClip in main.StageCollisions)
{
if (Game.playerPosKeeper_mc.hitTestObject(StageCollisions))
{
return true;
Game.inMotion = false;
}
}
return false;
}
}
}
}
EDIT:
Here's how I have done movement:
There is a movieclip thats binded to the coordinates of the player. This is what animations set their x and y coordinates to.
If a player starts moving, then an inMotion variable becomes true, and this means the player is moving.
A variable of the direction the player is going in also will change (if he's moving left goingLeft = true)
If the player hits something, or lets go of a direction on the DPAD, then inMotion is false.
This is done so that animations can be added to the stage at appropriate times, and be animated at appropriate times.
For example:
I press left DPAD
inMotion = true, goingLeft = true
If the left animation is not on the stage, add it to the stage.
left animation detects variables are responds to them accordingly:
inMotion && goingLeft
move left direction
!inMotion && !goingLeft
were idle then, do not animate
inMotion && !goingLeft
were moving in another direction, remove the animation
I press right DPAD
follows the same cycle mentioned above
This ensures the right animation is played at the correc times, and this code probably is longer than
it needs to be, but this is honestly shows the limits to what I know in code.

As soon as you see 2 blocks of code that look similar, know that code is bad: https://en.wikipedia.org/wiki/Duplicate_code. The formula less code = better is always right.
Empty blocks of code reduce readability:
// Bad.
if (condition)
{
}
else
{
// some code
}
// Good.
if (!condition)
{
// some code
}
You can also stack several conditions into one if case with logical and && and logical or || unless it becomes unreadable:
// Bad.
if (conditiona)
{
if (conditionb)
{
if (conditionc)
{
}
else
{
// some code
}
}
}
// Better.
if (conditiona && conditionb && !conditionc)
{
// some code
}
If your aim is to assign a single variable, instead of barrage of ifs you can use a ternar operator. Again, unless readability drops:
var foo:*;
// Block of ifs.
if (conditiona)
{
foo = 1;
}
else if (conditionb)
{
foo = 2;
}
// Ternar assignment.
var foo:* = conditiona? 1: conditionb? 2: foo;
// Ternar assignment in a more readable form.
var foo:* = conditiona? 1: (conditionb? 2: foo);
So, your code with all of above applied:
function setDirection(tox:Number, toy:Number):void
{
Game.goingUp = (toy < 0);
Game.goingDown = (toy > 0);
Game.goingLeft = (tox < 0);
Game.goingRight = (tox > 0);
main._Direction.y = Game.goingUp ? Game.upWalkspeed : Game.goingDown ? Game.downWalkspeed : 0;
main._Direction.x = Game.goingLeft? Game.leftWalkspeed: Game.goingRight? Game.rightWalkspeed: 0;
}
function onDown(e:TouchEvent):void
{
if (Game.player1 && !P1UAnim_mc)
{
var P1UAnim_mc:MovieClip = new mc_P1UAnim();
addChild(P1UAnim_mc);
}
if (Game.player2 && !P2UAnim_mc)
{
var P2UAnim_mc:MovieClip = new mc_P2UAnim();
addChild(P2UAnim_mc);
}
switch (e.currentTarget)
{
case main.up_dpad :
setDirection(0,-1);
break;
case main.down_dpad :
setDirection(0,1);
break;
case main.left_dpad :
setDirection(-1,0);
break;
case main.right_dpad :
setDirection(1,0);
break;
}
if (!Game.inMotion)
{
Game.inMotion = true;
addEventListener(Event.ENTER_FRAME, onFrame);
}
}
You can additionally spare yourself of programming UI layout by designing UI in Flash IDE (Animate or CS6 or whichever you have there). You design MovieClip in Library so that it has all interfaces you need in right places. All UI elements you need to have assess to must be given instance names. Then you create a class for this MovieClip:
package
{
public class Layout extends MovieClip
{
// Left, Right, Up and Down are instance names of the objects
// in your designed MovieClip. Their accessors must be public.
// Also you should understand what classes they should be:
// SimpleButton for button object, TextField or TLFTextField
// for texts, MovieClip or Sprite for containers.
public var Left :SimpleButton;
public var Right:SimpleButton;
public var Up :SimpleButton;
public var Down :SimpleButton;
// Then if you set everything right you can access then
// in the class constructor with no need to create them
// or set them up as they are already in their places by design.
function Layout()
{
super();
Left.addEventListener(...);
}
}
}

Related

How do I stop a sprite from jumping in midair? ActionScript 3/Flash Pro CC 2015

I am a beginner Flash/AS3 programmer and I have a very sophisticated problem. How can I prevent a sprite from jumping in midair? I've seen the other question related to "sprite/jump in midair", but I personally cannot figure out how to do that in AS3. Thank you for any response.
Code:
public class DocumentMain extends MovieClip {
private var _vx: Number;
import flash.utils.Timer;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
private var _vy: Number;
public function DocumentMain() {
// constructor code
_vx = 0;
_vy = 0
_startMarker.visible = false;
this.addEventListener("enterFrame", a);
stage.addEventListener("keyDown", b);
stage.addEventListener("keyUp", c);
_windows.addEventListener("enterFrame", handleCollision);
function handleCollision( e:Event ):void
{
{
var collisionWall:Boolean = false;
if (wall.hitTestObject(_windows)) {
collisionWall = true;
}
if (collisionWall) {
while (collisionWall) {
_windows.x += 0.1;
collisionWall = false;
if (wall.hitTestObject(_windows)) {
collisionWall = true;
}
}
_vx = 0;
}
}
}
function a(e:Event):void {
_vy += 2;
_windows.x += _vx;
_windows.y += _vy;
if (_vy > 0) {
if (_windows.y > stage.stageHeight) {
_windows.x = _startMarker.x;
_windows.y = _startMarker.y;
_vy = 0;
}
else {
var collision:Boolean = false;
if (ground.hitTestObject(_windows)) {
collision = true;
}
if (collision) {
while (collision) {
_windows.y -= 0.1;
collision = false;
if (ground.hitTestObject(_windows)) {
collision = true;
}
}
_vy = 0;
}
}
}
}
function b(e:KeyboardEvent):void {
var step:uint = 5
switch (e.keyCode) {
case 37:
_windows.rotationY = -180;
_vx = -7;
break;
case 39:
_windows.rotationY = 0;
_vx = 7;
break;
case 38:
_vy = -20;
break;
}
}
function c(e:KeyboardEvent):void {
switch (e.keyCode) {
case 37:
case 39:
_vx = 0;
}
}
}
}
You need to declare the condition "on the ground" for the player-controlled sprite (I expect from here it's called _windows), and based on that condition, either let the player change vertical speed with up key, or ignore.
You have here a block of code designed to handle ground collision (crude but it does work from what I'm seeing) in your function a(e:Event), this one is the place to set the "on the ground" flag, if there was a collision with ground, set that to true. Since your function first applies "gravity" then checks for collision, it should work properly handling cliffs/slopes together with jumping. So, you declare a Boolean variable in your game class, say "isOnGround", set it to false at first, then check collision with ground, if true, set that var to true. Then, at b() function (a "keyDown" handler) you check whether the var is true, and if yes, jumping is allowed so you happily set your _vy, otherwise you do nothing.
// adding only changed fragments
public class DocumentMain extends MovieClip {
private var _isOnGround:Boolean; // the flag
...
function a(e:Event):void {
...
_isOnGround = false; // reset flag
if (ground.hitTestObject(_windows)) {
collision = true;
_isOnGround = true; // we ARE on ground, rest isn't relevant here
}
...
}
}
function b(e:KeyboardEvent):void {
...
case 38:
if (_isOnGround) { // check here
_vy = -20;
_isOnGround = false; // just in case here
} // otherwise do nothing
break;

Hovering off DPAD sometimes makes character move infinitely in one direction

I have a DPAD in my game when the player holds down let's say the Left DPAD, if he moves his touch to the Up DPAD and let's go, the player continues going in the left direction.
It also works if you hold the a direction, lets say Up continue holding but move off the Up DPAD, sometimes you may continue going in that direction.
What I've tried to prevent this:
On direction clicks, trigger checks on whether your in motion, or
already going a different direction
Setting collisions to force these variables to become false; aka,
you hit something, inMotion = false, etc
That's about all I can think of on how to fix this.
Also, I use a lot of variables for my checks, is it better to change my functions to return booleans, or is this way fine? Just curious.
Game Class
package
{
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Game extends MovieClip
{
public var area1:Boolean = true;
public var area2:Boolean = false;
public var area3:Boolean = false;
public var player1:Boolean = true;
public var player2:Boolean = false;
public var upWalkspeed:Number = -5;
public var downWalkspeed:Number = 5;
public var leftWalkspeed:Number = -5;
public var rightWalkspeed:Number = 5;
public var inMotion:Boolean = false;
public var goingUp:Boolean = false;
public var goingDown:Boolean = false;
public var goingLeft:Boolean = false;
public var goingRight:Boolean = false;
public var playerPosKeeper_mc:MovieClip = new mc_PlayerPosKeeper();
public var up_dpad:MovieClip = new dpad_Up();
public var down_dpad:MovieClip = new dpad_Down();
public var left_dpad:MovieClip = new dpad_Left();
public var right_dpad:MovieClip = new dpad_Right();
public var menu_dpad:MovieClip = new dpad_Menu();
public var run_dpad:MovieClip = new dpad_Menu();
public var barrierRoof1_game:MovieClip = new game_BarrierRoof();
public var barrierRoof2_game:MovieClip = new game_BarrierRoof();
public var barrierSide1_game:MovieClip = new game_BarrierSide();
public var barrierSide2_game:MovieClip = new game_BarrierSide();
public var StageCollisions:Array = new Array(barrierRoof1_game, barrierRoof2_game, barrierSide1_game, barrierSide2_game);
// fix MC goes after not before ||| public var player1States:Array = new Array(mc_P1D1,mc_P1D2,"mc_P1L1","mc_P1L2","mc_P1R1","mc_P1R2","mc_P1U1","mc_P1U2");
public function Game()
{
trace("SUCCESS | Constructed Game Class");
var aMove:Movement = new Movement(this);
addChild(aMove);
}
}
}
Movement Class
package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TouchEvent;
import flash.net.dns.AAAARecord;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
public class Movement extends MovieClip
{
public function Movement(main:Game)
{
trace("SUCCESS | Constructed Movement Class");
addChild(main.playerPosKeeper_mc);
main.playerPosKeeper_mc.x = 384;
main.playerPosKeeper_mc.y = 46;
addChild(main.up_dpad);
main.up_dpad.x = 55;
main.up_dpad.y = 336;
addChild(main.down_dpad);
main.down_dpad.x = 57;
main.down_dpad.y = 432;
addChild(main.left_dpad);
main.left_dpad.x = 19;
main.left_dpad.y = 372;
addChild(main.right_dpad);
main.right_dpad.x = 118;
main.right_dpad.y = 372;
addChild(main.menu_dpad);
main.menu_dpad.x = 61;
main.menu_dpad.y = 377;
addChild(main.run_dpad);
main.run_dpad.x = 684;
main.run_dpad.y = 369;
addChild(main.barrierRoof1_game);
main.barrierRoof1_game.x = 0;
main.barrierRoof1_game.y = 0;
addChild(main.barrierRoof2_game);
main.barrierRoof2_game.x = 0;
main.barrierRoof2_game.y = 470;
addChild(main.barrierSide1_game);
main.barrierSide1_game.x = 0;
main.barrierSide1_game.y = 0;
addChild(main.barrierSide2_game);
main.barrierSide2_game.x = 790;
main.barrierSide2_game.y = 0;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
main.up_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, upBeginInput);
main.down_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, downBeginInput);
main.left_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, leftBeginInput);
main.right_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, rightBeginInput);
// Maybe add diagnol direction buttons in the future?;
// !! NOTE !!
// Use some sort of value, maybe a return or a variable to sync up animations
// to if the player is moving, in the future
// Movement Directions
// Start of UP Movement
function upBeginInput(e:TouchEvent):void
{
main.inMotion = true;
main.goingUp = true;
main.goingDown = false;
main.goingLeft = false;
main.goingRight = false;
main.up_dpad.addEventListener(TouchEvent.TOUCH_END, upEndInput);
addEventListener(Event.ENTER_FRAME,sendUpMovement);
}
function upEndInput(e:TouchEvent):void
{
main.inMotion = false;
main.goingUp = false;
main.up_dpad.removeEventListener(TouchEvent.TOUCH_END, upEndInput);
removeEventListener(Event.ENTER_FRAME,sendUpMovement);
}
function sendUpMovement():void
{
if (main.inMotion == true && main.goingUp == true && main.goingDown == false && main.goingLeft == false && main.goingRight == false)
{
movePlayer(0, main.upWalkspeed);
}
else
{
}
}
// End of UP Movement
// Start of DOWN Movement
function downBeginInput(e:TouchEvent):void
{
main.inMotion = true;
main.goingUp = false;
main.goingDown = true;
main.goingLeft = false;
main.goingRight = false;
main.down_dpad.addEventListener(TouchEvent.TOUCH_END, downEndInput);
addEventListener(Event.ENTER_FRAME,sendDownMovement);
}
function downEndInput(e:TouchEvent):void
{
main.inMotion = false;
main.goingDown = false;
main.down_dpad.removeEventListener(TouchEvent.TOUCH_END, downEndInput);
removeEventListener(Event.ENTER_FRAME,sendDownMovement);
}
function sendDownMovement():void
{
if (main.inMotion == true && main.goingUp == false && main.goingDown == true && main.goingLeft == false && main.goingRight == false)
{
movePlayer(0, main.downWalkspeed);
}
else
{
}
}
// End of DOWN Movement
// Start of LEFT Movement
function leftBeginInput(e:TouchEvent):void
{
main.inMotion = true;
main.goingUp = false;
main.goingDown = false;
main.goingLeft = true;
main.goingRight = false;
main.left_dpad.addEventListener(TouchEvent.TOUCH_END, leftEndInput);
addEventListener(Event.ENTER_FRAME,sendLeftMovement);
}
function leftEndInput(e:TouchEvent):void
{
main.inMotion = false;
main.goingLeft = false;
main.left_dpad.removeEventListener(TouchEvent.TOUCH_END, leftEndInput);
removeEventListener(Event.ENTER_FRAME,sendLeftMovement);
}
function sendLeftMovement():void
{
if (main.inMotion == true && main.goingUp == false && main.goingDown == false && main.goingLeft == true && main.goingRight == false)
{
movePlayer(main.leftWalkspeed, 0);
}
else
{
}
}
// End of LEFT Movement
// Start of RIGHT Movement
function rightBeginInput(e:TouchEvent):void
{
main.inMotion = true;
main.goingUp = false;
main.goingDown = false;
main.goingLeft = false;
main.goingRight = true;
main.right_dpad.addEventListener(TouchEvent.TOUCH_END, rightEndInput);
addEventListener(Event.ENTER_FRAME,sendRightMovement);
}
function rightEndInput(e:TouchEvent):void
{
main.inMotion = false;
main.goingRight = false;
main.right_dpad.removeEventListener(TouchEvent.TOUCH_END, rightEndInput);
removeEventListener(Event.ENTER_FRAME,sendRightMovement);
}
function sendRightMovement():void
{
if (main.inMotion == true && main.goingUp == false && main.goingDown == false && main.goingLeft == false && main.goingRight == true)
{
movePlayer(main.rightWalkspeed, 0);
}
else
{
}
}
// End of RIGHT Movement
function movePlayer(movementX:Number, movementY:Number):void
{
var originalX:Number = main.playerPosKeeper_mc.x;
var originalY:Number = main.playerPosKeeper_mc.y;
main.playerPosKeeper_mc.x += movementX;
if (checkCollision())
{
main.playerPosKeeper_mc.x = originalX;
}
main.playerPosKeeper_mc.y += movementY;
if (checkCollision())
{
main.playerPosKeeper_mc.y = originalY;
}
}
function checkCollision():Boolean
{
for each (var StageCollisions:MovieClip in main.StageCollisions)
{
if (main.playerPosKeeper_mc.hitTestObject(StageCollisions))
{
return true;
main.inMotion = false;
main.goingUp = false;
main.goingDown = false;
main.goingLeft = false;
main.goingRight = false;
}
}
return false;
}
}
}
}
Before you even start to debug behaviors, you need to understand what algorithmic approach is. You have 4 similar pieces of code which differ in minor details and make your whole script too long and unreadable and hard to manage. Here's the guideline:
var isMoving:Boolean;
var Direction:Point = new Point;
var Buttons:Array = [Up, Down, Left, Right];
// Subscribe all buttons for the same handlers and behaviors.
for each (var aButton:InteractiveObject in Buttons)
{
aButton.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
aButton.addEventListener(MouseEvent.MOUSE_OUT, onUp);
aButton.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
function onDown(e:MouseEvent):void
{
// Figure which button was pressed.
switch (e.currentTarget)
{
case Up:
Direction.x = 0;
Direction.y = -1;
break;
case Down:
Direction.x = 0;
Direction.y = 1;
break;
case Left:
Direction.x = -1;
Direction.y = 0;
break;
case Up:
Direction.x = 1;
Direction.y = 0;
break;
}
// Now start moving Hero into the Direction.
if (!isMoving)
{
isMoving = true;
addEventListener(Event.ENTER_FRAME, onFrame);
}
}
function onFrame(e:Event):void
{
Hero.x += Direction.x;
Hero.y += Direction.y;
}
function onUp(e:MouseEvent):void
{
// If any of buttons is released or mouse out, stop moving Hero.
removeEventListener(Event.ENTER_FRAME, onFrame);
Direction.x = 0;
Direction.y = 0;
isMoving = false;
}
As you can see, the beauty of algorithmic approach is that you need to handle differently only things that need to be handled differently, in the example case (which is pretty similar to what you want to create) it is the block to set the movement direction. The rest of the code is identical for all the buttons and that's why the whole script is short and readable, easy to understand and manageable.

Flash - Pause Game ActionScript 3

I'm only a beginner and this code is somewhere in the internet that I just want to learn
This is a snake game, I want to pause a game using spacebar keyboard
I don't know how to pause a game someone please help
import flash.ui.*;
public class Snake extends MovieClip
{
private var _Paused:Boolean = false
private var score, life, framesElapsed:Number;
private var p1speedX, p1speedY:Number;
private var spacePressed, readyToMove, gotoWin, gotoLose:Boolean;
private var left,right,up,down:Boolean;
private var snakes:Array;
private var mcFood:Food;
public function Snake()
{
}
//All Start Functions
public function startMenu()
{
stop();
btnStartGame.addEventListener(MouseEvent.CLICK, gotoStartGame);
btnHowToPlay.addEventListener(MouseEvent.CLICK, gotoHowToPlay);
}
public function startHowToPlay()
{
btnBack.addEventListener(MouseEvent.CLICK, gotoMenu);
}
public function startWin()
{
btnBack.addEventListener(MouseEvent.CLICK, gotoMenu);
}
public function startLose()
{
btnBack.addEventListener(MouseEvent.CLICK, gotoMenu);
}
public function startGame()
{
score = 0;
life = 3;
framesElapsed = 0;
p1speedX = 1; //snakek starts moving right
p1speedY = 0;
up = false;
down = false;
left = false;
right = false;
spacePressed = false;
readyToMove = false;
gotoWin = false;
gotoLose = false;
snakes = new Array();
//Create 1st body part of snake and push it into the array
var snakeHead = new SnakePart();
snakeHead.x = 400;
snakeHead.y = 300;
snakes.push(snakeHead);
addChild(snakeHead);
addEventListener(Event.ENTER_FRAME,update);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUpHandler);
stage.focus = this;
}
//All Goto Functions
private function gotoStartGame(evt:MouseEvent)
{
btnStartGame.removeEventListener(MouseEvent.CLICK, gotoStartGame);
btnHowToPlay.removeEventListener(MouseEvent.CLICK, gotoHowToPlay);
gotoAndStop("game");
}
private function gotoHowToPlay(evt:MouseEvent)
{
btnStartGame.removeEventListener(MouseEvent.CLICK, gotoStartGame);
btnHowToPlay.removeEventListener(MouseEvent.CLICK, gotoHowToPlay);
gotoAndStop("howtoplay");
}
private function gotoMenu(evt:MouseEvent)
{
btnBack.removeEventListener(MouseEvent.CLICK, gotoMenu);
gotoAndStop("menu");
}
private function keyDownHandler(evt:KeyboardEvent)
{
if (evt.keyCode == Keyboard.A)
{
//1st Player Left Key
left = true;
}
else if (evt.keyCode == Keyboard.D)
{
//1st Player Right Key
right = true;
}
if (evt.keyCode == Keyboard.W)
{
//1st Player Up Key
up = true;
}
else if (evt.keyCode == Keyboard.S)
{
//1st Player Down Key
down = true;
}
if (evt.keyCode == Keyboard.SPACE)
{
spacePressed = true;
}
}
private function keyUpHandler(evt:KeyboardEvent)
{
if (evt.keyCode == Keyboard.A)
{
left = false;
}
else if (evt.keyCode == Keyboard.D)
{
right = false;
}
else if (evt.keyCode == Keyboard.W)
{
up = false;
}
else if (evt.keyCode == Keyboard.S)
{
down = false;
}
if (evt.keyCode == Keyboard.SPACE)
{
spacePressed = false;
}
}
public function update(evt:Event)
{
handleUserInput();
handleGameLogic();
handleDraw();
if (gotoWin)
triggerGoToWin();
else if (gotoLose)
triggerGoToLose();
}
private function handleUserInput()
{
//Handle player 1 position
//if player wants to move left but snake is not
//already moving right
if (left && (p1speedX != 1))
{
p1speedX = -1;
p1speedY = 0;
}
//if player wants to move right but snake is not
//already moving left
else if (right && (p1speedX != -1 ))
{
p1speedX = 1;
p1speedY = 0;
}
//if player wants to move up but snake is not
//already moving down
else if (up && (p1speedY != 1))
{
p1speedY = -1;
p1speedX = 0;
}
else if (down && (p1speedY != -1))
{
p1speedY = 1;
p1speedX = 0;
}
if (spacePressed)
readyToMove = true;
}
private function handleGameLogic()
{
if (!readyToMove)
return;
framesElapsed++;
//Update the new position of the snake's head
if (framesElapsed % 2 == 0)
{
//Update motion of the snake's body
for (var i = snakes.length - 1; i >= 1; i--)
{
snakes[i].x = snakes[i-1].x;
snakes[i].y = snakes[i-1].y;
}
if (p1speedX > 0)
{
snakes[0].x += 20;
}
else if (p1speedX < 0)
{
snakes[0].x -= 20;
}
else if (p1speedY > 0)
{
snakes[0].y += 20;
}
else if (p1speedY < 0)
{
snakes[0].y -= 20;
}
//Check for collisions between the snake and its own body
for (var i = snakes.length - 1; i >= 1; i--)
{
if ((snakes[0].x == snakes[i].x) &&
(snakes[0].y == snakes[i].y))
{
collided();
break;
}
}
}
//Check for collisions between the snake and the walls
if (snakes[0].y < 0)
{
collided();
}
else if (snakes[0].x > 800)
{
collided();
}
else if (snakes[0].x < 0)
{
collided();
}
else if (snakes[0].y > 600)
{
collided();
}
//Add new food items
if (mcFood == null)
{
//Create a new food item
mcFood = new Food();
mcFood.x = Math.random() * 700 + 50;
mcFood.y = Math.random() * 500 + 50;
addChild(mcFood);
}
//Check for collisions between food item and Snake
if (mcFood != null)
{
if (snakes[0].hitTestObject(mcFood))
{
//Add score
score += 100;
if (score >= 5000)
gotoWin = true;
removeChild(mcFood);
mcFood = null;
//Add a body
var newPart = new SnakePart();
newPart.x = snakes[snakes.length-1].x;
newPart.y = snakes[snakes.length-1].y;
snakes.push(newPart);
addChild(newPart);
}
}
}
private function handleDraw()
{
//Handle display
if (!readyToMove)
txtHitSpaceBar.visible = true;
else
txtHitSpaceBar.visible = false;
txtScoreP1.text = String(score);
txtLife.text = String(life);
}
private function triggerGoToWin()
{
clearGame();
removeEventListener(Event.ENTER_FRAME, update);
gotoAndStop("win");
}
private function triggerGoToLose()
{
clearGame();
removeEventListener(Event.ENTER_FRAME, update);
gotoAndStop("lose");
}
//Misc Functions
private function resetGame()
{
//remove all food
removeChild(mcFood);
mcFood = null;
//remove all of snake body except first
for (var i = snakes.length - 1; i >= 1; i--)
{
removeChild(snakes[i]);
snakes.splice(i,1);
}
//Center the snake's head
snakes[0].x = 400;
snakes[0].y = 300;
readyToMove = false;
}
private function clearGame()
{
//remove all food
if (mcFood != null)
{
removeChild(mcFood);
mcFood = null;
}
//remove all of snake body
for (var i = snakes.length - 1; i >= 0; i--)
{
removeChild(snakes[i]);
snakes.splice(i,1);
}
}
private function collided()
{
life -= 1;
if (life > 0)
resetGame();
else
gotoLose = true;
}
}
}//end class
//end package
There are a few possibilities how to pause a game.
You already have a boolean variable called _Paused, this will help us to determine when to pause the execution of the game.
Change the contents of keyDownHandler(evt) to the following:
private function keyDownHandler(evt:KeyboardEvent)
{
...
//leave the if conditionals for movement as they are
if (evt.keyCode == Keyboard.SPACE)
{
if(_Pause == true){
_Pause = false;
}else{
_Pause = true;
}
}
}
The above code will toggle between a Paused state and the Game state. When the game first starts, the _Paused variable is false. Once you press Space on your keyboard, the if condition will check what state you need to be in. So at the very first time, _Paused will be set to true. if you press space again, it will set it to false again. Simple, right?
Now, you have an EventListener for ENTER_FRAME called update that executes for every frame. This function is responsible that things, well, work. You can see that it calls different functions that draw stuff on the screen or handle game logic. So, what would happen if you don't call this function? The game would stop. So we need a way to not call those functions when you are in your pause state. Again, this is very simple.
Change the contents of update(evt) to the following:
public function update(evt:Event)
{
if(_Paused == false){
handleUserInput();
handleGameLogic();
handleDraw();
if (gotoWin)
triggerGoToWin();
else if (gotoLose)
triggerGoToLose();
}
}
Now the functions will only be called when your _Paused variable is set to false.
I hope this helped you with your studying, although this is very basic stuff. Maybe you should try smaller steps first? Programming games can be pretty complex for beginner who have no experience with coding whatsoever.

AS3 - how to remove a child when it reaches a certain point, and re add the child

So first off i'd like to state that i am not very good at AS3, i'm completely self taught so i am sure that there are many things i've done badly, inefficiently or plain wrong and i'm happy for any comments on these if there is things i can improve.
In addition, i have done this with classes, however i am now running into a time problem and have decided to make things work first and sort out the class files properly later, i know this is also very bad practice and makes more work than needed, however as i'm not so confident in their use, i would rather complete the work.
So to my question, i am creating a platform game and so far i've got the movement and jumping from platform to platform down, and i am trying to add the scrolling functionality of the game now, the way i am attempting this is by removing a child when it reaches the bottom of the screen, and then adding that child back in a random position.
on the start function i have this array to add the child and randomize it's position:
for(i=0;i<8;i++) {
PlatformInstance[i] =new Platform();
PlatformInstance[i].y= Math.random()*900;
PlatformInstance[i].x= Math.random() *1500;
stage.addChild(PlatformInstance[i]);
}
the code for my collisions and the scrolling is shown below:
for (i=0; i<8; i++) {
if (PlatformInstance[i].hitTestPoint (Smallclock_hero.x,Smallclock_hero.y+130,true)) {
yescollision = true;
if (keyboard_input.is_up() && yescollision == true)
{
trace ("boop")
Smallclock.y_speed = -40
yescollision = false;
}
else {
Smallclock.y_speed *= 0;
}
}
if (Scrolling == true) {
PlatformInstance[i].y += 1; // this moves the platforms down.
}
}
is there a simple and easy way to remove the PlatformInstance when it reaches a point say (1000) and then add the instance again, with the same randomization code?
thanks in advance.
Adding all of my class files for clarities sake, not sure if you will need them
Start.as
package com {
import flash.display.MovieClip;
import flash.events.Event;
public class Start extends MovieClip {
public var keyboard_input:Keys;
public var Smallclock_hero = new Smallclock;
public var BasePlatformInstance:BasePlatform = new BasePlatform;
public var BackgroundInstance:Background = new Background();
public var PlatformInstance:Platform = new Platform();
public var keyboard_sprite = new MovieClip();
public static var yescollision:Boolean = false
var yScrollSpeed:int = 1;
var Scrolling:Boolean = false;
var i:int =0;
public var Running:Boolean = true;
public function Start () {
trace("Hello")
addChild (BackgroundInstance);
addChild (Smallclock_hero);
addChild (BasePlatformInstance);
BasePlatformInstance.x = 0;
BasePlatformInstance.y = 980;
BackgroundInstance.height = stage.stageHeight +50 ;
BackgroundInstance.width = stage.stageWidth +50 ;
Smallclock_hero.init();
var keyboard_sprite = new MovieClip();
addChild (keyboard_sprite);
keyboard_input = new Keys (keyboard_sprite);
stage.addEventListener(Event.ENTER_FRAME,on_enter);
addEventListener (Event.ENTER_FRAME, collisions);
//addEventListener (Event.ENTER_FRAME,refreshPlatform)
for(i=0;i<8;i++) {
PlatformInstance[i] =new Platform();
PlatformInstance[i].y= Math.random()*900;
PlatformInstance[i].x= Math.random() *1500;
stage.addChild(PlatformInstance[i]);
}
}
public function on_enter(event:Event) {
if (keyboard_input.is_left()){
Smallclock_hero.apply_force(-1,0);
Smallclock_hero.scaleX = -1
}
if (keyboard_input.is_right()) {
Smallclock_hero.apply_force(1,0);
Smallclock_hero.scaleX = 1
}
}
public function collisions (e:Event) {
if (BasePlatformInstance.hitTestPoint (Smallclock_hero.x,Smallclock_hero.y+130, true)) {
//trace ("touching!")
yescollision = true;
if (keyboard_input.is_up())
{
Smallclock.y_speed = -40
Start.yescollision = false;
}
if (Smallclock.y_speed ==-40) {
Scrolling = true;
removeChild(BasePlatformInstance);
}
else {
Smallclock.y_speed *= 0;
}
}
for (i=0; i<8; i++) {
if (PlatformInstance[i].hitTestPoint (Smallclock_hero.x,Smallclock_hero.y+130, true)) {
yescollision = true;
if (keyboard_input.is_up() && yescollision == true)
{
trace ("boop")
Smallclock.y_speed = -40
yescollision = false;
}
else {
Smallclock.y_speed *= 0;
}
}
if (Scrolling == true) {
PlatformInstance[i].y += 1;
}
}
Smallclock.as
package com {
import flash.display.Sprite;
import flash.events.Event;
public class Smallclock extends Sprite {
private var x_speed:Number;
public static var y_speed:Number;
private var power:Number;
public var friction:Number;
public static var gravity:Number;
public static var jumping:Boolean = false;
public static var jumppwr:Number;
public static var jumpSpeedLimit:int = 15;
public function Smallclock() {
addEventListener (Event.ENTER_FRAME, move);
}
private function move (e:Event) {
x+=x_speed;
y+=y_speed;
y_speed += gravity
x_speed *= friction ;
y_speed *= friction ;
if (x < -25) {
x = 1650
}
if (x > 1650) {
x = -25
}
}
public function apply_force (x_force,y_force){
x_speed += (x_force*power);
y_speed += (y_force*power);
}
public function init() {
jumppwr = 2;
gravity = 1.0;
power = 0.8;
friction = 0.9;
x_speed = 0;
y_speed = 0;
x= stage.stageWidth/2;
y = 850;
}
}
}
Keys.as
package com {
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Keys {
private var press_left = false;
private var press_right = false;
private var press_up = false;
private var press_down = false;
private var press_space = false;
public function Keys(movieclip) {
movieclip.stage.addEventListener(KeyboardEvent.KEY_DOWN, key_down);
movieclip.stage.addEventListener(KeyboardEvent.KEY_UP, key_up);/**/
}
public function is_left() {
return press_left;
}
public function is_right() {
return press_right;
}
public function is_up() {
return press_up;
}
public function is_down() {
return press_down;
}
public function is_space() {
return press_space;
}
public function key_down(event:KeyboardEvent) {
if (event.keyCode == 32) {
press_space = true;
}
if (event.keyCode == 37) {
press_left = true;
}
if (event.keyCode == 38) {
press_up = true;
}
if (event.keyCode == 39) {
press_right = true;
}
if (event.keyCode == 40) {
press_down = true;
}
}
public function key_up(event:KeyboardEvent) {
if (event.keyCode == 32) {
press_space = false;
}
if (event.keyCode == 37) {
press_left = false;
}
if (event.keyCode == 38) {
press_up = false;
}
if (event.keyCode == 39) {
press_right = false;
}
if (event.keyCode == 40) {
press_down = false;
}
}
}
}
I am not going to read thru all your code, sorry.
Of course there is. In the interval/event handler where you are updating your positions, you have to loop through all your platforms and check whether their position is >= 1000. If it is, you don't need to remove it, just randomize it and set its position again with the code you already have:
for(i=0;i<8;i++) {
if(PlatformInstance[i].x >= 1000) {
var inst:Platform = PlatformInstance[i];
inst.y= Math.random() * 900;
inst.x= Math.random() * 1500;
}
That should work just fine. If you really need to remove it (??), you can do so with stage.removeChild(inst) and then stage.addChild(inst) again.
A few tips from that few code I read in your question: do not give instance/variable names with capitalized first letter. That should be a class name (PlatformInstance is obviously an instance of Array or Vector, use platformInstance). Do not add object directly to stage. If possible, add them to your stage owner (which is your document class if you write your code in classes).

Can anyone help with the collision detect for my platformer? (Actionscript 3.0)

Im currently working on making a flash platformer engine...but my collision detect needs some serious help. Whenever my character 'jumps', and lands on the collision object, he goes about halfway through it for a split second, then goes back to the top (where I want him to be). If I continue to jump multiple times, the shadow of him, if you will, that appears for a split second goes further and further into the collision object, eventually making him fall all the way through it. Here's the code for my main class, and if you need me to clarify anything, please ask.
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.Stage;
import Player;
import HitObject;
public class TestGame extends MovieClip {
private var _hitObject:HitObject;
private var _player:Player;
private var _leftArrow:Boolean;
private var _rightArrow:Boolean;
private var _upArrow:Boolean;
private var _hit:Boolean;
private var _fall:Boolean;
private var _jump:Boolean = true;
private var _velR:Number = 0;
private var _velL:Number = 0;
private var _scale:Number = .1;
private var _jumpCount:Number = 0;
private var _i:Number = .5;
private var _i2:Number = 7;
private var _i3:Number = 0;
private var _adjustHit:Number;
private var _jumpRL:Number;
private var _jumpVel:Number;
public function TestGame() {
_hitObject = new HitObject();
_player = new Player();
addChild(_hitObject);
addChild(_player);
_hitObject.x = (stage.width * 0.5) + 50;
_hitObject.y = (stage.height * 0.5) + 150;
_hitObject.scaleY = 3;
_hitObject.alpha = .5;
_player.scaleX = _scale;
_player.scaleY = _scale;
_player.x += 200;
_player.y += 250;
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
private function enterFrameHandler(e:Event) {
if(_player.hitTestObject(_hitObject)) {
_adjustHit = _hitObject.y - _hitObject.height/2 - _player.height/2;
_player.y = _adjustHit;
_hit = true;
_jump = false;
if(_i3 > 8) {
_jump = true;
}
_jumpCount = 0;
_i2 = 7;
_fall = false;
_i3++;
}
else if(!_player.hitTestObject(_hitObject) && !_upArrow) {
_fall = true;
}
if(_fall) {
_player.y += _i;
_i += .5;
if(_i < 3) {
_i = 3;
}
_hit = false;
}
if(_upArrow && _hit && _jump) {
if(_velR > 0) {
_jumpRL = _velR;
_jumpVel = _velR;
}
else if(_velL > 0) {
_jumpRL = -_velL;
_jumpVel = _velL;
}
else {
_jumpVel = 1;
if(_player.scaleX == .1) {
_jumpRL = 1;
}
else {
_jumpRL = -1;
}
}
_player.y -= _i2 + _jumpVel/2;
_player.x += _jumpRL/2;
_jumpCount += _i2;
_i2 -= .5;
_fall = false;
if(_i2 < -3) {
_jumpCount = 61;
}
if(_jumpCount > 60) {
_i2 = 7;
_jump = false;
_fall = true;
_jumpCount = 0;
}
_i3 = 0;
}
if(_rightArrow) {
_player.startRun();
_player.scaleX = _scale;
_velL = 0;
_player.x += _velR;
if(_velR < 20) {
_velR += 2;
}
if(_velR > 20) {
_velR = 20;
}
}
else if(_leftArrow) {
_player.startRun();
_player.scaleX = -_scale;
_velR = 0;
_player.x -= _velL;
if(_velL < 20) {
_velL += 2;
}
if(_velL > 20) {
_velL = 20;
}
}
if(_velR > 0) {
_player.x += _velR;
_velR -= .7;
}
else if(_velL > 0) {
_player.x -= _velL;
_velL -= .7;
}
if(_velR < 0 || _velL < 0) {
_velR = 0;
_velL = 0;
}
}
private function keyDownHandler(e:KeyboardEvent):void {
if(e.keyCode == 39) {
_rightArrow = true;
}
if(e.keyCode == 37) {
_leftArrow = true;
}
if(e.keyCode == 38) {
_upArrow = true;
}
}
private function keyUpHandler(e:KeyboardEvent):void {
_upArrow = false;
_rightArrow = false;
_leftArrow = false;
}
}
}
For anyone having this problem, make sure you are applying a force in response to collision in addition to repositioning out of collision. This case sounds like maybe the velocity is being compounded by gravity, meaning you keep moving the object back but it's velocity isn't being zeroed out, so it moves further and further into the floor with each update step.
Applying normal force will cancel gravity and fix this.
If you just want easy-to-use collision detection, take a look at the Collision Detection Kit for Actionscript 3. I've used it before and it beats every other collision detection framework I've ever used.
From what you have said it sounds like at time 't' the player has not hit the object as yet but at time 't+1' the player has moved 10px (for example) so now appears stuck in the object until your collision handler moves the player to the correct spot.
Also with the jumping up and down perhaps the player has not been moved back correctly after a collision before his position increments which is why over time the player eventually falls through if you keep jumping.
Be careful about comparing numbers. I see a if (_player.scaleX == .1). Numbers in AS3 are called Floating Point numbers in other languages. Due to the way Floating Point numbers are handled by the computer they can give misleading results. Sometimes a value like 1.0 is really 0.999998 and if thats the case a compare statement will always fail.
As a tip you might want to change some of the values to CONST as you have a lot of hardcoded values, some which are related and could be changed easier by making them a CONST.