Does anyone have a good algorithm for generating a random y position for spawning a block, which takes into account a minimum and maximum height, allowing player to to jump on the block.

Blocks will continually be spawned, so the player must always be able to jump onto the next block, bearing in mind the minimum position which would be the ground, and the maximum which would the players jump height bearing in mind the ceiling

Blakey87 is obviously beginning game development, if you are going to cast a vote to close, write a comment as to why, don't just vote to close because it is easy.
–
AttackingHoboJun 23 '11 at 23:13

1

@AttackingHobo you are 100% correct and thanks, I come from a web based background (PHP), and this is my first time at trying to create a game, never used objective C before so everything is new to me, I dont normally ask for help but I thought why not
–
blakey87Jun 24 '11 at 7:56

1

@AttackingHobo I voted to close because the question basically asks for a way to get a random value between a given min and max, which is really trivial, as long as you figure out how to get a random value on your system (which is not the question). I think beginners questions are ok, but there's got to be a threshold. Also all the answers given don't provide a solution in plain Objective-C, so no real help there (assuming the OP is really totally new to Objective-C)
–
bummzackJun 24 '11 at 10:33

1

@bummzack: Generating a good random value between two numbers is actually something I see people do wrong very often; usually their results are either biased, or unnecessarily slow.
–
user744Jun 24 '11 at 18:12

2

@bummzack: There are two problems and you're conflating them - first, generating good random numbers. That's really hard. Second, generating good random numbers between two given values. That's not really hard, but people still screw it up a lot. (Duck's answer is biased, CaseyB's answer confuses noise and randomness, MrXee's answer is unbiased but unnecessarily slow.)
–
user744Jun 25 '11 at 12:26

6 Answers
6

You just have to generate some boundaries for the blocks you are going to make, maybe due to the last block or other limitations in your game; for example, if your game has some level of ground, no block should start below ground level. Having those parameters set, it's really easy to create a random number which has all the features you required.

In your game example: imagine a block starting at NewStartPositionY and ending at NewEndPositionY. We know GroundLevel is the ground height (you consider it as zero) and CeilingLevel is the ceiling height. A character might jump at most MaxJump units. Some other parameters might be PlayerHeight, which is the height of the character, and LastStartPositionY and LastEndPositionY which define the last block, and let's take MinimumBlockSize as the minimum size of platform. Knowing all these values you can set your boundaries :

Here is what the above code actually does; I just expanded it since it seems to cause many a headache! (It just needs more variables and does more operations but the result is the same.)

// -- first we define what are the boundaries of generated blocks
// it's obvious that no block can be under the ground level
MinimumBoundaryY = GroundLevel;
// we need to make sure player can jump over the new level
// and at the same time we have to make sure player can go over it
// and not hit the ceiling so we choose the minimum value from them both
MaximumBoundaryY = min(lastEndPositionY + maxJump, CeilingLevel - PlayerHeight)
// --now initialize startPosition of the Block
// we want the block to at least have `MinimumBlockSize` height
// so the start position should be somewhere between `minimumBoundaryY`
// and `MaximumBoundaryY - MinimumBlockSize`
StartYRange = MaximumBoundaryY - MinimumBoundaryY - minimumBlockSize;
// and now we a random value we assign the actual value of new StartPosition
newStartPositionY = random() % StartYRange + MinimumBlockSize;
// --now as the last part we have to calculate endPosition of the new block
// again we first calculate the range for endPosition value.
// note that end position should always be somewhere between
// `beginPositionY + MinimumBlockHeight` and `maximumBlockHeight` so the range well be
EndYRange = MaximumBoundaryY - newStartPositionY - MinimumBlockHeight;
// in the end just set the EndPosition of the Block, we now it's variation range
// and we know it's the minimum valid value is `beginPositionY + MinimumBlockheight`
NewEndPositionY = random() % EndYRange + newStartPositionY + MinimumBlockHeight;

Hope this second piece of code helps you all understand what my code does! (and change your downvotes to upvotes :D).

I don't understand why this was chosen as the accepted answer. Why do you generate two random values? Also your ys1 (which is the start position of the new block) can become bigger or smaller than ye1 (it can even end up with the same size). Your example does something... but it doesn't position a block randomly, so that it's reachable by the player.
–
bummzackJun 24 '11 at 14:53

2

@Gajet this seems incredibly complicated for what is a very simple idea..and your use of variable names is very confusing. I don't understand it.
–
The Communist DuckJun 24 '11 at 16:50

2

Use variables that are descriptive, not cryptic.
–
AttackingHoboJun 24 '11 at 17:03

1

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." — Martin Golding
–
KeeblebroxJun 24 '11 at 17:11

1

@Gajet, please check the revision history. It seems there was an edit collision and you might want to roll back the text, at least, to my version.
–
mmyersJun 27 '11 at 21:22

The easiest way to produce more satisfying results would be, rather than generate a height between ground_y and previousBlock_y + playerJumpHeight, generate a random value between previousBlock_y - playerJumpHeight and previousBlock_y + playerJumpHeight.

Of course, since we want to take ground_y and maxBlockHeight into consideration also, we really want to find a random value between max(ground_y, previousBlock_y - playerJumpHeight) and min(maxBlockHeight, previousBlock_y + playerJumpHeight). This will skew our distribution a bit (biased towards the center of the screen), but not enough to be noticeable.

If you then want the block to have a random height as well, just generate a random number between ground_y and block_y to be the height.

[Edit] There is a way to have a probability of jumping down by any amount, while still giving the player equal probability of being anywhere on the screen at any given point.

Thanks to Didier Piau on the math forums for figuring this out. The full explanation is complex, so I'll leave it out; the curious can visit that page, from which I generalized this algorithm. The algorithm itself is actually pretty simple, though.

random() % m produces non-uniform results. For a game it probably doesn't matter too much; on the other hand for a game the system rand()/random() functions may not be acceptable, and as long as you're going to deal with that you might as well do this part right too.
–
user744Jun 24 '11 at 18:30

1

Since the OP is asking for Objective-C I'd suggest arc4random as the random function.
–
bummzackJun 24 '11 at 21:35

1

-1 I think OP wanted both a random height off the ground AND a random block-height. Even if he didn't, this will not work - it will always produce a value between g and 2*g + jumpHeight. And even if you fixed it to be say what I assume you meant (m = previousBlockHeight + jumpHeight), it would still produce unsatisfying results - it would be heavily biased towards generating blocks near the ground, meaning the character would rarely be near the top of the screen.
–
BlueRaja - Danny PflughoeftJun 24 '11 at 22:35

Same problem as @Communist Duck's answer, will generate blocks that are heavily biased towards the bottom of the screen - being near the top of the screen would be rare, especially if playerJumpHeight is small.
–
BlueRaja - Danny PflughoeftJun 24 '11 at 23:09

@BlueRaja-DannyPtflughoeft: he has some value for his height min value. it makes his answer diffrent from the one CommunistDuck gave and more similar to mine. just by changeing heightMin in each cycle he will get out of hook.
–
Ali.SJun 26 '11 at 20:28