Copy link to clipboard
Copied
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
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;
Copy link to clipboard
Copied
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;
}
}
}
}
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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;
}
}
}
}
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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"?
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
if you uncomment the contents of enemyChase, what does it trace out?
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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);
}
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
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;
Copy link to clipboard
Copied
YESSS finally got it working .
Thanks so much mocca, you're a lifesaver!! I really appreciate you helping me work through it
Cheers
Copy link to clipboard
Copied
Congrats!
Find more inspiration, events, and resources on the new Adobe Community
Explore Now