Only a few new changes so far.
`Coding Challenge - ODE Ball Shooter
`Bill Robinson
`2-4-06
`Shoot boxes over the wall for 1000 points each
`If a box bounces back behind you and falls, you lose 3000 points
`Sometimes you have to shoot boxes moving toward you, to keep from losing 3000 points
`When the back wall gets higher, you may need to shoot the box in the air, to get it over the wall.
`
`Add your own level if you want - add data statements around line 100, change numlevels on line 28 if you add a level.
`
set display mode 1024,768,32
sync on : sync rate 0
hide mouse
set ambient light 10
color backdrop rgb(0,0,30)
randomize timer()
set camera range 1,20000
dim particles(30,5)
dim levelinfo(10)
dim blockinfo(10,30,2)
dim targetinfo(100,5)
#Constant WHITE=rgb(255,255,255)
#Constant YELLOW=rgb(255,255,0)
global numlevels=5
global level
global levelflag
global numballs
global targetsleft
global targetx#=1000.0
global targety#=300.0
global targetz#=-300.0
global hitnum
global gravity#
global screenxmax=1024
global screenymax=768
global screenwidth
global screenheight
global screenxcenter
global screenycenter
global screenzcenter
`balls
global ballx#
global bally#
global ballz#
global maxballspeed#
global ballflag
global ballsatonce
global maxballs=199
global ballcount
global nextballptr
global lastballtime
global newballtime
global balltiming=100
`walls
global leftwall=0
global rightwall=2000
global floor=5
global ceiling=1000
global backwall=2000
global backwallheight
global barrierheight
`Camera - position camera 500,200,-800
global camx=1000
global camy=200
global camz=-800
global mxold
`ODE - globals
global odeballptr
global numboxes
global targetsleft
`Particles
global intParticleDelay
global particlesptr
global particlesflag
leveldata:
`level 1 - #boxes, followed by the x,y coords for each box - also change the global 'numlevels' on line 20 if you add a level
data 12,150,0, 300,0, 450,0, 600,0, 750,0, 900,0, 1050,0, 1200,0, 1350,0, 1500,0, 1650,0, 1800,0
`level 2
data 16,400,0, 400,100, 400,200, 400,300, 800,0, 800,100, 800,200, 800,300, 1200,0, 1200,100, 1200,200, 1200,300, 1600,0, 1600,100, 1600,200, 1600,300
`level 3
data 15,700,0, 800,0, 900,0, 1000,0, 1100,0, 1200,0, 750,100, 1150,100, 800,200, 1100,200, 850,300, 1050,300, 900,400, 1000,400, 950,500
`level 4
data 20,900,0,900,100,900,200,900,300,900,400,900,500,900,600,900,700,900,800,900,900
data 1000,0,1000,100,1000,200,1000,300,1000,400,1000,500,1000,600,1000,700,1000,800,1000,900
`level 5
data 27,100,0, 150,100, 200,200, 250,300, 300,400, 350,500, 400,600, 450,700, 500,800, 550,900
data 1000,0, 950,100, 900,200, 850,300, 800,400, 750,500, 700,600, 650,700, 600,800
data 350,300, 400,200, 450,100, 500,0
data 750,300, 700,200, 650,100, 600,0
restore leveldata
for i=1 to numlevels
read levelinfo(i)
for j=1 to levelinfo(i)
read blockinfo(i,j,1)
read blockinfo(i,j,2)
next j
next i
screenwidth=screen width()
screenheight=screen height()
screenxcenter=screenwidth/2
screenycenter=screenheight/2
screenzcenter=0
rem --- make left wall
make object box 310,3000,1100,2
yrotate object 310,90
color object 310,rgb(200,200,0)
position object 310,0,500,1000
set object emissive 310,rgb(100,100,0)
rem --- make right wall
make object box 311,3000,1100,2
yrotate object 311,-90
color object 311,rgb(255,255,0)
position object 311,2000,500,1000
rem --- make floor
make object box 303,2100,2500,3
xrotate object 303,-91 :`floor is tilted so ball run off floor to be re-used
color object 303,rgb(0,200,0)
position object 303,1000,-7,700 :`was -2 for y
rem --- make back wall
make object box 304,2000,1000,150
color object 304,rgb(0,0,255)
backwallcenter=-500
rem --- make ceiling
make object box 305,2000,3000,2
xrotate object 305,90
color object 305,rgb(0,255,255)
position object 305,1000,1000,1000
set object emissive 305,rgb(0,70,70)
rem --- Create ODE tennis balls ---
for i=1000 to 999+maxballs
make object sphere i,30
set object i,1,1,0
color object i,rgb(255,0,0)
set object collision off i
position object i, -2000,-2000,-2000 :`move object WAY off screen
next i
rem Create Bazooka Tube
make object cylinder 300,40 :`Tennis ball CANNON
set object 300,1,1,0
scale object 300,42,250,42
color object 300,rgb(0,10,0)
xrotate object 300,90
fix object pivot 300
`texture object 300,406
rem Create Pivot Cone for Bazooka
make object cone 301,5 :`pivot for cannon
`hide limb 301,0
glue object to limb 300,301,0
offset limb 300,0,0,25,0
rem make target ball
make object sphere 302,10 :`Target ball
set object 302,1,1,0
color object 302,rgb(255,255,255)
`texture object 302,404
rem use my own collision for room walls and floor
set object collision off 300 :`Bazooka
set object collision off 301 :`Pivot cone for cannon
set object collision off 302 :`target ball for aiming cannon
rem position objects for room
hide object 301 :`hide cannon pivot
`position object 302,-1000,-1000,-1000 :`TARGET ball - move off screen for now
position object 301,camx,camy,camz+100
`-------------------------------------------------------
xpos=500
ypos=300
zpos=500
` Create the ODE World
ode start
ode set world gravity 0,-.3,0 :`-.3,0 :`was 0,-20,0
ode set world step 0.3 :`was 0.05
ode set world erp (0.2)*2.5 :`error correction each step
ode set world cfm (10^-5)*2.5 :`Constriant Force Mixing -
` Create a static floor, walls, ceiling.
` Implement in Dark Basic Professional first (above)
` and then ask ODE to do the same...
ode create static box 303 :`floor
ode create static box 305 :`ceiling
ode create static box 310 :`left wall
ode create static box 311 :`right wall
`ode set contact bounce 304,1
` Create dynamic sphere
` Implement in Dark Basic Professional first
` and then ask ODE to do the same...
make object sphere 400,120,16,16 :`Make sphere in DBPro first
position object 400, xpos-50,ypos+200,zpos :`Position object in DBPro
ode create dynamic sphere 400 :`Create same object in ODE, will have same position in ODE
ode set body mass 400,10 :`Set object MASS
ode set contact fdir1 400,30.0 :`Add FRICTION
`--------------------------------------------------------
`ODE floor is higher so balls seem to roll on the floor, and not 'IN' the floor
`Visible DBPro floor is lower, repositon it now, since ODE copy is made
position object 303,1000,-5,700 :`was 1000,-2,1000
nextballptr=100 :`pointer into array - points to next ball to fire
odeballptr=1000
ballcount=0 :`how many balls in use, on the screen
ballsatonce=100 :`how many balls on screen at the same time
numballs=5000 :`number of balls to shoot
maxballspeed#=8 :`how fast should the balls shoot
balltiming=100 :`pause between each ball being fired
gravityon=1 :`gravity is on
levelflag=0
level=1 :`start at this level
gravity# = 0.1
position camera camx,camy,camz
point camera targetx#,targety#,targetz#
position mouse screenxcenter,screenycenter
mxold#=mousex()
numboxes=levelinfo(level)
_textures()
texture object 400,3
do
if levelflag=0
_build_level(level)
_InitParticles()
endif
position camera camx,camy,camz
position object 301,camx,camy-40,camz-30
mx#=2000.0/screenwidth*mousex() :`get mouse x location
my#=1000.0/screenheight*mousey() :`get mouse y location
if mx#<>mxold#
targetx#=mx#
targety#=screenheight-my#
mxold=mx
if targetx#<0 then targetx#=0
if targetx#>2000.0 then targetx#=2000.0 :`limit target position to 1000, instead of 1024 which is past wall
endif
point object 301,targetx#,targety#,targetz# :`pivot cone points to target
position object 302,targetx#,targety#,targetz# :`target ball moves as the target object
point camera targetx#,targety#,targetz#
keypress=scancode() :`scan for keys pressed, subroutine to hadle keys
if keypress>0 then _key_action(keypress)
mouse=mouseclick() :`get mouse click for firing tennis ball
if mouse=1 then gosub _fire_tennis_ball :`FIRE!
gosub _show_score :`show score on screen
intParticleDelay=_check_event_triggers(1,numboxes,1)
`is it time to turn particles emission to zero for an object
for i=1 to numboxes
if particles(i,5)>0
t=timer()
delay=particles(i,5)
delay2=delay-500
if t>delay
set particle emissions i,0
particles(i,5)=0
endif
endif
next i
`check for Boxes leaving the room
for i=1 to numboxes
if object exist(i)
delflag=0
`Box shot off far end of screen - GOOD!
if object position y(i)<0 and object position z(i)>backwall
inc score,1000
delflag=1
else
` Box has fallen off behind player - deduct 5000 from score - BAD!
if object position z(i)<camz and object position y(i)<-400
dec score,3000
delflag=1
endif
endif
if delflag=1
ode destroy object i
delete object i
dec targetsleft
targetinfo(i,1)=0
endif
endif
next i
if targetsleft=0
for pf=1 to numboxes
if particles(pf,5)<>0 then particlesflag=1
next pf
if particlesflag=0
_finished_level(level)
inc level
levelflag=0
endif
endif
ode update :`let ODE update physics
sync
loop
ode end
end
rem --- show score on screen
_show_score:
ink rgb(255,255,255),0
set cursor 1,1:print screen fps()
center text screenxcenter,2,"Level:"+str$(level)+" Targets Left: "+str$(targetsleft)+" Score: "+str$(score)
if level=20 then center text screenxcenter,28,"Targets Left="+str$(level20targets)
return
rem ---------- fires tennis balls ----------
_fire_tennis_ball:
if ballcount=ballsatonce then return
newballtime=timer()
if newballtime-lastballtime<balltiming then return else lastballtime=newballtime :`control firing rate of tennis balls
if numballs=0 :`out of tennis balls to shoot
retryflag=1 :`set retry flag, do you want to try this level again?
return :`sound 3 = your gun is empty
endif
ballx#=object position x(301) :`get bazooka pivot location to start ball at
bally#=object position y(301)
ballz#=object position z(301)
ballxi#=(targetx#-ballx#)/300.0*maxballspeed# :`calculate some value to move ball each time toward target
ballyi#=(targety#-bally#)/300.0*maxballspeed# :`mostly an arbitrary calculation, to get lots of slices
ballzi#=(targetz#-ballz#)/300.0*maxballspeed# :`build screen routine then says how many slices each move
`----------- ODE STUFF -------------------------------------------------------------------
position object odeballptr,1000,100,-800 :`velocity 100 - was 1000,150,-800
`position object odeballptr,ballx#,bally#,ballz# :`start ball in bazooka
point object odeballptr,targetx#,targety#,-50
ode destroy object odeballptr
ode create dynamic sphere odeballptr
ode set body mass odeballptr,20 :`was 20
ode set contact bounce odeballptr,1
ode set linear velocity odeballptr,ballxi#*75.0,ballyi#*75.0,1000.0 :`targetz=0,use*48, -300 use 75
`velocity of 1000 - for targetz locataion use - targetz=0,use*48 for xi# and yi#, -300 use 75
`velocity of 2000 - use *75.0 for aiming - fudged numbers, shound fix this later
`inc ballcount :`one more ball on screen
dec numballs :`one less ball you can fired
inc odeballptr
if odeballptr>999+maxballs
odeballptr=1000
endif
`-----------------------------------------------------------------------------------------
return
function _finished_level(level)
set cursor 1,200
print "YOU FINISHED LEVEL - ";level
print "Press a key to continue"
sync
wait key
for i=1 to levelinfo(level)
if object exist(i)
ode destroy object i
delete object i
delete particles i
endif
targetinfo(i,1)=0
next i
if level=numlevels
print " "
print "That's all there is for now - Thanks for Playing!"
print "Press a key to exit game - Bye!"
sync
wait key
end
endif
endfunction
function _check_event_triggers(objmin,objmax,trigtype)
for i=objmin to objmax
if object exist(i)
objx=object position x(i) :`get bazooka pivot location to start ball at
objy=object position y(i)
objz=object position z(i)
select trigtype
case 1
if objz>backwall and objy<backwallheight :`and targetinfo(i,1)=1 :`level*200
intParticleDelay=_sparks(i)
` dec targetsleft
` targetinfo(i,1)=0
endif
endcase
endselect
endif
next i
endfunction intParticleDelay
function _sparks(objnum)
sparkx=object position x(objnum) :`get bazooka pivot location to start ball at
sparky=object position y(objnum)
sparkz=object position z(objnum)
position particles objnum,sparkx,barrierheight,sparkz
show particles objnum
color particles objnum, rnd(255),rnd(255),rnd(255)
particles(objnum,5)=Timer()+500
endfunction intParticleDelay
function _InitParticles()
for i=1 to numboxes
if particles exist(i)=0
make particles i,0,250,30
color particles i, 255, 200, 200
set particle emissions i,30 :`was 30
set particle speed i, 0.2 :`0.20
set particle gravity i,.1 :`was 10
set particle life i,500
hide particles i
endif
next i
endfunction
function _key_action(keypress)
select keypress
case 20
if level>=8
balltiming=balltiming-10
wait 100
if balltiming<40 then balltiming=100
endif
endcase
endselect
endfunction
function _textures()
for i=1 to 3
create bitmap i,50,50
if i=1 then ink rgb(255,0,0),0
if i=2 then ink rgb(255,255,0),0
if i=3 then ink rgb(255,0,255),0
for x=1 to 1000
ang=rnd(360)
rad=rnd(20)
dot 25+sin(ang)*rad,25+cos(ang)*rad
next x
blur bitmap i,1
get image i,0,0,50,50
delete bitmap i
next i
endfunction
function _build_level(level)
numboxes=levelinfo(level)
targetsleft=numboxes
for i=1 to numboxes
make object box i,100,100,80
position object i,blockinfo(level,i,1),blockinfo(level,i,2)+50,900 :`+60 for y, because the floor is tilted from back-to-front
color object i,rgb(rnd(255),rnd(255),rnd(255))
ode create dynamic box i
ode set body mass i,20
ode set contact fdir1 i,25.0
targetinfo(i,1)=1 :`target is active
next i
if level<6
barrierheight=level*100
else
barrierheight=6*100
endif
position object 304,1000,-500+barrierheight,2000 :`position backwall
ode create static box 304 :`tell ODE about backwall
levelflag=1
endfunction
You may have to adjust your mouse sensitivity in the control panel.
Read the top of the source code, you can lose points now.