Posted: 9th Oct 2011 0:02
I've found a need for some commands to return screen locations from particular sprite pixels...

These would come in handy if possible...

float GetScreenXFromSpritePixel(iSpriteIndex, iSpriteImageX, iSpriteImageY)

float GetScreenYFromSpritePixel(iSpriteIndex, iSpriteImageX, iSpriteImageY)



iSpriteIndex - The ID of the sprite to check.

iSpriteImageX - The x pixel of the sprite's image to check.

iSpriteImageY - The y pixel of the sprite's image to check.


The idea is to return the exact screen location under a particular pixel on a sprite.

I've found a need for this when trying to accurately place sprites at specific locations on sprites that have dynamically changing angles, that are not using physics.
Posted: 9th Oct 2011 5:57
Does anyone else wish to see these commands, they seem a little long to me also would these commands respond with the correct location if the sprite was stretched, rotated and offset? I personally can see a few uses of such a command (firing spot and exhaust spot on a ship, e.t.c.) and would replace some fiendish calculations that would otherwise be written in code. We are soon to look at adding a few extra commands to AppGameKit in the next few weeks, so your input on whether these commands make the grade (or better command suggestions) would be most welcome.
Posted: 9th Oct 2011 13:34
I would love to have the option to have some kind of bitmap in memory (non displayable) where we can paste sprites, draw single pixels, and hence build graphics, and then a command to grab parts of the screen as a sprite!
Posted: 9th Oct 2011 16:04
would these commands respond with the correct location if the sprite was stretched, rotated and offset?


I see your point - stretching, rotating and offsetting the image would all change the pixels location on the sprite.

Let me revise this to a more precise approach.


float GetScreenXFromSpriteXY(iSpriteIndex, fSpriteX, fSpriteY)

float GetScreenYFromSpriteXY(iSpriteIndex, fSpriteX, fSpriteY)



iSpriteIndex - The ID of the sprite to check.

fSpriteX - The percentage based x of the sprite to check.

fSpriteY - The percentage based y of the sprite to check.


Using fSpriteX and fSpriteY as percentage based sprite space locations in place of image pixels, will return an exactly precise location, even if you put the sprite through an industrial strength blender!.

It also has the added benefit of making the commands SHORTER!
Posted: 10th Oct 2011 0:11
I decided to see if I could figure out the math and wrote the functions.

I'm going to have to agree with you Lee, they were...

some fiendish calculations


I accounted for display aspect, rotation, resizing etc.

I'm releasing them here for the community. Everyone feel free to use the code as you wish.

I'd still like to see them added as commands


EDIT: Found a problem going to solve it and re-post the code later.
Posted: 10th Oct 2011 0:16
Hey there, I'm not sure that this is exactly what you want, but I've been planning for a game that me and my wife had in mind and we needed something similar to what you mentioned.

However I took a different approach, for the sake of calculations instead of trying to specify the exact x,y coordinates of the parent sprite I'm using a more trigonometrical approach, so what I do is, considering that the child sprite (the one that we will move according to the parent one) will have to obey angles and scaling according to the parent I assume that it will move in an imaginary circle inside the parent sprite.

Instead of saying that the child sprite will be in the x,y point of the parent I say that it will be in a circle that is x pixels away (basically the radius) from the center of the parent sprite.

I don't cater for sprites where you changed the default offset but I guess that it could easily be taken into account.

The functions go like this :

+ Code Snippet
function GetScreenXFromSpritePixel(spriteid, spriteAngle, angleOffset, radius, spriteOffset, scaleFactor#)
    //thix auxiliary x insures the small square will rotate
    //around the center of the big square
    AuxX# = GetSpriteX(spriteid) + (GetSpriteWidth(spriteid)/2)
    //heres comes the trigonometry bit, we define the points where
    //the small square stands as all that belong to a circle
    //around the center of the big square with a certain radius
    //the radius gets multiplied to the scale factor for obvious reasons
    //we add an angle offset in degrees to the current angle of the big square
    //because we need to take into account the offset of the
    //placement of the initial location of the small square inside
    //the big one
    trigoX# = (AuxX#) - (Cos(spriteAngle+angleOffset)*(radius*scaleFactor#))
    //here we remove, or add if value is negative, a certain offset size of the small square to ensure
    //which pixel from the small square gets to belong to the points of the
    //imaginary circle, again we take the scale factor into consideration
    coordX# = trigoX# - spriteOffset*scaleFactor#
endfunction coordX#

function GetScreenYFromSpritePixel(spriteid, spriteAngle, angleOffset, radius, spriteOffset, scaleFactor#)
    AuxY# = GetSpriteY(spriteid) + (GetSpriteHeight(spriteid)/2)
    trigoY# = (AuxY#) - (Sin(spriteAngle+angleOffset)*(radius*scaleFactor#))
    coordY# = trigoY# - spriteOffset*scaleFactor#
endfunction coordY#


The parameters are this :

spriteid - id of the parent sprite
spriteAngle - current angle of the parent sprite
angleOffset - this is the angle at which the child sprite will be placed, just remember that for AppGameKit 0 degrees is located where 180 degrees would be in an ordinary trigonometrical circle and then it counts clockwise
radius - the distance that the child sprite will be from the center of the parent sprite
spriteOffset - this can be used to adjust the location of the child sprite, you can use it to place the center of the child sprite at the rotation point
scaleFactor# - the scale that was used for the parent sprite in SetSpriteScale

Download the code if you want and try it out, maybe it will help you or at least point you in the right direction.
Posted: 10th Oct 2011 0:18
Oh by the way, I forgot to write, although you will see it in the code, pressing the left mouse button will rotate the parent square and the keys wasd will move it around the screen.
Posted: 10th Oct 2011 0:20
Eheh as soon as I posted I saw your solution, my post will take a while because I'm still on probation. Good work
Posted: 10th Oct 2011 1:52
Okay, I made a couple of updates to the functions and updated their usage in the comments.

I had to account for offsets changing the rotation point. In my absent mindedness I was only testing with a 0,0 offset.

Anyway here are the updated functions, enjoy...

+ Code Snippet
function GetScreenXFromSpriteXY(iSpriteIndex, fSpriteX#, fSpriteY#)

`fSpriteX# and fSpriteY# should be passed as a percentage of the distance to the edge of the sprite from the offset point.
`In otherwords if your sprite is rotating around its center (50,50) and you wanted to return the screen location under 0,0
`on the sprite, you would pass (-100, -100) into the function because 0,0 is negative 100 percent of the distance from the
`offset point to the sprite edge in both x and y.

`Note that if your offset point is 0,0 - Passing (100, 100) into the function returns the bottom right corner of the sprite.
`The distance to the edge is relative to the offset point and always totals 100 percent.

`The return value is a float

fSpriteY# = fSpriteY# / GetDisplayAspect()

SpriteX# = GetSpriteXByOffset(iSpriteIndex)
SpriteY# = GetSpriteYByOffset(iSpriteIndex)

SpriteAngle# = GetSpriteAngle(iSpriteIndex)


OffsetAmountX = (GetSpriteXByOffset(iSpriteIndex) - GetSpriteX(iSpriteIndex))
OffsetAmountY = (GetSpriteYByOffset(iSpriteIndex) - GetSpriteY(iSpriteIndex))


DistanceX# = (GetSpriteWidth(iSpriteIndex) - OffsetAmountX) * (fSpriteX# / 100)
DistanceY# = (GetSpriteHeight(iSpriteIndex) - OffsetAmountY) * (fSpriteY# / 100)

angle#= (SpriteAngle# + 90) + ATANFULL(DistanceX#,DistanceY#)

`These are not the droids you're looking for (err ANGLES! I mean ANGLES!)
if angle# + 180 >= 360
angle# = ABS(360 - (angle# + 180))
else
angle# = ABS(angle# + 180)
endif

TheDistance# = sqrt ((DistanceX# * DistanceX#) + (DistanceY# * DistanceY#))

GetCosine# = COS(angle#) * TheDistance#
GetSine# = SIN(angle#) * TheDistance# * GetDisplayAspect()

ScreenX# = SpriteX# + GetCosine#
ScreenY# = SpriteY# + GetSine#

endfunction ScreenX#



function GetScreenYFromSpriteXY(iSpriteIndex, fSpriteX#, fSpriteY#)

`fSpriteX# and fSpriteY# should be passed as a percentage of the distance to the edge of the sprite from the offset point.
`In otherwords if your sprite is rotating around its center (50,50) and you wanted to return the screen location under 0,0
`on the sprite, you would pass (-100, -100) into the function because 0,0 is negative 100 percent of the distance from the
`offset point to the sprite edge in both x and y.

`Note that if your offset point is 0,0 - Passing (100, 100) into the function returns the bottom right corner of the sprite.
`The distance to the edge is relative to the offset point and always totals 100 percent.

`The return value is a float


fSpriteY# = fSpriteY# / GetDisplayAspect()

SpriteX# = GetSpriteXByOffset(iSpriteIndex)
SpriteY# = GetSpriteYByOffset(iSpriteIndex)

SpriteAngle# = GetSpriteAngle(iSpriteIndex)

OffsetAmountX = GetSpriteXByOffset(iSpriteIndex) - GetSpriteX(iSpriteIndex)
OffsetAmountY = GetSpriteYByOffset(iSpriteIndex) - GetSpriteY(iSpriteIndex)

DistanceX# = (GetSpriteWidth(iSpriteIndex) - OffsetAmountX)  * (fSpriteX# / 100)
DistanceY# = (GetSpriteHeight(iSpriteIndex) - OffsetAmountY) * (fSpriteY# / 100)

angle#= (SpriteAngle# + 90) + ATANFULL(DistanceX#,DistanceY#)

`These are not the droids you're looking for (err ANGLES! I mean ANGLES!)
if angle# + 180 >= 360
angle# = ABS(360 - (angle# + 180))
else
angle# = ABS(angle# + 180)
endif

TheDistance# = sqrt ((DistanceX# * DistanceX#) + (DistanceY# * DistanceY# ))

GetCosine# = COS(angle#) * TheDistance#
GetSine# = SIN(angle#) * TheDistance# * GetDisplayAspect()

ScreenX# = SpriteX# + GetCosine#
ScreenY# = SpriteY# + GetSine#

endfunction ScreenY#






Download the code if you want and try it out, maybe it will help you or at least point you in the right direction.


Hey there Pedrolbs,

It looks like we were going for similar results with different approaches. It looks like your passing more values into the functions.

I hadn't accounted for offsets on my first draft, but quickly discovered the problem when I went to use it on an offset sprite. I think I've got it all working now.

Thanks for the post
Posted: 15th Oct 2011 6:07
If you would care to post this nifty 'GetScreenYFromSpriteXY' code as a feature request in the issues board, it might come in during our next command update: [href]null[/href]