SKY CAR 3D [ line version ]

General FreeBASIC programming questions.
bluatigro
Posts: 652
Joined: Apr 25, 2012 10:35
Location: netherlands

SKY CAR 3D [ line version ]

Postby bluatigro » Oct 20, 2014 12:01

this is a try at a sky car game

you control the sky car whit cursurkeys + mouse
- mouse moves lelt : sky car turn left
- mouse moves right : sky car turns right
- mouse moves up : sky car moves forwart
- mouse moves down : sky car moves back
- up key : sky car moves up
- down key : sky car moves down
- left key : sky car moves left
- right key : sky car moves right

error :
- the world does not move right

Code: Select all

''bluatigro : 20 okt 2014
''sky car [ line version ]

#include "3d-line-worlds.bas"
#include "t_joystick.bas"

dim shared as integer mouse_x
dim shared as integer mouse_y
dim shared as integer mouse_button

dim as double camx , camy , camz , campan
camy = 200
type ttree
  dim as double x,y,z,r
  dim as integer kl
  declare sub show
end type
sub ttree.show
  dodeca x , y , z , r , kl
  lijn x , 0 , z , x , y - r , z , kl
end sub
dim as integer i
dim as ttree tree( 20 )
for i = 0 to 20
  tree(i).x = range( -300 , 300 )
  tree(i).y = range( 50 , 200 )
  tree(i).z = range( -300 , 300 )
  tree(i).r = range( 10 , 50 )
  tree(i).kl = green
next i
do
  cls
  camara camx , camy , camz , campan , 0 , 0 , 1
  ground -300 , -300 , 300 , 300 , 5 ,  green
  for i = 0 to 20
    tree(i).show
  next i
''  joystick.read_joystick
''  if not joystick.dummy then
''    for i = 0 to 8
''     print i , joystick.a(i)
''    next i
''  end if
  if multikey( sc_up ) then
    if camy < 300 then camy += 5
  end if
  if multikey( sc_down ) then
    if camy > 30 then camy -= 5
  end if
  if multikey( sc_left ) then
    camx -= cos( rad( campan ) ) * 5
    camz -= sin( rad( campan ) ) * 5
  end if
  if multikey( sc_right ) then
    camx += cos( rad( campan ) ) * 5
    camz += sin( rad( campan ) ) * 5
  end if
  if not getmouse( mouse_x , mouse_y ) then
    if mouse_x <> -1 and mouse_y <> 0 then
      if mouse_x < winx / 3 then campan += 1
      if mouse_x > winx * 2 / 3 then campan -= 1
      if mouse_y < winy / 3 then
        camz += cos( rad( campan ) ) * 5
        camx -= sin( rad( campan ) ) * 5
      end if
      if mouse_y > winy * 2 / 3 then
        camz -= cos( rad( campan ) ) * 5
        camx += sin( rad( campan ) ) * 5
      end if
    end if
  end if
  sleep 40
  flip
loop while inkey() <> chr( 27 )

3d-line-world

Code: Select all

''bluatigro 30-dec-2013
''graphics lib : line 3d
#include "color.bas"
#include "basis3d_m.bas"
''create lim numbers for 4 legged skelet
const as integer arm = 0
const as integer elbow = 1
const as integer wrist = 2
const as integer leg = 3
const as integer knee = 4
const as integer enkle = 5
const as integer neck = 6
const as integer head = 7
const as integer eye = 8
const as integer lr = 10
sub lijn( x1 as single , y1 as single , z1 as single _
, x2 as single , y2 as single , z2 as single , kl as integer )
''draw a line using the curent matrix
  spot x1 , y1 , z1
  spot x2 , y2 , z2
  if z1 < -900 or z2 < -900 then exit sub
  dim as single a1 , b1 , a2 , b2
  a1 = winx / 2 + x1 / ( z1 + 1000 ) * 1000
  b1 = winy / 2 - y1 / ( z1 + 1000 ) * 1000
  a2 = winx / 2 + x2 / ( z2 + 1000 ) * 1000
  b2 = winy / 2 - y2 / ( z2 + 1000 ) * 1000
  line ( a1 , b1 ) - ( a2 , b2 ) , kl
end sub
sub bol( x as single , y as single , z as single , r as single , kl as integer )
  spot x , y , z
  if z < 900 then exit sub
  dim as single a , b , d
  a = winx / 2 + x / ( z + 1000 ) * 1000
  b = winy / 2 - y / ( z + 1000 ) * 1000
  d = r / ( z + 1000 ) * 1000
  circle ( a , b ) , d , kl
end sub 
sub dodeca( x as single , y as single , z as single , d as single , dik as integer )
''draw a dodecaherdron
dim f as single
  f = ( sqr( 5 ) - 1 ) / 2
  ''(±1, ±1, ±1)
  ''(0, ±1/f, ±f)
  ''(±1/f, ±f, 0)
  ''(±f, 0, ±1/f)
  lijn x + d , y + d , z + d , x , y + 1/f*d , z + f*d ,dik
  lijn x + d , y + d , z + d , x + 1/f*d , y + f*d , z ,dik
  lijn x + d , y + d , z + d , x + f*d , y , z + 1/f*d ,dik
  lijn x - d , y - d , z - d , x , y - 1/f*d , z - f*d ,dik
  lijn x - d , y - d , z - d , x - 1/f*d , y - f*d , z ,dik
  lijn x - d , y - d , z - d , x - f*d , y , z - 1/f*d ,dik
  lijn x+1/f*d,y+f*d,z,x+1/f*d,y-f*d,z,dik
  lijn x-1/f*d,y-f*d,z,x-1/f*d,y+f*d,z,dik
  lijn x,y+1/f*d,z+f*d,x,y+1/f*d,z-f*d,dik
  lijn x,y-1/f*d,z-f*d,x,y-1/f*d,z+f*d,dik
  lijn x-f*d,y,z-1/f*d,x+f*d,y,z-1/f*d,dik
  lijn x+f*d,y,z+1/f*d,x-f*d,y,z+1/f*d,dik
  lijn x+1/f*d,y+f*d,z,x+d,y+d,z-d,dik
  lijn x-1/f*d,y-f*d,z,x-d,y-d,z+d,dik
  lijn x+f*d,y,z+1/f*d,x-f*d,y,z+1/f*d,dik
  lijn x-f*d,y,z-1/f*d,x+f*d,y,z-1/f*d,dik
  lijn x-f*d,y,z+1/f*d,x-d,y+d,z+d,dik
  lijn x+f*d,y,z-1/f*d,x+d,y-d,z-d,dik
  lijn x+f*d,y,z-1/f*d,x+d,y+d,z-d,dik
  lijn x-f*d,y,z+1/f*d,x-d,y-d,z+d,dik
  lijn x-d,y+d,z+d,x,y+1/f*d,z+f*d,dik
  lijn x+d,y-d,z-d,x,y-1/f*d,z-f*d,dik
  lijn x-d,y+d,z+d,x-1/f*d,y+f*d,z,dik
  lijn x+d,y-d,z-d,x+1/f*d,y-f*d,z,dik
  lijn x+f*d,y,z+1/f*d,x+d,y-d,z+d,dik
  lijn x-f*d,y,z-1/f*d,x-d,y+d,z-d,dik
  lijn x+d,y-d,z+d,x,y-1/f*d,z+f*d,dik
  lijn x-d,y+d,z-d,x,y+1/f*d,z-f*d,dik
  lijn x+d,y+d,z-d,x,y+1/f*d,z-f*d,dik
  lijn x-d,y-d,z+d,x,y-1/f*d,z+f*d,dik
  lijn x+d,y-d,z+d,x+1/f*d,y-f*d,z,dik
  lijn x-d,y+d,z-d,x-1/f*d,y+f*d,z,dik
end sub
sub cube( x as single , y as single , z as single _
, x2 as single , y2 as single , z2 as single , kl as integer )
''draw a cube
  lijn x + x2 , y + y2 , z + z2 , x - x2 , y + y2 , z + z2 , kl
  lijn x + x2 , y + y2 , z - z2 , x - x2 , y + y2 , z - z2 , kl
  lijn x + x2 , y - y2 , z + z2 , x - x2 , y - y2 , z + z2 , kl
  lijn x + x2 , y - y2 , z - z2 , x - x2 , y - y2 , z - z2 , kl
 
  lijn x + x2 , y + y2 , z + z2 , x + x2 , y - y2 , z + z2 , kl
  lijn x + x2 , y + y2 , z - z2 , x + x2 , y - y2 , z - z2 , kl
  lijn x - x2 , y + y2 , z + z2 , x - x2 , y - y2 , z + z2 , kl
  lijn x - x2 , y + y2 , z - z2 , x - x2 , y - y2 , z - z2 , kl
 
  lijn x + x2 , y + y2 , z + z2 , x + x2 , y + y2 , z - z2 , kl
  lijn x + x2 , y - y2 , z + z2 , x + x2 , y - y2 , z - z2 , kl
  lijn x - x2 , y + y2 , z + z2 , x - x2 , y + y2 , z - z2 , kl
  lijn x - x2 , y - y2 , z + z2 , x - x2 , y - y2 , z - z2 , kl
end sub
sub lijnman( kl as integer )
''draws a man made op of lines
''uses seletal animation
''example of a to animate avatar
    lijn 30,0,0 ,-30,0,0 , kl
    lijn 0,0,0 , 0,120,0 , kl
    lijn 50,100,0 , -50,100,0 , kl
    cube 0,140,0 , 15,15,15 , kl
    child 2 , 30,0,0 , leg , yzx , 1
      lijn 0,0,0 , 0,-70,0 , kl
      child 3 , 0,-70,0 , knee , 0 , 2
        lijn 0,0,0 , 0,-70,0 , kl
        lijn 0,-70,0 , 0,-70,-20 , kl
    child 2 , -30,0,0 , leg + lr , yzx , 1
      lijn 0,0,0 , 0,-70,0 , kl
      child 3 , 0,-70,0 , knee + lr , 0 , 2
        lijn 0,0,0 , 0,-70,0 , kl
        lijn 0,-70,0 , 0,-70,-20 , kl
    child 2 , 50,100,0 , arm , xzy , 1
      lijn 0,0,0 , 0,-70,0 , kl
      child 3 , 0,-70,0 , elbow , 0 , 2
        lijn 0,0,0 , 0,-70,0 , kl
    child 2 , -50,100,0 , arm + lr , xzy ,  1
      lijn 0,0,0 , 0,-70,0 , kl
      child 3 , 0,-70,0 , elbow + lr , 0 , 2
        lijn 0,0,0 , 0,-70,0 , kl
end sub
sub ground( x1 as double , z1 as double _
  , x2 as double , z2 as double , q as integer , kl as integer )
  dim i as integer
  for i = 0 to q
    lijn x1+(x2-x1)*i/q, 0 , z1 , x1+(x2-x1)*i/q , 0 , z2 , kl
    lijn x1 , 0 , z1+(z2-z1)*i/q , x2 , 0 , z1+(z2-z1)*i/q , kl
  next i
end sub

t_joystick

Code: Select all

''bluatigro 20 okt 2014
''game lib : joystick object

#ifndef JOYSCICK_H
#define JOYSTICK_H

type t_joystick
  dim as single a( 8 )   
  dim as integer joyid , button , dummy
  declare sub read_joystick()
end type

sub t_joystick.read_joystick()
  dummy = getjoystick( joyid , button _
  , a( 0 ) , a( 1 ) , a( 2 ) , a( 3 ) , a( 4 ) , a( 5 ) , a( 6 ) , a( 7 ) )
end sub

dim shared as t_joystick joystick

#endif

colors

Code: Select all

''bluatigro 30-dec-2013
''game lib : some colors + functions

#include "_math.bas"

#ifndef COLOR_H
#define COLOR_H

''primary colors
const as integer black   = &h000000
const as integer red     = &hff0000
const as integer green   = &h00ff00
const as integer yellow  = &hffff00
const as integer blue    = &h0000ff
const as integer magenta = &hff00ff
const as integer cyan    = &h00ffff
const as integer white   = &hffffff
''mix colors
const as integer orange  = &hff7f00
const as integer gray    = &h7f7f7f
const as integer pink    = &hff7f7f
const as integer purple  = &h7f007f

function mix( kla as integer , f as single , klb as single ) as integer
  dim as integer ra , ga , ba , rb , gb , bb , r , g , b
  ra = ( kla shr 16 ) and 255
  ga = ( kla shr 8 ) and 255
  ba = kla and 255
  rb = ( klb shr 16 ) and 255
  gb = ( klb shr 8 ) and 255
  bb = klb and 255
  r = ra + ( rb - ra ) * f
  g = ga + ( gb - ga ) * f
  b = ba + ( bb - ba ) * f
  return rgb( r , g , b )
end function

function rainbow( deg as single ) as integer
  dim as integer r , g , b
  r = sin( rad( deg ) ) * 127 + 128
  g = sin( rad( deg - 120 ) ) * 127 + 128
  b = sin( rad( deg + 120 ) ) * 127 * 128
  return rgb( r , g , b )
end function

#endif

basis3d_m

Code: Select all

''bluatigro 30-dec-2013
''graphics lib : 3d engine

#ifndef BASIC3D_H
#define BASIC3D_H

#include "fbgfx.bi"
#if __FB_LANG__ = "fb"
  Using FB '' Scan code constants are stored in the FB namespace in lang FB
#endif

DIM shared AS INTEGER winx, winy, bitdepth
SCREENINFO winx, winy, bitdepth
SCREENRES winx, winy, 32, , FB.GFX_FULLSCREEN

''create matrix type to hold position & orentation
type matrix
  dim as single m( 3 , 3 )
end type
''create multyplycation operator for matrix
operator * ( a as matrix , b as matrix ) as matrix
  dim as integer i , j , k
  dim uit as matrix
  for i = 0 to 3
    for j = 0 to 3
''      uit.m( i , j ) = 0
      for k = 0 to 3
''        uit.m( i , j ) += a.m( i , k ) * b.m( k , j )
        uit.m( j , k ) += a.m( j , i ) * b.m( i , k )
      next k
    next j
  next i
  return uit
end operator
''create array of matrix's
dim shared as matrix v( 20 )
''create unity matrix
v( 0 ).m( 0 , 0 ) = 1
v( 0 ).m( 1 , 1 ) = 1
v( 0 ).m( 2 , 2 ) = 1
v( 0 ).m( 3 , 3 ) = 1
''create array to hold skeletal angles
dim shared as single sk( 64 , 2 )
''create some stuf for 3D engine
declare sub link( no as integer , x as single , y as single , z as single _
, pan as single , tilt as single , rol as single , ax as integer , p as integer )
declare sub child( no as integer , x as single , y as single , z as single _
, lim as integer , ax as integer , p as integer )
declare sub spot( byref x as single , byref y as single , byref z as single )
declare sub rotate( byref k as single , byref l as single , deg as single )
dim shared as integer number
dim shared as single cam( 6 )
declare sub camara( x as single , y as single , z as single _
, pan as single , tilt as single , rol as single , zoom as single )
declare function pend( f as single , a as single ) as single
declare sub skelet( no as integer , x as single , y as single , z as single )

const as integer xyz = 0
const as integer xzy = 1
const as integer yxz = 2
const as integer yzx = 3
const as integer zxy = 4
const as integer zyx = 5




function pend( f as single , a as single ) as single
''pendular motion for animation
''looks verry natural
  return sin( rad( f ) ) * a
end function
sub skelet( lim as integer , x as single , y as single , z as single )
''set angles of skeletal lim
''for animated avatars
  if lim < 0 or lim > 64 then exit sub
  sk( lim , 0 ) = x
  sk( lim , 1 ) = y
  sk( lim , 2 ) = z
end sub
sub camara( x as single , y as single , z as single _
, pan as single , tilt as single , rol as single , zoom as single )
''set look from point & look angles
  cam( 0 ) = x
  cam( 1 ) = y
  cam( 2 ) = z
  cam( 3 ) = pan
  cam( 4 ) = tilt
  cam( 5 ) = rol
  cam( 6 ) = zoom
end sub
Sub link( no As Integer, x As Single, y As Single, z As Single, pan As Single, tilt As Single, rol As Single, ax As Integer, p As Integer )
''set curent matrix wil afect folowing drawing comands
   If no < 1 Or no > 20 Then Exit Sub
   If p < 0 Or p > 20 Then Exit Sub
   If p = no Then Exit Sub
   ''create some lokal matrix's and fill them
   Dim As matrix mp, rotx, roty, rotz, translate
   mp = v( p )
   rotx = v( 0 )
   roty = v( 0 )
   rotz = v( 0 )
   translate = v( 0 )
   rotz.m( 0, 0 ) = Cos( rad( rol ))
   rotz.m( 0, 1 ) = -Sin( rad( rol ))
   rotz.m( 1, 0 ) = Sin( rad( rol ))
   rotz.m( 1, 1 ) = Cos( rad( rol ))
   roty.m( 0, 0 ) = Cos( rad( pan ))
   roty.m( 0, 2 ) = -Sin( rad( pan ))
   roty.m( 2, 0 ) = Sin( rad( pan ))
   roty.m( 2, 2 ) = Cos( rad( pan ))
   rotx.m( 1, 1 ) = Cos( rad( tilt ))
   rotx.m( 1, 2 ) = -Sin( rad( tilt ))
   rotx.m( 2, 1 ) = Sin( rad( tilt ))
   rotx.m( 2, 2 ) = Cos( rad( tilt ))
   translate.m( 3, 0 ) = x
   translate.m( 3, 1 ) = y
   translate.m( 3, 2 ) = z
   ''angles can permutate 6 ways
   Select Case ax
      Case xyz
         v( no ) = rotx * roty * rotz * translate * mp
      Case xzy
         v( no ) = rotx * rotz * roty * translate * mp
      Case yxz
         v( no ) = roty * rotx * rotz * translate * mp
      Case yzx
         v( no ) = roty * rotz * rotx * translate * mp
      Case zxy
         v( no ) = rotz * rotx * roty * translate * mp
      Case zyx
         v( no ) = rotz * roty * rotx * translate * mp
      Case Else
   End Select
   number = no
End Sub
sub child( no as integer , x as single , y as single , z as single _
, lim as integer , ax as integer , p as integer )
''set curent matrix for lim of animated avatar
''wil efect folowing drawings
  if lim < 0 or lim > 64 then exit sub
  link no , x , y , z , sk( lim , 1 ) , sk( lim , 0 ) , sk( lim , 2 ), ax , p
end sub
sub spot( byref x as single , byref y as single , byref z as single )
''calulate world coordinates from lokal coordinates
''using curent matrix
  dim as single hx , hy , hz
  dim as integer i
  ''use curent matrix
  i = number
  hx = x * v( i ).m( 0 , 0 ) + y * v( i ).m( 1 , 0 ) _
  + z * v( i ).m( 2 , 0 ) + v( i ).m( 3 , 0 )
  hy = x * v( i ).m( 0 , 1 ) + y * v( i ).m( 1 , 1 ) _
  + z * v( i ).m( 2 , 1 ) + v( i ).m( 3 , 1 )
  hz = x * v( i ).m( 0 , 2 ) + y * v( i ).m( 1 , 2 ) _
  + z * v( i ).m( 2 , 2 ) + v( i ).m( 3 , 2 )
  x = hx
  y = hy
  z = hz
  ''use camara matrix
  x += - cam( 0 )
  y += - cam( 1 )
  z += - cam( 2 )
  rotate x , z , -cam( 3 )
  rotate y , z , -cam( 4 )
  rotate x , y , -cam( 5 )
end sub
sub rotate( byref k as single , byref l as single , deg as single )
''help sub for rotating coordinates
 dim as single hk , hl , s , c
  s = sin( rad( deg ) )
  c = cos( rad( deg ) )
  hk = k * c - l * s
  hl = k * s + l * c
  k = hk
  l = hl
end sub

#endif
bluatigro
Posts: 652
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: SKY CAR 3D [ line version ]

Postby bluatigro » Oct 20, 2014 12:42

i fogot to post _math.bas

i think the error is in spot in basis3d_m

Code: Select all

''bluatigro 6-nov-2013
''game lib : math helper functions + connstands

#ifndef MATH_H
#define MATH_H

const as single pi = 3.1415926535897932384626433832795
const as single golden_divide = 0.61803398874989484820458683436564

const as integer false = 0
const as integer true = not false

declare function rad( x as single ) as single

function rad( x as single ) as single
''help function degrees to radians
  return x * pi / 180
end function

function range( l as single , h as single ) as single
  return rnd * ( h - l ) + l
end function

#endif

frisian
Posts: 249
Joined: Oct 08, 2009 17:25

Re: SKY CAR 3D [ line version ]

Postby frisian » Nov 01, 2014 21:41

bluatigro

In 3d-line-world the sub dodeca() contains two identical lines

Code: Select all

    lijn x - f * d, y, z - 1 / f * d, x + f * d, y, z - 1 / f * d, dik <-- 1
    lijn x + f * d, y, z + 1 / f * d, x - f * d, y, z + 1 / f * d, dik <-- 2
    lijn x + 1 / f * d, y + f * d, z, x + d, y + d, z - d, dik
    lijn x - 1 / f * d, y - f * d, z, x - d, y - d, z + d, dik
    lijn x + f * d, y, z + 1 / f * d, x - f * d, y, z + 1 / f * d, dik <-- 2
    lijn x - f * d, y, z - 1 / f * d, x + f * d, y, z - 1 / f * d, dik <-- 1


A dodecahedron consist of 12 pentagons having 20 corners and 30 ribs your sub draws 32 lines meaning that there are two lines that a drawn twice.

Also you have in 3d-line-world the variable f given a value of ( sqr( 5 ) - 1 ) / 2 which is the Golden Ratio.
In _math.bas you define a constant golden_divide as 0.61803398874989484820458683436564.
This is also the Golden Ratio. Since a Single can only hold about 7 digits the rest is ignored.
0.61803398 will be more than enough for a Single. Same goes for pi.

Golden Ratio is also known as Golden Cut but I can not say that I ever seen the name golden divide for it.

Return to “General”

Who is online

Users browsing this forum: No registered users and 14 guests