398 lines
18 KiB
HolyC
Executable File
398 lines
18 KiB
HolyC
Executable File
RegDft("TempleOS/BomberGolf","I64 best_score=99999;\n");
|
||
RegExe("TempleOS/BomberGolf");
|
||
|
||
|
||
|
||
$SP,"<1>",BI=1$
|
||
|
||
|
||
|
||
|
||
$SP,"<2>",BI=2$
|
||
|
||
|
||
|
||
$SP,"<3>",BI=3$
|
||
|
||
|
||
$SP,"<4>",BI=4$
|
||
|
||
|
||
$SP,"<5>",BI=5$
|
||
|
||
|
||
|
||
$SP,"<6>",BI=6$
|
||
|
||
|
||
|
||
|
||
$SP,"<7>",BI=7$
|
||
|
||
|
||
|
||
|
||
$SP,"<8>",BI=8$
|
||
|
||
|
||
|
||
|
||
$SP,"<9>",BI=9$
|
||
|
||
|
||
|
||
|
||
$SP,"<10>",BI=10$
|
||
|
||
|
||
#define MAP_WIDTH 600
|
||
#define MAP_HEIGHT 600
|
||
|
||
#define TREES_NUM 64
|
||
class Tree
|
||
{
|
||
I64 x,y;
|
||
} trees[TREES_NUM];
|
||
|
||
|
||
I64 target_cnt,key_cnt;
|
||
|
||
|
||
#define TARGETS_NUM 10
|
||
|
||
#define MDF_TANK 0
|
||
#define MDF_BUNKER 1
|
||
|
||
#define TANK_V 10.0
|
||
|
||
class Target
|
||
{
|
||
F64 x,y,é;
|
||
U8 *alive_img,*dead_img1,*dead_img2;
|
||
U8 type;
|
||
Bool dead,pad[6];
|
||
} targets[TARGETS_NUM];
|
||
|
||
#define FALL_TIME 3.00
|
||
#define EXPLODE_TIME 0.25
|
||
class Bomb
|
||
{
|
||
Bomb *next,*last;
|
||
F64 x,y,t;
|
||
Bool exploding;
|
||
} bomb_head;
|
||
|
||
F64 v,x,y,
|
||
é,éf; //éf is the final theta. é is gradually changed until it reaches éf.
|
||
|
||
U0 DrawIt(CTask *task,CDC *dc)
|
||
{
|
||
I64 i,j;
|
||
Bomb *tmpb;
|
||
Target *tmpt;
|
||
F64 ts=tS,dx,dy;
|
||
|
||
dc->color=ROPF_DITHER|BROWN<<16|YELLOW;
|
||
GrRect3(dc,0,0,0,dc->width,dc->height);
|
||
|
||
dc->x=task->pix_width>>1;
|
||
dc->y=task->pix_height>>1;
|
||
dc->flags|=DCF_TRANSFORMATION;
|
||
Mat4x4TranslationEqu(dc->r,x,y,0);
|
||
Mat4x4RotZ(dc->r,é);
|
||
dc->color=BLACK;
|
||
GrBorder(dc,-MAP_WIDTH>>1,-MAP_HEIGHT>>1,MAP_WIDTH>>1,MAP_HEIGHT>>1);
|
||
for (i=0;i<TARGETS_NUM;i++) {
|
||
tmpt=&targets[i];
|
||
if (tmpt->dead) {
|
||
if (i&1) {
|
||
dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
|
||
DCSymmetry3Set(dc,tmpt->x,tmpt->y,0,tmpt->x,tmpt->y,1,
|
||
tmpt->x+1024*Cos(tmpt->é),tmpt->y+1024*Sin(tmpt->é),0);
|
||
}
|
||
if (Blink(15))
|
||
Sprite3ZB(dc,tmpt->x,tmpt->y,0,tmpt->dead_img1,tmpt->é);
|
||
else
|
||
Sprite3ZB(dc,tmpt->x,tmpt->y,0,tmpt->dead_img2,tmpt->é);
|
||
dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
|
||
} else
|
||
Sprite3ZB(dc,tmpt->x,tmpt->y,0,tmpt->alive_img,tmpt->é);
|
||
}
|
||
|
||
for (i=0;i<TREES_NUM;i++)
|
||
Sprite3(dc,trees[i].x,trees[i].y,0,$IB,"<2>",BI=2$);
|
||
|
||
for (i=0;i<TARGETS_NUM;i++) {
|
||
tmpt=&targets[i];
|
||
if (tmpt->dead) {
|
||
for (j=0;j<40;j++) {
|
||
dc->thick=4;
|
||
if (j&1)
|
||
dc->color=ROPF_DITHER|LTGRAY<<16|BLACK;
|
||
else
|
||
dc->color=ROPF_DITHER|DKGRAY<<16|LTGRAY;
|
||
dx=15*Sin(ts/4+j<<6)+j>>2;
|
||
dy=10*FullTri(ts/3+j/2.0,20)+j>>2;
|
||
GrPlot3(dc,tmpt->x+5+dx+0.5*dy,tmpt->y+0.5*dx+dy,0);
|
||
}
|
||
}
|
||
}
|
||
|
||
tmpb=bomb_head.next;
|
||
while (tmpb!=&bomb_head) {
|
||
if (tmpb->t+FALL_TIME<tS) {
|
||
if (Blink(10))
|
||
Sprite3(dc,tmpb->x,tmpb->y,0,$IB,"<9>",BI=9$);
|
||
else
|
||
Sprite3(dc,tmpb->x,tmpb->y,0,$IB,"<10>",BI=10$);
|
||
}
|
||
tmpb=tmpb->next;
|
||
}
|
||
|
||
dc->flags&=~DCF_TRANSFORMATION;
|
||
Sprite3(dc,task->pix_width>>1,task->pix_height>>1,0,$IB,"<1>",BI=1$);
|
||
dc->color=RED;
|
||
GrPrint(dc,0,0,"Targets:%02d KeyStrokes:%04d Best:%04d",
|
||
target_cnt,key_cnt,best_score);
|
||
if (!target_cnt && Blink(4))
|
||
GrPrint(dc,(task->pix_width-FONT_WIDTH*14)>>1,
|
||
(task->pix_height-FONT_HEIGHT)>>1-32,"Game Completed");
|
||
}
|
||
|
||
U0 BombHit(Bomb *tmpb)
|
||
{
|
||
I64 i;
|
||
for (i=0;i<TARGETS_NUM;i++) {
|
||
if (!targets[i].dead &&
|
||
SqrI64(tmpb->x-targets[i].x)+SqrI64(tmpb->y-targets[i].y)<20*20) {
|
||
targets[i].dead=TRUE;
|
||
target_cnt--;
|
||
}
|
||
}
|
||
QueRem(tmpb);
|
||
Free(tmpb);
|
||
}
|
||
|
||
U0 BombDrop(F64 x,F64 y)
|
||
{
|
||
Bomb *tmpb=MAlloc(sizeof(Bomb));
|
||
tmpb->x=x;
|
||
tmpb->y=y;
|
||
tmpb->t=tS;
|
||
tmpb->exploding=FALSE;
|
||
QueIns(tmpb,bomb_head.last);
|
||
Sweep(FALL_TIME*1000,74,62);
|
||
}
|
||
|
||
I64 AnimateTask(CTask *)
|
||
{
|
||
F64 last_t=tS,dt;
|
||
I64 i;
|
||
Bomb *tmpb,*tmpb1;
|
||
Target *tmpt;
|
||
while (TRUE) {
|
||
dt=tS-last_t;
|
||
last_t=tS;
|
||
|
||
if (bomb_head.next==&bomb_head) {
|
||
if (target_cnt)
|
||
Snd(Freq2Ona(100+60*Clamp(0.1*(1.0+Abs(Wrap(éf-é,-ã)))`4.0,-3,3)));
|
||
else if (key_cnt<best_score) {
|
||
best_score=key_cnt;
|
||
Sleep(150); Snd(74);Sleep(150);Snd;
|
||
Sleep(150); Snd(74);Sleep(150);Snd;
|
||
} else
|
||
Snd;
|
||
}
|
||
|
||
é+=dt*(éf-é);
|
||
x+=dt*v*Sin(é);
|
||
y+=dt*v*Cos(é);
|
||
|
||
for (i=0;i<TARGETS_NUM;i++) {
|
||
tmpt=&targets[i];
|
||
if (!tmpt->dead && tmpt->type==MDF_TANK) {
|
||
tmpt->x+=dt*TANK_V*Cos(tmpt->é);
|
||
tmpt->y+=dt*TANK_V*Sin(tmpt->é);
|
||
if (i&1)
|
||
tmpt->é+=dt*ã/16;
|
||
else
|
||
tmpt->é-=dt*ã/16;
|
||
}
|
||
}
|
||
|
||
tmpb=bomb_head.next;
|
||
while (tmpb!=&bomb_head) {
|
||
tmpb1=tmpb->next;
|
||
if (tmpb->t+FALL_TIME+EXPLODE_TIME<tS)
|
||
BombHit(tmpb);
|
||
else if (tmpb->t+FALL_TIME<tS && !tmpb->exploding) {
|
||
Noise(EXPLODE_TIME*1000,62,74);
|
||
tmpb->exploding=TRUE;
|
||
}
|
||
tmpb=tmpb1;
|
||
}
|
||
|
||
Sleep(10);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
U0 Init()
|
||
{
|
||
I64 i;
|
||
Target *tmpt;
|
||
|
||
v=20;
|
||
x=-MAP_WIDTH>>1;
|
||
y=-MAP_HEIGHT>>1;
|
||
éf=é=1*ã/4;
|
||
|
||
QueInit(&bomb_head);
|
||
|
||
MemSet(trees,0,sizeof(trees));
|
||
for (i=0;i<TREES_NUM;i++) {
|
||
trees[i].x=RandU32%MAP_WIDTH -MAP_WIDTH >>1;
|
||
trees[i].y=RandU32%MAP_HEIGHT-MAP_HEIGHT>>1;
|
||
}
|
||
|
||
MemSet(targets,0,sizeof(targets));
|
||
for (i=0;i<TARGETS_NUM;i++) {
|
||
tmpt=&targets[i];
|
||
tmpt->x=RandU32%MAP_WIDTH -MAP_WIDTH >>1;
|
||
tmpt->y=RandU32%MAP_HEIGHT-MAP_HEIGHT>>1;
|
||
if (i<TARGETS_NUM/3) {
|
||
tmpt->type=MDF_BUNKER;
|
||
tmpt->é=(RandU16&3)*ã/2;
|
||
tmpt->alive_img=$IB,"<6>",BI=6$;
|
||
tmpt->dead_img1=$IB,"<7>",BI=7$;
|
||
tmpt->dead_img2=$IB,"<8>",BI=8$;
|
||
} else {
|
||
tmpt->type=MDF_TANK;
|
||
tmpt->é=Rand*2*ã;
|
||
tmpt->alive_img=$IB,"<3>",BI=3$;
|
||
tmpt->dead_img1=$IB,"<4>",BI=4$;
|
||
tmpt->dead_img2=$IB,"<5>",BI=5$;
|
||
}
|
||
}
|
||
key_cnt=0;
|
||
target_cnt=TARGETS_NUM;
|
||
}
|
||
|
||
U0 CleanUp()
|
||
{
|
||
QueDel(&bomb_head,TRUE);
|
||
}
|
||
|
||
U0 BomberGolf()
|
||
{
|
||
I64 sc;
|
||
MenuPush(
|
||
"File {"
|
||
" Abort(,CH_SHIFT_ESC);"
|
||
" Exit(,CH_ESC);"
|
||
"}"
|
||
"Play {"
|
||
" Restart(,'\n');"
|
||
" Faster(,,SC_CURSOR_UP);"
|
||
" Slower(,,SC_CURSOR_DOWN);"
|
||
" Left(,,SC_CURSOR_LEFT);"
|
||
" Right(,,SC_CURSOR_RIGHT);"
|
||
" Bomb(,CH_SPACE);"
|
||
"}"
|
||
);
|
||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||
AutoComplete;
|
||
WinBorder;
|
||
WinMax;
|
||
DocCursor;
|
||
DocClear;
|
||
Fs->animate_task=Spawn(&AnimateTask,Fs,"Animate",,Fs);
|
||
Fs->draw_it=&DrawIt;
|
||
Init;
|
||
try {
|
||
while (TRUE)
|
||
switch (GetKey(&sc)) {
|
||
case 0:
|
||
switch (sc.u8[0]) {
|
||
case SC_CURSOR_UP:
|
||
v+=10;
|
||
if (v>300) v=300;
|
||
break;
|
||
case SC_CURSOR_DOWN:
|
||
v-=10;
|
||
if (v<20) v=20;
|
||
break;
|
||
case SC_CURSOR_LEFT:
|
||
key_cnt++;
|
||
éf+=1.0/(Abs(Wrap(éf-é,-ã))+2*ã);
|
||
break;
|
||
case SC_CURSOR_RIGHT:
|
||
key_cnt++;
|
||
éf-=1.0/(Abs(Wrap(éf-é,-ã))+2*ã);
|
||
break;
|
||
|
||
}
|
||
break;
|
||
case CH_SPACE:
|
||
key_cnt++;
|
||
BombDrop(-x-0.8*FALL_TIME*v*Sin(é),-y-0.8*FALL_TIME*v*Cos(é));
|
||
break;
|
||
case '\n':
|
||
CleanUp;
|
||
Init;
|
||
break;
|
||
case CH_ESC:
|
||
case CH_SHIFT_ESC:
|
||
goto bm_done;
|
||
}
|
||
bm_done:
|
||
} catch
|
||
PutExcept;
|
||
SettingsPop;
|
||
CleanUp;
|
||
MenuPop;
|
||
RegWrite("TempleOS/BomberGolf","I64 best_score=%d;\n",best_score);
|
||
}
|
||
|
||
BomberGolf;
|
||
|