Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Class Enter Frame Problem

Explorer ,
Apr 16, 2013 Apr 16, 2013

Hello,

I am trying to make a simple game where an enemy chases the player if they get to close, and stops if the player moves a certain distance away.

I have a script for the enemy that looks like this :

------------------------------------------------------------------------------------------------------------------------------------------------

package  {

    import flash.display.MovieClip;

    import flash.events.Event;

    import flash.geom.Point;

    public class Enemy extends MovieClip

    {

        var positionX:int;

        var positionY:int;

        public function Enemy()

        {

            addEventListener(Event.ENTER_FRAME, enemyChase);

        }

        public function setPosition (playerX:int, playerY:int)

        {

            positionX = playerX;

            positionY = playerY;

        }

        public function enemyChase (event:Event):void

        {

            var des:Point = new Point(positionX, positionY);

            var loc:Point = new Point(x, y);

            var speed:Number = 1

            if (((Math.abs(positionX - x)) < 90) && ((Math.abs(positionY - y)) < 90))

            {

                var vel:Point = des.subtract(loc);

                vel.normalize( speed );

                x += vel.x;

                y += vel.y;

            }

        }

    }

}

------------------------------------------------------------------------------------------------------------------------------------------------

In my Main script I create a variable of the Enemy class like so :

var enemyScript:Enemy = new Enemy();

and on the Enter Frame function in the Main script I update the player's position for the Enemy class, like so :

enemyScript.setPosition (player.x, player.y);

However it isn't working. If I put something small into the Enemy class Enter Frame function like :

x += 1;

Then the enemies on the screen move every frame, so I know the class is linked properly. And I'm not getting any errors when I compile. What am I missing?

Thanks

P.S. the enemyChase function works when I put it in the Main function and link it directly using instance names, it's just getting it to work from a different class that's the problem

TOPICS
ActionScript
2.3K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guru , Apr 17, 2013 Apr 17, 2013

so in enemys init() function you call setPosition() without argument and then inside setPosition()

you get

positionX = MovieClip(root).player.x;

positionY = MovieClip(root).player.y;

Translate
LEGEND ,
Apr 16, 2013 Apr 16, 2013

I am not sure I understood exactly what the problem is but if you attempt to update enemy position from outside the enemy instance - you don't need its internal enter frame event listener.

Try this:

package

{

          import flash.display.MovieClip;

          import flash.events.Event;

          import flash.geom.Point;

 

          public class Enemy extends MovieClip

          {

 

                    private var positionX:Number;

                    private var positionY:Number;

 

                    public function Enemy()

                    {

 

                    }

 

                    public function setPosition(playerX:Number, playerY:Number):void

                    {

                              positionX = playerX;

                              positionY = playerY;

                              enemyChase();

                    }

 

                    private function enemyChase():void

                    {

                              if (Math.abs(positionX - x) < 90 && Math.abs(positionY - y) < 90)

                              {

                                        var des:Point = new Point(positionX, positionY);

                                        var loc:Point = new Point(x, y);

                                        var speed:Number = 1

                                        var vel:Point = des.subtract(loc);

                                        vel.normalize(speed);

                                        x += vel.x;

                                        y += vel.y;

                              }

 

                    }

 

          }

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 16, 2013 Apr 16, 2013

The problem was that the enemies weren't moving when I got close.

Thanks for the advice about not needing the internal event listener. Made things a bit neater, but unfortunately it still doesn't work. The enemies just don't move when I get close to them.

What I meant was, if I take the code from the enemyChase function and put it in my Main function (and use the instances to get the Point information) e.g. :

var des:Point = new Point(player.x, player.y);

var loc:Point = new Point(enemy1.x, enemy1. y);

Then it works. And also I know the Enemy Class is linked to the Enemy Symbol in the library cos I tested it.

But when I put the enemyChase code into another class, the enemies don't move when I get near them.

Still not getting any errors when I test either. Any ideas?

Thanks

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 16, 2013 Apr 16, 2013

First of all I am not sure what your usage of points tries to accomplish.

What do you see when enemyChase function is written like this?

package

{

          import flash.display.MovieClip;

          import flash.events.Event;

          import flash.geom.Point;

 

          public class Enemy extends MovieClip

          {

 

                    private var positionX:Number;

                    private var positionY:Number;

 

                    public function Enemy()

                    {

 

                    }

 

                    public function setPosition(playerX:Number, playerY:Number):void

                    {

                              positionX = playerX;

                              positionY = playerY;

                              enemyChase();

                    }

 

                    private function enemyChase():void

                    {

                              if (Math.abs(positionX - x) < 90 && Math.abs(positionY - y) < 90)

                              {

                                        var speed:Number = 1

                                        x += speed;

                                        y += speed;

                              }

 

                    }

 

          }

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 16, 2013 Apr 16, 2013

I mean I understand what you are trying to calculate by the points - I am just saying that at this stage try to see if object move at all without using points.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 16, 2013 Apr 16, 2013

Well I guess I had points becuase originally I was doing it slightly differently, and also I wasn't doing it in a separate class I was doing it in the main function.

I tried without points and it's the same, still no movement . Here's a link to my script and flash files in a zip :

http://speedy.sh/336Wu/Simple-Game.zip

For some reason I get the feeling it's something really basic that I'm missing

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 16, 2013 Apr 16, 2013

Well I checked, the setPosition function is getting the player co-ordinates just fine, but when I ask the Enemy class to trace the co-ordinates of the enemy it just says 0. That is, when I put in this line :

trace ((this.x).toString());

In the setPosition function it just says 0. Do I have to do something before this class recognises the position of the enemies that it's attached to? Why does the construction method ( public function Enemy() )  recongnise "this.x", but the public function setPosition doesn't recognise "this.x"?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Apr 16, 2013 Apr 16, 2013

You probably have a problem with your scope.

The moment you add an enemy on your stage (usually via addChild()) and give it a certain velocity in an enterframe method , say

enemy.x +=1 the enemy moves around your stage,

but within your enemy class if you trace out (this.x) it nevertheless stays 0.

because this.x relates to the enemys own coordinatesystem, not to the stageX property.

Make sure you understand the localToGlobal method in relation to Points

You have to convert local to global x/y porperties to make a validation if two objects inhabit the same space, or for calculating distances.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 16, 2013 Apr 16, 2013

Thanks mocca, I think this is what I'm missing.

I'm trying to get the local co-ordinates of the enemy MovieClip, but I can't seem to get them. I'm using :

public function setPosition (playerX:Number, playerY:Number):void

        {

            positionX = (playerX);

            positionY = (playerY);

            localPoint = new Point(0, 0);

            localPoint = localToGlobal (localPoint);

            enemyChase();

        }

but this still says 0. I've been looking up lots of tutorial and they say the new point (localPoint) should be the the centre of the MovieClip (in this case, the Enemy). But I don't understand how that works, since I set localPoint to (0, 0), so it's obviously just going to be 0, not the Enemy's actual co-ordinates on the stage.

I'm struggling with localToGlobal, any help?

Thanks

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Apr 17, 2013 Apr 17, 2013

first try:

stagePoint = new Point(this.x, this.y);

stagePoint = MovieClip(root).localToGlobal(stagePoint);

//the Line beneath should give the same result in your case

//stagePoint = this.parent.localToGlobal(stagePoint);

trace("ABSOLUTE POSITON:"+stagePoint.x +"|"+stagePoint.y);

see if that gives you the absolute coordinates

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 17, 2013 Apr 17, 2013

When I try that, either way, I get the error :

TypeError: Error #1009: Cannot access a property or method of a null object reference.

    at Enemy/enemyChase()

    at Enemy/setPosition()

    at Movement/updating()

referring to the localToGlobal line when I debug

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Apr 17, 2013 Apr 17, 2013

1.allowDebugging (->Publishing options) to get specific Lines where your errors happen

2.you never mentioned a Movement class before, also no updating function, my advise is based on the assumption that you are communicating the "essential" part of your problem

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 17, 2013 Apr 17, 2013

The specific line is this one :

stagePoint = MovieClip(root).localToGlobal(stagePoint);

And I get the same error when I use your other option :

//stagePoint = this.parent.localToGlobal(stagePoint);

The "Movement" class is my my Main class, I referred to it as "Main" in this thread, but it's called Movement. And the code from the update function that the error message is referring to is this ;

function updating (event:Event):void

     {

          var playerPos:Point = new Point(player.x, player.y);

          enemyScript.setPosition (player.x, player.y);

     }

Not sure why, the player co-ordinates aren't related to the enemyChase function.

The weird thing is, if I trace "this.x" in the Enemy class constructor code ( public function Enemy() ) it gives me the enemy's X co-ordinate on the stage, but it doesn't when I try and trace it in the other functions in the Enemy class

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Apr 17, 2013 Apr 17, 2013

Like Andrei1 above already mentioned its not a good idea to have multiple enter frame listeners (like you did in your Enemy class+ your main Movement.class)

they might interfere with each other

try to rewrite your logic so that all the relevant enter frame calculations/positioning is directed from one central point on the root

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 17, 2013 Apr 17, 2013

Yeah I already have, he showed me how. I now use this instead :

public function setPosition (playerX:Number, playerY:Number):void

        {

            positionX = (playerX);

            positionY = (playerY);

            enemyChase();

        }

       

        public function enemyChase():void

        {

            /*var stagePoint:Point;

            stagePoint = new Point(this.x, this.y);

            stagePoint = MovieClip(root).localToGlobal(stagePoint);

            trace("ABSOLUTE POSITON:"+stagePoint.x +"|"+stagePoint.y);*/

        }

So that when setPosition is called, enemyChase is called to, both via the Movement class's enter frame handler

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Apr 17, 2013 Apr 17, 2013

if you uncomment the contents of enemyChase, what does it trace out?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 17, 2013 Apr 17, 2013

That's code I tried before, it gives me the error :

TypeError: Error #1009: Cannot access a property or method of a null object reference.

And in debug that error refers to this line :

stagePoint = MovieClip(root).localToGlobal(stagePoint);

Also if I use this line instead :

stagePoint = this.parent.localToGlobal(stagePoint);

It gives me the exact same error on that line

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Apr 17, 2013 Apr 17, 2013

add these lines to the constructor of your enemy class:

public function Enemy()

        {

        if(stage == null){

            addEventListener(Event.ADDED_TO_STAGE, init)

           }

          else{

                  init();

               }

        }

private function init(e:Event = null):void{

addEventListener(Event.ENTER_FRAME, enemyChase);

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 17, 2013 Apr 17, 2013

When I add those I get the error :

ArgumentError: Error #1063: Argument count mismatch on Enemy/enemyChase(). Expected 0, got 1.

In debug it doesn't point to any particular line. I also still get the same error :

TypeError: Error #1009: Cannot access a property or method of a null object reference.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Apr 17, 2013 Apr 17, 2013

simply delete the line (I erroneously refered to an elder version of your code)

the 1009 code refers to the fact that your enemy-instance is not properly added to the display list when you call

"enemyScript.setPosition (player.x, player.y);"

make sure it is

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 17, 2013 Apr 17, 2013

Awesome, finally got the position working!! It gives the correct position of the enemy on the stage .

Now unfortunately there is one final step haha. How do I get the playerX (positionX) and playerY (positionY) values from the setPosition function into the enemyChase function?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Apr 17, 2013 Apr 17, 2013

so in enemys init() function you call setPosition() without argument and then inside setPosition()

you get

positionX = MovieClip(root).player.x;

positionY = MovieClip(root).player.y;

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 17, 2013 Apr 17, 2013

YESSS finally got it working .

Thanks so much mocca, you're a lifesaver!! I really appreciate you helping me work through it

Cheers

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Apr 18, 2013 Apr 18, 2013
LATEST

Congrats!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines