pinball - actually I do.
I made a VERY simple game for one of Ric's coding challenges.
It did win the challenge, but it has some bugs, using ODE physics is not easy, and there is no media in keeping with the rules of the challenges.
Here is my simple pinball game
`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
Hey, you should enter a coding challenge some time, they can be....umm...err......challenging!....sorry I had to.