Took me like 7 tries before I realized that the "stars" weren't collectible items but instead they were spikes.
Code structure looks good. The only thing is, and this just might be personal preference, the comments aren't indented with the rest of the code. So for me that throws things off a little bit when I'm trying to scan the code quickly.
titleScreen
Instead of calling
wait 400, it's probably better to display a counter to the user letting them get prepared to start. Like have a big number displayed counting down from 5 or something then GO! Providing feedback to the user is always better than sitting silently in the dark (even it is only .4 seconds).
createObjects
I see you duplicate a lot of the same sprites. An alternative would be to create a single sprite for platforms then use
paste sprite. Build an array of platform locations, then every sync you would draw the sprite at those position. You could even skip using the sprite altogether and just use
paste image as well but then you'd need to handle the collision manually.
positionObjects
Definitely needs work. Even though it's not likely to happen, theoretically speaking these loops could be infinite. Because the completion of the loop is dependent on random values not overlapping, there is no finite state to end the loop.
Quote: "-After space bar is pressed to start the game, the game goes to a black screen but does not draw the game sprites or start the game. Application must then be re-launched."
This is one possibility that can be related to the above issue.
moveObjects
This whole thing can be a lot more efficient. You have a lot of redundant subroutines that would benefit from creating functions instead. To fix that, I had to change how you track your data.
Here would be the updated code for creating the platform objects and building the initial array. A single array to store all platforms.
#CONSTANT IMG_PLATFORM = 4
type Platform_Object
id as integer
x as integer
y as integer
endtype
dim platforms(10) as Platform_Object
createObjects:
REM - Creates platform sprites.
for i = 1 to 10
rem use sprite IDs 11-20
platforms(i).id = i + 10
sprite platforms(i).id, 0, 0, IMG_PLATFORM
next i
return
Now remember all that code you had for the
moveObjects routine?
moveObjects:
refactorPlatforms(1, 5, 400)
refactorPlatforms(6, 10, 200)
RETURN
function refactorPlatforms(rangeA, rangeB, y_constant)
for i = rangeA to rangeB
dec platforms(i).x, 10
sprite platforms(i).id, platforms(i).x, y_constant, IMG_PLATFORM
if platforms(i).x < -200
platforms(i).x = rnd(1000) + 900
repeat
clearFlag = 1
for j = rangeA to rangeB
if i <> j
if sprite collision(i, j)
platforms(i).x = rnd(1000) + 900
sprite platforms(i).id, platforms(i).x, y_constant, IMG_PLATFORM
clearFlag = 0
endif
endif
next j
until clearFlag = 1
endif
next i
endfunction
This is a better approach for several reasons. The first is obvious, it's far less code. When you find yourself reusing the same code in multiple places, you should ask yourself if a function could be used instead. The other reason you're making the code a lot more manageable by storing the sprite IDs within the array. If for some reason you wanted to make a change to the sprite IDs or add more platforms, there are multiple areas where you'd have to update the code.
pasteScore
Probably better off as a function. If I wanna get picky, the routine is called pasteScore but yet it also updates the score as well. In other words, two different functions are being performed. So if you want to keep it all together it's a better practice to create a name that reflects that. This would be one option:
playerScore = updateScore(playerScore, 1, 0, 0)
function updateScore(currentScore, updateValue, x, y)
inc currentScore, updateValue
playerScore$ = str$(playerScore)
for i = 1 to len(playerScore$)
sprite (i + 30), x, t, asc(mid$(playerScore$, i))
inc x, 50
next i
endfunction currentScore
Also, I'm not sure why you have some values related to the score (location) as UDT values but left the actual score value itself separate. This doesn't hurt anything, but I'd either include it as part of the scoreNum variable or make it part of the set of player variables. But your method won't impact anything.
lossScreen
Inflictive already touched on this a little bit, but I had something to add. Instead of deleting all the sprites, which you will most likely recreate, simply hide them instead. When you're ready to restart the game, unhide them. This will reduce the overhead of constantly removing/re-adding data into memory. It's not wrong doing it your way. In fact on a larger scale you probably would want to do this when moving between levels so you don't fill up memory with unneeded junk. But since your game reuses the same images/sprites each time, may as well just keep them there until the player exits the game.
p.s. I think this is my longest reply ever! (Even by Raven's standards
)