Author Topic: detect sprite in range  (Read 3832 times)

Tanja

  • Clever
  • Fanatic
  • ***
  • Posts: 606
    • View Profile
detect sprite in range
« on: 2008-09-05, 04:33:39 AM »
durnurd made once this useful ShootInRange-sprite, which detects the player when inside a certain range. i would like to make more sprites than that, but i don't get the used code functions entirely. could someone explain me what the functions do and what all the expressions mean? i mean, i KNOW somehow what they do, but i fail in customize them. simple and plain english please?

Code: [Select]
// Get Nearest Player Sprite
         playerIdx = this.GetNearestSpriteIndex(ParentLayer.m_SpriteCategories.Player);

// If in range horizontally
            if (((((System.Math.Abs(this.x-(ParentLayer.m_SpriteCategories.Player[playerIdx]).x)) < (HorizontalRange))
                     && ((System.Math.Abs(this.y-(ParentLayer.m_SpriteCategories.Player[playerIdx]).y)) < (SolidHeight*2)))
                     && ((System.Math.Sign(state*-2+1)) == (System.Math.Sign(x - (ParentLayer.m_SpriteCategories.Player[playerIdx]).x)))))

so is the parameter HorizontalRange supposed to be 0? if i increase this number, will the range get bigger?
(unfortunately, i inserted the sprite, but i won't shoot  :(  i downloaded the sprite template again and inserted it into the sample project, but it isn't working here anymore)

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: detect sprite in range
« Reply #1 on: 2008-09-05, 05:28:01 AM »
HorizontalRange should be the number of pixels that the player is offset from the enemy horizontally.  If the player is within this range, the enemy will shoot, otherwise not.  (This is a rule that is applied on the enemy sprite's rules.)  So that means "this.x" refers to the horizontal location of the enemy sprite and "ParentLayer.m_SpriteCategories.Player[playerIdx].x" refers to the horizontal location of the sprite in the "Player" category that is nearest to this enemy (as calculated with GetNearestSpriteIndex).

It appears that this code also checks that the enemy sprite is facing the correct direction with "System.Math.Sign(state*-2+1)" to make sure that the enemy is facing the player before deciding to shoot.  I think this assumes that state #0 is facing left and state #1 is facing right:
Left: 0*-2+1 = 1, (Sign(1) = 1)
Right: 1*-2+1 = -1 (Sign(-1) = -1)

Player to the left of this: x - (some number smaller than x) = +n, (Sign(+n) = 1)
Player to the right of this: x - (some number larger than x) = -n, (Sign(-n) = -1)

Does that make any sense?

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: detect sprite in range
« Reply #2 on: 2008-09-05, 07:43:33 AM »
That just about covers it, yeah.  The second line:
((System.Math.Abs(this.y-(ParentLayer.m_SpriteCategories.Player[playerIdx]).y)) < (SolidHeight*2)))
checks to see if the sprite is within range vertically as well, otherwise, you could be at the top of the map and the enemy at the bottom and it would still try to shoot you.
It's checking to ensure that it's within a certain vertical area based on the enemy's height.  In this case, (height of the enemy * 2) in either direction:
Code: [Select]
----
o  \
o    \
o     > E
o    /
o  /
----
Edward Dassmesser

Tanja

  • Clever
  • Fanatic
  • ***
  • Posts: 606
    • View Profile
Re: detect sprite in range
« Reply #3 on: 2008-09-05, 10:42:29 AM »
okay then.
playerldx stores only the index of the nearest player sprite.
System.Math.Abs makes whole numbers out of floating-point numbers.

after long thinking about this whole  Left: 0*-2+1 = 1, (Sign(1) = 1)  thing i believe i understand it. yeah. a calculation only to compare two numbers. but why do need the two functions to be inside a System.Math.Sign?

hey bluemonk, couldn't you make this a standard rule somehow?
there could be a dropdown box, where one could chose which state would be the "left state" and which one the "right state". there would be no mess if someone had his left/right state at the end of the states or in the middle. after some time one would maybe like to change the state order for some reason.

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: detect sprite in range
« Reply #4 on: 2008-09-05, 05:32:32 PM »
System.Math.Abs doesn't do what you think it does.  It converts all numbers to their positive values.  Abs(-4) == 4.  Abs(-3.7) == 3.7.  Abs(5.9) == 5.9

The Sign(1) portion doesn't necessarily need to have the Sign() function, but if one wanted to rewrite the function such that the first N states were facing left and the next N states were facing right, it would be necessary to use the Sign function:

Left: [0,N-1]*-2-1+2N = [2N-1,1], (Sign([2N-1,1]) = 1)
Right: [N,2N-1]*-2-1+2N = [-1,-2N+1], (Sign([-1,-2N+1]) = -1)
Edward Dassmesser

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: detect sprite in range
« Reply #5 on: 2008-09-06, 08:50:02 AM »
hey bluemonk, couldn't you make this a standard rule somehow?
there could be a dropdown box, where one could chose which state would be the "left state" and which one the "right state". there would be no mess if someone had his left/right state at the end of the states or in the middle. after some time one would maybe like to change the state order for some reason.

I suppose anybody could make a "CanSeePlayer" rule like this.  But you would also need to specify a sprite category that contains all the players.  Maybe a better name would be "CanSeeSpriteInCategory" because it wouldn't necessarily have to be a player sprite.  To be more general purpose, it should probably also be able to return information about which sprite it can see so that you can use a rule that targets that specific sprite if the sprite can see someone.  Unfortunately, I think there aren't enough parameters for that.  What probably makes more sense is to provide a pre-made sprite template that knows how to react to players (or other sprites) so the designer doesn't have to deal with all the parameters and states.  Such a sprite would probably want to rely on a function like this, though.  Then I could probably make some assumptions about states and eliminate the state parameters (like assume that all odd numbered states are facing rightward).  Until I get a chance to provide such a function, my excuse is that Mario didn't do it, so I didn't do it :).  (I don't think Mario has things that only shoot when they can see you does it?  Mario hardly has anything that shoots period... and when they do, they name the bullets "Bill" ;))

v6v

  • Clever
  • Fanatic
  • ***
  • Posts: 500
  • Has renamed his project to Galaxy!
    • View Profile
    • My Developer Page!
    • Email
Re: detect sprite in range
« Reply #6 on: 2008-09-06, 11:10:54 AM »
For Mario, well, he had these enemies called boos, if I'm not mistaken...
When you see them , the hide, but when you turn away, they attack...

Sonic, however, has something more rellevant to what you're talking about...
If he sees and enemy on screen and you press the jumping button twice,
he charges at it...

For my sonic game, I've altered that- ( I was too lazy to figure out how to do that at the time)
It's a sonic game fused with a mario game. I can figure out how to do the boos... but....

I might need some tips on that "sonic charging thing" I stated earlier.
Or... am I posting this in the wrong topic? ???

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: detect sprite in range
« Reply #7 on: 2008-09-07, 06:45:49 AM »
Seems like this code would be exactly what you need, except it would be applied to the player sprite instead of an enemy, and instead of shooting, the player would automatically charge forward if the expression returned true.