Help with floating camera

Blitz3D Forums/Blitz3D Beginners Area/Help with floating camera

SkyCube(Posted 2005) [#1]
Hello everyone

It's been a little while since my last post. Been busy practicing modeling before getting into the programming. Anyway, I was trying to achieve an efect I have seen in some games: a floating camera. In some games, the camera seems to float up and down, like it was floating on water.

I typed the following code, but nothing happens. Could someone help me?
Graphics3D 800,600,16,2
SetBuffer BackBuffer()

cam = CreateCamera()
PositionEntity cam,0,2,0

piso = CreatePlane()
pisotex = LoadTexture("comp002.jpg")
EntityTexture piso,pisotex
FreeTexture pisotex

UpdateWorld
RenderWorld
Flip

Function FloatCamera(camera,speed)
dir = "up"
u=u+1
y# = EntityY(camera)
If dir = "up" 
  y# = y# +0.5
  MoveEntity camera,0,y#,0

  If y# = speed Then dir="down"
End If

If dir="down"
  y# = y# - 0.5
  MoveEntity camera,0,y#,0
  If y# = (speed *-1) Then dir="up"
End If
End Function

;main loop
While Not KeyDown(1)

FloatCamera(cam,5)
UpdateWorld
RenderWorld

Text 0,0,Str(EntityY(cam))

Flip
Wend
End


The point is to make the camera's Y position increase all the way to five, and then all the way to -5. Any help will be appreciated. Thanks.


octothorpe(Posted 2005) [#2]
1. dir needs a $ suffix if it's to be a string instead of a number

2. if you want to have your program remember the dir$ variable between executions of FloatCamera(), you'll need to give it global scope (I believe this is your only option in Basic). you'll need to initialize it in the main block instead of every time the function starts

3. MoveEntity() is relative, but EntityY() is absolute. you probably won't want to combine them ever. it would be like moving your car 157 miles north because it's 157 miles north of the equator. you either want to MoveEntity(e,0,.5,0) or PositionEntity(e,EntityX(e),EntityY(e)+.5,EntityZ(e))

4. because of how your state machine is set up, as soon as you change dir$="down", you'll enter the if for "down" and move the entity down, meaning you'll never actually stay at the highest point for a render. fixing this is a little tricky; one option is creating a new variable for new_dir$ (no distasteful jokes!) and not changing dir$ until the end of the function

5. when you want to keep a variable in a range, it's much safer to use > and < instead of just =. if EntityY() is 0.1 and you continually add 0.5 to it, it will never = 5.0.

Graphics3D 800,600,16,2
SetBuffer BackBuffer()

cam = CreateCamera()
PositionEntity cam,0,2,0

piso = CreatePlane()
pisotex = LoadTexture("comp002.jpg")
EntityTexture piso,pisotex
FreeTexture pisotex

UpdateWorld
RenderWorld
Flip

Global dir$ = "up"
Function FloatEntity(entity, limit)
	Local new_dir$ = ""
	If dir$ = "up" 
		MoveEntity entity,0,.5,0
		If EntityY(entity) >= limit Then new_dir$="down"
	End If
	If dir$ = "down"
		MoveEntity entity,0,-.5,0
		If EntityY(entity) <= -limit Then new_dir$="up"
	End If
	If new_dir$ <> "" Then dir$ = new_dir$
End Function

;main loop
While Not KeyDown(1)
	FloatEntity(cam,5)
	UpdateWorld
	RenderWorld
	Text 0,0,Str(EntityY(cam))
Flip
Wend
End


Note that FloatEntity() would be useless on more than one entity because of its reliance on the global variable. You'd need to tie the data to the entity somehow if you wanted to be able to make this work on multiple entities simultaneously. One approach would involve a map (I calls em hashes!) of Entities to data. Another approach would be to redesign the function to work with a custom type (one of the fields would be the entity) and the data in the other field(s).

Your approach also requires that the entities exist near the origin on the Y axis. I'm not sure if this is acceptable, but if it's not, I'd drop the EntityY() tests and keep track of a counter so you know when to reverse directions. You could combine both the counter and the direction into one variable.

You'll probably get a more pleasing effect with sine wave(s).