5006: An ActionScript file can not have more than one externally visible definition: AND TypeError: Error #1006: hitTestObject is not a function - actionscript-3

I have 2 issues in this code.
The first is:
5006: An ActionScript file can not have more than one externally visible definition: Sprayer, bugs
I've put multiple Actionscripts together to create this, i've seperated out the classes and am hoping to play this on a frame from a symbol.
and the second relates to:
Error #1006: hitTestObject is not a function
For this i'm trying to get the aagun/Sprayer to lose health then lives if the bugs touch it, but i'm not sure why it's saying it's not a function. Am I using the wrong words?
Thanks for your help, here's the code
package Shooter{
import flash.display.*;
import flash.events.*;
import flash.utils.getTimer;
class Sprayer extends MovieClip{
const speed:Number = 150.0;
var lastTime:int; // animation time
function Sprayer() {
// initial location of gun
this.x = 275;
this.y = 340;
// movement
addEventListener(Event.ENTER_FRAME,moveGun);
}
function moveGun(event:Event) {
// get time difference
var timePassed:int = getTimer()-lastTime;
lastTime += timePassed;
// current position
var newx = this.x;
// move to the left
if (MovieClip(parent).leftArrow) {
newx -= speed*timePassed/1000;
}
// move to the right
if (MovieClip(parent).rightArrow) {
newx += speed*timePassed/1000;
}
// check boundaries
if (newx < 10) newx = 10;
if (newx > 540) newx = 540;
// reposition
this.x = newx;
}
// remove from screen and remove events
function deleteGun() {
parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME,moveGun);
}
}
}
package BigBug{
import flash.display.*;
import flash.events.*;
import flash.utils.Timer;
import flash.text.TextField;
import flash.display.MovieClip;
class bugs extends MovieClip {
var dx:Number; // speed and direction
var lastTime:int; // animation time
function bugs(side:String, speed:Number, altitude:Number) {
if (side == "left") {
this.x = -50; // start to the left
dx = speed; // fly left to right
this.scaleX = 1; // reverse
} else if (side == "right") {
this.x = -50; // start to the right
dx = -speed; // fly right to left
this.scaleX = 1; // not reverse
}
this.y = altitude; // vertical position
// choose a random plane
this.gotoAndStop(Math.floor(Math.random()*4+1));
// set up animation
addEventListener(Event.ENTER_FRAME,movePlane);
lastTime = getTimer();
}
function movePlane(event:Event) {
// get time passed
var timePassed:int = getTimer()-lastTime;
lastTime += timePassed;
// move plane
this.x += dx*timePassed/2000;
// check to see if off screen
if ((dx < 0) && (x < -50)) {
deletePlane();
} else if ((dx > 0) && (x > 350)) {
deletePlane();
}
}
}
}
package Missiles{
import flash.display.*;
import flash.events.*;
import flash.utils.Timer;
import flash.text.TextField;
import flash.display.MovieClip;
class Bullets extends MovieClip {
var dx:Number; // vertical speed
var lastTime:int;
function Bullets(x,y:Number, speed: Number) {
// set start position
this.x = x;
this.y = y;
// get speed
dx = speed;
// set up animation
lastTime = getTimer();
addEventListener(Event.ENTER_FRAME,moveBullet);
}
function moveBullet(event:Event) {
// get time passed
var timePassed:int = getTimer()-lastTime;
lastTime += timePassed;
// move bullet
this.x += dx*timePassed/1000;
// bullet past top of screen
if (this.x < 0) {
deleteBullet();
}
}
// delete bullet from stage and plane list
function deleteBullet() {
MovieClip(parent).removeBullet(this);
parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME,moveBullet);
}
}
}
package MainGame{
import flash.display.*;
import flash.events.*;
import flash.utils.Timer;
import flash.text.TextField;
import flash.display.MovieClip;
import Missiles.Bullets;
import Shooter.Sprayer;
import BigBug.bugs;
public class AirRaid extends MovieClip {
private var aagun:Sprayer;
private var airplanes:Array;
private var buggood:Array;
private var bullets:Array;
public var leftArrow, rightArrow:Boolean;
private var nextGbug:Timer;
private var nextPlane:Timer;
private var shotsLeft:int;
private var shotsHit:int;
public function startAirRaid() {
// init score
shotsLeft = 20;
shotsHit = 0;
showGameScore();
// create gun
aagun = new Sprayer();
addChild(aagun);
// create object arrays
buggood = new Array();
airplanes = new Array();
bullets = new Array();
// listen for keyboard
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUpFunction);
// look for collisions
addEventListener(Event.ENTER_FRAME,checkForHits);
// start planes flying
setNextPlane();
setNextGbug();
}
public function setNextPlane() {
nextPlane = new Timer(1000+Math.random()*1000,1);
nextPlane.addEventListener(TimerEvent.TIMER_COMPLETE,newPlane);
nextPlane.start();
}
public function newPlane(event:TimerEvent) {
// random side, speed and altitude
if (Math.random() > .5) {
var side:String = "left";
} else {
side = "right";
}
var altitude:Number = Math.random()*50+20;
var speed:Number = Math.random()*150+150;
// create plane
var p:bugs = new bugs(side,speed,altitude);
addChild(p);
airplanes.push(p);
// set time for next plane
setNextPlane();
}
public function setNextGbug() {
nextGbug = new Timer(1000+Math.random()*1000,1);
nextGbug.addEventListener(TimerEvent.TIMER_COMPLETE,newGbug);
nextGbug.start();
}
public function newGbug(event:TimerEvent) {
// random side, speed and altitude
if (Math.random() > .5) {
var side:String = "left";
} else {
side = "right";
}
var altitude:Number = Math.random()*50+20;
var speed:Number = Math.random()*150+150;
// create Gbug
var p:Good_bug = new Good_bug(side,speed,altitude);
addChild(p);
buggood.push(p);
// set time for next Gbug
setNextGbug();
}
// check for collisions
public function checkForHits(event:Event) {
for(var bulletNum:int=bullets.length-1;bulletNum>=0;bulletNum--){
for (var airplaneNum:int=airplanes.length-1;airplaneNum>=0;airplaneNum--) {
if (bullets[bulletNum].hitTestObject(airplanes[airplaneNum])) {
airplanes[airplaneNum].planeHit();
bullets[bulletNum].deleteBullet();
shotsHit++;
showGameScore();
break;
}
}
for(var bulletNum:int=bullets.length-1;bulletNum>=0;bulletNum--){
for (var Good_bugNum:int=buggood.length-1;Good_bugNum>=0;Good_bugNum--) {
if (bullets[bulletNum].hitTestObject(buggood[Good_bugNum])) {
buggood[Good_bugNum].GbugHit();
bullets[bulletNum].deleteBullet();
shotsHit--;
showGameScore();
break;
}
}
}
if ((shotsLeft == 0) && (bullets.length == 0)) {
endGame();
}
}
if ((shotsLeft == 0) && (bullets.length == 0)) {
endGame();
}
}
// key pressed
public function keyDownFunction(event:KeyboardEvent) {
if (event.keyCode == 37) {
leftArrow = true;
} else if (event.keyCode == 39) {
rightArrow = true;
} else if (event.keyCode == 32) {
fireBullet();
}
}
// key lifted
public function keyUpFunction(event:KeyboardEvent) {
if (event.keyCode == 37) {
leftArrow = false;
} else if (event.keyCode == 39) {
rightArrow = false;
}
}
// new bullet created
public function fireBullet() {
if (shotsLeft <= 0) return;
var b:Bullets = new Bullets(aagun.x,aagun.y,-300);
addChild(b);
bullets.push(b);
shotsLeft--;
showGameScore();
}
public function showGameScore() {
showScore.text = String("Score: "+shotsHit);
showShots.text = String("Shots Left: "+shotsLeft);
}
// take a plane from the array
public function removePlane(plane:bugs) {
for(var i in airplanes) {
if (airplanes[i] == plane) {
airplanes.splice(i,1);
break;
}
}
}
// take a Gbug from the array
public function removeGbug(Gbug:Good_bug) {
for(var i in buggood) {
if (buggood[i] == Gbug) {
buggood.splice(i,1);
break;
}
}
}
// take a bullet from the array
public function removeBullet(bullet:Bullets) {
for(var i in bullets) {
if (bullets[i] == bullet) {
bullets.splice(i,1);
break;
}
}
}
// game is over, clear movie clips
public function endGame() {
// remove planes
for(var i:int=airplanes.length-1;i>=0;i--) {
airplanes[i].deletePlane();
}
for(var i:int=buggood.length-1;i>=0;i--) {
buggood[i].deleteGbug();
}
airplanes = null;
buggood = null;
aagun.deleteGun();
aagun = null;
stage.removeEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction);
stage.removeEventListener(KeyboardEvent.KEY_UP,keyUpFunction);
removeEventListener(Event.ENTER_FRAME,checkForHits);
nextPlane.stop();
nextPlane = null;
nextGbug.stop();
nextGbug = null;
gotoAndStop("gameover");
}
}
}

1.
5006: An ActionScript file can not have more than one externally visible definition: Sprayer, bugs
As it says exactly: you can't have more than one public definition in a file. You have to either split the code to several files or move definitions, that you don't need public, out of the package.
This would be Ok in one file:
package
{
import flash.display.MovieClip;
// public is the default access modifier
public class Test1 extends MovieClip
{
public function Test1()
{
trace("test1");
var t2:Test2 = new Test2();
var t3:Test3 = new Test3();
}
}
}
// Test2 and Test3 are defined outside of the package, otherwise it wouldn't compile.
// These definitions will only be visible to code in this file.
import flash.display.MovieClip;
class Test2 extends MovieClip
{
public function Test2()
{
trace("test2");
}
}
class Test3 extends MovieClip
{
public function Test3()
{
trace("test3");
}
}
2.
Error #1006: hitTestObject is not a function
This usually means that hitTestObject() is not defined on the object (or it's ancestors) you are trying to call it from (although there could be different kinds of errors for that).
hitTestObject() is accessed in two ways in your code: airplanes.hitTestObject() and bullets[bulletNum].hitTestObject(). You will have to debug your code to see what is actually airplanes and bullets[bulletNum], what types they are and whether they inherit hitTestObject() method. You could at least trace() them.

Related

AS3 ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller

I am making a minions game. My minion's instance name is sideMinion. The bananas are falling and everything works fine, but my removeChild() doesn't work properly. The error I'm getting is
Error #2025: The supplied DisplayObject must be a child of the caller.
The removeChild() or the hitTestObject doesn't work properly.
This is what I have in my banana as. class:
package {
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.Event;
public class banana extends MovieClip {
var velX: Number = 0;
var velY: Number = 0;
var falling: Boolean = false;
var gravity: Number = 0;
public function banana() {
var timing: Timer = new Timer(25, 0);
timing.addEventListener(TimerEvent.TIMER, moveMe);
timing.start();
}
private function moveMe(event: TimerEvent)
{
x += velX;
y += velY;
if (falling) velY += gravity;
/* trace("[BANANA] position:", x, y, "speed:", velX, velY);*/
}
public function setSpeed(dx,dy) {
velX = dx;
velY = dy;
}
public function setSpot(atX,atY){
this.x=atX;
this.y=atY;
}
public function makeItFall (){
falling=true;
}
}
}
And in my main program:
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.events.Event;
var leftKey:Boolean;
var rightKey:Boolean;
var upKey:Boolean;
var downKey:Boolean;
var jump:Boolean = false;
var xvelocity:int = 9;
var yvelocity:int = 3;
var gravity:Number = 7;
stage.addEventListener(Event.ENTER_FRAME, changeVelocity);
stage.addEventListener(KeyboardEvent.KEY_UP, checkKeyUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, checkKeyDown);
function changeVelocity(evt:Event){
moveMinion();
yvelocity += gravity;
}
function moveMinion(){
if (leftKey == true){
sideMinion.x -= xvelocity;
sideMinion.left();
}
if (rightKey == true){
sideMinion.x += xvelocity;
sideMinion.right();
}
}
function checkKeyDown(e:KeyboardEvent){
if (e.keyCode == Keyboard.LEFT){
leftKey = true;
}
else if (e.keyCode == Keyboard.RIGHT){
rightKey = true;
}
}
function checkKeyUp(e:KeyboardEvent){
if (e.keyCode == Keyboard.LEFT){
leftKey = false;
}
else if (e.keyCode == Keyboard.RIGHT){
rightKey = false;
}
}
btnStart.addEventListener(MouseEvent.CLICK, makeItFall);
function makeItFall(e:MouseEvent){
var numBananas = 6;
var theBananas: Array = new Array();
theBananas = [];
for (var i = 0; i < numBananas; i++) {
var aBanana: banana = new banana();
theBananas.push(aBanana);
btnStart.visible=false;
aBanana.y=30;
theBananas[i].setSpot(Math.random()*450+50,Math.random()*200+20);
theBananas[i].setSpeed((Math.random()), 1);
stage.addChild(aBanana);
}
var health: uint= 1;
addEventListener(Event.ENTER_FRAME, pickUpBananas);
function pickUpBananas(event:Event){
for( var i= 0; i<theBananas.length; ++i){
if (sideMinion.hitTestObject(theBananas[i])){
removeChild(theBananas[i]);
health=health+1;
trace(health);
}
}
}
}
stop();
Edit : format code
As you are adding child to stage, you'll have to remove it also from stage:
stage.removeChild(theBananas[i]);
For future, in some situations you can also use parent property if you don't know the actual parent:
theBananas[i].parent.removeChild(theBananas[i]);
In your game, I assume you want also to remove the bananas from theBananas-array when you remove bananas from stage, so that your array wont end up having already deleted bananas. So, here's couple modifications:
for(var i:int = theBananas.length-1; i>-1; i--){ //inverted loop
if (sideMinion.hitTestObject(theBananas[i])){
stage.removeChild(theBananas[i]);
theBananas.splice(i,1); //removing it from the array
health=health+1;
trace(health);
}
}
Inverted loop obviously loops from last element all the way to the first one, becouse if you'd remove the first element from the array, then second element would 'jump' into its place and loop would skip it.
I hope we all will soon get to see your game! :)

AS3 How to remove objects from the stage from various classes

So I'm Creating a game that generates different types of fish. I have the main class initilize everything then the fish are generated with another class. I then have another class listen for when they are added to the stage that controls their movement. After the fish leaves the scene I have gotten them to be deleted but I cannot get them all to be deleted once the fish is clicked. I have a listener that gets when a fish is clicked but I am having trouble deleting all the other generated fish so that I can load the fish information.
I probably have tons of problems but here is my Main class:
package
{
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.display.*;
import flash.events.*;
import flash.ui.*;
import Crappie;
/*import Bass;
import Bluegill;
import LongGar;
import Muskellunge;
import Perch;
import PumpkinSeed;
import ShortGar;
import SpotGar;*/
import GenerateFish;
public class FishGame extends MovieClip
{
private var randomFish:Number;
public function FishGame() //First function to be called
{
startMenu();
}
public function startMenu() //Loads the start menu
{
gotoAndStop("Start Menu");
StartButton.addEventListener(MouseEvent.CLICK, gotoStartGame);
}
private function gotoStartGame(evt:MouseEvent) //links to the start of th game
{
StartButton.removeEventListener(MouseEvent.CLICK, gotoStartGame);
gotoAndStop("Game");
game();
}
public function game() /generates fish
{
var genFish:GenerateFish = new GenerateFish();
this.addChild(genFish);
var genFish2:GenerateFish = new GenerateFish();
this.addChild(genFish2);
}
//This is where I need help. All the fish are children of other class. I tried deleting them in their own class but it seems like it would work best if it was in this class but I'm having trouble calling this class.
public function removeFish()
{
trace("Here");
}
}
}
Here is the generating fish class:
package {
import flash.display.MovieClip;
import flash.events.*;
import flash.display.*;
import Crappie;
//import Bass;
//import Bluegill;
//import LongGar;
//import Muskellunge;
//import Perch;
//import PumpkinSeed;
//import ShortGar;
//import SpotGar;
import FishGame;
public class GenerateFish extends MovieClip {
private var randomFish:Number;
public function GenerateFish() //When this is added via addchild it adds a fish
{
this.addEventListener(Event.ADDED_TO_STAGE, addFish, false, 0, true);
//addFish();
}
private function addFish(e:Event) //adds fish to scrence
{
this.removeEventListener(Event.ADDED_TO_STAGE, addFish);
randomFish = Math.floor(Math.random() * 2);
randomFish = 0; //for testing purposes
switch(randomFish)
{
case 0:
var crappie:Crappie = new Crappie();
this.addChild(crappie); //Calls the crappy funciton
break;
case 1:
var longgar:LongGar = new LongGar();
this.addChild(longgar);
break;
case 2:
var bluegill:Bluegill = new Bluegill();
this.addChild(bluegill);
break;
case 3:
var spotgar:SpotGar = new SpotGar();
this.addChild(spotgar);
break;
case 4:
var muskellunge:Muskellunge = new Muskellunge();
this.addChild(muskellunge);
break;
case 5:
var pumpkinseed:PumpkinSeed = new PumpkinSeed();
this.addChild(pumpkinseed);
break;
case 6:
var bass:Bass = new Bass();
this.addChild(bass);
break;
case 7:
var perch:Perch = new Perch();
this.addChild(perch);
break;
case 8:
var pike:Pike = new Pike();
this.addChild(pike);
break;
default:
break;
}
}
}
}
And here is one of the specific fish classes:
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.*;
import FishGame;
import GenerateFish;
public class Crappie extends MovieClip
{
private var Speed:Number;
private var randomBoolean:Boolean = (Math.random() > .5) ? true : false;
private var fishOnScreen:Boolean = false;
//public var remFish:FishGame = new FishGame();
public function Crappie() //Adds event listeners to control the fish
{
this.addEventListener(Event.ADDED_TO_STAGE, Setup, false, 0, true);
this.addEventListener(MouseEvent.CLICK, GoToFishInfo);
fishOnScreen =true;
}
public function GoToFishInfo(evt:MouseEvent):void //When fish is clicked Info pops up. It is here i want every fish to be deleted.
{
this.removeEventListener(Event.ADDED_TO_STAGE, Setup);
/*while (MovieClip(root).numChildren >= 1) //What I tried to delete all objects
{
MovieClip(root).removeChildAt(1);
}*/
var remFish:FishGame = new FishGame(); //Creates The SWF file file:///FishGame/classes/FishGame.swf contains invalid data.
remFish.removeFish();
MovieClip(root).gotoAndStop("FishInfo", "Scene 1");
var crappieinfo:CrappieInfo = new CrappieInfo();
stage.addChild(crappieinfo);
crappieinfo.x = 512;
crappieinfo.y = 384;
crappieinfo.alpha = 100;
}
private function Setup(e:Event) //Setup the fish position and adds info for movement
{
var randomBoolean:Boolean = (Math.random() > .5) ? true : false;
//true forwards
//false is backwards
if (randomBoolean)
{
this.x = 1030;
}
else
{
this.scaleX = -1;
this.x = -10;
}
this.y = this.GetRandomYPosition();
this.alpha = 100;
this.addEventListener(Event.ENTER_FRAME, MoveCircle);
Speed = GetRandomSpeed();
if (randomBoolean)
{
Speed *= -1
}
}
private function GetRandomSpeed():Number
{
return (Math.floor(Math.random() * 5) +5);
}
private function GetRandomYPosition():Number
{
//
//basic formula: Math.floor(Math.random()*(1+High-Low))+Low;
//
return (Math.floor(Math.random() * (650-this.height)) + 230);
}
public function MoveCircle(e:Event) //Moves the fish
{
if (fishOnScreen)
{
this.x += Speed;
if (this.x >1024 || this.x < -10 || this.y >768 || this.y < 200)
{
var genExtraFish:GenerateFish = new GenerateFish();
stage.addChild(genExtraFish);
this.parent.removeChild(this);
fishOnScreen = false;
this.removeEventListener(MouseEvent.CLICK, GoToFishInfo);
}
}
}
}
}
Thanks I'd appreciate all the help I can get!
////////
//Edit//
////////
I have modified my main class to package
{
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.display.*;
import flash.events.*;
import flash.ui.*;
import BaseFish;
import GenerateFish;
public class FishGame extends MovieClip
{
private var randomFish:Number;
private var basefish:BaseFish = new BaseFish();
public function FishGame()
{
startMenu();
}
public function startMenu()
{
gotoAndStop("Start Menu");
StartButton.addEventListener(MouseEvent.CLICK, gotoStartGame);
}
private function gotoStartGame(evt:MouseEvent)
{
StartButton.removeEventListener(MouseEvent.CLICK, gotoStartGame);
gotoAndStop("Game");
basefish.StartFish();
}
}
}
And I Created the basefish class as so:
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.*;
import FishGame;
public class BaseFish extends MovieClip
{
public var FishOnScreen:Array = new Array();
public var FishSpeed:Array = new Array();
private var Speed:Number;
private var randomBoolean:Boolean = (Math.random() > .5) ? true : false;
public var NumFish:int = -1;
private var randomFish:Number;
public function BaseFish()
{
}
public function StartFish()
{
addFish(5);
this.addEventListener(Event.ENTER_FRAME, MoveCircle);
}
public function addFish(NumAdd:Number)
{
for (var i:Number = 0; i < NumAdd; i++)
{
randomFish = Math.floor(Math.random() * 2);
randomFish = 0;
switch(randomFish)
{
case 0:
var crappie:Crappie = new Crappie();
this.addChild(crappie);
crappie.addEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.push(crappie);
trace(FishOnScreen[1]);
Setup(crappie);
NumFish += 1;
break;
case 1:
var longgar:LongGar = new LongGar();
this.addChild(longgar);
longgar.addEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.push(longgar);
Setup(longgar);
NumFish += 1;
break;
case 2:
var bluegill:Bluegill = new Bluegill();
this.addChild(bluegill);
bluegill.addEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.push(bluegill);
Setup(bluegill);
NumFish += 1;
break;
case 3:
var spotgar:SpotGar = new SpotGar();
this.addChild(spotgar);
spotgar.addEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.push(spotgar);
Setup(spotgar);
NumFish += 1;
break;
case 4:
var muskellunge:Muskellunge = new Muskellunge();
this.addChild(muskellunge);
muskellunge.addEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.push(muskellunge);
Setup(muskellunge);
NumFish += 1;
break;
case 5:
var pumpkinseed:Pumpkinseed = new Pumpkinseed();
this.addChild(pumpkinseed);
pumpkinseed.addEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.push(pumpkinseed);
Setup(pumpkinseed);
NumFish += 1;
break;
case 6:
var bass:Bass = new Bass();
this.addChild(bass);
bass.addEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.push(bass);
Setup(bass);
NumFish += 1;
break;
case 7:
var perch:Perch = new Perch();
this.addChild(perch);
perch.addEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.push(perch);
Setup(perch);
NumFish += 1;
break;
case 8:
var pike:Pike = new Pike();
this.addChild(pike);
pike.addEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.push(pike);
Setup(pike);
NumFish += 1;
break;
default:
this.addChild(crappie);
crappie.addEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.push(crappie);
Setup(crappie);
NumFish += 1;
break;
}
}
}
private function Setup(mc: MovieClip)
{
var randomBoolean:Boolean = (Math.random() > .5) ? true : false;
//true forwards
//false is backwards
if (randomBoolean)
{
MovieClip(mc).x = 1030;
}
else
{
MovieClip(mc).scaleX = -1;
MovieClip(mc).x = -10;
}
MovieClip(mc).y = GetRandomYPosition();
MovieClip(mc).alpha = 100;
FishSpeed[NumFish] = GetRandomSpeed();
if (randomBoolean)
{
FishSpeed[NumFish] *= -1
}
}
private function GetRandomSpeed():Number
{
return (Math.floor(Math.random() * 5) +5);
}
private function GetRandomYPosition():Number
{
//
//basic formula: Math.floor(Math.random()*(1+High-Low))+Low;
//
return (Math.floor(Math.random() * (650-this.height)) + 230);
}
public function MoveCircle(e:Event)
{
//trace(FishOnScreen.length);
for (var i:Number = 0; i < FishOnScreen.length; i++)
{
if (FishOnScreen[i]!=null)
{
MovieClip(FishOnScreen[i]).x += FishSpeed[i];
if (MovieClip(FishOnScreen[i]).x >1024 || MovieClip(FishOnScreen[i]).x < -10 || MovieClip(FishOnScreen[i]).y >768 || MovieClip(FishOnScreen[i]).y < 200)
{
addFish(1);
this.removeChild(MovieClip(FishOnScreen[i]));
MovieClip(FishOnScreen[i]).removeEventListener(MouseEvent.CLICK, GoToFishInfo);
FishOnScreen.splice(i, 1);
FishSpeed.splice(i,1);
}
}
//else trace("null");
}
}
public function GoToFishInfo(evt:MouseEvent):void
{
dispose();
MovieClip(root).gotoAndStop("FishInfo", "Scene 1");
var crappieinfo:CrappieInfo = new CrappieInfo();
stage.addChild(crappieinfo);
crappieinfo.x = 512;
crappieinfo.y = 384;
crappieinfo.alpha = 100;
}
public function dispose():void
{
for (var i : int = this.numChildren-1 ; i >= 0 ; i--)
{
if(this.getChildAt(i) is MovieClip)
{
this.removeChildAt(i);
MovieClip(FishOnScreen[i]).removeEventListener(Event.ADDED_TO_STAGE, Setup);
MovieClip(FishOnScreen[i]).removeEventListener(MouseEvent.CLICK, GoToFishInfo);
}
}
}
}
}
It doesn't give me any errors but it doesn't display any fish. If you could take a look at my updated code I would be grateful!
To make things better and avoid duplication of code, extend all your classes such as Crappie, Bass etc from a Base Class, call it BaseFish for example. You should create a dispose() method in this base class. That way this dispose method will be automatically available to all classes extending it. In fact, you can use this method to write common code at one place and avoid duplication.
Also, if you feel it suits the need, extend GenerateFish also from the base class, or create a similar method called dispose() in this class.
Then when you call your removeFish() method, you can call these dispose methods for your individual classes.
Create the method like this (this is just to get you started):
public function dispose():void
{
for (var i : int = this.numChildren-1 ; i >= 0 ; i--)
{
if(this.getChildAt(i) is MovieClip)
{
this.removeChildAt(i);
}
}
}
This code removes every child which is a movie clip. You may also want to remove any Event Listeners which are added in your class inside this method.
Then, move your variables genFish and genFish2 to class variables, and not declare them inside your method game()
Now in your removeFish() method do this:
public function removeFish()
{
genFish.dispose();
genFish2.dispose();
}
Follow the same logic inside your GenerateFish class to dispose all the children as they will now be instances of the same base class.
Another thing, which could be very important from a performance perspective is the ENTER_FRAME event that you are adding. Notice that this event is being added to each instance that you create inside GenerateFish. So, every instance will have its own enter frame. Maybe it will work ok in your current situation as the number of instances may be less, but this approach is not scalable, and tomorrow if you have many instances, it will certainly hinder performance.
Ideally, you should try to have only one ENTER_FRAME event listener in your main class and use the handler to change things inside your child classes.
Hope this helps you.

how to reference a hit test object between .as files [AS3]

i'm trying to make a top down shooter game, and have been following tutorials here: http://gamedev.michaeljameswilliams.com/2008/09/17/avoider-game-tutorial-1/
and here: as3gametuts.com/2013/07/10/top-down-rpg-shooter-4-shooting/
i've managed to get shooting and movement, but i need to get a hit test object to register when the bullet (defined in its own seperate as class file) and the enemy (also defined in seperate file) come into contact. code below:
Enemy code:
package
{
import flash.display.MovieClip;
public class Enemy extends MovieClip
{
public function Enemy()
{
x = 100;
y = -15;
}
public function moveDownABit():void
{
y = y + 3;
}
}
}
Bullet code:
package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Bullet extends MovieClip
{
private var stageRef:Stage;
private var speed:Number = 10;
private var xVel:Number = 0;
private var yVel:Number = 0;
private var rotationInRadians = 0;
public var enemy:Enemy;
public function Bullet(stageRef:Stage, X:int, Y:int, rotationInDegrees:Number):void
{
this.stageRef = stageRef;
this.x = X;
this.y = Y;
this.rotation = rotationInDegrees;
this.rotationInRadians = rotationInDegrees * Math.PI / 180;
}
public function bullethit():void{
if (Bullet.hitTestObject(enemy)){
gameTimer.stop();
}
}
public function loop():void
{
xVel = Math.cos(rotationInRadians) * speed;
yVel = Math.sin(rotationInRadians) * speed;
x += xVel;
y += yVel;
if(x > stageRef.stageWidth || x < 0 || y > stageRef.stageHeight || y < 0)
{
this.parent.removeChild(this);
}
}
}
}
Main.as document class code:
package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Main extends MovieClip
{
public var player:Player;
public var bulletList:Array = []; //new array for the bullets
public var enemy:Enemy;
public var gameTimer:Timer;
public function Main():void
{
player = new Player(stage, 320, 240);
stage.addChild(player);
enemy = new Enemy();
addChild( enemy );
gameTimer = new Timer( 25 );
gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
gameTimer.start();
stage.addEventListener(MouseEvent.CLICK, shootBullet, false, 0, true);
stage.addEventListener(Event.ENTER_FRAME, loop, false, 0, true); //add an EventListener for the loop
}
public function moveEnemy( timerEvent:TimerEvent ):void
{
enemy.moveDownABit();
}
public function loop(e:Event):void //create the loop function
{
if(bulletList.length > 0) //if there are any bullets in the bullet list
{
for(var i:int = bulletList.length-1; i >= 0; i--) //for each one
{
bulletList[i].loop(); //call its loop() function
}
}
}
public function shootBullet(e:MouseEvent):void
{
var bullet:Bullet = new Bullet(stage, player.x, player.y, player.rotation);
bullet.addEventListener(Event.REMOVED_FROM_STAGE, bulletRemoved, false, 0, true); //triggers the "bulletRemoved()" function whenever this bullet is removed from the stage
bulletList.push(bullet); //add this bullet to the bulletList array
stage.addChild(bullet);
}
public function bulletRemoved(e:Event):void
{
e.currentTarget.removeEventListener(Event.REMOVED_FROM_STAGE, bulletRemoved); //remove the event listener so we don't get any errors
bulletList.splice(bulletList.indexOf(e.currentTarget),1); //remove this bullet from the bulletList array
}
}
}
As Vesper said, you'll want to do your checks in the Main class. You've already got a game loop set up, so you can just add the check in there:
public function loop(e:Event):void //create the loop function
{
if(bulletList.length > 0) //if there are any bullets in the bullet list
{
for(var i:int = bulletList.length-1; i >= 0; i--) //for each one
{
bulletList[i].loop(); //call its loop() function
// check to see if the enemy has been hit
if(enemy.hitTestObject(bulletList[i]))
{
// the enemy has been hit by the bullet at index i
}
}
}
}
Since you currently only have a single enemy, you're just testing each bullet against that one enemy. If you had more enemies, you'd want to keep an array of references to those enemies and do a nested loop, checking to see if any of the enemies were hit by any of the bullets.

Can't remove object from stage

I have a problem. I am trying to make a copter game in Adobe Flash with ActionScript 3.0, but now the game works, but the obstacles can't be removed from stage. The obstacles are still going miles out of the stage. How can I remove the obstacles?? and same problem if you are game over, if you are game over the event end, but the last spawned obstacles you see still and aren't removed. And how can I make the obstacles go faster after a period of time??
There are standing some dutch words in it, such as 'hoeSpelen' that is for instructions text en 'af' is for the gameover text and 'tijd' = time and 'balkje' = obstacles.
I hope you can help me.
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.utils.getTimer;
import flash.events.Event;
public class iCopter extends MovieClip
{
private var copter : Copter = null;
private var gameover : GameOver = null;
private var balkje : Balkje = null;
private var tijd : int
var score = 0;
var highscore = 0;
public function onStartButton(event:MouseEvent)
{
startiCopter()
}
public function iCopter()
{
startButton.addEventListener(MouseEvent.CLICK, onStartButton);
af.visible = false
output.visible = false
hscore.visible = false
}
public function startiCopter()
{
removeChild(startButton);
removeChild(hoeSpelen);
removeChild(af);
score = 0
icopterlogo.visible = false
output.visible = true
hscore.visible = true
copter = new Copter();
copter.x = 100;
copter.y = 200;
addChild(copter);
tijd = getTimer();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
public function onEnterFrame(event:Event)
{
var now:int = getTimer();
if (now - tijd > 1250)
{
var balkje = new Balkje();
balkje.x = 350;
balkje.y = Math.random() * 150;
addChild (balkje);
tijd = now
score = score + 10;
output.text = "score: "+score;
if (balkje.x <= -10) //don't work.
{ //don't work.
removeChild (balkje); //don't work.
} //don't work.
}
addEventListener(Event.ENTER_FRAME, botsing);
}
function botsing (event:Event)
{
for (var i = 0; i < numChildren; i++)
{
if (getChildAt(i) is Balkje || getChildAt(i) is Vloer)
{
var b = getChildAt(i) as MovieClip;
if (b.hitTestObject(copter))
{
removeChild (copter);
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
var gameover = new GameOver();
addChild(af);
af.visible = true
addChild(hoeSpelen);
addChild(startButton);
if (score > highscore)
{
highscore = score
hscore.text = "highscore: "+highscore;
}
}
}
}
}
}
}
Here are the scripts for the copter and obstacle
copter:
muisKlik = mouseClick
muisDruk = mousePush
muisOmhoog = mouseUp
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
public class Copter extends MovieClip
{
var vy : Number = 0;
var muisKlik : Boolean = false;
public function Copter()
{
vy = 5;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(event:Event)
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, muisDruk);
stage.addEventListener(MouseEvent.MOUSE_UP, muisOmhoog);
}
public function onEnterFrame(event:Event)
{
if (muisKlik == true)
{
y -= vy;
}
else
{
y += vy;
}
}
public function muisDruk (event:MouseEvent)
{
muisKlik = true
}
public function muisOmhoog (event:MouseEvent)
{
muisKlik = false
}
}
}
obstacle:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Balkje extends MovieClip
{
var vx : Number = 1;
public function Balkje()
{
vx = 5;
addEventListener( Event.ENTER_FRAME, onEnterFrame );
}
public function onEnterFrame( event:Event )
{
x -= vx;
}
}
}
Not tested - probably full of errors, and I haven't done AS3 in a while:
When you initialize obstacles, pass in the stage object (not sure if this is the best practice)
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Balkje extends MovieClip
{
var vx : Number = 1;
public function Balkje()
{
vx = 5;
if(!stage){
//if stage isn't populated yet, wait for it
this.addEventListner(Event.ADDED_TO_STAGE,addedToStage);
}else{
init();
}
}
private function addedToStage(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE,addedToStage);
init();
}
protected function init():void {
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
public function onEnterFrame( event:Event )
{
x -= vx;
//check x
if(this.x + this.width <= 0 || this.x >= stage.stageWidth) {
if(this.parent) this.parent.remmoveChild(this);
removeEventListener( Event.ENTER_FRAME, onEnterFrame );
}
}
}
}
Again, not tested (is stage.stageWidth correct to get the stage width?) but you get the idea. Check the x of the object, if it is outside the visible stage remove it from its parent (I just put this.parent because you didn't add the obstacle to the stage).
Also, why do you add event listener to ENTER_FRAME in a function called by ENTER_FRAME?

Actionscript 3 Making the character to Jump

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();
}