Quote: "Sorry if I sound offensive or anything like that, but that's who I am"
No problem.
I used data statements because there's not a more effective way to display a readable and editable form of data without using external files. Normally I'd use some kind of media to create my levels, but I wanted my code to just run.
I decided to use subroutines over functions because of two reasons.
1) Variables set in subroutines are global, variables set in functions are only local and would be lost once out of scope.
2) There is no data to be passed or returned.
Quote: "Also your code in addition to demonstrate how to make proper collisions themselves demonstrates constructing level along the way which adds to the confusion."
Yes, it demonstrates two things, but one does not need the other in order to gain an understanding of how one works. If you were to ignore the level creation part, or even take it away and just place a cube there instead, nothing would change with the collision section of the code. I see it more of a bonus than confusion.
Possible solution to your problem
This is just a hunch. When you
#include a source file, it is simply appended on to the end of your code. What happens with your code is that this section is never executed:
global rtimer as integer
global stimer as integer
global vtimer as integer
rem player movement vector
global vx# as double float
global vy# as double float
global vz# as double float
global gravity# as double float : gravity# = -0.1
global slope# as double float : slope# = 0.5
global ground as integer : ground = 0
global jumptimer as integer : jumptimer = 0
global syncmode as integer : syncmode = 60
global view as integer : view = 1
global hide as integer : hide = 0
DBP requires to actually
execute declarations (unless this has changed with some update I'm not aware of), so you may want to shove that into an
init() function of some kind and call it at the very start of your program.
Assuming my theory is correct, the values you calculate in the function
movePlayer() are lost every time you exit the function, so make sure every variable you need is either global, or part of a user defined type.
Another thing that jumps out is this line:
collide = sc_SphereCastGroup(1,oldx#,oldy#,oldz#,oldx#,oldy#+vy#,oldz#,radius#,0)
Shouldn't that be this?
collide = sc_SphereCastGroup(1,oldx#,oldy#+vy#,oldz#,x#,y#,z#,radius#,0)
Or even this, if you prefer not to include the last position of the player into the collision calculation?
collide = sc_SphereCastGroup(1,oldx#,oldy#+vy#,oldz#,oldx#,oldy#+vy#,oldz#,radius#,0)
I'd also like to note that I don't like the way you're handling the act of jumping by adding an offset to the player's Y axis. You should apply the gravity# force directly to the player's Y position instead. If you were to simplify the method you're using, that's exactly what it would come down to anyway, so why do it the confusing way?
The way you're handling old positions is not normal either. Old positions should not be altered at all. The only purpose of old positions is to keep track of the last frame the player was in, and use that for differential calculations of some kind. Only the new values should be updated. If you take a look at the example code I linked and narrow it down, you'll see that the old positions are only updated once, and the new positions are the ones that determine where the player will be:
rem store old values
oldx#=x#
oldy#=y#
rem move left or right
if leftkey()=1 then dec x#,speed#
if rightkey()=1 then inc x#,speed#
rem jump
if upkey()=1 and grav#=0.0 then grav#=jumppower#
rem apply gravity
dec grav#,velocity#
inc y#,grav#
rem check for collision with level
if SC_SphereSlide(2,oldx#,oldy#,0,x#,y#,0,3.5,0)
rem reposition the player so it doesn't fall through any walls
x#=SC_GetCollisionSlideX()
y#=SC_GetCollisionSlideY()
rem cast a ray to the ground to check if the player is touching the ground. If so, reset gravity
if SC_RayCast(2,x#,y#,0,x#,y#-4,0,0)
grav#=0.0
endif
rem cast a ray to the roof to check if the player is touching the roof. If so, reset gravity
if SC_RayCast(2,x#,y#,0,x#,y#+4,0,0)
grav#=0-velocity#
endif
endif
rem update player positions
position object 1,x#,y#,0
I highly suggest you learn how to use user defined types. Here's an example:
type vec3_t
x# as float
y# as float
z# as float
endtype
type Player_t
gravity# as float
pos as vec3_t
endtype
global Player as Player_t
rem set values
Player.pos.x# = 5
Player.pos.y# = 2
Player.pos.z# = 5
It keeps your code organised and easier to maintain, plus you get the benefit of the compiler noticing typos, which you normally don't get if using regular global variables.
TheComet