Posted: 4th Sep 2011 14:36
Undoutedly it's something I'm doing (again!)

Anyway, I'm using GetSpriteInCircle to ensure that the player doesn't spawn inside another sprite.

I'm making the call as follows:
+ Code Snippet
    Repeat
        // pick a random position
        newX = Random(0, (GetDeviceWidth()-(GetSpriteWidth(RFS_player.cloneID)*2)) + GetSpriteWidth(RFS_player.cloneID))
        newY = Random(0, (GetDeviceHeight()-(GetSpriteHeight(RFS_player.cloneID)*2)) + GetSpriteHeight(RFS_player.cloneID))

        safe = RFS_spawnCheck(newX, newY, GetSpriteHeight(RFS_player.cloneID)*2)
    Until safe = RFS_TRUE

So this should keep picking random positions until the function RFS_spawnCheck returns RFS_TRUE (a constant set to 1).

The function looks like this:
+ Code Snippet
Function RFS_SpawnCheck(xPos, yPos, radius)
    For i = 0 to 26
        If GetSpriteExists(RFS_rocks[i].cloneID)
            If GetSpriteInCircle(RFS_rocks[i].cloneID, xPos, yPos, radius) = 1 Then ExitFunction RFS_FALSE
        EndIf
    Next i
EndFunction RFS_TRUE

It basically loops through all of the rocks, and if there's one inside the circle, it exits the function so another position can be chosen.

However it seems that sometimes the results are ignored and I end up spawning inside a rock. I've tried some debug stuff inside the RFS_spawnCheck function, but occaisonally that gets ignored too.

Not sure what's going on, but any advice would be greatly appreciated.
Posted: 4th Sep 2011 15:56
Function RFS_SpawnCheck()

blah
blah
blah

EndFunction RFS_TRUE


Shouldn't that be ...

EndFunction RFS_SpawnCheck

Posted: 4th Sep 2011 18:33
ndFunction RFS_SpawnCheck

No, because RFS_TRUE is the value that the function passes back. You don't need to specifiy the name of the function at the end.
Posted: 4th Sep 2011 22:02
Sorry, it was too early in the morning when I looked at it .

You did remember to make that variable Global, right?
You need to use a separate line for that too.

This works...
Global RFS_TRUE
RFS_TRUE = 1


This won't work...
Global RFS_TRUE = 1
Posted: 5th Sep 2011 0:13
RFS_TRUE and RFS_FALSE are constants, so yes, they're global. But it doesn't make any difference if I replace them with 1 and 0 respectively - I still spawn inside a rock every now and then.
Posted: 5th Sep 2011 1:16
Only thing I can think of might be your radius. Not sure how big the player sprite height, is but your checking a circle about 4 times bigger then the player. What size are the rocks?
Posted: 5th Sep 2011 10:50
Only thing I can think of might be your radius. Not sure how big the player sprite height, is but your checking a circle about 4 times bigger then the player. What size are the rocks?

I've tried all sorts of values.

I'm going to code up a little function to draw a circle of 1x1 sprites around the player so I can see exactly how far the circle check extends around the player.

The only thing I can think of is that it isn't as big as I think it is.
Posted: 5th Sep 2011 11:25
Ignore this post - I made a typo in my circle function. It's now centered on the player properly.

Time for some testing.
Posted: 5th Sep 2011 13:57
Right, so the circle below is centered on the player and has a radius of playerheight*2.



GetSpriteInCircle is called using the same information, and as you can see, the player has appeared with a rock inside the circle. This shouldn't happen.

So either there's a but in GetSpriteInCircle, or something odd is happening when it's working out the radius. Unfortunately with no way of being able to see the circle that GetSpriteInCircle is using, I'm a bit stuck at trying to debug this.
Posted: 6th Sep 2011 13:16
I'm still struggling with this, and it's pretty much the only thing holding me back from finishing.

I think I'm just going to give up with it and make the player invincible for a second or two when they appear.
Posted: 7th Sep 2011 0:35
The invincibility thing doesn't feel right for the game. Looks like my final step is raycasting around the player to see if I get a collision back.

If anyone has time, would you mind trying to code up a quick demo using GetSpriteInCircle to see if it works for you?
Posted: 7th Sep 2011 0:50
I did notice that the rock was entirely inside the circle. I'm guessing the condition is true if the rock is touching the circle's edge line.

I would do this by using a sprite with the image of a circle. Set it small so it's just about the size of the ship. Set it's physics type to kinematic, then scale it's size up until you reach the size of area you want clear around the ship. That should shove the rocks nearby out of the way. (in theory..)
Posted: 7th Sep 2011 10:41
Why not write up a get_distance function to check the distance between the ship and asteroids? If you use the distance formula in theory it should check if a sprite is within a circle because it doesn't matter where the asteroid(s) are in relation to the ship, so long as the distance is large enough the ship can spawn. That's how I would do it.
Posted: 7th Sep 2011 17:27
Yup, that would be better.
Posted: 7th Sep 2011 18:21
Right, well I've used GetSpriteInCircle, SpriteRayCaste, and GetSpriteDistance. I've also written my own code for overlapping circle collisions, and distance checks.

In every case the player can spawn too close to the rocks.

I can only guess that the problem must be in how I'm returning information from the detection function. There's only so much you can do with print statements to try and figure out where the problem is, but that's about the only thing I haven't really changed.

ExitFunction is not highlighted in the IDE, but it is listed in the docs, and I'm using it in other parts of my code without apparent problem.

I'm wondering if, because I'm using it inside a loop, it's just bailing out of the loop rather than the function, so I'm getting the wrong value returned.

Just to clarify, the detection code should be called until it returns RFS_TRUE indicating the player is at least the minimum distance away from all rocks.

here's my calling code:
+ Code Snippet
    safe = RFS_FALSE
    // if we spawn to close to a rock, pick a new position
    Repeat
        // pick a random position
        newX# = Random(GetSpriteWidth(RFS_player.cloneID), GetDeviceWidth()-GetSpriteWidth(RFS_player.cloneID))
        newY# = Random(GetSpriteHeight(RFS_player.cloneID), GetDeviceHeight()-GetSpriteHeight(RFS_player.cloneID))
        SetSpritePositionByOffset(RFS_player.cloneID, newX#, newY#)

        safe = RFS_SpawnCheck(RFS_player.cloneID, GetSpriteHeight(RFS_player.cloneID)*2.0)
    Until safe = RFS_TRUE


And here's my detection code:
+ Code Snippet
Function RFS_spawnCheck(spriteID, distance#)
    For i=0 to 26
        if GetSpriteExists(RFS_rocks[i].cloneID) = 1
            If GetSpriteDistance(spriteID, RFS_rocks[i].cloneID) < distance# Then ExitFunction RFS_False
        EndIf
    Next i
EndFunction RFS_TRUE
Posted: 7th Sep 2011 23:25
Apparently the GetSpriteDistance command uses up a bit of performance so just keep an eye on your game's performance when testing on mobile devices.

You might be right about the exitfunction bit (I haven't tested it myself) so try this:
+ Code Snippet
Function RFS_spawnCheck(spriteID, distance#)
    local RFS_SpawnTrue as integer
    RFS_SpawnTrue = RFS_True
    For i=0 to 26
        if GetSpriteExists(RFS_rocks[i].cloneID) = 1
            If GetSpriteDistance(spriteID, RFS_rocks[i].cloneID) < distance# Then RFS_SpawnTrue = RFS_False
        EndIf
    Next i
EndFunction RFS_SpawnTrue

I haven't been able to test this however but I'm 90% sure it will work as expected.
Posted: 8th Sep 2011 0:19
Apparently the GetSpriteDistance command uses up a bit of performance

Not bothered about performance at the moment, I just want it to work right!

I'll have another play with it tomorrow and see what I can come up with.
Posted: 8th Sep 2011 3:00
To see if your calling code is the problem, you could make your detection code always return false. Then, when you get stuck in an endless loop, you know it is working

Hopefully AppGameKit will get some propper debugger support in the future, since that would probably make life considerably easier.