Here is my latest code
`Coding Challenge - Pinball Game
`Bill Robinson
`Started 7-27-06 --- Deadline 8-8-06
`All Rights Reserved for use as a published game.
`
`Launch ball with RETURN key, or left mouse button.
`The mouse y-direction controls the power of the ball launch
`The Up & Down arrow keys also control the ball launch power
`Left Flipper - use either the Z key, Left Shift, or Left CTRL
`Right Flipper - use either the / key, Right Shift, or Right CTRL
`Complete a work to blast a ball into the multi-ball hopper
`
`set display mode 1024,768,32
set display mode 1280,1024,32
sync on : sync rate 0
hide mouse
autocam off
set ambient light 15
color backdrop rgb(0,0,30)
randomize timer()
set camera range 1,20000
` Create the ODE World
ode start
ode set world gravity 0,-3.5,-3.0 :`was 0,-1.5,-3.0
ode set world step 0.08 :`was 0.3
ode set world erp (0.4)*2.5 :`error correction each step
ode set world cfm (10^-5)*2.5 :`Constriant Force Mixing
`ode set dynamic minimum 2.0
#constant MAXNUMBALLS 20
dim pocketinfo(10,10)
dim doorstatus(10)
dim ballcolor(10,3)
dim collisions(1000)
dim lflip(360,3)
dim rflip(360,3)
dim ballsinplay(MAXNUMBALLS)
dim targets(300,10)
dim targetgroups(20,10)
dim gates(10,10)
#Constant WHITE=rgb(255,255,255)
#Constant YELLOW=rgb(255,255,0)
#Constant RED1=rgb(255,0,0)
#Constant CYAN=rgb(0,100,100)
#Constant MAGENTA=rgb(100,0,100)
#Constant GREEN1=rgb(0,255,0)
global numballs
global score
global screenxcenter
global screenycenter
`balls
global ballx#
global bally#
global ballz#
global maxballspeed#
global ballsatonce
global maxballs=MAXNUMBALLS
global ballcount
global nextballptr
global lastballtime
global newballtime
global balltiming=300
global ballsize=18
global ballsleft
global mx
global my
global ballinplay=0
global tiltflag=0
global tiltcount=0
global balltime=0
global safe_flag=0
global fire_flag=1
global ballsinhopper=0
global multi_ballflag=0
global hopperdoordelay=0
global ballhit
`walls
global leftwall=0
global rightwall=360
global bottomwall=0
global topwall=600
global playfield=0
global playfieldglass=40
global ballchannel=328 :`rightwall-40
global shootingwall_upper=40
global wallthickness=5
global wallheight=40
global railwidth=5
global railheight=25
global channelwidth=25
global gatesize=40
global gatewidth=5
`pockets
global pocketsize
global doorsize
global pocketsopen=5
global bonusopenflag=0
`bumpers
global slotxstart=100
global slotspacing=30
global numslotbumpers=6
global slotbumperzpos=450
global kick_flag=0
global kicktime=0
`flippers
global leftflipper
global leftflipperkey=
global leftflipperangle
global leftflippergoal
global rightflipper
global rightflipperkey
global rightflipperangle
global flippermaxangle=130
global flipperminangle=50
global flipspeed=10
global flipperlength=40
global lflipx
global lflipy
global lflipz
global rflipx
global rflipy
global rflipz
`decals & targets
global decal_idstart
global decal_objid
global decal_id
global target_id
global target_idfirst
global target_idlast
global numtargets
global numtargetgroups
global targetgroup
`particles
global blastoff_flag=1
global rocketflag
global rocket_xpos#
global rocket_ypos#
global rocket_zpos#
`Camera
global camx=180
global camy=100
global camz=-100
`ODE - globals
global odeballptr
remstart
create bitmap 1,9,9 :`make image for particles
ink rgb(255,255,255),0
dot 4,4
get image 1,1,1,9,9
set current bitmap 0
remend
_load_gatedata()
_ball_textures() :`build textures for balls
_playfield_graphics() :`build playfield graphics
gosub _intro
screenxcenter=screen width()/2
rem --- make LEFT wall
_make_rail(310,wallthickness*2,wallheight,topwall,YELLOW,leftwall,wallheight/2,topwall/2,0,50,1)
rem --- make RIGHT wall
_make_rail(311,wallthickness*2,wallheight,topwall,YELLOW,rightwall,wallheight/2,topwall/2,0,50,1)
rem --- make TOP wall
_make_rail(304,rightwall,wallheight,wallthickness*3,YELLOW,rightwall/2,wallheight/2,topwall,0,50,1)
rem --- make BALL CHANNEL wall
_make_rail(312,wallthickness/2,railheight,topwall-250,YELLOW,ballchannel,railheight/2,(topwall-230)/2,0,50,1)
rem --- make TOP LEFT Corner wall
_make_rail(315,50,wallheight,wallthickness*4,YELLOW,leftwall+12,wallheight/2,topwall-17,-60,10,1)
rem --- make TOP RIGHT Corner wall
_make_rail(316,50,wallheight,wallthickness*4,YELLOW,rightwall-12,wallheight/2,topwall-17,60,10,1)
rem --- make slanted rails for bottom exit
rail_length=125
_make_rail(303,rail_length,railheight,wallthickness,rgb(0,0,255),rail_length/2,railheight/2,20,20,10,1)
_make_rail(306,rail_length,railheight,wallthickness,rgb(0,0,255),ballchannel-rail_length/2,railheight/2,20,-20,10,1)
rem --- playfield board
make object box 305,rightwall,4,topwall
color object 305,rgb(100,100,0)
position object 305,rightwall/2+leftwall/2,-2,topwall/2
ode create static box 305
ode set contact fdir1 305,0
texture object 305,10
set object emissive 305,rgb(100,100,0)
remstart
rem --- make playfieldglass
make object box 307,rightwall,3,topwall
color object 307,rgb(0,0,0)
position object 307,rightwall/2+leftwall/2,playfieldglass,topwall/2
ode create static box 307
ghost object on 307
hide object 307
remend
rem --- make SLOT Bumpers
`global slotxstart=100
`global slotspacing=30
`_make_rail(objid, xsize, ysize, zsize, color, posx, posy, posz, yangle, bounce, ODE item)
objid=350
for i=0 to numslotbumpers-1
xloc=slotxstart+i*slotspacing
_make_rail(objid,railwidth,railheight,50,YELLOW,xloc,railheight/2,slotbumperzpos,0,10,1)
inc objid
next i
`-------------------------------------------------------------------------------------------------------
rem _make_rail(objid,xsize,ysize,zsize,color,posx,posy,posz,yangle,bounce)
rem --- make BALL KICKERS
_make_rail(360,railwidth*2,railheight,70,RED1,80,railheight/2,130,-45,100,1)
_make_rail(361,railwidth*2,railheight,70,RED1,240,railheight/2,130,45,100,1)
rem --- make FLIPPERS
flipperlength=48
lflipx=112
lflipy=railheight/2
lflipz=52
rflipx=216
rflipy=railheight/2
rflipz=52
rem --- LEFT FLIPPER
_make_rail(370,railwidth*2,railheight,flipperlength,WHITE,lflipx,lflipy,lflipz,flippermaxangle,10,1)
rem --- RIGHT FLIPPER
_make_rail(371,railwidth*2,railheight,flipperlength,WHITE,rflipx,rflipy,rflipz,flipperminangle,10,1)
leftflipperangle=flippermaxangle
rightflipperangle=flipperminangle
rem --- ODE has rotation problems if you chang the pivot point, so move position of flipper with pivot still in the middle
rem --- to simulate the flipper pivoting on the end, build curved position array for flippers
_lflipposition(lflipx,lflipy,lflipz,flipperlength/2-2) :`radius=30, half of flipper size
_rflipposition(rflipx,rflipy,rflipz,flipperlength/2-2) :`radius=30, half of flipper size
position object 370,lflip(leftflipperangle,1),lflip(leftflipperangle,2),lflip(leftflipperangle,3)
position object 371,rflip(rightflipperangle,1),rflip(rightflipperangle,2),rflip(rightflipperangle,3)
rem - Left Flipper guide rails
_make_rail(380,railwidth/4,railheight,40,RED1,leftwall+channelwidth+1,railheight/2,125,0,1,1)
_make_rail(381,railwidth/4,railheight,90,RED1,70,railheight/2,80,-60,1,1)
rem --- Right Flipper guide rails
_make_rail(390,railwidth/4,railheight,40,RED1,ballchannel-channelwidth+2,railheight/2,125,0,1,1)
_make_rail(391,railwidth/4,railheight,96,RED1,ballchannel-68,railheight/2,80,60,1,1)
rem --- Left Side Bump on side rail
_make_rail(400,12,railheight,13,RED1,leftwall+wallthickness/2+7,railheight/2,210,0,1,1)
rem --- Right Side Bump on side rail
_make_rail(410,12,railheight,13,RED1,ballchannel-railwidth/2-5,railheight/2,210,0,1,1)
rem --- Gates
_open_gate(1)
_open_gate(2)
_open_gate(3)
rem --- Scoreboard
_make_rail(420,wallthickness*2,200,railwidth,YELLOW,leftwall,100,topwall,0,1,0)
_make_rail(421,wallthickness*2,200,railwidth,YELLOW,rightwall,100,topwall,0,1,0)
_make_rail(422,rightwall,wallthickness,wallthickness,YELLOW,rightwall/2,200,topwall,0,1,0)
rem --- multi-ball chute
_make_rail(423,4,160,railheight*2,MAGENTA,180-railheight,100,topwall-railheight/2,0,1,1)
_make_rail(424,railheight*2,160,4,MAGENTA,180,100,topwall-railheight*2,0,1,1)
_make_rail(425,4,160,railheight*2,MAGENTA,180+railheight,100,topwall-railheight/2,0,1,1)
`_make_rail(426,railheight*2,4,railheight*2,MAGENTA,180,railheight,topwall-railheight/2,0,1,1)
_make_hopperdoor()
fade object 423,50
fade object 424,50
fade object 425,50
ghost object on 423
ghost object on 424
ghost object on 425
rem --- make objects and decals ---------------------------------------------------------------------------------------
decal_idstart=1000
decal_id=1000
decal_objid=1000
target_idfirst=900
target_id=900
rem --- read target group info into array
targetgroupinfo:
data 3
data 1,1,6
data 2,7,10
data 3,11,15
restore targetgroupinfo
read numtargetgroups
for i=1 to numtargetgroups
read targetgroups(i,1)
read targetgroups(i,2)
read targetgroups(i,3)
next i
rem --- "ROCKET" targets
xsize=4
for i=0 to 5
_make_target(target_id,xsize,railheight,railheight,CYAN,leftwall+8,railheight/2,420-i*(railheight+10))
set object emissive target_id,CYAN
set object collision on target_id
set object collision to boxes target_id
inc target_id
next i
rem --- "SHIP" targets
for i=0 to 3
_make_target(target_id,xsize,railheight,railheight,CYAN,ballchannel-4,railheight/2,350-i*(railheight+10))
set object emissive target_id,CYAN
set object collision on target_id
set object collision to boxes target_id
inc target_id
next i
`remstart
rem --- "BLAST" targets
for i=0 to 4
_make_target(target_id,slotspacing-16,railheight,4,CYAN,slotxstart+slotspacing/2+i*slotspacing,railheight/2,slotbumperzpos)
set object emissive target_id,CYAN
set object collision on target_id
set object collision to boxes target_id
inc target_id
next i
`remend
target_idlast=target_id-1
numtargets=target_id-1
rem --- make ROCKET DECALS
savedecal_id=decal_id
decal_id=_make_decals(decal_id,"ROCKET",rgb(0,100,100),rgb(0,0,0),16)
temp=_make_decals(savedecal_id+100,"ROCKET",rgb(0,255,255),rgb(0,0,0),16)
for i=0 to 5
make object plain decal_objid,railheight,railheight
texture object decal_objid,decal_objid
xrotate object decal_objid,-90
position object decal_objid,leftwall+railheight,1,420-i*(railheight+10)
set object emissive decal_objid,CYAN
inc decal_objid
next i
rem --- make SHIP DECALS
savedecal_id=decal_id
decal_id=_make_decals(decal_id,"SHIP",rgb(50,100,100),rgb(0,0,0),16)
temp=_make_decals(savedecal_id+100,"SHIP",rgb(50,255,255),rgb(0,0,0),16)
for i=0 to 3
make object plain decal_objid,railheight,railheight
texture object decal_objid,decal_objid
xrotate object decal_objid,-90
position object decal_objid,ballchannel-railheight+4,1,350-i*(railheight+10)
set object emissive decal_objid,CYAN
inc decal_objid
next i
rem --- make BLAST DECALS
savedecal_id=decal_id
decal_id=_make_decals(decal_id,"BLAST",rgb(0,100,100),rgb(0,0,0),16)
temp=_make_decals(savedecal_id+100,"BLAST",rgb(0,255,255),rgb(0,0,0),16)
for i=0 to 4
make object plain decal_objid,railheight,railheight
texture object decal_objid,decal_objid
xrotate object decal_objid,-90
position object decal_objid,slotxstart+slotspacing/2+i*slotspacing,1,slotbumperzpos-60
set object emissive decal_objid,CYAN
inc decal_objid
next i
rem --- Create ODE pinballs --------------------------------------------------------------------
for i=1 to maxballs
make object sphere i,ballsize,16,16 :`was i,30
set object i,1,1,0
set object collision off i
position object i, 5000,5000,0 :`move object WAY off screen
texnum=rnd(5)+11
texture object i,texnum
dec texnum,10
` color object i,rgb(ballcolor(texnum,1),ballcolor(texnum,2),ballcolor(texnum,3))
set object emissive i,rgb(ballcolor(texnum,1),ballcolor(texnum,2),ballcolor(texnum,3))
hide object i
set object collision on i
set object collision to spheres i
next i
`remstart
rem --- make power bar
make object box 201,25,2,2
color object 201,rgb(255,0,255)
`position object 201,leftwall+150,1,160 :`position power bar
`remend
remstart
rem --- make firing rate bar
make object box 202,100,100,2
color object 202,rgb(255,255,0)
position object 202,rightwall-1100+100,1,160 :`was ceiling-120,160
remend
`--------------------------------------------------------
nextballptr=1 :`pointer into array - points to next ball to fire
odeballptr=1
ballcount=0 :`how many balls in use, on the screen
ballsatonce=1 :`how many balls on screen at the same time
numballs=10 :`number of balls to shoot
maxballspeed#=8 :`how fast should the balls shoot
balltiming=200 :`pause between each ball being fired
level=1 :`start at this level
position camera 180,400,-100
point camera 180,0,300
ink rgb(255,255,255),0
set text font "Arial"
set text size 30
rem ---------------------------------------------------------------------------------------------------------------------
rem ----- main loop -----------------------------------------------------------------------------------------------------
rem --- ODE has changed pivot rotation problems, so move position of flipper with pivot still in the middle
rem --- to simulate the flipper pivoting on the end, build curved position array for flippers
ballcheck=1
blastoff_flag=0
safe_flag=1
_close_gate(2)
_close_gate(3)
balltime=timer()
do
if fire_flag=1 and ballcount=0
mess$="Ball #"+str$(ballinplay+1)+" - Ready to Fire!"
size=_decal_signs(1300,mess$,rgb(255,0,255),0,16)
if object exist(1300) then delete object 1300
make object plain 1300,size,70
xrotate object 1300,-90
position object 1300,180,20,230
texture object 1300,1300
set text size 30
fire_flag=0
endif
keypress=scancode() :`scan for keys pressed, subroutine to hadle keys
if keypress>0
_key_action(keypress)
else
endif
`if rightkey()=1 then rocketflag=1 :`right arrow key
`if rocketflag=1 and blastoff_flag=0 then targetgroup=1:_blast_off(ballhit)
leftflipperkey=0
rightflipperkey=0
if keystate(44)=1 then _left_flipper() :`Z key
if keystate(29)=1 then _left_flipper() :`Left CTRL key
if keystate(42)=1 then _left_flipper() :`Left Shift key
if keystate(53)=1 then _right_flipper() :`/ key
if keystate(157)=1 then _right_flipper() :`Right CTRL key
if keystate(54)=1 then _right_flipper() :`Right Shift key
if upkey()=1 then position mouse mousex(),mousey()-2
if downkey()=1 then position mouse mousex(),mousey()+2
if returnkey()=1 then gosub _fire_pinball :`FIRE!
if spacekey()=1 then _tilt(ballinplay) :`tilt machine to nudge sleeping ball
if safe_flag=1
if leftflipperkey=1 or rightflipperkey=1 then _close_gate(1)
endif
rem --- return LEFT flipper to start position
if leftflipper=1 and leftflipperkey=0
if leftflipperangle<flippermaxangle
inc leftflipperangle,flipspeed
ode destroy object 370
position object 370,lflip(leftflipperangle,1),lflip(leftflipperangle,2),lflip(leftflipperangle,3)
_make_ode_flipper(370,leftflipperangle,10)
else
leftflipper=0
endif
endif
rem --- return RIGHT flipper to start position
if rightflipper=1 AND rightflipperkey=0
if rightflipperangle>flipperminangle
dec rightflipperangle,flipspeed
ode destroy object 371
position object 371,rflip(rightflipperangle,1),rflip(rightflipperangle,2),rflip(rightflipperangle,3)
_make_ode_flipper(371,rightflipperangle,10)
else
rightflipper=0
endif
endif
rem --- allow 10 seconds of safe play mode, where gates close side exits
if safe_flag=1
if timer()-balltime>10000
safe_flag=0
_open_gate(2)
_open_gate(3)
_close_gate(1)
endif
endif
mx#=mousex()
my#=mousey()
mousebutton=mouseclick()
if mousebutton=1 then gosub _fire_pinball :`also FIRE!
position object 201,rightwall-20,1,150-my#/7 :`position power meter line
rem --- has ball kicker activated, reset after a time has passed
if kick_flag>0
if kicktime>0
dec kicktime
else
_kick_reset(kick_flag)
endif
endif
` --- clear balls falling thru bottom hole
if object position z(ballcheck)<-10
position object ballcheck,5000,500,0
hide object ballcheck
ode destroy object ballcheck
ballsinplay(ballcheck)=0
dec ballcount
if ballcount=0 then fire_flag=1
endif
inc ballcheck
if ballcheck>maxballs then ballcheck=1
remstart
for i=1 to maxballs
if ballsinplay(i)=1
endif
next i
remend
if ballinplay>0
for i=1 to maxballs
` _check_droptargethits(ballinplay)
if ballsinplay(i)>0
_check_droptargethits(i)
endif
next i
endif
remstart
set cursor 0,200
print "ballinplay=";ballinplay
print "rocketflag=";rocketflag
print "blastoff_flag=";blastoff_flag
print "targetgroup=";targetgroup
print "ballcount=";ballcount
print "ballsinhopper=";ballsinhopper
print "hopperdoordelay=";hopperdoordelay
remend
if hopperdoordelay>0
dec hopperdoordelay
if hopperdoordelay=0 then _make_hopperdoor()
endif
if blastoff_flag=1
goalflag=1
if rocket_xpos#<179 then inc rocket_xpos#,0.5:goalflag=0
if rocket_xpos#>181 then dec rocket_xpos#,0.5:goalflag=0
if rocket_ypos#<190 then inc rocket_ypos#,0.5:goalflag=0
if rocket_zpos#<topwall-ballsize-5 then inc rocket_zpos#,0.5:goalflag=0
if goalflag=1
if ballsinhopper=2
_remove_hopperdoor()
multi_ballflag=1
inc ballcount,ballsinhopper
ballsinhopper=0
hopperdoordelay=500
else
inc ballsinhopper
dec ballcount
` dec ballinplay
endif
` _drop_multiball(ballinplay)
_drop_multiball(ballhit)
` inc ballsinhopper
` dec ballcount
_reset_targets(targetgroup)
fire_flag=1
else
` _move_particles(ballinplay,rocket_xpos#,rocket_ypos#,rocket_zpos#,3)
_move_particles(ballhit,rocket_xpos#,rocket_ypos#,rocket_zpos#,3)
endif
endif
rem --- checks for groups of targets completed
if targetgroup=0
targetgroup=_check_target_groups(1,6,1)
if targetgroup>0 and blastoff_flag=0
` _blast_off(ballinplay)
_blast_off(ballhit)
endif
endif
if targetgroup=0
targetgroup=_check_target_groups(7,10,2)
if targetgroup>0 and blastoff_flag=0
` _blast_off(ballinplay)
_blast_off(ballhit)
endif
endif
if targetgroup=0
targetgroup=_check_target_groups(11,15,3)
if targetgroup>0 and blastoff_flag=0
` _blast_off(ballinplay)
_blast_off(ballhit)
endif
endif
gosub _show_score :`show score on screen
ode update :`let ODE update physics
if tiltflag>0
ode destroy object 401
delete object 401
tiltflag=0
endif
sync
loop
rem --------------------------------------------------------------------
ode end
end
function _make_hopperdoor()
_make_rail(426,railheight*2,4,railheight*2,MAGENTA,180,railheight,topwall-railheight/2,0,1,1)
endfunction
function _remove_hopperdoor()
ode destroy object 426
if object exist(426)=1 then delete object 426
endfunction
function _kick_out(objid)
if objid=360
ode destroy object objid
if object exist(objid)=1 then delete object objid
_make_rail(360,railwidth*3,railheight,70,RED1,90,railheight/2,140,-45,100,1)
kick_flag=360
kicktime=20
endif
if objid=361
ode destroy object objid
if object exist(objid)=1 then delete object objid
_make_rail(361,railwidth*3,railheight,70,RED1,230,railheight/2,140,45,100,1)
kick_flag=361
kicktime=20
endif
endfunction
function _kick_reset(objid)
if objid=360
ode destroy object objid
if object exist(objid)=1 then delete object objid
_make_rail(360,railwidth*2,railheight,70,RED1,80,railheight/2,130,-45,100,1)
kick_flag=0
endif
if objid=361
ode destroy object objid
if object exist(objid)=1 then delete object objid
_make_rail(361,railwidth*2,railheight,70,RED1,240,railheight/2,130,45,100,1)
kick_flag=0
endif
endfunction
function _tilt(objid)
x=object position x(objid)
y=object position y(objid)
z=object position z(objid)
make object sphere 401,ballsize,16,16
set object 401,1,1,0
set object collision off 401
position object 401, x,y+ballsize,z
ode destroy object 401
ode create dynamic sphere 401
ode set body mass 401,0.002
ode set contact bounce 401,1
ode set linear velocity 401,0,-1,0
tiltflag=401
endfunction
function _reset_targets(group)
for targetnum=targetgroups(group,2) to targetgroups(group,3)
objid=targetnum+target_idfirst-1
decalid=targetnum+decal_idstart-1
move object up objid,targets(targetnum,5)
texture object decalid,decalid
targets(targetnum,1)=1
next targetnum
targetgroup=0
blastoff_flag=0
rocketflag=0
endfunction
function _drop_multiball(ball)
`while object position y(ballinplay)>ballinplay*ballsize
` move object down ballinplay,1
`endwhile
`print "_drop_multiball(ballinplay)"
`sync
`wait key
blastoff_flag=0
rocketflag=0
ode create dynamic sphere ball
ode set body mass ball,0.002 :`was 20, then 40
ode set contact bounce ball,1
ode set contact fdir1 ball,0 :` was 30.0 Add FRICTION
ode set contact slip1 ball,1000
ode set contact slip2 ball,1000
ode set linear velocity ball,0,-5,0
delete particles 1
endfunction
function _check_target_groups(targetmin,targetmax,group)
rocketflag=group
for i=targetmin to targetmax
if targets(i,1)=1 then rocketflag=0
next i
endfunction rocketflag
function _blast_off(objid)
ode destroy object objid
_make_particles()
blastoff_flag=1
rocket_xpos#=object position x(objid)
rocket_ypos#=object position y(objid)-20
rocket_zpos#=object position z(objid)
inc score,1000
`dec ballinplay
`position camera 180,500,topwall
`point camera 180,0,topwall
endfunction
function _make_particles()
make particles 1,1,2,30 :`rocket particles
set particle velocity 1,12 :`was 10
set particle emissions 1,20 :`was 8
set particle gravity 1,-4
set particle life 1,20
rotate particles 1,0,0,180 :`rocket exhaust particles point down
color particles 1,255,0,0
set particle chaos 1,100
endfunction
function _move_particles(objid,xpos#,ypos#,zpos#,thrust#)
position object objid,xpos#,ypos#+20,zpos#
position particles 1,xpos#,ypos#,zpos#
set particle life 1,thrust#
endfunction
function _check_droptargethits(obj)
hitnum=object collision(obj,0)
rem --- ball hitting drop targets ---
if hitnum>=target_idfirst and hitnum<=target_idlast
arrayindex=hitnum-899 :`targets objects start at 900, target info array starts at 1
objid=hitnum+100 :`letter objects start at 1000
decalid=objid+100 :`decals start at 1100
` ballnum=0
if targets(arrayindex,1)=1
texture object objid,decalid
move object down hitnum,targets(arrayindex,5)
targets(arrayindex,1)=0
inc score,100
ballhit=obj
endif
endif
if hitnum=360 or hitnum=361
_kick_out(hitnum)
endif
endfunction
rem --- targets(x,1=active, 2=posx, 3=posy, 4=posz, 5=downposy)
function _target_add(index,xpos,ypos,zpos,yposdown)
targets(index,1)=1
targets(index,2)=xpos
targets(index,3)=ypos
targets(index,4)=zpos
targets(index,5)=yposdown
endfunction
function _make_target(objid,xsize,ysize,zsize,color,xpos,ypos,zpos)
make object box objid,xsize,ysize,zsize
color object objid,color
position object objid,xpos,ypos,zpos
_target_add(objid-899,xpos,ypos,zpos,railheight-1)
endfunction
function _make_decals(decal_id,word$,fgcolor,bgcolor,fontsize)
set text font "Arial"
set text size fontsize
set text to bold
set text opaque
ink fgcolor,bgcolor
for i=0 to len(word$)-1
cls bgcolor
l$=mid$(word$,i+1)
if l$="I"
set cursor 9,3
else
set cursor 6,3
endif
center text 10,3,l$
circle 10,10,8
get image decal_id,0,0,20,20
inc decal_id
`sync
`wait key
next i
endfunction decal_id
function _key_action(keypress)
select keypress
`T key
case 20
if numballs<100
inc numballs,100
endif
endcase
endselect
endfunction
function _left_flipper()
if leftflipperangle>flipperminangle
dec leftflipperangle,flipspeed
ode destroy object 370
position object 370,lflip(leftflipperangle,1),lflip(leftflipperangle,2),lflip(leftflipperangle,3)
_make_ode_flipper(370,leftflipperangle,10)
leftflipper=1
endif
leftflipperkey=1
endfunction
function _right_flipper()
if rightflipperangle<flippermaxangle
inc rightflipperangle,flipspeed
ode destroy object 371
position object 371,rflip(rightflipperangle,1),rflip(rightflipperangle,2),rflip(rightflipperangle,3)
_make_ode_flipper(371,rightflipperangle,10)
rightflipper=1
endif
rightflipperkey=1
endfunction
rem --- show score on screen
_show_score:
set cursor 1,1
print screen fps()
center text 100,100,"SCORE: "+str$(score)
return
rem ---------- fires pinballs --------------------------------------------------------
_fire_pinball:
if ballcount=ballsatonce then return
_open_gate(1)
_close_gate(2)
_close_gate(3)
safe_flag=1
fire_flag=0
hide object 1300
balltime=timer()
newballtime=timer()
if newballtime-lastballtime<balltiming then return else lastballtime=newballtime :`control firing rate of pinballs
if numballs=0 :`out of pinballs to shoot
retryflag=1 :`set retry flag, do you want to try this level again?
return :`sound 3 = your gun is empty
endif
ballx#=rightwall-20
bally#=15
ballz#=0
`----------- ODE STUFF -------------------------------------------------------------------
position object odeballptr,ballx#,bally#,ballz#
`position object odeballptr,180,190,topwall-railheight/2
show object odeballptr
inc ballinplay
if ballinplay>maxballs then ballinplay=1
ode destroy object odeballptr
ode create dynamic sphere odeballptr
ode set body mass odeballptr,0.002 :`was 20, then 40
ode set contact bounce odeballptr,1
ode set linear velocity odeballptr,0,0,80.0-my#/60.0
`ode set linear velocity odeballptr,0,-5,0
ode set contact fdir1 odeballptr,0 :` was 30.0 Add FRICTION
ode set contact slip1 odeballptr,1000
ode set contact slip2 odeballptr,1000
dec numballs
inc ballcount :`one more ball on screen, one less ball you can fired
ballsinplay(odeballptr)=1
inc odeballptr
if odeballptr>maxballs
odeballptr=1
endif
`-----------------------------------------------------------------------------------------
return
rem - gatedata(gatenum,1=gate#, 2=objid, 3=openangle, 4=closeangle, 5=open xpos, 6=zpos, 7=close xpos
gatedata:
data 3
data 1,415,0,35,328,385,338
data 2,416,0,-35,26,165,16
data 3,417,0,35,305,165,315
function _load_gatedata()
restore gatedata :`rem - point to gate data above
read numgates
for i=1 to numgates
for j=1 to 7
read gates(i,j)
next j
next i
endfunction
function _open_gate(gatenum)
objid=gates(gatenum,2)
openangle=gates(gatenum,3)
xpos=gates(gatenum,5)
zpos=gates(gatenum,6)
ode destroy object objid
if object exist(objid)=1 then delete object objid
`_make_rail(objid,railwidth,railheight,railheight*2,GREEN1,ballchannel,railheight/2,380,openangle,1,1)
_make_gate(objid,gatewidth,railheight,gatesize,GREEN1,xpos,railheight/2,zpos,openangle,1,1)
endfunction
function _close_gate(gatenum)
objid=gates(gatenum,2)
closedangle=gates(gatenum,4)
xpos=gates(gatenum,7)
zpos=gates(gatenum,6)
ode destroy object objid
if object exist(objid)=1 then delete object objid
`_make_rail(objid,railwidth,railheight,railheight*2,GREEN1,ballchannel+12,railheight/2,380,closedangle,1,1)
_make_gate(objid,gatewidth*2,railheight,gatesize,GREEN1,xpos,railheight/2,zpos,closedangle,1,1)
endfunction
function _make_gate(objid,xsize,ysize,zsize,color,posx,posy,posz,yangle,bounce,odeflag)
make object box objid,xsize,ysize,zsize
color object objid,color
if odeflag=1 and yangle<>0
rotate object objid,0,-yangle,0
endif
position object objid,posx,posy,posz
if odeflag=1
ode create static box objid
ode set contact fdir1 objid,0
ode set contact bounce objid,bounce
endif
scale object objid,25,100,100
if odeflag=1 and yangle<>0
rotate object objid,0,yangle,0
endif
endfunction
function _Game_Over()
`set cursor 1,200
center text screen width()/2,200,"Game Over"
center text screen width()/2,250,"Play Again Y/N?"
if a$="Y"
`more code needed here
else
print "Thanks for Playing!"
print "Press a key to exit game - Bye!"
sync
wait key
end
endif
endfunction
`remend
function _lflipposition(posx,posy,posz,radius)
for i=0 to 360
lflip(i,1)=posx+sin(wrapvalue(i))*radius
lflip(i,2)=railheight/2
lflip(i,3)=posz+cos(wrapvalue(i))*radius :`was (radius*-1)
next i
endfunction
function _rflipposition(posx,posy,posz,radius)
for i=0 to 360
rflip(i,1)=posx+sin(wrapvalue(i+180))*radius
rflip(i,2)=railheight/2
rflip(i,3)=posz+cos(wrapvalue(i+180))*radius :`was (radius*-1)
next i
endfunction
ballcolors:
data 255,0,0
data 0,255,0
data 0,0,255
data 255,255,0
data 0,255,255
data 255,0,255
function _ball_textures()
restore ballcolors
for i=1 to 6
for j=1 to 3
read ballcolor(i,j)
next j
next i
for i=1 to 6
create bitmap i,50,50
ink rgb(10,10,10),0
box 0,0,50,50
if i=1 then ink rgb(255,0,0),0
if i=2 then ink rgb(0,255,0),0
if i=3 then ink rgb(0,0,255),0
if i=4 then ink rgb(255,255,0),0
if i=5 then ink rgb(0,255,255),0
if i=6 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,3
get image i+10,0,0,50,50
delete bitmap i
next i
endfunction
function _playfield_graphics()
ink rgb(255,255,255),rgb(0,0,200)
cls 0
maxx=360
maxy=600
ink rgb(255,255,255),0
line 0,0,maxx,0
line maxx,0,maxx,maxy
line maxx,maxy,0,maxy
line 0,maxy,0,0
ink rgb(255,0,255),0
label$="POWER 987654321"
ptr=1
xloc=rightwall-18
yloc=360
for y=1 to len(label$)
set cursor xloc,yloc
print mid$(label$,ptr)
inc yloc,15
inc ptr
next y
x=rightwall-25
for y=450 to 650 step 15
line x,y,x+20,y
next y
get image 10,0,0,maxx,maxy,1
endfunction
_intro:
sync
set text font "Arial"
set text size 30
cx=screen width()/2
cy=100
introtext:
data "-green"
data "Rocket Ship Pinball"
data " "
data "-purple"
data "You get 5 balls per game"
data " "
data "Complete the target words to blast balls off playfield."
data "This earns you a a BONUS score of 1000."
data "You get to launch the ball on the table again"
data " "
data " "
data "-cyan"
data "The mouse y-position, or UP/DOWN arrow keys to adjust power"
data "The LEFT mouse button, or RETURN key Launches the pinball"
data "The Z KEY, Left Shift, or Left CTRL key, controls the LEFT Flipper"
data "The / KEY, Right Shift, or Right CTRL key, controls the RIGHT Flipper"
data " "
data " "
data " "
data "(Press the SPACE BAR to tilt the table if a balls gets stuck!)"
data " "
data "-yellow"
data "Press a key to continue"
data "999"
cls
restore introtext
read t$
while t$<>"999"
if left$(t$,1)="-"
if t$="-green" then ink rgb(0,255,0),0
if t$="-purple" then ink rgb(200,0,200),0
if t$="-yellow" then ink rgb(255,255,0),0
if t$="-cyan" then ink rgb(0,255,255),0
else
center text cx,cy,t$
inc cy,30
endif
read t$
endwhile
sync
wait key
ink rgb(0,255,255),0
cls
sync
return
function _decal_signs(decal_id,word$,fgcolor,bgcolor,fontsize)
set text font "Arial"
set text size fontsize
set text to bold
set text opaque
ink fgcolor,bgcolor
signlen=len(word$)*10
cls bgcolor
center text signlen/2,3,word$
get image decal_id,0,0,signlen,fontsize+4,1
endfunction signlen
function _make_rail(objid,xsize,ysize,zsize,color,posx,posy,posz,yangle,bounce,odeflag)
make object box objid,xsize,ysize,zsize
color object objid,color
if odeflag=1 and yangle<>0
rotate object objid,0,-yangle,0
endif
position object objid,posx,posy,posz
if odeflag=1
ode create static box objid
ode set contact fdir1 objid,0
ode set contact bounce objid,bounce
endif
if odeflag=1 and yangle<>0
rotate object objid,0,yangle,0
endif
endfunction
function _make_ode_flipper(objid,yangle,bounce)
if yangle<>0
rotate object objid,0,-yangle,0
endif
ode create static box objid
ode set contact fdir1 objid,0
ode set contact bounce objid,bounce
if yangle<>0
rotate object objid,0,yangle,0
endif
endfunction
function _remove_gravity(objid)
ode set gravity objid,0
endfunction
function _add_gravity(objid)
ode set gravity objid,gravity#
endfunction
function _add_force(objid,angle,force)
x1#=object position x(objid)
y1#=object position y(objid)
z1#=object position z(objid)
x2#=x1#-50.0
y2#=y1#
z2#=z1#-50.0
ode add force objid,x1#,y1#,z1#,x2#,y2#,z2#
endfunction
function _check_collisions()
` while ODE COLLISION MESSAGE EXISTS()
` ODE COLLISION GET MESSAGE
` endwhile
phyptr=0
while ODE COLLISION MESSAGE EXISTS()
`
rem collision event
ODE COLLISION GET MESSAGE
phya=ODE GET OBJECT A()
phyb=ODE GET OBJECT B()
if phya>0
collisions(ptr)=phya
inc phyptr
endif
phyavelocity#=abs(ODE GET OBJECT A VELOCITY X())+abs(ODE GET OBJECT A VELOCITY Y()/4)+abs(ODE GET OBJECT A VELOCITY Z())
phybvelocity#=abs(ODE GET OBJECT B VELOCITY X())+abs(ODE GET OBJECT B VELOCITY Y()/4)+abs(ODE GET OBJECT B VELOCITY Z())
set cursor 0,20
print "VelA=";phyavelocity#
print "VelB=";phybvelocity#
endwhile
endfunction