AS3 Game - Jump Doesn't Alter Velocity - actionscript-3

I'm having problems making my Player jump in AS3. I'll upload everything relevant, I'm really struggling to figure out exactly what I've done wrong. It used to work but now it doesn't, I spent so long fixing errors I can't figure out where this messed up. The Player Class is extended from the BoundaryObject class. I know the function is activated because the Player's this.gotoAndStop("jump"); works.
Player Class - Function for Jump
public function startJumping():void
{
if (isJumping == false)
{
isJumping = true;
this.gotoAndStop("jump");
downwardVelocity = -28;
}
}
BoundaryObject Class - Variables/Loop for gravity
public var downwardVelocity:Number;
protected var isRunning:Boolean;
public var isJumping:Boolean;
public function BoundaryObject()
{
trace("i am any object that collides with the boundary");
downwardVelocity = 0;
isRunning = false;
this.gotoAndStop("jump");
addEventListener(Event.ENTER_FRAME,enterFrameHandler);
// constructor code
}
private function enterFrameHandler(event:Event):void
{
downwardVelocity += 2; //equals itself plus 2
this.y += downwardVelocity;
}
public function incrementUpward()
{
//increment the y up until not colliding
this.y -= 0.1;
}
public function keepOnBoundary()
{
downwardVelocity = 0;//stops pulling the object down
}

Just at first glance, maybe set your jump boolean to true as you are setting this frame in constructor.

Try setting the downwardVelocity of the parent.
parent.downwardVelocity = -28;

Related

Restore dragged movieclips to their original position as they are dragged outside the stage in action script 3

I am creating a drag and drop the game for kids and I realized that when the kid drags a movie clip by mistake outside the stage the movie clip hangs where it is dragged onto and doesn't return back to its original position or it overlaps over other movie clips.
Thanks in advance
the code I am basically using is:
* square_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickUp2);
square_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt2);
function pickUp2(event: MouseEvent): void {
square_mc.startDrag(true);
event.target.parent.addChild(event.target);
startX = event.currentTarget.x;
startY = event.currentTarget.y;
}
function dropIt2(event: MouseEvent): void {
square_mc.stopDrag();
var myTargetName:String = "target" + event.target.name;
var myTarget:DisplayObject = getChildByName(myTargetName);
if (event.target.dropTarget != null && event.target.dropTarget.parent ==
myTarget){
event.target.removeEventListener(MouseEvent.MOUSE_DOWN, pickUp2);
event.target.removeEventListener(MouseEvent.MOUSE_UP, dropIt2);
event.target.buttonMode = false;
event.target.x = myTarget.x;
event.target.y = myTarget.y
} else {
event.target.x = startX;
event.target.y = startY;
}
}*
What you need to do is to preserve the initial position of the clip somewhere and then use it.
Basic algorithm I can think of can look as follows: 1 - player starts dragging a clip, init position is saved 2 - player releases the clip.
Two outcomes are possible: (a): the clip is on the right position or (b): it is misplaced. In case (b) you just need to assign initial coordinates back to the clip.
Very simple example:
private const initialCoords: Dictionary = new Dictionary();
private function saveInitialCoords(clip: DisplayObject): void {
initialCoords[clip] = new Point(clip.x, clip.y);
}
private funciton retreiveInitialCoords(clip: DisplayObject): Point {
return initialCoords[clip]; // it would return null if there is no coords
}
UPD: As it was pointed by #kaarto my answer might be irrelevant. If the issue is to keep the dragging movieclip
within some bounds I usually use something like this:
private var currentTarget: DisplayObject; // clip we're dragging currently
private var areaBounds: Rectangle = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight); // you might want to ensure stage is not null.
private function startDrag(e: MouseEvent): void {
// I'll drop all checks here. Normally you want to ensure that currentTarget is null or return it to initial position otherwise
currentTarget = e.currentTarget as DisplayObject;
saveInitialCoords(currentTarget);
addEventListener(MouseEvent.MOUSE_MOVE, checkAreaBounds);
}
private funciton stopDrag(e: MouseEvent): void {
// some checks were dropped.
if (clipIsOnDesiredPlace(currentTarget)) {
// do something
} else {
const initialCoords: Point = retreiveInitialCoords(currentTarget);
currentTarget.x = initialCoords.x;
currentTarget.y = initialCoords.y;
}
currentTarget = null;
removeEventListener(MouseEvent.MOUSE_MOVE, checkAreaBounds);
}
private funciton checkAreaBounds(e: MouseEvent): void {
// you might need to convert your coords localToGlobal depending on your hierarchy
// this function gets called constantly while mouse is moving. So your clip won't leave areaBounds
var newX: Number = e.stageX;
var newY: Number = e.stageY;
if (currentTarget) {
if (newX < areaBounds.x) newX = areaBounds.x;
if (newY < areaBounds.y) newY = areaBounds.y;
if (newX + currentTarget.width > areaBounds.x + areaBounds.width) newX = areaBounds.x + areaBounds.width - currentTarget.width;
if (newY + currentTarget.height > areaBounds.y + areaBounds.heght) newY = areaBounds.y + areaBounds.height - currentTarget.height;
currentTarget.x = newX;
currentTarget.y = newY;
}
}
... somewhere ...
// for each clip you're going to interact with:
for each (var c: DisplayObject in myDraggableClips) {
c.addEventListener(MouseEvent.MOUSE_DOWN, startDrag);
c.addEventListener(MouseEvent.MOUSE_UP, stopDrag);
}
Another option (if you don't want to limit the area with some bounds) is to use MouseEvent.RELEASE_OUTSIDE event and return a clip to it's initial position once it gets released:
stage.addEventListener(MouseEvent.RELEASE_OUTSIDE, onMouseReleaseOutside);
private function onMouseReleaseOutside(e:MouseEvent):void {
// return clip to it's position.
}
More info you can find in documentation: https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/MouseEvent.html#RELEASE_OUTSIDE

What causes stack overflows to occur? Why do these lines cause stack overflowing and how do I fix it?

I'm getting stack overflow errors and i'm not sure what a stack overflow error is or how to fi it. I've looked online to try to understand stack overflows but i'm pretty lost. If anyone could explain to me what in my code is causing the overflow that'd be great
Here is my Hero class:
package {
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.MovieClip;
public class Hero extends DocumentMainNew
{
public var health:Number;
public var mana:Number
public var vx:Number;
public var vy:Number;
public var allowJump:Boolean;
public var collision:Boolean;
public function Hero():void
{
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
public function enterFrameHandler(e:Event):void
{
//Gravitates the player
vy += 2;
//Moves the player
angela.x += vx;
angela.y += vy;
//processes collisions
processCollisions();
//scrolls the stage
scrollStage();
}
public function keyDownHandler(e:KeyboardEvent):void
{
switch (e.keyCode)
{
case 37: //left arrow
vx = -7;
break;
case 39: //right arrow
vx = 7;
break;
case 38: //up arrow
if(allowJump)
{
vy = -20;
}
break;
default:
}
}
public function keyUpHandler(e:KeyboardEvent):void
{
switch (e.keyCode)
{
case 37:
vx = 0;
break;
case 39:
vx = 0;
break;
case 38:
break;
default:
}
}
public function processCollisions():void
{
//detects when player is falling
if(vy > 0)
{
//respawns the player if they fell of the stage
if(angela.y > stage.stageHeight)
{
angela.x = _startMarker.x;
angela.y = _startMarker.y;
_boundaries.x = 0;
_boundaries.y = 0;
vy = 0;
}
//otherwise, processes collisions with boundaries
while(_boundaries.hitTestPoint(angela.x, angela.y, true))
{
allowJump = true;
angela.y -= 0.1
vy = 0;
}
}
}
}
}
And here is my main document:
package {
import flash.display.MovieClip
import flash.events.Event
import flash.events.KeyboardEvent
import Hero
public class DocumentMainNew extends MovieClip
{
public var angela:Hero = new Hero;
public var enemy1:Enemy = new Enemy;
public var _boundaries:Boundaries;
var _startMarker:StartMarker;
public function DocumentMainNew():void
{
_startMarker.visible = false;
addChild(angela);
addChild(enemy1);
angela.health = 100;
angela.mana = 100;
stage.focus = stage;
}
public function scrollStage():void
{
_boundaries.x += (stage.stageWidth * 0.5) - angela.x;
angela.x = stage.stageWidth * 0.5;
enemy1.x = _boundaries.x + 30;
_powerup.x = _boundaries.x - 200;
}
}
}
Heres the error:
Error: Error #1023: Stack overflow occurred.
at DocumentMainNew()[/Users/s2111908/Desktop/Game/DocumentMainNew.as:9] at Hero()[/Users/s2111908/Desktop/Game/Hero.as:16]
Line 9 of DocumentMainNew is: public var angela:Hero = new Hero;
Line 16 of Hero is: public function Hero():void
It says at DocumentMainNew() and at Hero() many many times but i didn't want to paste all of it. If the number of times is important let me know and i'll ad a picture. I'm fairly new to AS3 so if anyone has any tips on how to improve my code in anyway please let me know.
First. Please learn how to format your code while posting. The whole code block must be indented. There's a {} button just for that.
Second. Your mistake is Hero extending DocumentMainNew class. The problem is not extending itself but the fact you call new Hero in the DocumentMainNew variable declaration area. Lets see, how it goes.
Root instance of DocumentMainNew is created.
Declaring angela variable and assigning a new Hero to it.
An instance of Hero is created.
Hero is extending DocumentMainNew so the superclass initializes first.
Declaring angela variable and assigning a new Hero to it.
An instance of Hero is created.
...and so on.
I don't know why did you inherited the Hero class from the DocumentMainNew class, but that was a totally wrong move. You should explain what you did try to solve doing so. It should probably be solved in a very different way.

AS3 Jumping (flying) issue

Ive searched around a bit but I couldnt find an answer I can work with.I probably didnt look hard enough. I have been out of school for about a year now and I came across a flash game we made in class. I was trying to fix some errors on it that Ive made to make it function properly. The issues Ive come across are a Jumping issue : The character can endlessly jump as if it is flying through the sky. The next error is the attack graphic doesnt play unless the player is in the sky. Im rusty with the coding and I am looking to get back into as3 and using the flash program. I have a "player.as" file, I will paste its code below.
Any help is appreciated, thanks in advance.
package {
import flash.display.MovieClip;
import CollisionObject;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Player extends CollisionObject {
private var xMovement:Number;
public var isAttacking:Boolean;
private var attackTimer:Timer = new Timer (500, 1);
public function Player() {
// constructor code
trace("I am the player");
xMovement = 0;
isAttacking:false;
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
} // end constructor
private function enterFrameHandler(event:Event):void{
this.x += xMovement;
} //end function
public function attack() {
isAttacking = true;
this.gotoAndStop("attack");
attackTimer.addEventListener(TimerEvent.TIMER_COMPLETE, doneAttacking);
attackTimer.start();
}
public function startJumping(){
if (isJumping == false) {
isJumping == true;
this.gotoAndStop("jump");
downwardVelocity = -20;
}
}
public function doneAttacking (event:TimerEvent):void{
isAttacking = false;
this.gotoAndStop("stop");
}
public function moveLeft() : void{
xMovement =-7;
this.scaleX = -1;
this.gotoAndStop("run");
isRunning = true;
} //end function
public function moveRight() : void{
xMovement =7;
this.scaleX = 1;
this.gotoAndStop("run");
isRunning = true;
} //end function
public function standStill() : void{
xMovement = 0;
isRunning = false;
} //end function
override public function positionOnLanding(){
if(isRunning == true){
this.gotoAndStop("run");
}else{
this.gotoAndStop("stop");
} //end else
} //end function
} // end class
Your player is jumping endlessly because you never set the iSJumping to true. It should be
isJumping = true;
instead of
isJumping == true;
Attack is probably not working because you have an own frame for the attack and the frame is probably reset by the running or positionOnLanding ?
And please move your attackTimer event listener into the constructor, now a new event listener is created each time you are attacking, this leads to a memory leak and there is really no reason to do so.

My Character Won't Move :( Multiple .as files AS3

I have a few .as files. They are: MainClass.as, FrontEnd.as, Levels.as, and Hero.as. My problem (as far as I know) is in my Hero.as file. Let me descibe how I have it all set up thusfar because I have been a bit concerned that there are better ways of doing things in AS3.
MainClass.as makes a variable of FrontEnd (menus, namely the main menu) and calls it up (addChild).
FrontEnd.as are my menus. buttons and whatnot...
Levels.as right now just calls up level 1 when the start new game button is pressed on the main menu. Had one hell of a time figuring out how to use functions from a different .as file. Hero.as I will add my code for. I'm posting the whole thing because I don't know where my problem is.
public class Hero extends MovieClip
{
public var roger:player = new player();
private var animationState:String = "down";
public var facing:String = "down";
private var isLeft:Boolean = false;
private var isRight:Boolean = false;
private var isUp:Boolean = false;
private var isDown:Boolean = false;
public var currentPlayer:MovieClip = roger;
public function Hero()
{
addEventListener(Event.ENTER_FRAME, loop);
addEventListener(Event.ADDED_TO_STAGE, onStage);
trace(currentPlayer);
}
public function onStage( event:Event ):void
{
removeEventListener( Event.ADDED_TO_STAGE, onStage );
}
public function addCurrentPlayer():void
{
roger.x = stage.stageWidth * .5;
roger.y = stage.stageHeight * .5;
addChild(roger);
currentPlayer = roger;
setBoundaries();
}
public function keyDownHandler(event:KeyboardEvent)
{
if (event.keyCode == 39)//right press
{
isRight = true;
}
if (event.keyCode == 37)//left pressed
{
isLeft = true;
}
if (event.keyCode == 38)//up pressed
{
isUp = true;
}
if (event.keyCode == 40)//down pressed
{
isDown = true;
}
}
public function keyUpHandler(event:KeyboardEvent)
{
if (event.keyCode == 39)//right released
{
isRight = false;
}
if (event.keyCode == 37)//left released
{
isLeft = false;
}
if (event.keyCode == 38)//up released
{
isUp = false;
}
if (event.keyCode == 40)//down released
{
isDown = false;
}
}
public function loop(Event):void
{
if (currentPlayer == null)
{
addCurrentPlayer();//make sure at least roger is on the screen
}
currentPlayer.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
currentPlayer.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
//----------------------------------0
//Animation States
//----------------------------------0
if (isDown == true)
{
currentPlayer.y += 5;
animationState = "walk_down";
facing = "down";
currentPlayer.gotoAndStop(animationState);
}
else if (isUp == true)
{
currentPlayer.y -= 5;
animationState = "walk_up";
facing = "up";
currentPlayer.gotoAndStop(animationState);
}
else if (isRight == true)
{
currentPlayer.x += 5;
animationState = "walk_right";
facing = "right";
currentPlayer.gotoAndStop(animationState);
}
else if (isLeft == true)
{
currentPlayer.x -= 5;
animationState = "walk_left";
facing = "left";
currentPlayer.gotoAndStop(animationState);
}
//----------------------------------0;
//IDLE STATES
//----------------------------------0
else if (isDown == false)
{
currentPlayer.gotoAndStop(facing);
}
else if (isUp == false)
{
currentPlayer.gotoAndStop(facing);
}
else if (isRight == false)
{
currentPlayer.gotoAndStop(facing);
}
else if (isLeft == false)
{
currentPlayer.gotoAndStop(facing);
}
}
public function setBoundaries():void
{
var halfHeight:int = currentPlayer.height * .5;
var halfWidth:int = currentPlayer.width * .5;
if(currentPlayer.y <= 1)
{
currentPlayer.y += halfHeight;
}
else if(currentPlayer.y > stage.stageHeight)
{
currentPlayer.y -= halfHeight;
}
else if(currentPlayer.x <= 1)
{
currentPlayer.x += halfWidth;
}
else if(currentPlayer.x > stage.stageWidth)
{
currentPlayer.x -= halfWidth;
}
}
}
}
trace(currentPlayer); is giving me [object player] instead of the instance name "roger". (Later on I want more playable characters.) I'm not sure if the problem is there or in my levels file, which I'll post here. (not as long as Hero.as)
public class Levels extends MovieClip
{
var currentLevel:MovieClip;
public function Levels()
{
addEventListener(Event.ADDED_TO_STAGE, onStage);
}
private function onStage(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, gotoLevelOne);
}
public function gotoLevelOne():void
{
var levelOne:LevelOne = new LevelOne();
var hero:Hero = new Hero();
addChild(hero);
levelOne.x = stage.stageWidth * .5;
levelOne.y = stage.stageHeight * .5;
addChild(levelOne);
currentLevel = levelOne;
hero.currentPlayer.x = 100;
hero.currentPlayer.y = 100;
addChild(hero.currentPlayer);
}
}
}
If I remove = roger; from var currentPlayer:MovieClip = roger; it gives me #1009 null object even though I told it in addCurrentPlayer() to change currentPlayer to roger. On level 1, everything shows up but I can't move my character. I know that it worked when I was working on his animations and I would call him to the main menu. Everything worked on him. What's the problem now?
Firstly, there's a lot of things wrong with your code:
In your Hero Class, the 'onStage' Event handler doesn't actually do anything other than remove the event listener that triggers it. While it's good practice to remove the event listener, there should be some other purpose to the Event handler. If there isn't you can remove it and not bother listening for the ADDED_TO_STAGE Event.
Similarly, in your Levels Class 'onStage' Event handler you attempt to remove the event, but name the wrong handler. I assume you want to remove the event handler and then run the 'gotoLevelOne' method. If so, just have the Event.ADDED_TO_STAGE listener call 'gotoLevelOne' and then remove the Event listener there:
public function Levels()
{
addEventListener(Event.ADDED_TO_STAGE, gotoLevelOne);
}
public function gotoLevelOne():void
{
removeEventListener(Event.ADDED_TO_STAGE, gotoLevelOne);
// class continues....
OK, so to your question:
You will be getting the null error because you are referring to currentPlayer from outside the Hero Class, before calling addCurrentPlayer (where it is set).
If you temporarily define currentPlayer as a private variable, the compiler should give you a line number where you first refer to currentPlayer from OUTSIDE the Hero Class (the error will be something like 'Class X is trying to access a private (or non-existent) property of Y Class').
You can then sort out WHY you are accessing currentPlayer before calling addCurrentPlayer. You may also want to think about if currentPlayer NEEDS to be public (if so, then what is 'addCurrentPlayer' for? That function effectively works as a setter for currentPlayer).
EDIT:
At the moment you are adding new KEY_DOWN and KEY_UP event listeners EVERY frame of your game loop. This is unnecessary. Add them both ONCE in the initialisation of your game (perhaps in your Hero's onStage handler), and count on them to trigger the appropriate handlers.
You will want to add the KEY_DOWN and KEY_UP listeners to 'stage', not currentPlayer, so:
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
You will need to add the listeners AFTER your Hero instance has been added to the Stage though, so it has access to 'stage'. That's why it makes sense to add the listeners in the Hero's onstage handler.

How to do you get an character to jump?

This is my fist time ever needing to use this for one of my games. I want to have the character jump. I have been trying to get this result for about an hour, but with no luck =( I am using AS3, and flash CS5.5. So far all my code does is make the character go left, and right based on keyboard input. Could someone please help?
Here is my code so far:
public class Dodgeball extends MovieClip
{
public var character:Character;
public var rightDown:Boolean = false;
public var leftDown:Boolean = false;
public var speed:Number = 3;
public var timer:Timer;
public function Dodgeball()
{
character= new Character();
addChild(character);
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, MyKeyUp);
timer = new Timer(24);
timer.addEventListener(TimerEvent.TIMER, moveClip);
timer.start();
}
public function myKeyDown(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.RIGHT)
{
rightDown = true;
if(character.currentLabel != "walkingRight")
{
character.gotoAndStop ("walkingRight");
}
}
if (event.keyCode == Keyboard.LEFT)
{
leftDown = true;
if (character.currentLabel != "backingUp")
{
character.gotoAndStop("backingUp");
}
}
}
public function MyKeyUp(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.RIGHT)
{
character.gotoAndStop("standing");
rightDown = false;
}
if (event.keyCode == Keyboard.LEFT)
{
character.gotoAndStop("standingLeft");
leftDown = false;
}
}
public function moveClip(event:TimerEvent):void
{
if (rightDown)
{
character.x += speed;
}
if (leftDown)
{
character.x -=speed;
}
event.updateAfterEvent();
}
}
}
One method you can try is found here: http://www.actionscript.org/forums/showthread.php3?t=256009 Like your speed variable, grav determines the vertical position of the character.
var grav:Number = 10;
var jumping:Boolean = false;
var jumpPow:Number = 0;
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(Event.ENTER_FRAME, update);
function onKeyDown(evt:KeyboardEvent):void
{
if(evt.keyCode == Keyboard.UP)
{
if(jumping != true)
{
jumpPow = -50;
jumping = true;
}
}
}
function update(evt:Event):void
{
if(jumping)
{
player_mc.y += jumpPow;
jumpPow += grav;
if(player_mc.y >= stage.stageHeight)
{
jumping = false;
player_mc.y = stage.stageHeight;
}
}
}
Edit: Jason's method is fine, but I'm not sure if it would be useful if you plan to have some kind of collision detection.
What I would do is create a motion tween of the character jumping. then call gotoAndPlay on that frame, and on the last frame of the tween put a stop, or a gotoAndStop on the "stationary" frame, or whatever frame represents a neutral position.
if (event.keyCode == Keyboard.SHIFT)
{
character.gotoAndPlay("simpleJump");
jumpDown = false;
}
This will give you the greatest animation control over the look and feel. You could also do it programmatically, but personally, I recommend against it. It will take less time to set it up, and you can tweak and refine the jump animations later. You could make several types of jump animations based on object near the target etc.
I would also change this stuff:
if(character.currentLabel != "walkingRight")
By defining a new function where you have all the rules for when and where something can be done, so that in your control logic, you just call
if(characterCan(character,"walkright")) ...
Where characterCan(String) is a method that check if this is possible. For instance, if you are jumping and shooting, you obviously cannot walk right, so in the end, you will have to start adding pieces of logic into those if statements and it's gonna become a cluttered mess.
A very simple approach is to have a vertical speed as well as a horizontal speed.
When the user presses "UP" or "JUMP", set y speed to a negative value and update it in your movieClip function. When the character gets to a certain height, reverse the speed.
Using gravity and acceleration looks better but this is a really good place to start. Look into kinematic equations to see how you would make the character accelerate.
public var originalY;
public function myKeyDown(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.UP && vSpeed == 0)
{
originalY = character.y;
ySpeed = -1;
}
}
public function moveClip(event:TimerEvent):void
{
if (vSpeed != 0)
{
character.y += vSpeed;
/* make the character fall down after reaching max jump height */
if(originalY - character.y > jumpHeight) {
vSpeed = vSpeed * -1;
}
/* level the character after he's hit the ground (so he doesn't go through) */
else if(character.y >= originalY) {
character.y = originalY;
vSpeed = 0;
}
}
}