A Flash Developer Resource Site

Results 1 to 16 of 16

Thread: [CS3] Seeking Auto-targetting Code

  1. #1
    Junior Member
    Join Date
    Nov 2008
    Posts
    7

    [CS3] Seeking Auto-targetting Code

    I'm making a shooter for my flash class. I have an enemy who fires a missile which is to fire at the current location of the player and, if it misses, keeps going off screen. I'm having trouble finding the right trigonometry for it. The missiles aren't going towards the player and just seem to be firing randomly. Here's the code I've currently got after a few different attempts:

    Code:
    			while (fired == false)
    			{
    				locx = _root.player_mc.x + 15;
    				locy = _root.player_mc.y + 15;
    				fired = true;
    			}
    			if (this.x > locx){
    				if (xspeed == 0){
    					xspeed = Math.cos(locx) * speed;}
    				this.x -= xspeed;
    				locx -= xspeed;
    				}
    			if (this.x < locx){
    				if (xspeed == 0){
    					xspeed = Math.cos(locx) * speed;}
    				this.x += xspeed;
    				locx += xspeed;
    				}
    			if (this.y < locy){
    				if (yspeed == 0){
    					yspeed = Math.sin(locy) * speed;}
    				this.y += yspeed;
    				locy += yspeed;
    				}
    			if (this.y > locy){
    				if (yspeed == 0){
    					yspeed = Math.sin(locy) * speed;}
    				this.y -= yspeed;
    				locy -= yspeed;
    				}
    This is in the Enter Frame event function.

    The While function ensures it sets "fired" to true so it doesn't fill the screen with missiles and also gets the location of the player. The If statements make sure to fire in the correct direction and set a horizontal and vertical speed. What is happening now is that they often fire with very little xspeed and completely off target. Any help greatly appreciated.

    At first, I wasn't using any trigonometry, and it seemed to work better but still fired off target. I think things were firing correctly if I didn't update the location variables, but then the missile would just sit there indefinitely instead of moving beyond, and this also happened if the location variables weren't updated at the rate of the missile's speed.

  2. #2
    Funkalicious TOdorus's Avatar
    Join Date
    Nov 2006
    Location
    Nijmegen, Netherlands
    Posts
    697
    Quote Originally Posted by CAPTAIN BRUMBL3
    At first, I wasn't using any trigonometry
    And neither are you now.

    To use geometry you should calculate the angle to the target. And then calculate the x and y components of a vector in that direction. I'm nog going into detail here, as I've done this recently here.

    If you want to keep on using the finite states than it should look something more like this.

    Code:
    var dX:Number = Targ.X - this.X
    var dY:Number = Targ.Y - this.Y
    var speed:Number = 5
    if(dX < 0){
        this.X -= speed
    } else if (dX > 0){
        this.X += speed
    }
    //
    if(dY < 0){
        this.Y -= speed
    } else if (dY > 0){
        this.Y += speed
    }
    And why are you adding 15 to the X and Y position of the target?

  3. #3
    Junior Member
    Join Date
    Nov 2008
    Posts
    7
    Like I said, most recent iteration. I was playing around with the Pythagorean and wound up with humongous numbers so I played around with other Math functions. I was looking at some other posts and just toyed around. As to the 15, it was just old code trying to center the location to see if it helped.

    I'll give this all a shot when I can and get back to ya, thanks.

  4. #4
    Member
    Join Date
    Nov 2005
    Posts
    32
    Trigonometric funtions take angles, not coordinates. The functions in Flash also require that the angles be in radians and not degrees. So replace locx and locy in your trig functions with ( _root.player_mc._rotation / 180 / Math.PI ). The division of 180/PI converts it to radians. I'll look for some text for you to read to better understand this if you'd like.

  5. #5
    Senior Member Draxus's Avatar
    Join Date
    Sep 2007
    Location
    Florida
    Posts
    123
    It's faster to do rotation * .0174 to get radians. It's not as accurate of course but that kind of accuracy is rarely needed

  6. #6
    Junior Member
    Join Date
    Nov 2008
    Posts
    7
    TOdarus: The missile is firing forward, backward, downward, but not upward. I don't know what the problem is. I have it set that when the locy is < 0 then this.y -= yspeed. However, it keeps going down if I'm above the enemy. In front and behind, it fires a perfect missile to me either way, but it'll only hit if I'm below it because they won't fire upwards.

    Either I'm missing something stupidly obvious or there's a really odd glitch messing me over. I'll repost my current code.

    Code:
    			while (fired == false)
    			{
    				locx = _root.player_mc.x - this.x;
    				locy = _root.player_mc.y - this.y;
    				fired = true;
    			}
    			xspeed = locx*speed;
    			yspeed = locy*speed;
    			
    			if (locx < 0){
    				this.x -= xspeed;}
    			else if (locx > 0){
    				this.x += xspeed;}
    				
    			if (locy < 0){
    				this.y -= yspeed;}
    			else if (locy > 0){
    				this.y += yspeed;}
    The weird thing about it is that when I trace locy it does give me a negative when I'm above the enemy and gives me a positive when below it. However, missiles only ever fire downwards.

  7. #7
    Senior Member Draxus's Avatar
    Join Date
    Sep 2007
    Location
    Florida
    Posts
    123
    You shouldn't be multiplying your speed by locy and locx for that code to work... and locy and locx are deceiving variable names because they represent distances between the player and the missile, rather than any location.

    Is there a particular reason you're doing it this way? That code would only allow your missile to travel on 8 possible axes. Full speed upward, full speed left, full speed upward and left at the same time, etc... see what I'm saying? This will obviously lead to very inaccurate missiles, especially since you only check the direction it needs to travel once, right when it fires.

  8. #8
    Funkalicious TOdorus's Avatar
    Join Date
    Nov 2006
    Location
    Nijmegen, Netherlands
    Posts
    697
    I agree with Draxus. The mulitiplication with the distance makes the missile go slower and slower when it closes in on it's target. Also this method has the obvious disadvantage that when it moves over both axes, it's velocity is higher (= it won't move at a constant speed), which will look weird. There's no way around this with finite state, the only way would be to learn trigeometry, which is a lot easier than it sounds. Also, if you learn geometry about 90% of the math you need in games is in the bag (I'll probably get flamed on that one).

    To contineu on your coding. By forward and backward, do you mean left and right? I'm asuming that you're using a sideview perspective from now on, but since forward and backward is relative (to the missiles heading) I'll be using left and right from now on.

    I can't really see why you get those results. As I read the code now, it should gave either the wrong behavior on both sides of the x-axis or the right behavior. Could you trace the variables, when you are above and below the missile to see if it gives a different result?
    Code:
    trace("missileX "+this._x)
    trace("missileY "+this._y)
    trace("playerY "+ _root.player_mc._y)
    trace("playerX "+ _root.player_mc._x)
    trace("locx "+locx)
    trace("locy "+locy)
    trace("speed "+speed)
    Place this at the end of the function.

    Btw, I assume you're using AS2 because you use _root. I believe the properties of a mc in AS2 are referred to as mc._property and not mc.property (you use mc.x instead of mc._x). Maybe that's the bug. If not, trace your variables.

  9. #9
    Junior Member
    Join Date
    Nov 2008
    Posts
    7
    Enemies fly in from the left to the right. Player starts on the right and can move in two dimensions.

    If _root is supposed to be AS2, then I found a bad tutorial. I'm using AS3 and the tutorial I found was for a AS3 shooter. What it gave me worked fine, so I'm now adding to it with the enemies that can shoot. If perhaps there's some sort of conflict being caused, I don't know about it. To stay on the tutorial a moment longer, when killed, it sometimes doesn't display the final score and sometimes it does. I have yet to notice a pattern or triggering reason why this is.

    I used this tutorial at www.mrsunstudios.com and have built up from there to fit my needs. Short of the 2nd enemy and the 2nd enemy's missiles, nothing was changed except dimensions so mine is a left-right instead of an up-down.

    Anyways, I tried again using a flat speed. The issue here is that it is incredibly inaccurate, which is what I was trying to fix by using multiplication. This made it much more accurate but introduced the Y axis issue. Using a flat speed, it either under shoots or over shoots.

    Suffice to say, I'm god damned confused right now I do not see why it's not firing upwards with the multiplication and I otherwise see no way with this current code for it to fire accurately using flat rates.

  10. #10
    Funkalicious TOdorus's Avatar
    Join Date
    Nov 2006
    Location
    Nijmegen, Netherlands
    Posts
    697
    Nah it's not a bad tutorial. Not a good one either, as to keep on using _root via an instance variable in AS3 isn't the best OOP practice. I wouldn't let it bother you now though, as it's easier to learn. So screw good practice atm.

    I think your problem is a little deeper then just this. Would you mind if I'd take a look at the .fla?

  11. #11
    Junior Member
    Join Date
    Nov 2008
    Posts
    7
    Hopefully this works, never used this place before.

    http://www.mediafire.com/?sharekey=a...db6fb9a8902bda

    Good luck and thanks a ton for the help.

    I edited some code so it only sends out one missile enemy at a time, the other won't show up for a long time. Don't mind the placeholder graphics lol

  12. #12
    Junior Member
    Join Date
    Nov 2008
    Posts
    7
    UPDATE

    I've got it working, but the code seems excessive. If you have a better way or a good algorithm, I'd greatly appreciate it. However, as it stands, this is working perfectly as intended. The enemies fire at the same moment and the xspeed variable remains the same, it's yspeed that gets altered depending on the value of locy to make it slower or faster so it goes in the right direction.

    Also, it seems that since the this.y -= yspeed code line was somehow resulting in never shooting up, I multiplied it by -1 which fixed it. Here's the current code as it is now. Again, if you've a better way or algorithm, it'd be greatly appreciated, but this is working perfectly as intended now.

    Code:
    	if (locy < 0){
    		yspeed = .01;
    		if (locy < -50){
    			yspeed = .015;
    			if (locy < -100){
    				yspeed = .02;
    				if (locy < -150){
    					yspeed = .0204;
    					if (locy < -200){
    						yspeed = .02075;
    					}
    				}
    			}
    		}
    		this.y -= (locy*-1)*yspeed;
    	}
    			
    	if (locy > 0){
    		yspeed = .01;
    		if (locy > 50){
    			yspeed = .015;
    			if (locy > 100){
    				yspeed = .02;
    				if (locy > 150){
    					yspeed = .0204;
    					if (locy > 200){
    						yspeed = .02075;
    					}
    				}
    					}
    		}
    		this.y += locy*yspeed;
    	}
    On another note, I've run into a neglegable error after adding in my shotgun powerup and use it. Sometimes after hitting an enemy, it gives an error like this:
    ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
    at flash.display::DisplayObjectContainer/removeChild()
    at EnemyB/eFrame()
    ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
    at flash.display::DisplayObjectContainer/removeChild()
    at eMissle/eFrame()
    I have a feeling it's because there's a chance for more than one shotgun pellet to hit an enemy or missile at once and I'm not sure how to error catch with actionscript, but this doesn't appear to be causing any problems so I won't be worrying about it.

    Oh, and thank you =D

  13. #13
    Funkalicious TOdorus's Avatar
    Join Date
    Nov 2006
    Location
    Nijmegen, Netherlands
    Posts
    697

    Post

    That made me chuckle. Because of your comment on it only happening in the y-axis I completely overlooked that. Your locx and locy were already negative, so there's no need to use -= .

    Code:
    var xspeed
    var yspeed
    //
    //Move the eMissle to the player upon firing
    while (fired == false)
    {
    	locx = _root.player_mc.x - this.x;
    	locy = _root.player_mc.y - this.y;
    	fired = true;
    }
    if (locx < 0) {
    	xspeed = -2
    } else {
    	xspeed = 2
    }
    //
    if (locy < 0) {
    	yspeed = -2
    } else {
    	yspeed = 2
    }
    			
    this.x += xspeed;
    this.y += yspeed;
    This means, you should also have had the problem on your x-axis

    About your new problem. I don't use movieclips in AS3, so I'm somewhat unfamiliair with the error. Googling it up, it means that you're calling to a movieclip that doesn't exist or that you're not using the parent (the movieclip containing the bullet-movieclip) to remove the movieclip.

  14. #14
    Junior Member
    Join Date
    Nov 2008
    Posts
    7
    Fixed rates do not work. What I need is an algorithm that properly sets the yspeed and xspeed so that the missile fires directly towards the spot the player was standing when it was fired and passes through it. Everything I have tried either undershoots or overshoots. It's becoming beyond aggravating.

    Sorry for the late reply, it's been a busy week.

  15. #15
    Funkalicious TOdorus's Avatar
    Join Date
    Nov 2006
    Location
    Nijmegen, Netherlands
    Posts
    697
    In that case. Learn vectors.

    You can calculate the angle towards the player and then calculate the x and y component of a speedvector in that direction. It's all pretty basic trigonometry. http://board.flashkit.com/board/showthread.php?t=782793

  16. #16
    Senior Member
    Join Date
    Oct 2008
    Posts
    120
    umm I have a fla of a project i started and never finished that might be exactly what you are looking for...

    it a mess but it works...

    want me 2 pm it to u?

    EDIT: I'm pretty damn sure its what you want lol.
    EDIT2: actually I don't really want to give away the games original idea, but I can post some code that your looking for(it's actually really simple lol). I'll edit the code in when I'm not busy.

    EDIT3:

    This is how I did it...
    So, lets say u have an enemy turret and doing its rotation like so:
    PHP Code:
          rad Math.atan2(_root.me._y-this._y_root.me._x-this._x);
        
    deg Math.round((rad*180/Math.PI));
        
    this._rotation deg 90
    me being the player...
    now when it fires a shot attach your shot mc with something like so:

    PHP Code:
    this._x _root.cTurret._x;
    this._y _root.cTurret._y;

    shotX=10*Math.sin(_root.cTurret._rotation*(Math.PI/180));
    shotY=10*Math.cos(_root.cTurret._rotation*(Math.PI/180));

    onEnterFrame = function()
    {
        
    this._x += shotX;
        
    this._y -= shotY;

        if(
    this.hitTest(_root.me))
        {
            
    removeMovieClip(this);
        }

    Worked perfectly for me. Hope it helps =P.
    Last edited by DeadRiver; 12-08-2008 at 11:55 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center