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.
Related
Please do forgive me if this is a stupid question, by I really need to know the solution. So here I have a program that generates particles every set distance of space. My program consists of a document class, called supportForce and an object class(of the particle) called TheDot.
In the TheDot object class, I have the following code-
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class TheDot extends MovieClip
{
var base:Object = MovieClip(root);
public function TheDot()
{
this.addEventListener(Event.ENTER_FRAME, eFrame);
}
private function eFrame(event:Event):void
{
if (base.currentFrame == 1){
trace ("G");
}
}
}
}
This code works perfectly (outputs G) until I add the following code into the document class, suportForce, under an ENTER_FRAME event-
var ctX:int = 0,ctY:int = 0,done:Boolean = false;
while (done == false)
{
var dots:TheDot = new TheDot ;
dots.alpha = 0;
dots.x += (25 * ctX);
dots.y += (25 * ctY);
ctX++;
if (ctX == 22 && ctY == 20)
{
done = true;
break;
}
else if (ctX == 22)
{
ctX = 0;
ctY++;
}
stage.addChild(dots);
}
So now, there is an Error #1009: Cannot access a property or method of a null object reference at TheDot/eFrame(). I have declared all the variables in the correct place, and also the functions. Thanks in advance. I have the link to the .fla and .as files in my drive here, do use it if necessary.
https://drive.google.com/folderview?id=0B8QnUfRAn9lKLUVqRjNSRHNpRkU&usp=sharing
FIRST
var dots:TheDot = new TheDot(stage);
public class TheDot extends MovieClip
{
var base:Object;
public function TheDot(stageRef:Stage)
{
base = stageRef;
this.addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event) {
this.removeEventListener(Event.ADDED_TO_STAGE, init);
this.addEventListener(Event.ENTER_FRAME, eFrame);
}
private function eFrame(event:Event):void
{
if (base.currentFrame == 1){
trace ("G");
}
}
Try this!
I've set up three buttons in the first frame which are supposed to switch frames. When the program first runs, there are no errors, and i can click any of the buttons and end up where I want. However, when going back to the first frame, the buttons no longer work. The stage listener still works though. I added the "Clicked" output to check if the function was called, which it wasn't. I know I disable the buttons in the code, but only after that button is clicked, and the task is done. I should mention I don't have the code on the timeline, but on a separate document. Here is my code:
package{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.SimpleButton;
public class DocumentClass extends MovieClip
{
public var matteOppgave:Boolean = false;
public var engelskOppgave:Boolean = false;
public var flaggOppgave:Boolean = false;
public function DocumentClass()
{
stop();
btnBok.addEventListener(MouseEvent.CLICK, matte);
btnFlagg.addEventListener(MouseEvent.CLICK, flagg);
btnPc.addEventListener(MouseEvent.CLICK, engelsk);
stage.addEventListener(Event.ENTER_FRAME, sjekk);
btnBok.enabled = true;
btnPc.enabled = true;
btnFlagg.enabled = true;
function matte(evt:MouseEvent)
{
gotoAndStop(2);
frame2();
trace("Clicked");
}
function engelsk(evt:MouseEvent)
{
gotoAndStop(3);
frame3();
trace("Clicked");
}
function flagg(evt:MouseEvent)
{
gotoAndStop(4);
frame4();
trace("Clicked");
}
function sjekk(evt:Event)
{
if(matteOppgave == true && engelskOppgave == true && flaggOppgave == true)
{
gotoAndStop(5);
}
if(matteOppgave == true)
{
btnBok.alpha = 0.5;
btnBok.enabled = false;
låsEin.alpha = 0;
}
if(engelskOppgave == true)
{
btnPc.alpha = 0.5;
btnPc.enabled = false;
låsTo.alpha = 0;
}
if(flaggOppgave == true)
{
btnFlagg.alpha = 0.5;
btnFlagg.enabled = false;
låsTre.alpha = 0;
}
}
}
I got it working from a solution posted on another forum. I made the five frames i had into movieclips, and changed back and forth using addChild() and removeChild().
I'm trying to create a beat em up game and right now i got my character attacking. I have 3 attack animation so far and works just about. If you keep mashing the attack button it will attack but the problem is it goes to the next attack animation as soon as the attack button is down and I don't want that. How can i make it go to the next attack animation once the current attack animation has finished instead of jumping to the next frame midway of it's current animation. So i want the character to finish its attack and if the player still keys in the attack key it will go to the next attack frame.
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Player extends MovieClip
{
//Attack variables
var Attacking:Boolean = false;
var Punches:int = 0;
var Punching:Boolean = false;
var Kicks:int = 0;
var Kicking:Boolean = false;
public function Player()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyPressed);
addEventListener(Event.ENTER_FRAME,Update);
}
function KeyPressed(event:KeyboardEvent):void
{
stage.removeEventListener(KeyboardEvent.KEY_DOWN, KeyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, KeyUp);
//If A key is down
if (event.keyCode == 65)
{
Attacking = true;
Punching = true;
Punches++;
}
}
function Update(event:Event)
{
//If player is not attacking
if (Attacking == false)
{
Punching = false;
Punches = 0;
Kicking = false;
Kicks = 0;
}
else if (Attacking == true)
{
if (Punching == true)
{
gotoAndStop('Jab' + Punches);
}
}
}
function KeyUp(event:KeyboardEvent)
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyPressed);
}
}
}
Also within the last frame of every attack animation i have put down
import flash.display.MovieClip;
import flash.events.Event;
stop();
MovieClip(parent).Attacking = false;
MovieClip(parent).Punches = 0;
First of all you should remove the event listener adding and removing from both KeyPressed and KeyUp methods (they are not needed and they will just cause problemes) and register the key up event in the costructor just like the other two.
Secondly, to accomplish this you will need to check if the key is down instead of listening for the key press. To do this you will need a new field called, for instance, holdingAttackKey.
var holdingAttackKey:Boolean = false;
function KeyPressed(event:KeyboardEvent):void {
if (event.keyCode == 65)
{
holdingAttackKey = true;
Attacking = true;
Punching = true;
//...
function KeyUp(event:KeyboardEvent)
{
holdingAttackKey = false;
}
function Update(event:Event)
{
if(holdingAttackKey && Attacking==false) {
Attacking = true;
Punching = true;
Punches++;
}
//....
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;
I am making a platformer game. But I am having issue because whenever I pressed the spacebar to jump, the character will stuck in the mid-air. However, I can resolved the problem by holding spacebar and the character will land.
The issue is at mainJump() located inside Boy class.
I seen many people solved the problem by using action timeline, but my main problem is, are there anyway I can solve the problem by using an external class?
Main class
package
{
import flash.display.*;
import flash.text.*;
import flash.events.*;
import flash.utils.Timer;
import flash.text.*;
public class experimentingMain extends MovieClip
{
var count:Number = 0;
var myTimer:Timer = new Timer(10,count);
var classBoy:Boy;
//var activateGravity:gravity = new gravity();
var leftKey, rightKey, spaceKey, stopAnimation:Boolean;
public function experimentingMain()
{
myTimer.addEventListener(TimerEvent.TIMER, scoreUp);
myTimer.start();
classBoy = new Boy();
addChild(classBoy);
stage.addEventListener(KeyboardEvent.KEY_DOWN, pressTheDamnKey);
stage.addEventListener(KeyboardEvent.KEY_UP, liftTheDamnKey);
}
public function pressTheDamnKey(event:KeyboardEvent):void
{
if (event.keyCode == 37)
{
leftKey = true;
stopAnimation = false;
}
if (event.keyCode == 39)
{
rightKey = true;
stopAnimation = false;
}
if (event.keyCode == 32)
{
spaceKey = true;
stopAnimation = true;
}
}
public function liftTheDamnKey(event:KeyboardEvent):void
{
if (event.keyCode == 37)
{
leftKey = false;
stopAnimation = true;
}
if (event.keyCode == 39)
{
rightKey = false;
stopAnimation = true;
}
if (event.keyCode == 32)
{
spaceKey = false;
stopAnimation = true;
}
}
public function scoreUp(event:TimerEvent):void
{
scoreSystem.text = String("Score : "+myTimer.currentCount);
}
}
}
Boy class
package
{
import flash.display.*;
import flash.events.*;
public class Boy extends MovieClip
{
var leftKeyDown:Boolean = false;
var upKeyDown:Boolean = false;
var rightKeyDown:Boolean = false;
var downKeyDown:Boolean = false;
//the main character's speed
var mainSpeed:Number = 5;
//whether or not the main guy is jumping
var mainJumping:Boolean = false;
//how quickly should the jump start off
var jumpSpeedLimit:int = 40;
//the current speed of the jump;
var jumpSpeed:Number = 0;
var theCharacter:MovieClip;
var currentX,currentY:int;
public function Boy()
{
this.x = 600;
this.y = 540;
addEventListener(Event.ENTER_FRAME, boyMove);
}
public function boyMove(event:Event):void
{
currentX = this.x;
currentY = this.y;
if (MovieClip(parent).leftKey)
{
currentX += mainSpeed;
MovieClip(this).scaleX = 1;
}
if (MovieClip(parent).rightKey)
{
currentX -= mainSpeed;
MovieClip(this).scaleX = -1;
}
if (MovieClip(parent).spaceKey)
{
mainJump();
}
this.x = currentX;
this.y = currentY;
}
public function mainJump():void
{
currentY = this.y;
if (! mainJumping)
{
mainJumping = true;
jumpSpeed = jumpSpeedLimit * -1;
currentY += jumpSpeed;
}
else
{
if (jumpSpeed < 0)
{
jumpSpeed *= 1 - jumpSpeedLimit / 250;
if (jumpSpeed > -jumpSpeedLimit/12)
{
jumpSpeed *= -2;
}
}
}
if (jumpSpeed > 0 && jumpSpeed <= jumpSpeedLimit)
{
jumpSpeed *= 1 + jumpSpeedLimit / 120;
}
currentY += jumpSpeed;
if (currentY >= stage.stageHeight - MovieClip(this).height)
{
mainJumping = false;
currentY = stage.stageHeight - MovieClip(this).height;
}
}
}
}
First of all, formalize your code, eliminating sassy things like 'pressTheDamnKey,' which doesn't even describe the function very well because a function cannot press a key. That is an event handler and should be named either keyDownHandler or onKeyDown, nothing else.
Secondly, you rarely want to do any actual work in event handlers beyond the immediate concerns of the event data. Instead call out to the function which does the actual work. A handler handles the event, then calls the code which does the work. This separates out concerns nicely for when you want something else to be able to also make the little boy animate besides the enterFrameHandler, like perhaps a mouse.
I can imagine your trace log is getting filled up pretty quickly with "Score" lines since your timer is firing 100 times a second (10 milliseconds per). I would change that to not fire on a timer, but to be refreshed when the score actually changes.
The problem with the jumping, aside from spaghetti code, is that you are basing his movements upon whether the key is pressed or not by saving the state of the key press in a variable and having him continually inspect it. This is bad for a couple of reasons: 1. he should not need to reach out to his environment for information, it should be given to him by whatever object owns him or by objects that are responsible for telling him and 2. It requires you to continually hold down the spacebar or he will stop moving, since he checks to see if it is being held down (see problem 1).
I will address all these issues below, leaving out the scoring, which is another matter altogether.
package
{
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.utils.*;
// Sprite is preferred if you are not using the timeline
public class Application extends Sprite
{
private var boy:Boy;
public function Application()
{
boy = new Boy();
addChild(boy);
boy.x = 600; // set these here, not in the boy
boy.y = 540;
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler );
}
public function keyDownHandler(event:KeyboardEvent):void
{
switch(event.keyCode)
{
case 32: boy.jump();
break;
case 37: boy.moveLeft();
break;
case 39: boy.moveRight();
break;
default:
// ignored
break;
}
}
public function keyUpHandler(event:KeyboardEvent):void
{
switch(event.keyCode)
{
// ignored for jumping (32)
case 37: // fall through
case 39: boy.stop();
break;
default:
// ignored
break;
}
}
}//class
}//package
package
{
import flash.display.*;
import flash.events.*;
// It is assumed that there is an asset in the library
// that is typed to a Boy, thus it will be loaded onto
// the stage by the owner
public class Boy extends Sprite
{
private var horzSpeed :Number = 0;
private var vertSpeed :Number = 0;
private var floorHeight :Number;
private var jumpHeight :Number;
private var amJumping :Boolean = false;
public function Boy()
{
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
public function moveLeft():void
{
horzSpeed = -1;
}
public function moveRight():void
{
horzSpeed = 1;
}
public function stop():void
{
horzSpeed = 0;
}
public function jump():void
{
if (amJumping) return;
floorHeight = y;
jumpHeight = floorHeight + 20;
vertSpeed = 2;
amJumping = true;
animateJump();
}
private function enterFrameHandler(event:Event):void
{
animate();
}
private function animate():void
{
x += horzSpeed;
if( amJumping )
{
animateJump();
}
}
// Doing a simple version for this example.
// If you want an easier task of jumping with gravity,
// I recommend you employ Greensock's superb
// TweenLite tweening library.
private function animateJump():void
{
y += vertSpeed;
if( y >= jumpHeight )
{
y = jumpHeight;
vertSpeed = -2;
}
else if( y <= floorHeight )
{
y = floorHeight;
amJumping = false;
}
}
}//class
}//package
Another way to approach this, and probably the better way long-term, is for the boy to not even be responsible for moving himself. Instead, you would handle that in the parent, his owner or some special Animator class that is responsible for animating things on schedule. In this even more encapsulated paradigm, the boy is only responsible for updating his own internal look based upon the outside world telling him what is happening to him. He would no longer handle jumping internally, but instead would be responsible for doing things like animating things he owns, like his arms and legs.
You've got a mainJumping variable that is only true while the jump is running. Why not just use that?
if (MovieClip(parent).spaceKey || mainJumping)
{
mainJump();
}