Flash as3 platform game Error 1009 - actionscript-3

Im making a platform game with patrolling enemies with an enemy class and a bumper class which changes the direction of the enemies when they collide. Once you open the door and call on the nextLevel function I need the enemies and bumpers to be removed. This is the code for the nextLevel function:
function nextLevel():void {
currentLevel++;
trace("Next Level: " + currentLevel);
if (enemyList.length>0) {
for (var i:int = 0; i < enemyList.length; i++) {
trace("enemyRemoved");
enemyList[i].removeSelf();
}
}
if (bumperList.length>0) {
for (var b:int = 0; b < bumperList.length; b++) {
trace("bumperRemoved");
bumperList[b].removeSelf();
}
}
if (currentLevel==2) {
gotoLevel2();
addEnemiesToLevel2();
addBumpersToLevel2();
}
}
if (currentLevel==3) {
gotoLevel3();
addEnemiesToLevel3();
addBumpersToLevel3();
trace("gotoLevel3");
}
which works fine for going to level 2. But somehow when I go to level 3, I get error 1009 cannot access a property of a null object reference when removing the bumpers. I don't understand why it would work for level 2 but not 3 and also the enemies get removed just fine which is almost identical to the remove bumper code. Here is my removeSelf function in the bumper class
public function removeSelf():void {
trace("remove bumper");
removeEventListener(Event.ENTER_FRAME, bumperloop);
this.parent.removeChild(this);
Also my function for pressing the down arrow key while on the open door to call the nextLevel function
} else if (e.keyCode == Keyboard.DOWN) {
downPressed=true;
if (doorOpen&&player.hitTestObject(back.other.lockedDoor)) {
nextLevel();
}
Anyone know what could be the problem here? I would be very grateful to anyone who could answer Iv'e been working at this for days. It gives me an error on the bumperList[b].removeSelf(); line on the nextLevel function and this.parent.removeChild(this); in the bumper class and on the nextLevel(); line in my keydown code

Related

flash as3 platform game (I am noob)

I am making a platform game in flash cs4 as3 and am having a lot of trouble getting my different classes to work right together. I have a bullet class, enemy class, and a bumper class which determines the boundaries for the enemy. When the bullet hits the enemy the enemies death animation plays and then both are removed from the game. When the last enemy on that level gets removed though, i get this error saying a term is undefined and has no properties. Also if I kill the enemies out of the order they are called things don't work properly my codes must have some errors. Here is my code between the bullet and enemy classes:
if (enemyList.length>0) {
for (var i:int = 0; i < enemyList.length; i++) {
if (bulletList.length>0) {
for (var j:int = 0; j < bulletList.length; j++) {
if (enemyList[i].hitTestObject(bulletList[j])) {
trace("Bullet and Enemy are colliding");
enemyList[i].gotoAndPlay("dead");
bulletList[j].removeSelf();
enemyList[i].xSpeedConst=0;
enemyList[i].isDead = true;
} else {
enemyList[i].isDead = false;
}
}
}
}
}
}
and also between the player and enemy and bumper and enemy.
if (enemyList[k].isDead == false && enemyList.length>0) {
for (var k:int = 0; k < enemyList.length; k++) {
if (enemyList[k].isDead == false && bumperList.length>0) {
for (var h:int = 0; h < bumperList.length; h++) {
if (enemyList[k].hitTestObject(bumperList[h])) {
enemyList[k].changeDirection();
}
}
}
}
}
if (enemyList[m].isDead == false && enemyList.length>0) {
for (var m:int = 0; m < enemyList.length; m++) {
if (enemyList[m].hitTestObject(player)) {
trace("player collided with enemy");
currentHP-=5;
if (currentHP<=0) {
currentHP=0;
trace("you died");
gotoAndStop(1);
}
updateHealthBar();
}
}
}
Sorry it's kinda long I just feel like Im missing something obvious in here or maybe all my code is just poorly structured. Either way any help would be greatly appreciated thanks!
Don't you need to remove the bullet and enemy from the lists once a bullet hit an enemy? Because you do
bulletList[j].removeSelf();
which will probably remove the bullet from the display list, but the bullet reference will still stay in the bulletList and will be checked against on the next iteration.
Also your very first check should be
if (enemyList.length != 0 && bulletList.length != 0)
There is no point to loop trough all enemies if there are no bullets and vice versa :)

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.

As3: _root.removeChild(this) not working with array IN SPECIFIC CASES?

I have a class for a ninja star.
In the loop function, I have:
private function loop (event:Event):void
{
trace(this);
for (var i:int=0; i<_root.guardArray.length; i++)
{
//if movieClip at position [i] (enemy) hits this
if (_root.guardArray[i].hitTestObject(this))
{
if(this.hitTestObject(_root.guardArray[i].hitbox))
{
_root.guardArray[i].killThis();
_root.removeChild(this);
removeEventListener(Event.ENTER_FRAME, loop);
}
}
}
y-=Math.cos(rotation/-180*Math.PI)*(ninjaStarSpeed);
x-=Math.sin(rotation/-180*Math.PI)*(ninjaStarSpeed);
if(this.x < 0 || this.x > _root.stagewidth || this.y > _root.stageheight || this.y < 0)
{
_root.removeChild(this);
removeEventListener(Event.ENTER_FRAME, loop);
}
}
}
The ninja star removes itself successfully without any errors when it goes out of the screen.
HOWEVER, when it hits a guard, it removes itself but gives me a #2025 error # line 40!
This is line 40: _root.removeChild(this); - it's part of the array collision checking.
Is flash bugged out or am I doing something VERY wrong?
Yep, you are doing something wrong, because of Error ;)
Code snippet for you:
private function safeRemove():void{
if(this.parent != null){
this.parent.removeChild(this);
}
}
Add this method to the NinjaStar class, and use it. So 40-th line of code will look like
//And don't forget not only kill guard, but also clear reference on him from the guardArray.
_root.guardArray[i].killThis();
safeRemove();
removeEventListener(Event.ENTER_FRAME, loop);

I added animation to the timeline of my movie clip, now its no longer colliding with objects as it did before

I'm working on a platform game in AS3 for Flash. There is of course a player character and enemies for him to interact with. I first made a simple placeholder graphic for the enemy while I worked on the code. I got the enemy to move back and forth between two bumpers with code. He also collides with the player, sending them back to the start screen. Now that I got the code working, I wanted to add some animations to the enemies so they walk instead of just skate across the ground. I added the animations to the timeline of the enemy movie clip. Now when I test the game, the animations play fine and the enemy begins to move, but he passes through the first bumper and doesn't collide with the player at all. If I force the movie clip to stop and not play the collision starts to work again. What would be causing this?
This is the code within the main timeline of the .fla file.
addEnemiesToLevel1();
addBumpersToLevel1();
function addEnemiesToLevel1():void
{
addEnemy(700, -54);
addEnemy(1341, -54);
addEnemy(2187, -54);
}
function addBumpersToLevel1():void
{
addBumper(900, -80);
addBumper(644, -80);
addBumper(1135, -90);
addBumper(1380, -90);
addBumper(2053, -90);
addBumper(2226, -90);
}
function addEnemy(xLocation:int, yLocation:int):void
{
var enemy:Enemy = new Enemy(xLocation, yLocation);
back.addChild(enemy);
enemy.addEventListener(Event.REMOVED, enemyRemoved);
enemyList.push(enemy);
}
function addBumper(xLocation:int, yLocation:int):void
{
var bumper:Bumper = new Bumper(xLocation, yLocation);
back.addChild(bumper);
bumper.visible = false;
bumperList.push(bumper);
}
//corralling the bad guys with bumpers
if (enemyList.length > 0){ //enemies left in the enemyList?
for (var k:int = 0; k < enemyList.length; k++){ // for each enemy in the enemyList
if (bumperList.length > 0){
for (var h:int = 0; h < bumperList.length; h++){ // for each bumper in the List
if ( enemyList[k].hitTestObject(bumperList[h]) ){
enemyList[k].changeDirection();
}
}
}
}
}
//player and enemy collisions
if (enemyList.length > 0){ //enemies left?
for (var m:int = 0; m < enemyList.length; m++){ // for each enemy in the enemyList
if ( enemyList[m].hitTestObject(player) ){
trace("player collided with enemy");
gotoAndStop(4);
enemyList[m].removeSelf();
}
}
}
}
This is the enemy class file.
package {
import flash.display.MovieClip;
import flash.events.Event;public class Enemy extends MovieClip {
private var xSpeedConst:int = 2;
private var flip:int = 1;
public function Enemy(xLocation:int, yLocation:int) {
// constructor code
x = xLocation;
y = yLocation;
addEventListener(Event.ENTER_FRAME, loop);
}
public function loop(e:Event):void {
if ((flip%2) == 1){
x += xSpeedConst;
} else if((flip%2) == 0){
x += (-xSpeedConst);
}
}
public function removeSelf():void {
trace("remove enemy");
removeEventListener(Event.ENTER_FRAME, loop);
this.parent.removeChild(this);
}
public function changeDirection():void{
trace("x ="+x);
flip++;
this.scaleX *= -1;
}
}
}
I had a problem that was very similar to this:
2D Platform Game using hitTestPoint:glitches
My problem was that my character's hitTestPoint wouldn't work after I animated the character. However, it wasn't because of the animation, it was because of my turning code for the character. I was using scaleX to flip the character. However, this flipped the points nested within the character as well (which were used to handle my collisions). I notice that you also flipped the character's scale:
public function changeDirection():void{
trace("x ="+x);
flip++;
this.scaleX *= -1;
}
Perhaps you are having the same problem as I did. If so, try removing this line of code for now:
this.scaleX *= -1;
...and see what happens...We can figure out what to do next from there
Drake Swartzy

Animated presentation navigation by arrows - AS3

I'm new to AS3 and although I was looking for a solution to my problem truly long time, I was not successful. I have an animated presentation and I just want to make navigation through that by arrows. Everything is on the main timeline. In the first frame I made this code
var zpet: Number;
if (currentFrame == 1) {
zpet = 1;
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, posun);
function posun(event: KeyboardEvent): void {
if (event.keyCode == 37) {
addEventListener(Event.ENTER_FRAME, playReverse);
function playReverse(event: Event): void {
if (currentFrame == zpet) {
stopPlayReverse();
} else {
prevFrame();
}
}
function stopPlayReverse(): void {
if (hasEventListener(Event.ENTER_FRAME)) {
removeEventListener(Event.ENTER_FRAME, playReverse);
}
}
} else if (event.keyCode == 39) {
if (currentFrame < totalFrames - 1) {
play();
} else {
stop();
}
}
}
stop();
Moving forward works perfect as I put stop(); in every keyframe of the presentation. The problem is how to go back just to the previous keyframe (and I also want to go back in reverse playing). I thought it would be quite easy if I made a variable (called "zpet") and set it the specific number of frame where to go back in each keyframe. But it doesn't work, all the time it's going back to frame 1. For example I put in the frame 26 the code zpet = 13; that should say when playing back from the frame 26 stop at the frame 13. Any ideas how to solve this? I would be really grateful for that..
You can label each keyframe of your animation anything you want directly from the timeline and then something like this :
function playReverse(event: Event): void
{
prevFrame();// You can also use gotoAndStop(currentFrame - 1)
if(currentFrameLabel != null)
stopPlayReverse();
}
Looks cleaner imo, plus you can use labels value later in case you make a scene selection menu.