Okay, here's some (prolly unstable) code I just boiled up this morning. Think of it as a very crude concept. Perhaps it'll be useful. It should solve you dbl-model and your spacebar problem.
Use the direction keys to move and spacebar to jump. You can perform double-jumps too
remstart
nonZero's cheap@$$ tutorial! >_<
This is just to teach some basic concepts. Everything here is done "manually", meaning I haven't used many of the
DBPro "make-life-easier" commands. The idea is to give an understanding. Things here can (and should) be done in
a far more efficient way. The code has been broken down and done in longer steps forunderstanding purposes. You
should be able to use it as a basic outline though.
remend
#CONSTANT camsmooth 50 `You can change this before run. You must decide how smoothly your camera follows
`bearing in mind that higher number = more resources used. Since this value is a
`#CONSTANT, it is substitued for the real number before compile, meaning it uses no
`extra resources the way a variable may.
`Create a texture for the ground
FOR a = 1 TO 20
FOR b = 1 TO 20
r = RND(150) + 100
v = RND(50)
INK RGB(r, r - v, 0), RGB(0,0,0)
DOT a, b
NEXT b
NEXT a
GET IMAGE 1, 0,0,20,20, 1
CLS
`Create texture for sphere
INK RGB(200,200,200), RGB(0,0,0)
BOX 0, 0, 10, 20
INK RGB(140,140,140), RGB(0,0,0)
BOX 11, 0, 20, 20
GET IMAGE 2, 0,0,20,20, 1
CLS
`Set autocam off to prevent it from repositioning during object creation
AUTOCAM OFF
SYNC RATE 60 `Important to decide on your FPS from start. 60 is recommended. This setting affects the appearance of all motion!
SET AMBIENT LIGHT 0
SET AMBIENT LIGHT 40
SET NORMALIZATION ON
POSITION LIGHT 0, -0, 50, 1000
POINT LIGHT 0, 0, 0, 0
`MAKE LIGHT
`POSITION LIGHT 0, 0,100,1000
`POINT LIGHT 0, 0, 0, -400
COLOR BACKDROP RGB(150,150,250)
`make the floor
MAKE OBJECT PLAIN 1, 800, 800
TEXTURE OBJECT 1, 1
XROTATE OBJECT 1, -90
POSITION OBJECT 1, 0,-4,0
`make a sun
MAKE OBJECT SPHERE 2, 150
POSITION OBJECT 2, 0, 100, 1000
SET OBJECT EMISSIVE 2, RGB(250,250,0)
`make the player
sphere = 99
MAKE OBJECT SPHERE sphere, 1
`Take note of the notation. The axact point of cantact is the sphere's y-radius and the plain's y-position (in this scenario)
POSITION OBJECT sphere, 0, OBJECT POSITION Y(1) + (OBJECT SIZE Y(sphere) / 2), 5
TEXTURE OBJECT sphere, 2
SET OBJECT LIGHT sphere, 0
SET SHADOW SHADING ON sphere
`These are following distances for the camera. In order to place the camera perfectly outside the
`model, we use 1/2 hieght and width as the object position is the center of the model. We can now
`control our following distance manually without needing to do any calculations in the future.
obj_zrad# = OBJECT SIZE Z(sphere, 1) / 2 `This is z-radius of the object's width, the center being inside the object.
obj_yrad# = OBJECT SIZE Y(sphere, 1) / 2 `Same as above but with height
walkspeed# = 0.5 `You should have a walking speed variable that you can tailor to your game. Allows running too!
spherev# = 0.0 `This is your velocity when 0, you're touching the ground
jumpheight# = 4 `Determines your jumping height. Change it based on environment changes, ie underwater.
jumping = 0 `Flag determines if jumping
jumpvelocity# = 0.15 `Your jump's velocity you can use this to alter the speed of your jumping
gravity# = -0.15 `Your gravity. Change it based on thing like planet, environment, etc.
DO
`This shall be our camera's following distance. It can be changed easily depending on the "room".
`Change the numbers 3 and 5 for different results.
followdist# = 10.0 + obj_zrad#
followheight# = 2.0 + obj_yrad#
`These variable here are for easy reference, you can pass these functions directly to other functions
spherex# = OBJECT POSITION X(sphere) `sphere's x position: sphere X
spherey# = OBJECT POSITION Y(sphere)
spherez# = OBJECT POSITION Z(sphere)
sphereAx# = OBJECT ANGLE X(sphere) `sphere's x angle: sphere Angle X
sphereAy# = OBJECT ANGLE Y(sphere)
sphereAz# = OBJECT ANGLE Z(sphere)
`Now we set the camera to follow the sphere's x and y coords and offset them byour following distances.
POSITION CAMERA 0, spherex#, spherey# + followheight#, spherez# - followdist#
`Controls for the object
IF UPKEY() = 1
YROTATE OBJECT sphere, 0
MOVE OBJECT sphere, walkspeed#
ENDIF
IF DOWNKEY() = 1
YROTATE OBJECT sphere, 180
MOVE OBJECT sphere, walkspeed#
ENDIF
IF LEFTKEY() = 1
YROTATE OBJECT sphere, -90
POSITION OBJECT sphere, spherex# - walkspeed#, spherey#, spherez#
ENDIF
IF RIGHTKEY() = 1
YROTATE OBJECT sphere, 90
POSITION OBJECT sphere, spherex# + walkspeed#, spherey#, spherez#
ENDIF
`Jumping bit
IF SPACEKEY() = 1
`First check if space has been released, if so
IF spacepushed = 0
`Check jumping. If jumping = 1, it means we're in mid jump/fall so we can dbl-jump
IF jumping = 1
`Since we're double-jumping, set jumping to 2
jumping = 2
`I just added a little velocity on the second jump for fun.
spherev# = jumpvelocity# + (jumpvelocity / 10)
`Now spacebar's been pressed so set flag to 1
spacepushed = 1
ENDIF
ENDIF
`Check to see if were in the process of a jump. If not, this is our first, so
IF jumping = 0
`set the spacekey falg to 1
spacepushed = 1
`Set jumping to 1 (1st jump)
jumping = 1
`Set volocity to our jump velocity
spherev# = jumpVelocity#
ENDIF
ELSE
`If the spacekey is not being pushed, set the spacepushed flag to 0
spacepushed = 0
ENDIF
`This bit must be repeated to update the variable agian. This is why you should directly pass
`OBJECT POSITION/ANGLE. As I said, this is just to make code more readable
spherex# = OBJECT POSITION X(sphere) `sphere's x position: sphere X
spherey# = OBJECT POSITION Y(sphere)
spherez# = OBJECT POSITION Z(sphere)
sphereAx# = OBJECT ANGLE X(sphere) `sphere's x angle: sphere Angle X
sphereAy# = OBJECT ANGLE Y(sphere)
sphereAz# = OBJECT ANGLE Z(sphere)
`This but handles jumping/falling. To save CPU power, it only bothers to do anything if the velocity is not 0
IF spherev# <> 0
POSITION OBJECT sphere, spherex#, spherey# + spherev#, spherez#
ENDIF
`Handles the gravity and jumping
`Check if the sphere's y-position is higher than the ground position + the jump height
IF OBJECT POSITION Y(sphere) > OBJECT POSITION Y(1) + jumpheight#
`If so, check to see if jumping phase is 2
IF jumping = 2
`If it is 2, we check to see if the sphere's y-position is dbl the jumpheight from ground level
IF OBJECT POSITION Y(sphere) > OBJECT POSITION Y(1) + (jumpheight# * 2)
`If it is, we set jumping to 3 to signify that no more jumps can be performed.
`We also set the object's velocity to that of the gravity (a negative number)
spherev# = gravity#
jumping = 3
ENDIF
ELSE
`Now if jumping did not equal two it means we've reached the end of our height and must begin descending.
`In this case we set the sphere's velocity to the gravity.
spherev# = gravity#
ENDIF
ENDIF
`The esiest way to prevent falling through the ground it to check the actual positions.
`On a non-flat surfuce you'de have to check collisions.
IF OBJECT POSITION Y(sphere) < OBJECT POSITION Y(1)
`So if the sphere is lower than the ground, our jump has ended.
`Hence we set jumping to 0 and velocity to 0
spherev# = 0.0
jumping = 0
`Then we place the object on the ground
POSITION OBJECT sphere, OBJECT POSITION X(sphere), OBJECT POSITION Y(1) + (OBJECT SIZE Y(sphere) / 2), OBJECT POSITION Z(sphere)
ENDIF
`Handlers to keep you on the map... Hahahaha, no escape!
IF OBJECT POSITION Z(sphere) > 380: POSITION OBJECT sphere, OBJECT POSITION X(sphere), OBJECT POSITION Y(sphere), 380: ENDIF
IF OBJECT POSITION Z(sphere) < -380: POSITION OBJECT sphere, OBJECT POSITION X(sphere), OBJECT POSITION Y(sphere), -380: ENDIF
IF OBJECT POSITION X(sphere) > 380: POSITION OBJECT sphere, 380, OBJECT POSITION Y(sphere), OBJECT POSITION Z(sphere): ENDIF
IF OBJECT POSITION X(sphere) < -380: POSITION OBJECT sphere, -380, OBJECT POSITION Y(sphere), OBJECT POSITION Z(sphere): ENDIF
LOOP
EDIT: I have examined your code. The reason why you get that "copy of your object" is that you called the SYNC command mid-loop and then again at the end of the loop. The clone is actually your object, drawn twice because of the SYNC being done twice. Never call sync twice in a loop, always call it once
at the end of the loop (apparently some versions of DBPro require an initial call before the loop. I cannot confirm this, sufficed to say my version doesn't require this). IMHO, you don't need to call SYNC at all. Just set the SYNC RATE above your main loop and that's that. The engine can handle the rest. Unless you absolutely need to control your refreshing due to resources (a situation which I've yet to encounter and I'm working on a program running around 1900+ 3D objects, 1500 of which are textured).
As for your jumping problem, take a look at the code I posted. You'll see what went wrong with your flags.