Okay so my idea might seem a little complicated... but I'll try to make it simple.
I'm assuming you don't have fixed levels here, and you just have unending waves of enemies that you keep track of (higher wave number = further along in the game the player is). If I'm wrong and you do have levels, then this is even easier and you can just use "levels" instead of "waves" as outlined below.
My idea is basically this:
1) Assign each enemy one or more 'natural' waves. IE: the wave they occur most frequently on.
2) The further away you are from that enemy's natural wave(s) (in either direction), the less likely that enemy is to appear.
3) Assign some other kind of "spread" value that indicates how far away from the natural wave you can be before the enemy frequency starts dropping off. IE, say for example the natural wave for an enemy is wave 10. If you assign a spread of 1, then the enemy will be extremely rare before wave 8 or after wave 12. But with a spread of 5, they will be seen frequently between waves 1-20.
4) In statistical terms... the "natural wave" is the mean... and the "spread" is the standard deviation. It effectively creates a bell curve of where the enemies will appear.
5) The tricky part (that I don't really know how to do), is to get a % chance based on that mean/stddev. IE, if your mean is wave 10, and you have a spread of 1.... then you'll have a 36% chance of it appearing on wave 10, but only a 25% chance of it appearing on wave 9, and like a 2% chance of it appearing on wave 8 (note: I'm pulling these percentages out of my ass, I have no idea what they are in reality -- that's the thing I can't figure out how to calculate). I posted another thread asking how to do this but no response yet:
http://www.cplusplus.com/forum/lounge/159133/
Anyway, let's call this percentage 'X'. In theory you should be able to calculate X from the following info:
-- mean (natural wave)
-- stddev (spread)
-- current wave the player is on
6) Once you have X for all possible enemies, you normalize them (IE, adjust them linearly so the sum of all percentages is 100%). Example, on wave 2:
-- Slimes have a 36% chance
-- Rats have a 10% chance
-- Wolves have a 1% chance
Sum of all enemies' X = 47%. Normalize that to 100%: N = 100/47 = 2.128. So multiply each X value by N:
-- Slime: 36 * 2.128 = 76.6%
-- Rats: 10 * 2.128 = 21.3%
-- Wolves: 1 * 2.128 = 2.1
(total) = 100%
|
7) Generate a random real number between [0,1) and use it to pick a enemy based on their appropriate percentages.
IE, if you get [0 , 0.766), you get a slime
if you get [0.766 , 0.979), you get a rat
if you get [0.979 , 1.0), you get a wolf
Again this might be unnecessarily complicated, but it is probably how I would approach this problem.
EDIT:
Okay so instead of using mean/stddev, you can create a bell curve with a sine wave to get 'X' for step 5.
This will create a more sudden dropoff, but should create a similar effect:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
// 3 values:
// natural = the enemy's natural wave (IE, where they appear most frequently
//
// spread = the spread. In this implementation, it is the 'endcap' of where the enemy can appear.
// so for example, if natural=10 and spread=5, then the enemy will only appear on waves 5-15
// (being more common the closer you are to wave 10)
//
// curwave = the wave the player is currently on
double distance = natural - curwave; // First, see how far the player is from the natural wave
distance /= spread*2.0; // Then normalize that value so it is between -0.5 and +0.5
distance += 0.5; // and ultimately between 0 and 1
// make sure it's in bounds
if(spread <= 0) return 0;
if(spread >= 1) return 0;
// use sine() as a bell curve generator (not ideal, but whatever)
return std::sin( spread * 3.14159 );
|
That code will get you 'X' as described in step 5.