RegDft("TempleOS/ZoneOut","F64 best_score=9999;\n"); RegExe("TempleOS/ZoneOut"); <1>/* Graphics Not Rendered in HTML */ <2>/* Graphics Not Rendered in HTML */ <3>/* Graphics Not Rendered in HTML */ /* Graphics Not Rendered in HTML */ #define THEM_NUM 10 class Obj { Obj *next,*last; F64 t0,theta; I64 x,y,z; Bool hit,pad[7]; } us,them[THEM_NUM],shots; I64 num_them; F64 t0,tf; #define SCRN_SCALE 512 #define TANK_HEIGHT 32 U0 ZOTransform(CDC *dc,I64 *x,I64 *y,I64 *z) { I64 zz; Mat4x4MulXYZ(dc->r,x,y,z); zz=*z; if (zz<1) zz=1; *x=SCRN_SCALE/2* *x/zz; *y=SCRN_SCALE/2* (*y+TANK_HEIGHT)/zz; *x+=dc->x; *y+=dc->y; *z+=dc->z; } U0 DrawIt(CTask *task,CDC *dc) { Obj *tmpo; I64 i,dd,y,w=task->pix_width,h=task->pix_height,cx=w>>1,cy=h>>1; U8 *img; F64 tt,theta; theta=640*Wrap(2*us.theta)/pi; Sprite3(dc,theta-1280,90,0,<4>); Sprite3(dc,theta ,90,0,<4>); Sprite3(dc,theta+1280,90,0,<4>); DCDepthBufAlloc(dc); dc->transform=&ZOTransform; dc->x=cx; dc->y=cy; Mat4x4TranslationEqu(dc->r,-us.x,-us.y,-us.z); Mat4x4RotY(dc->r,us.theta-pi/2); Mat4x4RotX(dc->r,pi/16); dc->flags|=DCF_TRANSFORMATION; for (i=0;i<THEM_NUM;i++) { y=them[i].y; tmpo=shots.next; while (tmpo!=&shots) { dd=SqrI64(them[i].x-tmpo->x)+SqrI64(them[i].z-tmpo->z); if (dd<SCRN_SCALE/2*SCRN_SCALE/2) { y-=Sqrt(dd); if (!them[i].hit) { them[i].hit=TRUE; if (!--num_them) { tf=tS; if (tf-t0<best_score) best_score=tf-t0; } } } tmpo=tmpo->next; } if (them[i].hit) img=<2>; else img=<1>; Sprite3YB(dc,them[i].x,y,them[i].z,img,-them[i].theta); } tmpo=shots.next; while (tmpo!=&shots) { Sprite3YB(dc,tmpo->x,tmpo->y,tmpo->z,<3>,-tmpo->theta); tmpo=tmpo->next; } dc->flags&=~DCF_TRANSFORMATION; dc->color=LTGREEN; GrLine(dc,cx-5,cy,cx+5,cy); GrLine(dc,cx,cy-5,cx,cy+5); if (tf) { dc->color=RED; if (Blink) GrPrint(dc,cx-(FONT_WIDTH*14)/2,cy-FONT_HEIGHT/2,"Game Completed"); tt=tf; } else { dc->color=BLACK; GrLine(dc,cx-5,cy,cx+5,cy); GrLine(dc,cx,cy-5,cx,cy+5); tt=tS; } dc->color=BLACK; GrPrint(dc,0,0,"Enemy:%d Time:%3.2f Best:%3.2f",num_them,tt-t0,best_score); } U0 Fire() { Obj *tmpo=MAlloc(sizeof(Obj)); tmpo->x=us.x; tmpo->y=TANK_HEIGHT; tmpo->z=us.z; tmpo->theta=us.theta; tmpo->t0=tS; QueIns(tmpo,shots.last); } U0 MoveUs(F64 theta) { us.x+=0.1*SCRN_SCALE*Cos(theta); us.z+=0.1*SCRN_SCALE*Sin(theta); } U0 AnimateTask(I64) { I64 i; Obj *tmpo,*tmpo1; while (TRUE) { for (i=0;i<THEM_NUM;i++) { them[i].x+=SCRN_SCALE/32*Cos(them[i].theta); them[i].z+=SCRN_SCALE/32*Sin(them[i].theta); them[i].theta+=Rand/100.0; } tmpo=shots.next; while (tmpo!=&shots) { tmpo1=tmpo->next; if (tS-tmpo->t0>1.0) { QueRem(tmpo); Free(tmpo); } else { tmpo->x+=0.25*SCRN_SCALE*Cos(tmpo->theta); tmpo->z+=0.25*SCRN_SCALE*Sin(tmpo->theta); } tmpo=tmpo1; } Sleep(20); } } U0 Init() { I64 i; DocClear; "$BG,LTCYAN$%h12c",'\n'; QueInit(&shots); MemSet(&us,0,sizeof(us)); MemSet(them,0,sizeof(them)); num_them=THEM_NUM; for (i=0;i<THEM_NUM;i++) { them[i].x=10000*Rand-5000; them[i].z=10000*Rand-5000; them[i].theta=2*pi*Rand; them[i].hit=FALSE; } tf=0; t0=tS; } U0 CleanUp() { QueDel(&shots,TRUE); } U0 SongTask(I64) {//Randomly generate (by God :-) Fs->task_end_cb=&SndTaskEndCB; MusicSettingsRst; while (TRUE) { Play("5sD4B5D4B5qEsG4B5G4B5eD4GsB5F4B5FeD4A5qFG"); Play("5sD4B5D4B5qEsG4B5G4B5eD4GsB5F4B5FeD4A5qFG"); Play("5eGDsFGFGqDE4eB5E4sG5D4G5DqF4sGAGA"); Play("5eGDsFGFGqDE4eB5E4sG5D4G5DqF4sGAGA"); } } U0 ZoneOut() { I64 sc; PopUpOk( "I refuse to rip-off the original\n" "so this is intentionally crappy\n" "and included for demonstration\n" "purposes.\n\n" "Write games, don't play them.\n"); MenuPush( "File {" " Abort(,CH_SHIFT_ESC);" " Exit(,CH_ESC);" "}" "Play {" " Restart(,'\n');" " Fwd(,,SC_CURSOR_UP);" " Bwd(,,SC_CURSOR_DOWN);" " Left(,,SC_CURSOR_LEFT);" " Right(,,SC_CURSOR_RIGHT);" " Fire(,CH_SPACE);" "}" ); SettingsPush; //See SettingsPush Fs->text_attr=YELLOW<<4+WHITE; AutoComplete; WinBorder; WinMax; DocCursor; Init; Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs); Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs); Fs->draw_it=&DrawIt; try { while (TRUE) { switch (GetKey(&sc)) { case CH_SPACE: Fire; break; case '\n': CleanUp; Init; break; case CH_ESC: case CH_SHIFT_ESC: goto zo_done; case 0: switch (sc.u8[0]) { case SC_CURSOR_RIGHT: us.theta-=pi/256; break; case SC_CURSOR_LEFT: us.theta+=pi/256; break; case SC_CURSOR_UP: MoveUs(us.theta); break; case SC_CURSOR_DOWN: MoveUs(us.theta+pi); break; } break; } } zo_done: } catch PutExcept; CleanUp; DocClear; SettingsPop; MenuPop; RegWrite("TempleOS/ZoneOut","F64 best_score=%5.4f;\n",best_score); } ZoneOut;