Skip to main content
Known Participant
January 4, 2017
Answered

object self destruction?

  • January 4, 2017
  • 2 replies
  • 755 views

Hello Community,

(If you have no time for backstory and explainations scroll down to "My Problem", but it would be helpful to understand my problem if you read it and I would be very thankful if you do)

First of all I'm a Actionscript newbie and I want to learn the basics of AS3 game programming (Im also new to the forum, so sorry if I do anything wrong. Also english is my second language, so some formulations may not be correct... sorry). I know general coding basics from school and I want to develop a mini flash game as IT-Class project. The problem is that we only programmed buissness/economy applications and stuff like this with C++ and java. We also went threw object oriented programming, but in game development to me everything ist very different. So if you have good books, tutorials, websites, videos etc. to recomment that would be very helpful.

At the moment I am able to "get things working... somehow" but it isn't very elegant or system friendly.

The Game:
It's a minigame (endless runner) where you try to defend a human butt from bloodsucking flies. They fly, land and start draining. You have to survive and loose when your blood-level is 0.

How it works:

the Flies spawn in the off (around the stage) at a random coordinate. then they get a target coordinate on the landing plane (Le human butt ) and turn to that point. they fly there, land and start draining. The user can hit them from the moment they enter the stage. If the user hits them in the air, they just explode, if he hits them after landing, they splatter. if they drain, your blood level decreases, the flies get bigger and the butt color goes from a healthy pink to a vampirish white. You have to survive as long as possible. The flies become faster and more the longer you play.

I want to add some special abilities later on (like time freeze for 10 sec. or an exploding fart that kills all flies on stage etc.), but thats pie in the sky at the moment. (don't judge me for my humor haha )

What I've done:

- half of the art/animation part (butt, life-bar, and kill animations missing)

- I use the TweenLite engine for my animations

- 1 Main class with all the game logic (tried to be object oriented)
- a Fly class with all the functionality of those suckers

- a Blood class with the bloodlevel Var linked to a textbox (As I said, no bar yet)

the game work's, but I want a good class structure and system. I imagine it like legos. One core brick with the basic functionality that i can expand with smaller bricks, like the mentioned special abilities etc.

     Le Game

     Le Flies doing Fly stuff                              Le Fly draining blood

My Problem:

I dont always know what belongs to wich class. It's some kind of general problem but this specific case is very annoying:

I spawn the fly objects with a timer in the main class. First I tried to do keep control over them by putting every fly by spawning in an Array. I thought like this I am able to remove the object with my main class if the user clicks it, just like it was created... It worked, but only with the first fly, because if you removed for example [object fly] on Arrayfield 43 the flies on field 44, 45 etc. budge up to close the gap in the Array. Thats why you lose control after a while and if you click one fly, sometimes a random other fly anywhere on the screen dies . I needed an Array thats not budging up but would leave a empty placeholder on field 43 till the next fly spawns and closes that gap.

Long story short: I didn't find a way to keep control over them via the main class and after hours of frustration I wrote a kill function inside the fly class. Like this the object destroys itself...

public function kill(event:MouseEvent):void

        {   

           

            suckTimer.stop();

           

            TweenLite.killTweensOf(this);

            this.removeEventListener(MouseEvent.MOUSE_DOWN, kill);

            suckTimer.removeEventListener(TimerEvent.TIMER, drain);

            parent.removeChild(this);

        }

It works now, but I think thats not a nice way to do... what do you think? I am willing to redo all of my classes with your help. I really want a nice performing and structured code

2 Questions:

-Does my solution at the moment leave any unwanted rests of the object, that influence the performance after a while and do you know a way to check that besides using the trace function?

-Do you know an elegant solution for my problem? I can imagine that there is an obvious way a experienced programmer would do it, but i have no idea.

As I said, I also would be very happy about general advices and recommendations (books, tutorials etc.) so I dont have to annoy you haha

A very very big thanks to every help I get

PS: I would like to add the class ( .as ) files for those who want to read them and give tips on style and structure. Is this somehow possible?

This topic has been closed for replies.
Correct answer kglad

Well I still have a problem with the simplified version I wanted to upload.

the problem is (Array or not) that I have no reference to the fly object. Your example with the for-loop is just a way to go threw the Array, and you wrote "whatever condition" for the if statement, but I'm not able to get the number/name of the fly that has been klicked and they are all called [object fly] so with what condition should I search for THE ONE?

I have a solution, but this solution brings another problem:

I've declared a private int variable "number" in my fly class and linked it to the constructor function. So every fly gets a number by constructing. I wrote a getNumber() function to give the value from my fly object to the main.

so far so good. Now I put the eventlistener on my fly directly after constructing it and I tried to put the getNumber() inside the eventlistener, because otherwise I wouldnt be able to reference on the specific fly. The problem is that the eventListener() function doesn't allow more arguments in the listener function.

I tried to get around the "1067: Implicit coercion of a value of type void to an unrelated type Function" Error I got, but now the clicklistener doesn't work and the function is triggered immediately.

Heres my Code: (i've deleted unimportant parts)

package  {

   

    public class Main extends MovieClip{

       

        var fliesArray:Array = new Array();

        var flyNumber:int = 0;

       

        public function Main() {

           

            addFliesTimer.addEventListener(TimerEvent.TIMER, addFly);

            addFliesTimer.start();

           

        }

       

        function deleteFly(n:int):Function{

       

        // delete the object "fliesArray"

       

        }

        function addFly(event:TimerEvent):void{

              

            flyNumber++;

           

            var fly:Fly = new Fly(flyNumber)

                       

            fliesArray.push(fly);

            fly.addEventListener(MouseEvent.MOUSE_DOWN, deleteFly(fly.getNumber()));

            addChild(fly);

           

        }

    }

   

}

package  {

   

    public class Fly extends MovieClip {

       

        private var number:int;

       

        public function Fly(n:int) {

           

            number = n;

        }

       

        public function getNumber():int{

           

            return number;

        }

    }

   

}


use the indexOf method to find the clicked fly:

function clickedFly(e:MouseEvent):void{

var i:int=flyA.indexOf(e.currentTarget);

flyparent.removeChild(flyA);

flyA.splice(i,1);

}

you can also assign properties to your flies to identiy them.  assigning their index as a property is one option, but all the indices after a removed index are changed when you remove a fly from your array so trying to use that would be a mess and inefficient.

2 replies

Known Participant
January 4, 2017

btw. this is how the flies were added in my actual non array version. all the fly functions are called directly after adding the object. From that point on they are out of control. The rest of the functionality is done by eventListeners inside the fly... theyre somehow autonomous

public function addFlies(event:TimerEvent):void

    {

       

        randTime=(Math.random()*300+timerDelay);

        AddFliesTimer.delay = randTime;

        timerDelay -= spawnAcceleration;

       

        if(timerDelay<=1)

        timerDelay = 1;

       

        var fly:Fly=new Fly();

        fly.startPos(stage.stageWidth,stage.stageHeight);

        fly.gotoAndStop("Fly");

        fly.turn();

        fly.attack();

       

        addChild(fly);

       

    }

kglad
Braniac
January 4, 2017

do you have a question about the snippet in message 4?

Known Participant
January 5, 2017

Well I still have a problem with the simplified version I wanted to upload.

the problem is (Array or not) that I have no reference to the fly object. Your example with the for-loop is just a way to go threw the Array, and you wrote "whatever condition" for the if statement, but I'm not able to get the number/name of the fly that has been klicked and they are all called [object fly] so with what condition should I search for THE ONE?

I have a solution, but this solution brings another problem:

I've declared a private int variable "number" in my fly class and linked it to the constructor function. So every fly gets a number by constructing. I wrote a getNumber() function to give the value from my fly object to the main.

so far so good. Now I put the eventlistener on my fly directly after constructing it and I tried to put the getNumber() inside the eventlistener, because otherwise I wouldnt be able to reference on the specific fly. The problem is that the eventListener() function doesn't allow more arguments in the listener function.

I tried to get around the "1067: Implicit coercion of a value of type void to an unrelated type Function" Error I got, but now the clicklistener doesn't work and the function is triggered immediately.

Heres my Code: (i've deleted unimportant parts)

package  {

   

    public class Main extends MovieClip{

       

        var fliesArray:Array = new Array();

        var flyNumber:int = 0;

       

        public function Main() {

           

            addFliesTimer.addEventListener(TimerEvent.TIMER, addFly);

            addFliesTimer.start();

           

        }

       

        function deleteFly(n:int):Function{

       

        // delete the object "fliesArray"

       

        }

        function addFly(event:TimerEvent):void{

              

            flyNumber++;

           

            var fly:Fly = new Fly(flyNumber)

                       

            fliesArray.push(fly);

            fly.addEventListener(MouseEvent.MOUSE_DOWN, deleteFly(fly.getNumber()));

            addChild(fly);

           

        }

    }

   

}

package  {

   

    public class Fly extends MovieClip {

       

        private var number:int;

       

        public function Fly(n:int) {

           

            number = n;

        }

       

        public function getNumber():int{

           

            return number;

        }

    }

   

}

kglad
Braniac
January 4, 2017

when removing objects from an array in a for-loop (where more than 1 object may be removed per), loop through your array in reverse order:

private function removeFlies():void{

for(var i:int=flyA.length-1;i>=0;i--){

if(whatever condition to determine which flies to remove){

whateverparent.removeChild(flyA);

flyA.splice(i,1);

}

}

}

and in your fly class use a removedfromstage listener to stop whatever processes inside the fly class that need to be stopped

Known Participant
January 4, 2017

Thank you for your quick response, I will do a simplyfied version of the classes including your solution and post it here, because I think there will still be complications and like that you exactly know what I'm talking about.

kglad
Braniac
January 4, 2017

sounds good.