1009 Error Flash game CS4 AS3 - actionscript-3

I am coding a flash game in which the ball hits a movie clip object and this takes the user to a new scene.
I have 3 main methods:
movePaddle, moveBall and changeFrame.
it works fine but when i execute the changeFrame method (ball hits movie clip)to go to a new frame i get a whole page of 1009 errors:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at FlashGameNEW_fla::MainTimeline/changeFrame()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at FlashGameNEW_fla::MainTimeline/movePaddle()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at FlashGameNEW_fla::MainTimeline/moveBall()
This is repeated many times.
Any help would be greatly appreciated.
Thanks.
EDIT: with code below
function beginCode():void{
mcPaddle.addEventListener(Event.ENTER_FRAME, movePaddle);
mcBall.addEventListener(Event.ENTER_FRAME, moveBall);
mcBall.addEventListener(Event.ENTER_FRAME, changeFrame);
}
function movePaddle(event:Event):void{
mcPaddle.x = mouseX - mcPaddle.width / 2;
if(mouseX < mcPaddle.width / 2){
//Keep the paddle on stage
mcPaddle.x = 0;
}
if(mouseX > stage.stageWidth - mcPaddle.width / 2){
mcPaddle.x = stage.stageWidth - mcPaddle.width;
}
}
function changeFrame(event:Event):void{
if (mcBall.hitTestObject(Northcote)) {
this.gotoAndPlay(3);
}
}

The problem is you havent instances of mcPaddle and mcBall in frame 3 (For instance, they are not created right now and will be created later). Do check for existing instance:
function movePaddle(event:Event):void {
if (!mcPaddle)
return;
mcPaddle.x = mouseX - mcPaddle.width / 2;
if(mouseX < mcPaddle.width / 2){
//Keep the paddle on stage
mcPaddle.x = 0;
}
if(mouseX > stage.stageWidth - mcPaddle.width / 2) {
mcPaddle.x = stage.stageWidth - mcPaddle.width;
}
}
function changeFrame(event:Event):void{
if (mcBall && Northcote && mcBall.hitTestObject(Northcote)) {
this.gotoAndPlay(3);
}
}

Related

Actionscript3 shooter game error 1009 and 2009

Good day everyone! I'm Jeremy, a college student. I'm working on a shooter game that has story and up to 3 levels (this is our finals that is due in 2 days). I know that I must know this stuff bcoz of school, but honestly I dont. And I'm really not good with actionscript 3 so I really need ur help guys. I know that this problem has been all over the net. But I still don't know how to solve the Error Code 1009 and 2007..
So this is my code for frame4:
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.events.Event;
stop();
var container:MovieClip = new MovieClip();
addChild(container);
//move the spaceship using our mouse
function controlSpaceShip(event:Event):void
{
shipMC.x = stage.mouseX;
Mouse.hide();
}
stop();
var score:int = 0;
stage.addEventListener(Event.ENTER_FRAME, controlSpaceShip);
//shoot bullets when we left click on the mouse
function shootBullet(event:MouseEvent):void
{
var thebullet:MovieClip = new bullet(); //calls the bullet symbol from the library
//positions the bullet at the position of your ship
thebullet.x = shipMC.x + 30;
thebullet.y = shipMC.y + 20;
//we add the bullet onto the stage
container.addChild(thebullet);
}
stage.addEventListener(MouseEvent.CLICK, shootBullet);
//when bullet hits the enemy1
function hitEnemy(event:Event):void {
if (container.hitTestObject(enemy1)) {
enemy1.alpha = 0;
score = score + 5;
txtScore.text = (score).toString();
}
}
stage.addEventListener(Event.ENTER_FRAME, hitEnemy);
//when bullet hits the enemy2
function hitEnemy2(event:Event):void {
if (container.hitTestObject(enemy2)) {
enemy2.alpha = 0;
score = score + 5;
txtScore.text = (score).toString();
}
}
stage.addEventListener(Event.ENTER_FRAME, hitEnemy2);
//when bullet hits the enemy3
function hitEnemy3(event:Event):void {
if (container.hitTestObject(enemy3)) {
enemy3.alpha = 0;
score = score + 5;
txtScore.text = (score).toString();
}
}
stage.addEventListener(Event.ENTER_FRAME, hitEnemy3);
//when bullet hits the enemy4
function hitEnemy4(event:Event):void {
if (container.hitTestObject(enemy4)) {
enemy4.alpha = 0;
score = score + 5;
txtScore.text = (score).toString();
}
}
stage.addEventListener(Event.ENTER_FRAME, hitEnemy4);
//when bullet hits the enemy5
function hitEnemy5(event:Event):void {
if (container.hitTestObject(enemy5)) {
enemy5.alpha = 0;
score = score + 5;
txtScore.text = (score).toString();
}
}
stage.addEventListener(Event.ENTER_FRAME, hitEnemy5);
//when bullet hits the enemy6
function hitEnemy6(event:Event):void {
if (container.hitTestObject(enemy6)) {
enemy6.alpha = 0;
score = score + 5;
txtScore.text = (score).toString();
}
if (txtScore.text == (150).toString())
{
gotoAndStop(5);
}
}
stage.addEventListener(Event.ENTER_FRAME, hitEnemy6);
//move the enemies vertically
function moveEnemies(event:Event):void {
//ENEMY 1
enemy1.y += 8; //increment the y location of my enemy 6 pixels
if (enemy1.y > 600) { //if my enemy is outside the stage
enemy1.y = 0; //place it back on the stage
enemy1.x = Math.random() * 550; //randomize its horizontal location
}
//ENEMY 2
enemy2.y += 4; //increment the y location of my enemy 3 pixels
if (enemy2.y > 600) { //if my enemy is outside the stage
enemy2.y = 0; //place it back on the stage
enemy2.x = Math.random() * 550; //randomize its horizontal location
}
//ENEMY 3
enemy3.y += 3; //increment the y location of my enemy 3 pixels
if (enemy3.y > 600) { //if my enemy is outside the stage
enemy3.y = 0; //place it back on the stage
enemy3.x = Math.random() * 550; //randomize its horizontal location
}
//ENEMY 4
enemy4.y += 4; //increment the y location of my enemy 3 pixels
if (enemy4.y > 600) { //if my enemy is outside the stage
enemy4.y = 0; //place it back on the stage
enemy4.x = Math.random() * 550; //randomize its horizontal location
}
//ENEMY 5
enemy5.y += 4; //increment the y location of my enemy 3 pixels
if (enemy5.y > 600) { //if my enemy is outside the stage
enemy5.y = 0; //place it back on the stage
enemy5.x = Math.random() * 550; //randomize its horizontal location
}
//ENEMY 6
enemy6.y += 4; //increment the y location of my enemy 3 pixels
if (enemy6.y > 600) { //if my enemy is outside the stage
enemy6.y = 0; //place it back on the stage
enemy6.x = Math.random() * 550; //randomize its horizontal location
}
}
stage.addEventListener(Event.ENTER_FRAME, moveEnemies);
so after killing all 6 enemies and scoring at least 150, I want the frame to jump to frame5(success) while frame 5 has the button to click going to frame6(story and goes to level2)..
and here's the error that keeps on going and going..
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at finals_interactivegame2_fla::MainTimeline/moveEnemies()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at finals_interactivegame2_fla::MainTimeline/controlSpaceShip()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy2()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy3()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy4()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy5()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy6()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at finals_interactivegame2_fla::MainTimeline/moveEnemies()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at finals_interactivegame2_fla::MainTimeline/controlSpaceShip()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy2()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy3()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy4()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy5()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy6()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at finals_interactivegame2_fla::MainTimeline/moveEnemies()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at finals_interactivegame2_fla::MainTimeline/controlSpaceShip()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy2()
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at finals_interactivegame2_fla::MainTimeline/hitEnemy3()
I hope somebody help me because I don't know what to do anymore. I don't have people to help me. My classmates are not approachable and friendly. and this will be submitted in 2 days. So I don't want to fail. I just hope someone.. someone to help me with my game.
You can check my file at Actionscript3 shooter game
Thank you.
Your problem is that your adding all these ENTER_FRAME listeners, but then not removing them before you go to the next frame. So they keep running forever, and they try to reference all your enemy's and container even though those things got unloaded when you changed frames.
To resolve this issue, you need to remove ALL those listeners before you move on to frame 5.
I'd recommend creating a function called checkGameComplete or something like that:
function checkGameComplete():void {
if (txtScore.text == (150).toString()){
stage.removeEventListener(Event.ENTER_FRAME, hitEnemy6); //repeat for ALL enter frame listeners
//rest of the removeEventListeners
gotoAndStop(5);
}
}
Then call that checkGameComplete() on every hitEnemy check.
As an aside, make your code less redundant by making ONE hit enemy method, ONE move method, and ONE enter frame listener:
stop();
var score:int = 0;
var container:MovieClip = new MovieClip();
addChild(container);
stage.addEventListener(Event.ENTER_FRAME, gameLoop); //just the one ENTER FRAME handler
Mouse.hide(); //you only need to call this once, instead of every bullet fire
stage.addEventListener(MouseEvent.CLICK, shootBullet);
function shootBullet(event:MouseEvent):void
{
var thebullet:MovieClip = new bullet(); //calls the bullet symbol from the library
//positions the bullet at the position of your ship
thebullet.x = shipMC.x + 30;
thebullet.y = shipMC.y + 20;
//we add the bullet onto the stage
container.addChild(thebullet);
}
function gameLoop(event:Event):void {
if(!shipMC) return;
shipMC.x = stage.mouseX;
moveEnemy(enemy1, 8);
moveEnemy(enemy2, 4);
moveEnemy(enemy3, 3);
moveEnemy(enemy4, 4);
moveEnemy(enemy5, 4);
moveEnemy(enemy6, 4);
}
function hitEnemyCheck(enemy):void {
if (container.hitTestObject(enemy)) {
//enemy.visible = false; //instead of hiding it, move it back up
enemy.y = -100;
score = score + 5;
txtScore.text = (score).toString();
checkGameComplete();
}
}
function moveEnemy(enemy, amount):void {
enemy.y += amount; //increment the y location of my enemy
if (enemy.y > 600) { //if my enemy is outside the stage
enemy.y = 0; //place it back on the stage
enemy.x = Math.random() * 550; //randomize its horizontal location
}
hitEnemyCheck(enemy);
}
function checkGameComplete():void {
if (txtScore.text == (150).toString()){
stage.removeEventListener(Event.ENTER_FRAME, gameLoop);
stage.removeEventListener(MouseEvent.CLICK, shootBullet); //clean up listeners
removeChild(container); //get rid of this container you created
Mouse.show(); //show the mouse again
gotoAndStop(5);
}
}
I also noticed, that on your frame 5 code (and frame 6 code too), you're calling the wrong function on the next3_btn click:
next3_btn.addEventListener(MouseEvent.CLICK,next2Click); // <-- your calling next2Click instead of next3Click
Should be:
next3_btn.addEventListener(MouseEvent.CLICK,next3Click);
In your hitEnemy6 function and before gotoAndStop(5), you should remove all event listeners that you have already added, to goto to the 5th frame :
stage.removeEventListener(Event.ENTER_FRAME, hitEnemy)
stage.removeEventListener(Event.ENTER_FRAME, hitEnemy2)
stage.removeEventListener(Event.ENTER_FRAME, hitEnemy3)
stage.removeEventListener(Event.ENTER_FRAME, hitEnemy4)
stage.removeEventListener(Event.ENTER_FRAME, hitEnemy5)
stage.removeEventListener(Event.ENTER_FRAME, hitEnemy6)
stage.removeEventListener(Event.ENTER_FRAME, moveEnemies)
stage.removeEventListener(Event.ENTER_FRAME, controlSpaceShip)
stage.removeEventListener(MouseEvent.CLICK, shootBullet)
gotoAndStop(5)
In your moveEnemies function, you should verify every time if your enemy object is not null using a simple if as :
if (enemy1) {
enemy1.y += 8
if (enemy1.y > 600){
enemy1.y = 0
enemy1.x = Math.random() * 550
}
}
You should do that for all your enemy objects (1 -> 6).
I don't know why you created 6 Event.ENTER_FRAME, one for every enemy object !? you can simply do :
stage.addEventListener(Event.ENTER_FRAME, hitEnemy)
function hitEnemy(event:Event):void {
if (container.hitTestObject(enemy1)) {
enemy1.alpha = 0
score = score + 5
txtScore.text = (score).toString()
}
if (container.hitTestObject(enemy2)) {
enemy2.alpha = 0
score = score + 5
txtScore.text = (score).toString()
}
// do the same thing for all your enemy objects ...
}
...

Error 1009 Actionscript Flash CC

So I have been trying to figure out this error for the past two hours, I've tried researching the entire internet for an answer and so far I haven't been able to figure it out.
Would someone be able to help me! This is my code :
stop();
countdown_mc.visible = false;
stage.focus = stage;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.sensors.Accelerometer;
import flash.events.AccelerometerEvent;
var myAccel: Accelerometer = new Accelerometer();
var score: Number = 0;
var countDown: Timer = new Timer(1000);
stage.addEventListener(Event.ENTER_FRAME, checkHit);
myAccel.setRequestedUpdateInterval(100); //Every half second.
countDown.addEventListener(TimerEvent.TIMER, count);
countDown.start();
if (Accelerometer.isSupported == true) {
myAccel.addEventListener(AccelerometerEvent.UPDATE, update);
function update(e: AccelerometerEvent) {
x_mc.x -= (e.accelerationX * 30);
o_mc.x -= (e.accelerationX * 30);
if (x_mc.x < 150) {
x_mc.x = 150;
}
if (x_mc.x >= stage.stageWidth - 150) {
x_mc.x = stage.stageWidth - 150;
}
if (o_mc.x < 150) {
o_mc.x = 150;
}
if (o_mc.x >= stage.stageWidth - 150) {
o_mc.x = stage.stageWidth - 150;
}
}
}
function count(eeee: TimerEvent) {
var drop: Number = Math.floor(Math.random() * 5) + 1;
if (drop == 1) {
x_mc.gotoAndPlay(2);
countDown.stop();
gotoAndPlay(180);
o_mc.stop();
stage.removeEventListener(Event.ENTER_FRAME, checkHit);
stage.removeEventListener(AccelerometerEvent.UPDATE, update);
stage.removeEventListener(TimerEvent.TIMER, count);
} else if (drop == 2) {
o_mc.gotoAndPlay(2);
countDown.stop();
gotoAndPlay(180);
x_mc.stop();
stage.removeEventListener(Event.ENTER_FRAME, checkHit);
stage.removeEventListener(AccelerometerEvent.UPDATE, update);
stage.removeEventListener(TimerEvent.TIMER, count);
} else if (drop) {
x_mc.stop();
o_mc.stop();
} else if (x_mc.hitTestObject(exoHit_mc)) {
score++;
}
}
function checkHit(eeee: Event) {
if (x_mc.hitTestObject(exeHit_mc)) {
gotoAndStop(257);
stage.removeEventListener(Event.ENTER_FRAME, checkHit);
stage.removeEventListener(AccelerometerEvent.UPDATE, update);
stage.removeEventListener(TimerEvent.TIMER, count);
}
}
And this is the error :
[SWF] flash%20gmae.swf - 2013164 bytes after decompression
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at flashgmae_fla::MainTimeline/count()[flashgmae_fla.MainTimeline::frame179:91]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at flashgmae_fla::MainTimeline/count()[flashgmae_fla.MainTimeline::frame179:91]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at flashgmae_fla::MainTimeline/count()[flashgmae_fla.MainTimeline::frame179:79]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at flashgmae_fla::MainTimeline/count()[flashgmae_fla.MainTimeline::frame179:91]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at flashgmae_fla::MainTimeline/count()[flashgmae_fla.MainTimeline::frame179:79]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at flashgmae_fla::MainTimeline/count()[flashgmae_fla.MainTimeline::frame179:67]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
[UnloadSWF] flash%20gmae.swf
Test Movie terminated.
I have figured out that is has something to do with the x_mc and o_mc movie clips but I have no idea what the issue is as I am new to action script.
Thank you so much!
x_mc and o_mc are not present on the frames, or don't have an instance name set. Verify that both objects have the correct instance name set. After doing that, verify this for exoHit_mc and exeHit_mc as well.

I got an Error #1009 saying I Cannot access a property or method of a null object reference. Now what?

So I got that error when trying to run my game. It's a simple little game that revolves around picking up orbiting jerry cans whilst trying to avoid orbiting enemies. So I hit Ctrl+Shft+Enter and found the problem was at line 26 (if (this.y +...) in my Ship Class.
package
{
import flash.display.Sprite;
import flash.events.Event;
public class Ship extends Sprite
{
public function Ship(_x:int,_y:int)
{
this.x = _x;
this.y = _y;
//adds event listener that allows the player to move
addEventListener(Event.ENTER_FRAME, player_move);
}
public function player_move(e:Event)
{
//check if at left or right side of stage
if (this.y - this.height / 2 <= 0)
{
this.y = 50;
}
if (this.y + this.height / 2 >= stage.height - this.height)
{
this.y = 370;
}
if (this.x - this.width / 2 <= 0)
{
this.x = 50;
}
if (this.x + this.width / 2 >= stage.width - this.width)
{
this.x = 500;
}
}
public function left():void
{
//the speed in which the player will move left
this.x -= 10;
}
public function right():void
{
//the speed in which the player will move right
this.x += 10;
}
public function up():void
{
//the speed in which the player will move right
this.y -= 10;
}
public function down():void
{
//the speed in which the player will move right
this.y += 10;
}
}
}
Now what do I do? How do I fix this? I can't find the answer anywhere. I know it has something to do with my Main class as in it, I have stated that if the Player his the enemy, his ship is placed back at his original co-ords.
Any help would be greatly appreciated. Thanks.
Your null object is the stage reference. Every DisplayObject has a reference to the stage, however, this is null until the object is actually on the stage.
The stage is the main container of your application. Everything that is visual in your application will be on the stage in some way. Your main document class will be on the stage, all timeline objects, etc.
Your object is counted as being on stage even if its added to a different container, just as long as that container is on the stage in some way. So to put it in the most basic terms, if the object is somewhere where the user should be able to see it, stage will not be null.
To work around this, you're going to have to add your ENTER_FRAME event listener after your object has been added to the stage. Luckily, you can listen for an event that is fired when this happens.
In the constructor:
addEventListener(Event.ADDED_TO_STAGE, init);
Then add your handler:
private function init(evt:Event){
addEventListener(Event.ENTER_FRAME, player_move);
}
Remember, stage will be null until an object is added to the stage, which is the event we're listening for now. Then, just add your ship to the main game or whichever container it's going in, container.addChild(ship), and if that container is a part of the stage, you should be good to go.

AS3 removing event listener before child still causing null object reference

I made a game of Pong with external classes, it's currently configured so that when the playerScore/cpuScore == 1, the player, CPU and ball is removed from the stage. These are removed by the main.as file calling removePlayer(), removeBall() and removeCPU() e.g.
public function removePlayer(): void
{
removeEventListener(Event.ENTER_FRAME, loop);
parent.removeChild(this);
}
The event listener gets rid of the main loop for the element before the child is removed from stage. This works fine for both the player and CPU, but for the ball I'm getting the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.classes::ball/loop()
Commenting out parent.removeChild(this); gets rid of the error, but obviously the ball stays visible. removeEventListener seems to have worked as the ball stops moving when called, but I'm at a loss as to why I would get the null object reference if the loop has been removed. Here is the code for my ball:
package com.classes
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
public class ball extends MovieClip
{
private var theBackground:bg;
private var bounce:Sound = new Sound();
private var point:Sound = new Sound();
private var channel:SoundChannel = new SoundChannel();
public var ballSpeedX:int = -3;
public var ballSpeedY:int = -2;
public function ball(score:bg)
{
theBackground = score;
bounce.load(new URLRequest("com/sounds/sfxBounce.mp3"));
point.load(new URLRequest("com/sounds/sfxScore.mp3"));
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
private function loop(e:Event)
{
x += ballSpeedX;
y += ballSpeedY;
if (x <= width/2)
{
x = width/2;
ballSpeedX *= -1;
theBackground.cpuScore++;
theBackground.updateScores();
channel = point.play();
}
else if (x >= stage.stageWidth - width/2)
{
x = stage.stageWidth - width/2;
ballSpeedX *= -1;
theBackground.playerScore++;
theBackground.updateScores();
channel = point.play();
}
if (y <= height/2)
{
y = height/2;
ballSpeedY *= -1;
channel = bounce.play();
}
else if (y >= stage.stageHeight - height/2)
{
y = stage.stageHeight - height/2;
ballSpeedY *= -1;
channel = bounce.play();
}
}
public function removeBall(): void
{
removeEventListener(Event.ENTER_FRAME, loop);
parent.removeChild(this);
}
}
}
Any help or pointers would be greatly appreciated!
You can add a if (!stage) return; statement in the beginning of the loop function. Apparently you are trying to call removeBall() while processing another Event.ENTER_FRAME listener, maybe on the clock or the player or elsewhere, this hits an issue with event's listener sequence already cached inside Flash. That is, if you are removing an event listener for a certain event type from within another listener of the very same event (enter frame event qualifies), the listener still gets called for that event. You should either call removeBall() from elsewhere, not from an enterframe listener, or just have a null check in that listener to avoid weird errors popping up.
EDIT: Apparently your removeBall() is called while you do theBackground.updateScores(), and after you do this, the ball that processes the event is already removed, thus further processing of the listener is useless. Place a return statement after your sound is triggered to play in all clauses that call theBackground.updateScores() and you should be fine.
if (x <= width/2)
{
x = width/2;
ballSpeedX *= -1;
theBackground.cpuScore++;
theBackground.updateScores();
point.play();
return; // here
}
else if (x >= stage.stageWidth - width/2)
{
x = stage.stageWidth - width/2;
ballSpeedX *= -1;
theBackground.playerScore++;
theBackground.updateScores();
point.play();
return; // and here
}

Updating element position using ENTER_FRAME event

I have an issue in simple arkanoid game in updating paddle position, I am using following listener to react:
paddle.addEventListener(Event.ENTER_FRAME, movePaddle)
when movePaddle() function is defined in Main everything is working just fine, but when I refactored code and putted movePaddle() functions into Paddle class and changed listener into:
paddle.addEventListener(Event.ENTER_FRAME, paddle.movePaddle)
The result is paddle changing position every frame between the desired one, and some other value
Below movePaddle() function:
public function movePaddle(event:Event):void
{
// DEBUG
trace(this.x);
trace(this.y);
this.x = mouseX - this.width / 2;
if(mouseX < this.width / 2)
{
this.x = 0;
}
// To much to right
if(this.x >= stage.stageWidth - this.width)
{
// To much to left
this.x = stage.stageWidth - this.width;
}
}
Second question:
Is using ENTER_FRAME event good in terms of optimalisation for games ?
As Cameron mentioned, if you move movePaddle() to the Paddle class itself, mouseX and mouseY will refer to the mouse position within the Paddle MovieClip. That is, if the Paddle is at 50,50 on the stage, and the mouse is at 100, 100 on the stage, the mouse coordinates you will receive will be 50,50.
A safer option is to use the mouseX and mouseY values given by the Stage:
public function movePaddle(event:Event):void
{
if(stage != null)
{
x = stage.mouseX - width / 2;
if(stage.mouseX < width / 2)
{
this.x = 0;
}
// To much to right
if(x >= stage.stageWidth - width)
{
// To much to left
x = stage.stageWidth - width;
}
}
}
Another thing I would do is rather than having this line in the Main class:
paddle.addEventListener(Event.ENTER_FRAME, paddle.movePaddle);
I would instead put that in Paddle's constructor like so:
public function Paddle()
{
addEventListener(Event.ENTER_FRAME, movePaddle);
}
As for performance of ENTER_FRAME, this is fine however in a properly structured game I would have a single ENTER_FRAME handler which loops over an Array of game entities and them updates them all by calling a method on each.