334 lines
109 KiB
HolyC
Executable File
334 lines
109 KiB
HolyC
Executable File
RegDft("TempleOS/ZoneOut","F64 best_score=9999;\n");
|
||
RegExe("TempleOS/ZoneOut");
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<1>",BI=1$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<2>",BI=2$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<3>",BI=3$
|
||
|
||
$SP,"",BI=4$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
#define THEM_NUM 10
|
||
|
||
class Obj
|
||
{
|
||
Obj *next,*last;
|
||
F64 t0,é;
|
||
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,é;
|
||
|
||
é=640*Wrap(2*us.é)/ã;
|
||
Sprite3(dc,é-1280,90,0,$IB,"<4>",BI=4$);
|
||
Sprite3(dc,é ,90,0,$IB,"<4>",BI=4$);
|
||
Sprite3(dc,é+1280,90,0,$IB,"<4>",BI=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.é-ã/2);
|
||
Mat4x4RotX(dc->r,ã/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=$IB,"<2>",BI=2$;
|
||
else
|
||
img=$IB,"<1>",BI=1$;
|
||
Sprite3YB(dc,them[i].x,y,them[i].z,img,-them[i].é);
|
||
}
|
||
tmpo=shots.next;
|
||
while (tmpo!=&shots) {
|
||
Sprite3YB(dc,tmpo->x,tmpo->y,tmpo->z,$IB,"<3>",BI=3$,-tmpo->é);
|
||
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->é=us.é;
|
||
tmpo->t0=tS;
|
||
QueIns(tmpo,shots.last);
|
||
}
|
||
|
||
U0 MoveUs(F64 é)
|
||
{
|
||
us.x+=0.1*SCRN_SCALE*Cos(é);
|
||
us.z+=0.1*SCRN_SCALE*Sin(é);
|
||
}
|
||
|
||
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].é);
|
||
them[i].z+=SCRN_SCALE/32*Sin(them[i].é);
|
||
them[i].é+=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->é);
|
||
tmpo->z+=0.25*SCRN_SCALE*Sin(tmpo->é);
|
||
}
|
||
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].é=2*ã*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 $LK,"SettingsPush",A="MN: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.é-=ã/256;
|
||
break;
|
||
case SC_CURSOR_LEFT:
|
||
us.é+=ã/256;
|
||
break;
|
||
case SC_CURSOR_UP:
|
||
MoveUs(us.é);
|
||
break;
|
||
case SC_CURSOR_DOWN:
|
||
MoveUs(us.é+ã);
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
zo_done:
|
||
} catch
|
||
PutExcept;
|
||
CleanUp;
|
||
DocClear;
|
||
SettingsPop;
|
||
MenuPop;
|
||
RegWrite("TempleOS/ZoneOut","F64 best_score=%5.4f;\n",best_score);
|
||
}
|
||
|
||
ZoneOut;
|
||
|