`Coding Challenge - 3D Shooter `Bill Robinson - San Francisco,CA. `The A and D keys move your player, and the mouse button fires! `You get 10 shots on screen at a time `Each Robot only gets 1 shot at a time, and will only fire if his head sees you `There are as many Robots at one time as the level#, example level#4 has 4 Robots at a time. `Watch your health - each enemy hit cost 10 health points, health reaches 0(zero), GAME OVER. `There are 20 levels, see how far you can get `Robots get closer to you in each level, in level 20, they are in your face! `I run sync rate 0 on my system, runs great, probably too fast for your faster systems, so you set sync rate 60, which `is too slow, higher sync rate don't seem to work right, I still need to learn timer based movement, sorry. `also, still some collision issues, but mostly works. set display mode 1024,768,32 sync on : sync rate 0 hide mouse backdrop on:color backdrop rgb(0,0,0) set text opaque set ambient light 20 set camera range 1,5000 randomize timer() dim ballinfo#(200,10) :`ballnum,1=active ,2=ballspeed, ballx, bally, ballz dim intro(10,10) :`1=key, 2=x, 3=y, 4=z, 5=newx, 6=newy, 7=newz, 8=xinc, 9=yinc, 10=zinc dim walldata(100,5) :`column walls dim enemy#(20,15) :`store box info, location, rotations, motions, etc. dim enemyinfo#(20,10) :`enemy unit info 1=active, 2=speed, 3=xloc, 4=yloc, 5=zloc, 6=xinc, 7=yinc, 8=zinc, 9=minx, 10=maxx dim enemyshots#(20,10) :`enemy shot info dim gunangle#(20,2) :`enemy gun angle #Constant WHITE=rgb(255,255,255) #Constant YELLOW=rgb(255,255,0) global testval=0 global offset=0 global gunangleinc#=2.0 global level global numballs global targetsleft global targetx#=500.0 global targety#=300.0 global targetz#=500.0 global bazooka_angle=180 global hitnum global gravity# global egravity# global gravityon global health global screenxmax=1024 global screenymax=768 global screenwidth global screenheight global screenxcenter global screenycenter global screenzcenter global v3dymax=768 `Box global boxxangle# global boxyangle# global iconptr global boxxmin global boxymin global boxzmin `balls global ballxangle# global ballyangle# global ballx global bally global ballz global maxballspeed# global ballflag global ballsatonce global maxballs global ballcount global nextballptr global lastballtime global newballtime global balltiming=100 global shadownum=500 `walls global leftwall=0 global rightwall=2000 global floor=5 global ceiling=1000 global backwall=2000 `Camera - position camera 500,200,-800 global camx=1000 global camy=300 global camz=-800 global camxr global camyr global camzr global camspeed=4 global walkflag=0 :`can player walk around flag global mxold `Enemies global enemiesonscreen global enemiesleft global numshots global enemyballspeed#=3.0 global eshotfired screenwidth=screen width() screenheight=screen height() screenxcenter=screenwidth/2 screenycenter=screenheight/2 screenzcenter=0 `enemy unit info 1=active, 2=speed, 3=xloc, 4=yloc, 5=zloc, 6=xinc, 7=yinc, 8=zinc, 9=minx, 10=maxx enemydata: data 1,2,0,100,1800,1,0,0,100,1900 data 1,3,0,100,1700,1,0,0,100,1900 data 1,3,0,100,1600,1,0,0,100,1900 data 1,3,0,100,1500,1,0,0,100,1900 data 1,3,0,100,1400,1,0,0,100,1900 data 1,4,0,100,1300,1,0,0,100,1900 data 1,4,0,100,1200,1,0,0,100,1900 data 1,4,0,100,1100,1,0,0,100,1900 data 1,5,0,100,1000,1,0,0,100,1900 data 1,5,0,100,900,1,0,0,100,1900 data 1,2,0,100,800,1,0,0,100,1900 data 1,3,0,100,700,1,0,0,100,1900 data 1,3,0,100,600,1,0,0,100,1900 data 1,3,0,100,500,1,0,0,100,1900 data 1,3,0,100,400,1,0,0,100,1900 data 1,4,0,100,300,1,0,0,100,1900 data 1,4,0,100,200,1,0,0,100,1900 data 1,4,0,100,100,1,0,0,100,1900 data 1,5,0,100,0,1,0,0,100,1900 data 1,5,0,100,-100,1,0,0,100,1900 restore enemydata for i=1 to 20 for j=1 to 10 read enemyinfo#(i,j) next j enemyinfo#(i,3)=300+rnd(1500) :`random starting x position next i rem --- make left wall make object box 310,3000,1004,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,1004,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,2000,3000,2 xrotate object 303,-90 color object 303,rgb(0,140,0) position object 303,1000,-2,1000 :`was -10 for z rem --- make back wall make object box 304,2000,1000,2 color object 304,rgb(0,0,200) position object 304,1000,500,2000 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 Tennis Balls maxballs=199 for i=100 to 99+maxballs :`balls are objects from 100 to 199 make object sphere i,40 set object i,1,1,0 scale object i,40,40,40 :`scale ball smaller than bazooka tube=28 color object i,rgb(255,255,0) hide object i set object collision off i ballinfo#(i,1)=0 next i `Make shadow texture create bitmap 1,64,64 set current bitmap 1 cls 0 ink rgb(10,10,10),0 for i=0 to 20 circle 32,32,i next i `blur bitmap 1,6 get image 1,1,1,64,64,1 set current bitmap 0 delete bitmap 1 rem make SHADOW plains for i=500 to 500+maxballs-1 make object plain i,30,30 :`SHADOWS for ball set object i,1,1,0 xrotate object i,-90 color object i,rgb(10,10,10) texture object i,1 set object collision off i hide object i 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 Player Body for enemy to hit make object box 315,150,250,100 `ghost object on 315 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 glue object to limb 315,301,0 rem make target ball make object sphere 302,40 :`Target ball set object 302,1,1,0 color object 302,rgb(255,255,200) `texture object 302,404 headcolor: data 255,0,0 data 0,255,0 data 0,100,255 data 255,255,0 data 0,255,255 data 255,0,255 data 255,125,0 data 0,255,125 data 255,0,125 data 255,100,255 data 255,0,0 data 0,255,0 data 0,100,255 data 255,255,0 data 0,255,255 data 255,0,255 data 255,125,0 data 0,255,125 data 255,0,125 data 255,100,255 restore headcolor for i=0 to 19 read r,g,b rem ----- Create Enemy Body ----- make object box 400+i,100,200,20 :`Enemy Body color object 400+i,rgb(255,150,0) make object box 420+i,50,50,50 :`Enemy Head color object 420+i,rgb(r,g,b) xrotate object 420+i,45 fix object pivot 420+i rem Create Enemy Bazooka Tube make object cylinder 450+i,40 :`Enemy Tennis ball CANNON set object 450+i,1,1,0 scale object 450+i,60,250,60 color object 450+i,rgb(250,250,0) xrotate object 450+i,90 fix object pivot 450+i hide object 400+i hide object 420+i hide object 450+i next i rem Create Enemy Shots numenemyshots=20 for i=800 to 800+numenemyshots :`balls are objects from 100 to 199 make object sphere i,50 set object i,1,1,0 scale object i,40,40,40 :`scale ball smaller than bazooka tube=28 color object i,rgb(255,0,0) hide object i set object collision on i ballinfo#(i,1)=0 next i pillardata: rem x,y,size,height data 300,300,200,400 data 900,300,200,600 data 1500,300,200,400 restore pillardata objnum=0 for i=1 to 3 read x,z,s,h for j=1 to 4 inc objnum make object plain objnum,s,h color object objnum,rgb(100,100,100) if j=1 yrotate object objnum,90 position object objnum,x,h/2,z :`column left wall walldata(objnum,1)=1 :`column left or right wall endif if j=2 position object objnum,x+s/2,h/2,z+s/2 walldata(objnum,1)=3 :`column front or back wall endif if j=3 yrotate object objnum,-90 position object objnum,x+s,h/2,z walldata(objnum,1)=1 endif if j=4 position object objnum,x+s/2,h/2,z-s/2 walldata(objnum,1)=3 endif set object collision on objnum set object collision to boxes objnum ` ghost object on objnum next j make static collision box x,0,z,x+s,h,z+s next i 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 :`shooters view `position enemy position object 400,200,100,800 nextballptr=100 :`pointer into array - points to next ball to fire ballcount=0 :`how many balls in use, on the screen ballsatonce=10 numballs=5000 maxballspeed#=4 balltiming=120 :`was 100 gravityon=1 gravity# = 0.01 egravity#=0.001 position camera camx,camy,camz-offset targetx#=screenwidth/2 point camera sw/2,200,2000 level=1 enemiesleft=level*3 health=100 time=timer() ink rgb(255,255,255),0 `------------------------------------------------------------------------------------------------------ do position camera camx,camy,camz-offset 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 newmx#=mousemovex() inc targetx#,newmx# targety#=screenheight-my# 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 position object 302,targetx#,targety#,targetz# :`target ball moves as the target object point object 301,targetx#,targety#,targetz# :`pivot cone points to target point camera 1000,200,2000 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! if ballcount>0 then gosub _moveballs :`move any visible balls on screen if enemiesleft<=0 and enemiesonscreen<=0 sync if level=20 then gosub _game_won gosub completed_level inc level enemiesleft=level*3 startflag=0 endif if enemiesleft>0 and startflag=0 gosub _start_level startflag=1 health=100 enemiesonscreen=0 endif if enemiesleft>enemiesonscreen gosub _start_enemy endif if health<=0 gosub _game_over endif gosub _move_enemy gosub _enemy_shots gosub _move_eshots gosub _show_score sync loop `------------------------------------------------------------------------------------------------------ _start_level: sync level$="Level#"+str$(level)+" - "+str$(enemiesleft)+" Enemy Robots to kill on this level - Good Luck!" while (keypress=keystate(57)) center text screenwidth/2,screenheight/2-100,level$ center text screenwidth/2,screenheight/2-70,"Press space bar to continue" gosub _moveballs gosub _move_eshots gosub _show_score sync endwhile return completed_level: done$="Level#"+str$(level)+" COMPLETED!!! GREAT JOB!" while (keypress=keystate(57)) center text screenwidth/2,screenheight/2,done$ center text screenwidth/2,screenheight/2+30,"Press space bar to continue" gosub _moveballs gosub _move_eshots gosub _show_score sync endwhile return _game_won: dim textloc(20,3) set text font "Arial" set text size 18 set text to bold gameover$="YOU DID GREAT!!! - YOU WON!!! - Thanks for Playing!!!" ptr=1 while (keypress=keystate(57)) textloc(ptr,1)=rnd(screenwidth) textloc(ptr,2)=rnd(screenheight) textloc(ptr,3)=rgb(rnd(255),rnd(255),rnd(255)) for i=1 to 20 ink textloc(i,3),0 center text textloc(i,1),textloc(i,2),gameover$ next i ink rgb(255,255,255),0 center text screenwidth/2,screenheight/2+30,"--- Press space bar to exit, bye,bye ---" gosub _moveballs gosub _move_eshots gosub _show_score wait 100 sync inc ptr if ptr>20 then ptr=1 endwhile end return _game_over: gameover$="YOU DIED A PAINFULL DEATH! - You didn't move enough - GAME OVER" center text screenwidth/2,screenheight/2,gameover$ center text screenwidth/2,screenheight/2+30,"Sorry, Thanks for Playing! - Press space bar to exit - bye" gosub _moveballs gosub _move_eshots gosub _show_score sync wait key end return rem --- show score on screen _show_score: set cursor 1,1:print screen fps() `print "enemiesleft=";enemiesleft `print "enemiesonscreen=";enemiesonscreen `print "enemy shots=";numshots center text screenxcenter,2,"Level:"+str$(level)+" Robots Left: "+str$(enemiesleft)+" Score: "+str$(score)+" Health: "+str$(health) 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 ` play sound 3 :`play empty gun sound 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) position object nextballptr,ballx#,bally#,ballz# point object nextballptr,targetx#,targety#,targetz# move object nextballptr,100 `position object nextballptr,ballx#,bally#,ballz# ballx#=object position x(nextballptr) :`get bazooka pivot location to start ball at bally#=object position y(nextballptr) ballz#=object position z(nextballptr) ballinfo#(nextballptr,3)=ballx# :`store ball location ballinfo#(nextballptr,4)=bally# ballinfo#(nextballptr,5)=ballz# `----------------------- 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 ballinfo#(nextballptr,6)=ballxi# :`store ball increment values in array ballinfo#(nextballptr,7)=ballyi# ballinfo#(nextballptr,8)=ballzi# `------------------------ position object nextballptr,ballx#,bally#,ballz# :`start ball in bazooka point object nextballptr,targetx#,targety#,-50 :`angle ball toward target on screen shadownum=400+nextballptr :`calculate next shadow plain to use position object shadownum,ballx#,2,ballz# :`attemp at shadow for ball show object shadownum `play sound 1 show object nextballptr set object collision on nextballptr :`use DBPro collision for balls and boxes only set object collision to spheres nextballptr ballinfo#(nextballptr,1)=1 :`show ball is active ballinfo#(nextballptr,2)=maxballspeed# :`store max ball speed inc ballcount :`one more ball on screen dec numballs :`one less ball you can fire inc nextballptr :`points to next ball to fire if nextballptr>99+maxballs :`if next ball doesn't exist nextballptr=100 :`reset nextballptr to first ball object endif return rem --- moves balls that have been fired _moveballs: for i=100 to 100+maxballs-1 if ballinfo#(i,1)=1 :`only worry about active balls on screen ballxi#=ballinfo#(i,6) :`get movement values for next ball position stored in array ballyi#=ballinfo#(i,7) ballzi#=ballinfo#(i,8) ballx#=ballinfo#(i,3)+ballxi# :`calculate balls NEW POSITION bally#=ballinfo#(i,4)+ballyi# ballz#=ballinfo#(i,5)+ballzi# if ballx#<0 or ballx#>rightwall :`ball hit left or RIGHT WALL ballxi#=ballxi#*-1 ballinfo#(i,6)=ballxi# ballx#=ballx#+ballxi# endif if bally#<floor :`ball hit FLOOR routine ballyi#=ballyi#*-1 ballinfo#(i,7)=ballyi# bally#=bally#+ballyi# endif if ballz#>backwall :`ball hit BACK WALL routine ballzi#=ballzi#*-1 ballinfo#(i,8)=ballzi# ballz#=ballz#+ballzi# endif if bally#>ceiling :`ball hit CEILING routine ballyi#=ballyi#*-1 ballinfo#(i,7)=ballyi# bally#=bally#+ballyi# endif if gravityon=1 :`gravity on, drop ball y increment down more to simulate gravity ballyi#=ballyi#-gravity# ballinfo#(i,7)=ballyi# endif ballinfo#(i,3)=ballx# :`store balls new location for next update ballinfo#(i,4)=bally# ballinfo#(i,5)=ballz# position object i, ballx#, bally#, ballz# :`position ball at new location on screen shadownum=400+i :`which shadow to use position object shadownum,ballx#,2,ballz# :`position shadow for ball, same x,z, y=always near floor `------------------------- rem Check for Collision Hits hitnum=object hit(i,0) if ballz#<-900 or bally#>1200 :`balls bouncing behind player or too high are removed ballinfo#(i,1)=0 dec ballcount hide object i set object collision off i hide object shadownum endif rem --- ball hitting columns in room --- if hitnum>=1 and hitnum<=12 if walldata(hitnum,1)=1 ballxi#=ballxi#*-1 ballinfo#(i,6)=ballxi# ballx#=ballx#+ballxi# ballinfo#(i,3)=ballx# position object i, ballx#, bally#, ballz# :`position ball at new location on screen shadownum=400+i :`which shadow to use position object shadownum,ballx#,2,ballz# :`position shadow for ball, same x,z, y=always near floor ` hitnum=0 endif if walldata(hitnum,1)=3 ballzi#=ballzi#*-1 ballinfo#(i,8)=ballzi# ballz#=ballz#+ballzi# ballinfo#(i,5)=ballz# position object i, ballx#, bally#, ballz# :`position ball at new location on screen shadownum=400+i :`which shadow to use position object shadownum,ballx#,2,ballz# :`position shadow for ball, same x,z, y=always near floor ` hitnum=0 endif endif if hitnum>=400 and hitnum<=439 if hitnum>=420 dec hitnum,20 endif position object hitnum,-2000,-2000,-2000 position object hitnum+20,-2000,-2000,-2000 position object hitnum+50,-2000,-2000,-2000 hide object hitnum hide object hitnum+20 hide object hitnum+50 enemy#(hitnum-399,1)=100+100*rnd(10) dec enemiesonscreen dec enemiesleft inc score,100 set object collision off i :`turn collision off for ball hide object i :`hide ball position object i,-2000,-2000,-2000 shadownum=400+i hide object shadownum :`which shadow to hide position object shadownum,-2000,-2000,-2000 :`position shadow off screen endif `------------------------- endif next i return function _key_action(keypress) select keypress `for next section of game where player can move around - not completed yet - used for debugging so far case 30 :`A key - move camera/player left if camx>50 dec camx,camspeed dec targetx#,camspeed position camera camx,camy,camz-offset position object 302,targetx#,targety#,targetz# :`target ball moves as the target object point object 301,targetx#,targety#,targetz# :`pivot cone points to target endif endcase case 32 :`D key - move camera/player right if camx<1950 inc camx,camspeed inc targetx#,camspeed position camera camx,camy,camz-offset position object 302,targetx#,targety#,targetz# point object 301,targetx#,targety#,targetz# endif endcase case 20 :`T key - Turbo mode for balls if level>=8 :`I left this in, for players looking at the source code to have some fun with balltiming=balltiming-10 :`you may need to increase the maxballs variable for a level, this turbo wait 100 :`mode really uses up balls fast if balltiming<40 then balltiming=100 endif endcase case default :`do nothing yet endcase endselect endfunction rem ----- start a new enemy on the screen ----- _start_enemy: `enemy unit info 1=active, 2=speed, 3=xloc, 4=yloc, 5=zloc, 6=xinc, 7=yinc, 8=zinc, 9=minx, 10=maxx `data 1,3,100,100,1500,1,0,0,100,1900 startone=0 for i=1 to level if startone=0 if enemy#(i,1)=0 for j=1 to 10 enemy#(i,j)=enemyinfo#(i,j) next j edir=rnd(10) if edir>4 enemy#(i,6)=enemyinfo#(i,2) else enemy#(i,6)=-enemyinfo#(i,2) endif inc enemiesonscreen show object 399+i show object 419+i show object 449+i enemy#(i,1)=1 startone=1 else if enemy#(i,1)>1 then dec enemy#(i,1),2 endif endif next i return rem --- moves any active enemy on the screen `enemy unit info 1=active, 2=speed, 3=xloc, 4=yloc, 5=zloc, 6=xinc, 7=yinc, 8=zinc, 9=minx, 10=maxx _move_enemy: for i=1 to 20 eobj=399+i if enemy#(i,1)=1 :`is enemy active newx=enemy#(i,3)+enemy#(i,6) if newx<enemy#(i,9) or newx>enemy#(i,10) enemy#(i,6)=enemy#(i,6)*-1 newx=newx+enemy#(i,6) endif enemy#(i,3)=newx position object eobj,enemy#(i,3),enemy#(i,4),enemy#(i,5) position object eobj+20,enemy#(i,3),enemy#(i,4)+125,enemy#(i,5) position object eobj+50,enemy#(i,3)-50,enemy#(i,4)+100,enemy#(i,5)-25 vis=static line of sight(camx,camy,camz,enemy#(i,3),enemy#(i,4),enemy#(i,5),1,1) if vis=0 :`can enemy head see me, yes then fire ready to fire if gunangle#(i,1)>0 dec gunangle#(i,1),gunangleinc# xrotate object eobj+50,gunangle#(i,1) gunangle#(i,2)=0 else point object eobj+50,camx,camy-500,camz gunangle#(i,2)=1 endif else if gunangle#(i,1)<120 inc gunangle#(i,1),gunangleinc# xrotate object eobj+50,gunangle#(i,1) gunangle#(i,2)=0 endif endif point object eobj+20,camx,camy-500,camz endif next i return rem --- controls shots already fired or starts a new enemy shot if needed, by calling 2 routines _enemy_shots: if enemiesonscreen>0 for i=1 to 20 numenemy=399+i if enemyshots#(i,1)=0 :`shot is active already if enemy#(i,1)=1 :`is enemy active if gunangle#(i,2)=1 :`enemy is pointing at you _fire_enemyshot(i) inc numshots endif endif endif next i endif return _move_eshots: if numshots>0 for i=1 to 20 if enemyshots#(i,1)=1 then _move_enemyshots(i) next i endif return rem --- moves enemy shots --- function _move_enemyshots(numenemy) if gravityon=1 :`gravity on, drop ball y increment down more to simulate gravity ballyi#=enemyshots#(numenemy,7)-egravity# enemyshots#(numenemy,7)=ballyi# endif inc enemyshots#(numenemy,3),enemyshots#(numenemy,6) inc enemyshots#(numenemy,4),enemyshots#(numenemy,7) inc enemyshots#(numenemy,5),enemyshots#(numenemy,8) position object 800+numenemy,enemyshots#(numenemy,3),enemyshots#(numenemy,4),enemyshots#(numenemy,5) if enemyshots#(numenemy,5)<-800 enemyshots#(numenemy,1)=0 hide object 800+numenemy dec numshots endif rem --- enemy collision section --- hitnum=object hit(800+numenemy,0) ballx#=enemyshots#(numenemy,3) bally#=enemyshots#(numenemy,4) ballz#=enemyshots#(numenemy,5) ballxi#=enemyshots#(numenemy,6) ballyi#=enemyshots#(numenemy,7) ballzi#=enemyshots#(numenemy,8) if ballx#<0 or ballx#>rightwall :`ball hit left or RIGHT WALL ballxi#=ballxi#*-1 enemyshots#(numenemy,6)=ballxi# ballx#=ballx#+ballxi# endif if bally#<floor :`ball hit FLOOR routine ballyi#=ballyi#*-1 enemyshots#(numenemy,7)=ballyi# bally#=bally#+ballyi# endif if ballz#>backwall :`ball hit BACK WALL routine ballzi#=ballzi#*-1 enemyshots#(numenemy,8)=ballzi# ballz#=ballz#+ballzi# endif rem --- ball hitting columns in room ---\ if hitnum>=1 and hitnum<=12 :`and enemiesleft>0 and enemiesonscreen>0 if walldata(hitnum,1)=1 ballxi#=ballxi#*-1 enemyshots#(numenemy,6)=ballxi# ballx#=ballx#+ballxi# enemyshots#(numenemy,3)=ballx# position object 800+numenemy, ballx#, bally#, ballz# :`position ball at new location on screen hitnum=0 endif if walldata(hitnum,1)=3 ballzi#=ballzi#*-1 enemyshots#(numenemy,8)=ballzi# ballz#=ballz#+ballzi# enemyshots#(numenemy,5)=ballz# position object 800+numenemy, ballx#, bally#, ballz# :`position ball at new location on screen hitnum=0 endif endif if hitnum=315 dec health,10 endif endfunction `enemy unit info 1=active, 2=speed, 3=xloc, 4=yloc, 5=zloc, 6=xinc, 7=yinc, 8=zinc, 9=minx, 10=maxx function _fire_enemyshot(numenemy) enemyshots#(numenemy,1)=1 enemyshots#(numenemy,2)=2 enemyshots#(numenemy,3)=object position x(449+numenemy) :`enemyinfo#(numenemy,3) enemyshots#(numenemy,4)=object position y(449+numenemy) :`enemyinfo#(numenemy,4) enemyshots#(numenemy,5)=object position z(449+numenemy)-50 :`enemyinfo#(numenemy,5)-100 enemyshots#(numenemy,6)=(camx-enemyshots#(numenemy,3))/1200.0*enemyballspeed# enemyshots#(numenemy,7)=(camy+50-enemyshots#(numenemy,4))/1200.0*enemyballspeed# enemyshots#(numenemy,8)=(camz-enemyshots#(numenemy,5))/1200.0*enemyballspeed# position object 800+numenemy,enemyshots#(numenemy,3),enemyshots#(numenemy,4),enemyshots#(numenemy,5) show object 800+numenemy endfunction