Let's say we have a simple game where you run and jump, with every successful jump over an object you get 1 point. Now... I want to make it so you as a player get a little faster every 10 points, but i don't want to make it like you get faster at 10 then 20, 30 etc... because that would be too much copying of code and i totally don't have the mood to make it up to 1000+, i want some short or long code which will make it automatically every 10 points.
Speeding up every 10 points
Root / Programming Questions / [.]
ChaseCZCreated:
WHILE 1 'Main loop IF POINTS% MOD 10 == 0 THEN INC SPEED 'Game stuff VSYNC WEND
The modulus function (MOD) finds the integer remainder of a division. So, by asking in the IF statement whether POINTS MOD 10 is equal to zero, you find out when your POINTS is completely divisible by 10, because any multiple of 10 divided by 10 yields a remainder of zero.
This works for values other than 10 as well.
Oh yeah forgot to mention that.
While this simple solution looks like it would work at a glance, it might not function the way you would expect or want it to. Let's see why.WHILE 1 'Main loop IF POINTS% MOD 10 == 0 THEN INC SPEED 'Game stuff VSYNC WEND
- 1. Acceleration may occur erratically. Since the code says to increase speed if the points are at a number evenly divisible by 10, when the condition is satisfied, the speed will continue to increase until the next point is gained. This means that if you have randomly generated spaces between jumps, the speed will increase further.
- 2. If you start with 0 points, the game will immediately crash upon executing this code. The modulo operator is just a glorified dividing operator that returns the remainder. Because you cannot divide by zero, you cannot get the remainder of a number divided by zero.
WHILE !. 'one day you'll understand, lad IF POINTS > 9 && !(POINTS MOD 10) THEN INC SPEED 'game logic VSYNC WENDThe reason why this doesn't crash the program is because SB is lazy, and won't even try to check conditions past a false one. The reason why I put POINTS > 9 instead of POINTS > 0 is because it cuts down on a tiny tiny fraction of time dedicated to MOD, while it doesn't need it. Next, we'll need to make the code execute upon the first frame of the point gained. Maybe you want to gradually increase speed, but over a set amount of time. To do this, we can use a special variable to hold a framecount gathered from MAINCNT to see when the 10th point was gained, and work from there.
WHILE !. 'one day you'll understand, lad IF POINTS > 9 && !(POINTS MOD 10) THEN IF !TENCNT THEN TENCNT = MAINCNT IF MAINCNT-TENCNT < 20 THEN INC SPEED, 0.2 ELSE TENCNT=0 ENDIF 'game logic VSYNC WENDHere, we set TENCNT to 0 while not being used to signify that it hasn't been used yet. While it is being used (for 19-20 frames), we increase the speed slowly. Fin. That's probably all you need. Have a wonderful day. <(°< ° )>
Actually, we're not dividing by zero here. We are asking whether POINTS divided by 10 yields a remainder, not 10 divided by POINTS. However, you were right about the sporadic acceleration, especially at 0. Therefore, you want to check the POINTS MOD 10 condition only when you have an increase in points AND points is not 0. To do this, I would suggest sticking the increase of speed code into the same block responsible for increasing points. The code may look like this...
- 2. If you start with 0 points, the game will immediately crash upon executing this code. The modulo operator is just a glorified dividing operator that returns the remainder. Because you cannot divide by zero, you cannot get the remainder of a number divided by zero.
WHILE TRUE IF(PlayerGetsAPoint)THEN INC POINTS IF (POINTS) && (POINTS MOD 10 == 0) THEN INC SPEED ENDIF 'Rest of code WEND
There's another problem though.
If the number of points increases by more than one at a time, it might skip a multiple of 10.
A safer solution might be something like:
NEXTINCREASE=10 WHILE 1 'main loop ... WHILE POINTS>=NEXTINCREASE INC NEXTINCREASE,10 INC SPEED 'do other things WEND ... WENDYou could simplify this is you just want to increase speed by 1 per 10 points, and don't want to play a sound, or animation, or anything else when this happens:
WHILE 1 ... SPEED=ORIGINAL_SPEED + (POINTS DIV 10) ... WEND
Maybe something along the lines of this would work?
VAR SCORE=0 VAR NEXT_TEN=1 VAR SPEED=4 VAR ACCELERATION=.2 'REWARD THE PLAYER 'P' POINTS (OR TAKE AWAY IF P IS NEGATIVE) DEF REWARD P IF ABS(P)==P THEN WHILE SCORE+P>NEXT_TEN*10 INC NEXT_TEN INC SPEED,ACCELERATION WEND ELSE DEC SCORE,P ENDIF END WHILE 1 'GAME LOGIC WENDhere's a simpler one:
VAR SCORE=0 VAR HSCORE=0 VAR ACCELERATION=.2 VAR SPEED=4 DEF REWARD P IF P<0 THEN DEC SCORE,P ELSE INC SCORE,P HSCORE=MAX(SCORE,HSCORE) SPEED=INT(HSCORE/10)*ACCELERATION ENDIF END WHILE 1 'GAME CODE HERE WEND
Ooh right those problems. Thanks for bringing them up
Oh my goodness.
SPEED% = BASESPEED% + POINTS% / 10
Huh that works.
MOD is a fancy division function and it shows up several times in this thread so why not.Oh my goodness.Is DIV preferred here?SPEED% = BASESPEED% + POINTS% / 10