Undefined Property Error 1120 moving functions? - actionscript-3

I'm very, VERY new at flash, and I've tried really hard to figure this out but it's not working. I keep getting the same error: "1120 Access of undefined property goGame" on line 96 and "1136 Incorrect number of arguments expected 1" on line 82.
I know both of these errors has something to do with the ordering of my functions, but I find that when I move the functions to be in front of the listener, more errors pop up demanding the same thing, and the only way I can fix those is moving them in front of each other etc. etc. So I'm kind of stuck. Help would be great appreciated!
package
{
import flash.display.*;
import flash.events.*;
import flash.ui.*;
import fl.motion.MotionEvent;
import flash.utils.Timer;
import flash.utils.*;
public class StartGame extends MovieClip
{
var questions: Array=new Array();
var correctAnswers: Array=new Array("blue","Russia","10","stone","true","hydrogen and oxygen","Rapunzel","magician","The Mona Lisa","string","12","mammal","lightning bolt","lacrosse","do");
//Creates am array used for the Quiz Time function
var i = 0;
//used to track player's movements on board
var lives = 3;
//the # of lives given at the beginning of the game
var collide: Boolean;
var myTimer: Timer = new Timer(1000, 60);
//used for timer in Storming the Castle Game
var count = 0;
//used to manage chibiKing movements
//stage.addEventListener(Event.ENTER_FRAME,onFrameLoop);
//loops frames card so animation plays
//function to get to the master instructions page
//function to get the the main board
function randomNumber(){
var number=Math.round(Math.random()*5)+1;
return number;
}//end randomNumber function
function StartGame()
{
instructionsButton.addEventListener(MouseEvent.CLICK, masterInstructions);
//listener on instructions button to open the instructions page
goButton.addEventListener(MouseEvent.CLICK, playGame);
//listener on the first play button to go to the game board
}//end StartGame function
function masterInstructions (event:MouseEvent) {
gotoAndPlay(2);
//takes you to the master instructions page
goButton2.addEventListener(MouseEvent.CLICK, playGame);
//listener on the first play button to go to the game board
}// end masterInstructions function
function rollDie (event:MouseEvent) {
goRollButton.removeEventListener (MouseEvent.CLICK, rollDie);
//makes player unable to click roll button after pressing once
goRollButton.visible = false;
//removes visiblity of the roll button one clicked
goButtonGame.visible = true;
//makes game button appear so player can proceed to game
var currentRoll=randomNumber();
//randomly rolls a number between 1 and 6
outputNumber.text=String(currentRoll);
//displays the number rolled
var newMoves = i + currentRoll*10;
//moves player forward, i being the number already moved
//roll multipled by ten for frame movements of tween
gameboy.gotoAndStop(newMoves);
//player stops at the new position
i = newMoves;
//i now changed to rolled number
if (i<=300) {
bossGame();
}//if player gets to end of board, automatically start boss game
}//end rollDie function
function playGame (event: MouseEvent) {
gotoAndPlay(3);
//goes to main board game
livesOutput.text=String(lives);
//displays the 3 of lives the player has in the output box
gameBoard.addEventListener(MouseEvent.CLICK, girlJumps);
//event listener for a pop up
goRollButton.addEventListener(MouseEvent.CLICK, rollDie);
//when pressed, button calls die roll function
goButtonGame.addEventListener(MouseEvent.CLICK, goGame);
//when pressed, chooses a random mini game
ball.addEventListener(MouseEvent.MOUSE_DOWN,ballStartDrag);
ball.addEventListener(MouseEvent.MOUSE_UP, ballEndDrag);
bear.addEventListener(MouseEvent.MOUSE_DOWN, bearStartDrag);
bear.addEventListener(MouseEvent.MOUSE_UP, bearEndDrag);
//functions to create drag and drops for objects on stage game board
goButtonGame.visible=false;
//does not display go button so player must roll dice before playing game
}//end playGame function
function ballStartDrag (evt:MouseEvent) {
ball.startDrag();
}//end ballStartDrag function
function bearStartDrag (evt:MouseEvent) {
bear.startDrag();
}//end bearStartDrag function
function ballEndDrag (evt:MouseEvent) {
ball.stopDrag();
}//end ballEndDrag function
function bearEndDrag (evt:MouseEvent) {
bear.stopDrag();
}//end bearEndDrag function
function girlJumps (evt:MouseEvent) {
girlJump.gotoAndPlay(2);
//has character on board to appear by playing tween
}//end girlJumps function
function bossGame (event:KeyboardEvent) {
stage.addEventListener( KeyboardEvent.KEY_DOWN, finalBoss);
//listener to player movement when keyboard is pressed
addEventListener(Event.ENTER_FRAME,movefireball);
//listener to move the fireball
stage.addEventListener(Event.ENTER_FRAME, collision);
//listener to collisions between symbols on stage
livesBoss.text=String(lives);
//displays number of lives in text box
fireball.height = 100;
fireball.width = 100;
fireball.x=40
fireball.y=40
fireball.xVelocity=8;
fireball.yVelocity=8;
//sets fireball parameters
}//end bossGame function
function movefireball (evt: Event) {
fireball.x +=fireball.xVelocity;
fireball.y +=fireball.yVelocity;
//creates speeds of fireball
checkfireballtoWall();
//calls function
var move1:Number=Math.ceil(Math.random()*stage.stageWidth) + 1;
var move2:Number=Math.ceil(Math.random()*stage.stageWidth) + 1;
//movements randomly created for king's movements
if (count%100 == 0) {
chibiKing.x= move1;
chibiKing.y= move2;
//reassigns chibiKing's movements
}
count++;
//adds to count after so many seconds
}//end movefireball function
function checkfireballtoWall(){
const TOP: Number= 50;
const BOTTOM: Number= stage.stageHeight;
const LEFT: Number= 50;
const RIGHT: Number= stage.stageWidth - 50;
const REVERSE: int = -1;
//limits to fireball's movements
if (fireball.y<TOP) {
fireball.y=TOP;
fireball.yVelocity*=REVERSE;
}
else if (fireball.y>BOTTOM) {
fireball.y=BOTTOM;
fireball.yVelocity*=REVERSE;
}
if (fireball.x<LEFT) {
fireball.x=LEFT;
fireball.xVelocity*=REVERSE;
}
else if (fireball.x>RIGHT) {
fireball.x=RIGHT;
fireball.xVelocity*=REVERSE;
}
//reassignes fireball's direction if fireball hits a certain area
}//end checkfireballtoWall function
function finalBoss (evt: KeyboardEvent) {
if( evt.keyCode == Keyboard.LEFT )
{player.x = player.x - 6;
}
else if( evt.keyCode == Keyboard.UP )
{player.y = player.y - 6;
}
else if( evt.keyCode == Keyboard.RIGHT )
{player.x = player.x + 6;
}
else if( evt.keyCode == Keyboard.DOWN )
{player.y = player.y + 6;
}//allows player to move via keyboard control
}//end finalBoss function
function collision (evt: Event) {
if (player.hitTestObject(chibiKing)) {
gotoAndPlay(14);
//if player hits the king, automatically go to win game screen
if (player.hitTestObject(fireball)) {
lives = lives - 1;
//if player hits fireball, lose a life
if (lives == 0) {
gotoAndPlay(11);}
//if lives equal to zero, go automatically to lose game screen
livesBoss.text=String(lives);
//display the lives remaining the text box
}
}//end collision function
function dragonBattle (event:KeyboardEvent) {
//inset Dragon Battle code
}//end dragonBattle function
function goGame (event:MouseEvent) {
var gameChoose=randomNumber();
//randomly chooses a game to play from the existing mini games
if (gameChoose==1 || gameChoose == 2) {
gotoAndPlay(4);
//game 1 start screen
goButton3.addEventListener (MouseEvent.CLICK, stormingTheCastle);
//listener to go to Storming the Castle Game
}//end goGame function
else if (gameChoose==3 && correctAnswers.length>0) {
gotoAndPlay(7)
//quiz time start screen
quizTimeButton.addEventListener (MouseEvent.CLICK, quizTime);
//quiz time start
}
else {gotoAndPlay(6);
//game 2 start screen
goButton5.addEventListener (MouseEvent.CLICK, dragonBattle);
//listener to start game 2
//wizardess.addEventListener (MouseEvent.CLICK, wizardessMagic);}
}
}//end goGame function
function quizTime (event:MouseEvent) {
questions [0]= "What colour is the sky?";
questions [1]= "What is the world's biggest country in land mass?";
questions [2]= "Do Re Mi Fa So La Ti...";
questions [3]= "How many tentacles does a squid have?";
questions [4]= "In Greek Mythology, looking into Medusa's eyes would turn you to...?";
questions [5]= "True or False: Winnipeg has a hockey team.";
questions [6]= "Water is made out of...?";
questions [7]= "Which princess is the star of Disney's movie 'Tangled'?";
questions [8]= "Harry Houdini was famous for being a(n)...?";
questions [9]= "Leonardo Da Vinci famously painted what?";
questions [10]= "What type of instrument is a sitar?";
questions [11]= "How many are in a dozen?";
questions [12]= "Humans are...?";
questions [13]= "Harry Potter is famous for having a scar shaped as what on his forehead?";
questions [14]= "What is the national sport of Canada?";
//creates questions to go with answers created in startGame function
questionBox.text=questions[questions.length];
//displays the question at the end of the array
answerQuizTime.addEventListener(MouseEvent.CLICK, quiz);
//button to proceed to get quiz marker
}//end quizTime function
function quiz (evt:MouseEvent){
var userAnswer=String(answerInput.text);
//saves the user's answer in userAnswer variable
if (userAnswer==correctAnswers[questions.length]) {
questions.pop();
//removes question from end of array
lives = lives + 1;
//adds life to player's total lives
gotoAndPlay(9);
//goes to minigame win screen
}
else {
questions.pop();
//removes question from end of array
lives = lives - 1;
//removes life from player's total lives
gotoAndPlay(10);
//goes to minigame lose screen
}
}//end quiz function
// handler function for the Arrow Keys to move Player across the stage
function movePlayer(evt: KeyboardEvent) {
// if key is right arrow, move Player to the right
if (evt.keyCode == Keyboard.RIGHT) {
Player.x += 20;
// if key is left arrow, move Player to the left
} else if (evt.keyCode == Keyboard.LEFT) {
Player.x -= 20;
}
}//end movePlayer function
function stormingTheCastle (event:MouseEvent) {
// add a listener for a Frame Event
stage.addEventListener(Event.ENTER_FRAME, onFrameLoop);
// add the listener for Keyboard events to the stage
stage.addEventListener(KeyboardEvent.KEY_DOWN, movePlayer);
// create a custom speed property for each knight
//start timer
knight1.velocity = 4;
knight2.velocity = 6;
knight3.velocity = 3;
knight4.velocity = 5;
collide = false;
myTimer.start();
}//end stormingTheCastle function
// each time frame 1 plays, move each knight
//continues if no collision and count less than 60
//return each night to top if it reaches the bottom
function onFrameLoop(evt: Event) {
if (collide == false && myTimer.currentCount < 60) {
if (knight1.y > 292.2)
{knight1.y = 42.45;}
if (knight2.y > 292.2)
{knight2.y = 42.45;}
if (knight3.y > 292.2)
{knight3.y = 42.45;}
if (knight4.y > 292.2)
{knight4.y = 42.45;}
//move knights down by its speed property amount
knight1.y = knight1.y + knight1.velocity;
knight2.y = knight2.y + knight2.velocity;
knight3.y = knight3.y + knight3.velocity;
knight4.y = knight4.y + knight4.velocity;
//trace timer count
trace(myTimer.currentCount);
//if Player is hit by a knight collision is true
if (knight1.hitTestObject(Player) == true) {
collide = true;
trace("test");
}
if (knight2.hitTestObject(Player) == true) {
collide = true;
}
if (knight3.hitTestObject(Player) == true) {
collide = true;
}
if (knight4.hitTestObject(Player) == true) {
collide = true;
}
else {
if (lives == 0) {
gotoAndPlay(11);}
//trace Game Over when collision is true
trace("GAME OVER");
gotoAndPlay(10);
}
} //end onFrameLoop function
}
}//end startGame function
}//end class function
}//end package

In a class file, the order of functions and var definitions is not an issue (aside from anonymous and nested functions which you should probably steer clear of anyway).
Let's start with line 82. You call bossGame(), but when you look at the function, you've defined it so it requires a parameter:
function bossGame (event:KeyboardEvent)
It's expecting you to pass a KeyboardEvent to the function. Though I'm not sure why because looking at that function it seems to have nothing to do with Keyboard input nor does it use that event in any way.
So, take out the parameter:
function bossGame()
Or, make it optional by giving it a default value:
function bossGame(event:KeyboardEvent = null)
For the second error. Your goGame function is actually nested inside another function collision() , so it has no scope except inside the collision function. If you want to be able to access it outside of that function, then you should break it out.
As an aside, you comments beside your closing function brackets are often incorrect making it difficult to read your code.

Related

Need help fixing player jumping diagonally Flash CS4

I can't figure out why when I try and get my player to jump diagonally by pressing the right and up arrow key it does nothing, I've used trace to see if anything was happening and nothing was when they were used together.
Up won't work by itself or with right but when right is by itself it works.
player is named hero, platforms are named platform, platform2, platform3 etc
platforms are in the platform layer
stop();
var gravity:Number=5; //Very important, allows player to fall
var movex:Number=0; // Moving players X
// Moving player
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveHero);
var speed=10;
function moveHero(event:KeyboardEvent) {
if (event.keyCode==Keyboard.LEFT) {
hero.x-=speed;
hero.play();
}
if (event.keyCode==Keyboard.RIGHT) {
hero.x+=speed;
hero.play();
}
}
hero.addEventListener(Event.ENTER_FRAME, testCollision2);
// Allowing player to jump when on platform
function testCollision2(e: Event) {
//Allowing player to jump when on platform continued
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveHeroUP);
function moveHeroUP(event:KeyboardEvent) {
if (hero.hitTestObject(platform) && event.keyCode==Keyboard.UP) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform2) && event.keyCode==Keyboard.UP) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform4) && event.keyCode==Keyboard.UP) {
gravity=-50;
hero.y=hero.y+gravity;
}
if(hero.hitTestObject(platform) && event.keyCode==Keyboard.UP && event.keyCode==Keyboard.RIGHT){
movex = 20;
hero.x = hero.x + movex;
gravity =-50;
hero.y = hero.y + gravity;
}
}
I'm trying to get the player to jump in the code chunk at the very end
Flash CS4
AS3
To start, let's go through how you've set up this code and explain what's happening.
You have this line:
hero.addEventListener(Event.ENTER_FRAME, testCollision2);
Which is saying, every frame tick that hero exists, run the function testCollision2. Frame tick here doesn't relate to timeline frames, it relates to the frame rate of your application. So if that is set to 12, that function will run 12 times every second.
Inside testCollision2, you add another listener:
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveHeroUP);
and create an inline function called moveHeroUP. So every frame tick, you create a new function, and attach it to a key down event. So (assuming 12 frames per second) 5 seconds into your application, you'll have 60 keyboard listeners all doing the same thing. This is also a memory leak (as you keep creating a new function every frame), so eventually your program will crash.
To get to the actual question, a keyboard event is tied to one specific key. This means the event's keyCode is only ever one key (the key that triggered the event). So doing something like (event.keyCode==Keyboard.UP && event.keyCode==Keyboard.RIGHT) will always be false because event.keyCode only ever holds one value.
A common approach to your situation, is to have one global key down and key up listener. Then use a dictionary to store which keys are currently down:
//create just one key down listener
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
//create a dictionary to store key presses
var keyboardDown:Dictionary = new Dictionary();
function keyDownHandler(e:KeyboardEvent):void {
keyboardDown[e.keyCode] = true;
}
function keyUpHandler(e:KeyboardEvent):void {
keyboardDown[e.keyCode] = false;
}
What you're doing here, is when a key down event fires, you set the value in the dictionary to true (with the keycode as the dictionary key), then on the key up event you set it to false.
Now, in your ENTER_FRAME handler, you use the dictionary values to check for key combinations:
hero.addEventListener(Event.ENTER_FRAME, moveHero);
function moveHero(event:Event) {
//DO ALL YOUR MOVEMENTS IN ONE ENTER FRAME FUNCTION
if (keyboardDown[Keyboard.LEFT]) {
hero.x-=speed;
hero.play();
}
if (keyboardDown[Keyboard.RIGHT]) {
hero.x+=speed;
hero.play();
}
if (hero.hitTestObject(platform) && keyboardDown[Keyboard.UP]) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform2) && keyboardDown[Keyboard.UP]) {
gravity=-50;
hero.y=hero.y+gravity;
} else if (hero.hitTestObject(platform4) && keyboardDown[Keyboard.UP]) {
gravity=-50;
hero.y=hero.y+gravity;
}
if(hero.hitTestObject(platform) && keyboardDown[Keyboard.UP] && keyboardDown[Keyboard.RIGHT]){
movex = 20;
hero.x = hero.x + movex;
gravity =-50;
hero.y = hero.y + gravity;
}
}

stop() caller not working properly

I am making a brick breaker game with three frames. The first frame is the start screen, the second frame is the game itself, and the third frame is the "game over" screen (with a try again button). When I hit "Start game" the program jumps to the second frame and stops. If you fail to hit the ball with the racket, the program jumps to frame three.
My problem occurs here, because the program instantly jumps to the second frame again. Any idea why the stop(); caller fails to work? I have tried to remove all content from the last frame (except for the stop(); caller), but it still just skips back to frame 2.
I really can't figure out why this is happening. I am using Adobe Flash Professional CC. The only actionscript on frame 3 are "stop();". This is the entire code block on frame 2:
import flash.events.KeyboardEvent;
import flash.display.Stage;
import flash.events.Event;
import flash.ui.Keyboard;
import fl.transitions.Tween;
import fl.transitions.easing.*;
trace(currentFrame);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
this.addEventListener(Event.ENTER_FRAME, moveBall);
var rackert: bar = new bar();
rackert.name = "rackert";
rackert.y = 740;
rackert.x = 640;
addChild(rackert);
var ball: circle = new circle();
ball.y = 80;
ball.x = 640;
addChild(ball);
var ballXSpeed: Number = 12; //X Speed of the Ball
var ballYSpeed: Number = 12; //Y Speed of the Ball
function keyDown(e: KeyboardEvent) {
var key: uint = e.keyCode;
var step: uint = 35;
switch (key) {
case Keyboard.LEFT:
if (rackert.x > 0) {
var myTween: Tween = new Tween(rackert, "x", Regular.easeOut, rackert.x, rackert.x - step, 0.2, true);
} else rackert.x = 0;
break;
case Keyboard.RIGHT:
if (rackert.x + rackert.width < 1000) {
var myTween2: Tween = new Tween(rackert, "x", Regular.easeOut, rackert.x, rackert.x + step, 0.2, true);
} else rackert.x = 1000 - rackert.width;
break;
}
}
var gameOver: Boolean = false;
function moveBall(event: Event): void {
ball.x += ballXSpeed;
ball.y += ballYSpeed;
if (ball.x >= 1000 - (ball.width / 2)) {
ballXSpeed *= -1;
}
if (ball.x <= 0 + (ball.width / 2)) {
ballXSpeed *= -1;
}
if (ball.y >= stage.stageHeight) {
if (gameOver == false) {
gotoAndStop(3);
this.removeEventListener(Event.ENTER_FRAME, moveBall);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDown);
gameOver = true;
rackert.visible = false;
}
}
if (ball.y <= 22) {
ballYSpeed *= -1;
}
if (ball.hitTestObject(rackert)) {
calcBallAngle();
}
}
function calcBallAngle(): void {
var ballPosition: Number = ball.x - rackert.x;
trace("Position: " + ballPosition);
var hitPercent: Number = (ballPosition / (rackert.width - ball.width)) - .7;
trace("percent: " + hitPercent);
ballXSpeed = hitPercent * 10;
ballYSpeed *= -1;
}
function getRandom(min: Number, max: Number): Number {
return min + (Math.random() * (max - min));
}
Change this:
if (gameOver == false) {
gotoAndPlay(3); //gotoAndPlay(); caller
gameOver = true;
rackert.visible = false;
}
To:
if (gameOver == false) {
gotoAndStop(3); //gotoAndPlay(); caller
gameOver = true;
rackert.visible = false;
}
Difference is goToAndStop(). The default behavior is to "loop" an animation, so you tell it to go to frame 3 (last frame) and it "plays" through that frame back around to 1, then 2, where you most likely have a frame script that calls stop(); to stop the play head.
Update
I believe you that you're calling stop(); in frame 3. It seems like it should work and indeed it actually is, it's just not working on the object that you're expecting it to work on. Since you're using a frame script, stop(); is being called on the InteractiveObject who's scope the frame script is inside of. Let me clarify.
Frame 3 Of Stage
-> Child on frame three called FrameScriptsArePITA
-> Double click FrameScriptsArePITA and write a frame script "stop()", the script will do nothing but stop FrameScriptsArePITA from playing.
Watch your scope. That's part of why frame scripts are... best to avoid. Using your own DocumentClass and hooking everything in your design view into corresponding classes will make things easier to solve in AS3.
I finally found the issue. I had a timer event on frame 1, which caused the bug. I simply used removeEventListener for the timer function where i skip to frame 2. As Technick Empire said, you should always be cleaning up anything including even listeners as they can even interfere with the garbage collector and cause memory leaks.

How to stop a movieClip from playing in Flash CS6 AS3 (with Box2D)

I've spent 14 hours on this problem. This is a basic collision checker that sets a MovieClip animation to play when a collision occurs. The clip is
currentBallObject.clip.
It works. The clips plays. But it repeats over and over.
private function checkCollisions():void
{
var i = balls.length;
while (i--)
{
var currentBallObject = balls[i];
if (currentBallObject.contact)
{
//condition hits ground
if (currentBallObject.ground)
{
currentBallObject.body.SetPosition(new b2Vec2(currentBallObject.startX / PIXELS_TO_METRE, currentBallObject.startY / PIXELS_TO_METRE));
currentBallObject.body.SetLinearVelocity(new b2Vec2(0, 0));
currentBallObject.body.SetAngularVelocity(0);
//currentBallObject.texture.pop();
}
else // it hit player
{
// assign clip texture to current position
currentBallObject.clip.x = currentBallObject.body.GetPosition().x * PIXELS_TO_METRE;
currentBallObject.clip.y = currentBallObject.body.GetPosition().y * PIXELS_TO_METRE;
// whisk old object away
currentBallObject.body.SetPosition(new b2Vec2(currentBallObject.startX / PIXELS_TO_METRE, currentBallObject.startY / PIXELS_TO_METRE));
currentBallObject.body.SetLinearVelocity(new b2Vec2(0, 0));
currentBallObject.body.SetAngularVelocity(0);
currentBallObject.contact = false;
}
}
}
}
I added this code to delete the MovieClip or somehow get rid of it after it has played through once. (42 frames). I also tried to add a frameListener and at least a dozen other suggestions. When I add
stop()
The animation doesn't play. It just loads the last frame. The code I have now is:
private function updateClips():void
{
var i = balls.length;
while (i--)
{
var currentBallObject = balls[i];
if(currentBallObject.clip)
{
var frame:int = currentBallObject.clip.currentFrame;
//trace(currentBallObject.clip.currentFrame);
if(frame == 42)
{
currentBallObject.clip._visible = false;
currentBallObject.clip.removeMovieClip();
currentBallObject.clip.enabled = -1;
}
}
}
}
I've tried counting the frames, putting it a run-once function, a frame exit listener, I am out of ideas. I just want to make a MovieClip run one time through. I also tried putting stop() in the timeline and then the animation didn't play. It just loaded the last frame.
Right now the collisions work but the animations stay on the screen forever, looping forever.
Edit: I got the code by Patrick to run without errors.
I added the event listener with the others like this:
_input = new Input(stage);
...
addEventListener(Event.ENTER_FRAME, oEF);
addEventListener(Event.ENTER_FRAME, update);
time_count.addEventListener(TimerEvent.TIMER, on_time);
time_count.start();
}
And then created a function:
private function oEF(e:Event):void{
var i = balls.length;
while (i--)
{
var currentBallObject = balls[i];
if (currentBallObject.clip.currentFrame >= currentBallObject.clip.totalFrames)
{
currentBallObject.clip.stop();
currentBallObject.clip.removeEventListener(Event.ENTER_FRAME, oEF);
if (currentBallObject.clip.parent) currentBallObject.clip.parent.removeChild(currentBallObject.clip);
}
}
}
But I still get the same problem as any other result. The MovieClip disappears on contact without the animation happening.
Through debugging I've learned more. The value of currentFrame starts off going 1-40 then stays at 40 for the rest of the execution.
So the MovieClip is always on the last frame for every object.
if clip is a MovieClip then you can use clip.totalFrames in an enterframe listener.
function oEF(e:Event):void{
if (this.currentFrame >= this.totalFrames){
this.stop();
this.removeEventListener(Event.ENTER_FRAME, oEF);
if (this.parent) this.parent.removeChild(this);
}
}
this.addEventListener(Event.ENTER_FRAME, oEF);
I figured it out.
if (currentBallObject.clip.currentFrame == currentBallObject.clip.totalFrames)
{
trace("Frame before kill: ", currentBallObject.clip.currentFrame);
currentBallObject.clip.x = 0;
currentBallObject.clip.y = 0;
}
The above block goes right after
var currentBallObject = balls[i];
It checks if the movieClip is on the last frame and then gets rid of the clip by setting clip.x & clip.y to 0. I could find no other way to stop the movie in this particular case.

timerEvent within enterFrame function?

I'm calling a timerEvent function from enterFrame, it's running the timerEvent function on everyFrame. Is there a way to control it?
I've got my bullets firing function with timerEvent of 500, so it shoots a bullet every half a second on 24fps. It's working fine for now. Now I want to change bullet speed and skin with respect to weapon.
////////////////////////////////
//this function is called first time within an EnterFrame function
///////////////////////////////
function weaponCheck():void
{
switch (weaponState)
{
case STATE_GUN :
gun();
break;
case STATE_DOUBLE_GUN :
doubleGun();
break;
}
}
function gun():void
{
trace("single gun");
laserTimer = new Timer(600);
laserTimer.addEventListener(TimerEvent.TIMER, timerListener);
laserTimer.start();
function timerListener(e:TimerEvent):void
{
var tempLaser:MovieClip = new Laser();
var tempGunBlast:MovieClip = new Gun_blast_01();
tempLaser.x = player.x +((player.width/2)+12);
tempLaser.y = player.y;
tempGunBlast.x = stage.mouseX + 104;
tempGunBlast.y = tempLaser.y;
Lasers.push(tempLaser);
addChildAt(tempLaser,1);
addChildAt(tempGunBlast, 3);
if (tempGunBlast.currentFrame >= tempGunBlast.totalFrames)
{
removeChild(tempGunBlast);
}
}
}
function doubleGun():void
{
trace("Double gun");
doubleGunTimer = new Timer(400);
doubleGunTimer.addEventListener(TimerEvent.TIMER, timerListener2);
doubleGunTimer.start();
function timerListener2(e:TimerEvent):void
{
var tempLaser:MovieClip = new doubleG();
var tempGunBlast:MovieClip = new Gun_blast_01();
tempLaser.x = player.x +((player.width/2)+12);
tempLaser.y = player.y;
tempGunBlast.x = stage.mouseX + 104;
tempGunBlast.y = tempLaser.y;
Lasers.push(tempLaser);
addChildAt(tempLaser,1);
addChildAt(tempGunBlast, 3);
if (tempGunBlast.currentFrame >= tempGunBlast.totalFrames)
{
removeChild(tempGunBlast);
}
}
}
///////////////////////////////////////////////////
//Following function is called within an enterFrame event function
/////////////////////////////////////////////////
function playGame():void
{
weaponCheck();
blah1();
blah2();
blah3();
testForEnd();
}
function testForEnd():void
{
if (level == 3)
{
laserTimer.stop();
weaponState = STATE_DOUBLE_GUN;
weaponCheck();
}
}
So when the game runs for first time, it works fine and uses the timer event of 600 to hit the bullets, but when level == 3 and weaponState changes, the 2nd firing function doubleGun(); is called but it starts to fire the bullets on a per frame count, not on a controlled timerEvent. Please Help. Thanks.
Why don't you drop timers and use enter frame listener as a manner to count time? You are already calling weaponCheck() from an enterframe listener. Make it so that the actual gun() and doublegun() calls will only generate animation, such as firin' mah lazers and blasts, and the main function will just count time.
function weaponCheck():void
{
this.reloading+=this.weaponFiringSpeed; // you alter this to make your weapon fire slower or faster
if (this.reloading<FULLY_RELOADED) return; // we are not yet ready to fire
this.reloading=0;
switch (weaponState) // and here we fire with the gun state
{
case STATE_GUN :
gun();
break;
case STATE_DOUBLE_GUN :
doubleGun();
break;
}
}
function gun():void
{
trace("single gun");
var tempLaser:MovieClip = new Laser();
var tempGunBlast:MovieClip = new Gun_blast_01();
tempLaser.x = player.x +((player.width/2)+12);
tempLaser.y = player.y;
tempGunBlast.x = stage.mouseX + 104;
tempGunBlast.y = tempLaser.y;
Lasers.push(tempLaser);
addChildAt(tempLaser,1);
addChildAt(tempGunBlast, 3);
}
And similarly double gun. FULLY_RELOADED is a constant, reloading is a variable used to track time, it should be a property of the one who's firing.
Note, this approach requires you to manage your "tempGunBlast"s elsewhere, perhaps in the very weaponCheck function, if so, modify it as follows:
function weaponCheck():void
{
if (tempGunBlast) if (tempGunBlast.currentFrame >= tempGunBlast.totalFrames)
removeChild(tempGunBlast);
this.reloading+=this.weaponFiringSpeed; // you alter this to make your weapon fire slower or faster
if (this.reloading<FULLY_RELOADED) return; // we are not yet ready to fire
... // rest of code unchanged
You will most likely not be able to copypastely implement this, but please try.

Creating collision detection on more than one variable in a for loop?

Essentially I am trying to create a game, where the player has to dodge certain items, so far I have a piece of code that randomly adds 3 sharks to the stage.
The idea is that once the player has hit a shark he/she returns to the start location, I have an Action Script file that contains the speed,velocity etc of the shark, the every time the program is run the sharks will appear in a different location.
However, when I attempt to do a collision test of the sharks only one of the sharks respond, I cannot figure out how to make it that all 3 sharks effect the player (square_mc). Any help would be greatly appreciated.
//Pirate game, where you have to avoid particular object and get to the finish line to move onto the final level.
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveMode );
function moveMode(e:KeyboardEvent):void {
//movements for the pirate ship, this will allow the ship to move up,down,left and right.
if (e.keyCode == Keyboard.RIGHT) {
trace("right");
square_mc.x = square_mc.x + 25;
}
else if (e.keyCode == Keyboard.LEFT) {
trace("left");
square_mc.x = square_mc.x - 25;
}
else if (e.keyCode == Keyboard.UP) {
trace("up");
square_mc.y = square_mc.y - 25;
}
else if (e.keyCode == Keyboard.DOWN) {
trace("down");
square_mc.y = square_mc.y + 25;
}
}
//for.fla
//this program uses a for loop to create my Sharks
//a second for loop displays the property values of the sharks
function DisplayShark():void{
for (var i:Number=0;i<3;i++)
{
var shark:Shark = new Shark(500);
addChild(shark);
shark.name=("shark"+i);
shark.x=450*Math.random();
shark.y=350*Math.random();
}
}
DisplayShark();
for(var i=0; i<3;i++){
var currentShark:DisplayObject=getChildByName("shark"+i);
trace(currentShark.name+"has an x position of"+currentShark.x+"and a y position of"+currentShark.y);
}
//here we will look for colliosion detection between the two move clips.
addEventListener(Event.ENTER_FRAME, checkForCollision);
function checkForCollision(e:Event):void {
if (square_mc.hitTestObject(currentShark))
{
trace("The Square has hit the circle");
square_mc.x=50
square_mc.y=50 //these lines of code return the square back to it's original location
}
}
Just move your for loop into the ENTER_FRAME:
addEventListener(Event.ENTER_FRAME, checkForCollision);
function checkForCollision(e:Event):void {
for(var i=0; i<3;i++){
var currentShark:DisplayObject=getChildByName("shark"+i);
if (square_mc.hitTestObject(currentShark))
{
trace("The Square has hit the circle");
square_mc.x=50;
square_mc.y=50;
}
}
}
You can't just go through the for loop once and set the currentShark variable - you'll just end up testing against one shark every time you perform the collision test. Rather, every time you want to check collisions you must loop through all the sharks and do the collision testing.