345 lines
7.5 KiB
HolyC
Executable File
345 lines
7.5 KiB
HolyC
Executable File
RegDft("TempleOS/FlapBat","F64 best_score=9999;\n");
|
||
RegExe("TempleOS/FlapBat");
|
||
|
||
|
||
$BG,7$
|
||
|
||
|
||
|
||
$SP,"<1>",BI=1$
|
||
|
||
|
||
$SP,"<2>",BI=2$
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<3>",BI=3$
|
||
|
||
|
||
$SP,"<4>",BI=4$
|
||
|
||
|
||
$SP,"<5>",BI=5$
|
||
|
||
|
||
|
||
$BG$
|
||
#define BORDER 6
|
||
#define EAT_TIME 0.5
|
||
#define FLAP_TIME 0.5
|
||
#define BAT_BOX 10
|
||
|
||
Bool flap_down,flap_up;
|
||
F64 flap_phase,delta_phase,bat_y,bat_x,eat_timeout,flap_time;
|
||
F64 frame_x,game_t0,game_tf;
|
||
|
||
#define BUGS_NUM 32
|
||
I32 bug_cnt,bugs_x[BUGS_NUM],bugs_y[BUGS_NUM];
|
||
Bool bugs_dead[BUGS_NUM];
|
||
|
||
#define GLOW_PERIOD 3.0
|
||
F64 bugs_glow_phase[BUGS_NUM];
|
||
|
||
CDC *limit_flood_fill_dc; //Prevent uncontrolled flood-fill flicker.
|
||
|
||
U0 DrawIt(CTask *task,CDC *dc)
|
||
{
|
||
I64 i,y,x,
|
||
h=MaxI64(1,task->pix_width-2*BORDER),
|
||
v=MaxI64(1,task->pix_height-2*BORDER);
|
||
U8 *tmps,*tmps2,*tmps3;
|
||
F64 tt=flap_phase*flap_phase*flap_phase,ts=tS;
|
||
|
||
bat_x=task->pix_width>>3;
|
||
Sprite3(dc,(7*task->pix_width)>>3,20,0,$IB,"<5>",BI=5$);
|
||
|
||
dc->color=DKGRAY;
|
||
GrCircle(dc,bat_x+5+20*Saw(15*tS,2),bat_y,10+20*Saw(15*tS,2),5,-ã/4,ã/2);
|
||
|
||
tmps=SpriteInterpolate(tt,$IB,"<1>",BI=1$,$IB,"<2>",BI=2$);
|
||
if (eat_timeout && tS<eat_timeout) {
|
||
tmps2=SpriteInterpolate(tt,$IB,"<3>",BI=3$,$IB,"<4>",BI=4$);
|
||
tmps3=SpriteInterpolate(1.0-(eat_timeout-tS)/EAT_TIME,tmps2,tmps);
|
||
Free(tmps);
|
||
Free(tmps2);
|
||
tmps=tmps3;
|
||
}
|
||
|
||
DCFill(limit_flood_fill_dc);
|
||
Sprite3(limit_flood_fill_dc,16,32,0,tmps);
|
||
if (GrPeek(limit_flood_fill_dc,0,0)!=TRANSPARENT) {//Did FloodFill go crazy?
|
||
limit_flood_fill_dc->color=TRANSPARENT;
|
||
GrFloodFill(limit_flood_fill_dc,0,0);
|
||
}
|
||
GrBlot(dc,bat_x-16,bat_y-32,limit_flood_fill_dc);
|
||
|
||
Free(tmps);
|
||
for (i=0;i<BUGS_NUM;i++)
|
||
if (!bugs_dead[i]) {
|
||
x=(bugs_x[i]+frame_x)%h+BORDER;
|
||
y=bugs_y[i]%v+BORDER;
|
||
if (Saw(ts+bugs_glow_phase[i],GLOW_PERIOD)<0.2) {
|
||
if (i&1)
|
||
dc->color=YELLOW;
|
||
else
|
||
dc->color=LTGREEN;
|
||
} else
|
||
dc->color=BLACK;
|
||
GrPlot(dc,x,y);
|
||
GrPlot(dc,x+1,y);
|
||
dc->color=BLACK;
|
||
GrPlot(dc,x,y-1);
|
||
}
|
||
if (game_tf) {
|
||
dc->color=RED;
|
||
GrPrint(dc,(task->pix_width-FONT_WIDTH*14)/2,
|
||
(task->pix_height-FONT_HEIGHT)/2,"Game Completed");
|
||
tt=game_tf;
|
||
} else {
|
||
dc->color=BLACK;
|
||
tt=tS;
|
||
}
|
||
GrPrint(dc,0,0,"Bugs:%3.1f%% Time:%3.2f Best:%3.2f",
|
||
100.0*(BUGS_NUM-bug_cnt)/BUGS_NUM,tt-game_t0,best_score);
|
||
}
|
||
|
||
U0 CheckBugs(CTask *task)
|
||
{
|
||
I64 i,x,y,
|
||
h=MaxI64(1,task->pix_width-2*BORDER),
|
||
v=MaxI64(1,task->pix_height-2*BORDER);
|
||
if (eat_timeout && eat_timeout-tS<0.75*EAT_TIME) {
|
||
Suspend(task->song_task,FALSE);
|
||
if (tS>=eat_timeout)
|
||
eat_timeout=0;
|
||
}
|
||
for (i=0;i<BUGS_NUM;i++)
|
||
if (!bugs_dead[i]) {
|
||
x=(bugs_x[i]+frame_x)%h+BORDER;
|
||
y=bugs_y[i]%v+BORDER;
|
||
if (AbsI64(x-bat_x)<BAT_BOX && AbsI64(y-bat_y)<BAT_BOX) {
|
||
bugs_dead[i]=TRUE;
|
||
eat_timeout=tS+EAT_TIME;
|
||
Snd(74);
|
||
Suspend(task->song_task);
|
||
bug_cnt--;
|
||
}
|
||
}
|
||
if (!game_tf && !bug_cnt) {
|
||
game_tf=tS;
|
||
Suspend(task->song_task);
|
||
Snd;
|
||
if (game_tf-game_t0<best_score)
|
||
best_score=game_tf-game_t0;
|
||
}
|
||
frame_x-=0.1;
|
||
if (frame_x<0)
|
||
frame_x+=h;
|
||
}
|
||
|
||
U0 Init()
|
||
{
|
||
I64 i;
|
||
limit_flood_fill_dc=DCNew(32,40);
|
||
flap_down=flap_up=FALSE;
|
||
flap_phase=0;
|
||
bat_x=Fs->pix_width>>3;
|
||
bat_y=0;
|
||
frame_x=0;
|
||
bug_cnt=BUGS_NUM;
|
||
for (i=0;i<BUGS_NUM;i++) {
|
||
bugs_dead[i]=FALSE;
|
||
bugs_x[i]=RandU16;
|
||
bugs_y[i]=RandU16;
|
||
bugs_glow_phase[i]=GLOW_PERIOD*Rand;
|
||
}
|
||
Suspend(Fs->song_task,FALSE);
|
||
flap_time=eat_timeout=0;
|
||
delta_phase=game_tf=0;
|
||
game_t0=tS;
|
||
}
|
||
|
||
U0 SongTask(I64)
|
||
{//Song by Terry A. Davis
|
||
Fs->task_end_cb=&SndTaskEndCB;
|
||
MusicSettingsRst;
|
||
while (TRUE) {
|
||
Play("4eB5E4B5C4B5EsEFqE4eB5E4B5C4B5EsEF");
|
||
Play("5qE4eA5D4ABA5DsDCqD4eB5E4B5C4B");
|
||
Play("5EsEDqE");
|
||
}
|
||
}
|
||
|
||
U0 AnimateTask(I64)
|
||
{
|
||
while (TRUE) {
|
||
if (flap_down) {
|
||
flap_down=FALSE;
|
||
delta_phase=-0.005*Min(1.0,(tS-flap_time)/FLAP_TIME);
|
||
flap_time=tS;
|
||
} else if (flap_up) {
|
||
flap_up=FALSE;
|
||
delta_phase= 0.005;
|
||
}
|
||
if (delta_phase<0) {
|
||
bat_y+=75*delta_phase;
|
||
delta_phase+=0.000015;
|
||
} else
|
||
bat_y+=0.15;
|
||
bat_y=Clamp(bat_y,BORDER,Fs->parent_task->pix_height-BORDER);
|
||
flap_phase=Clamp(flap_phase+delta_phase,0.0,1.0);
|
||
CheckBugs(Fs->parent_task);
|
||
Sleep(1);
|
||
}
|
||
}
|
||
|
||
U0 CleanUp()
|
||
{
|
||
DCDel(limit_flood_fill_dc);
|
||
}
|
||
|
||
U0 FlapBat()
|
||
{
|
||
Bool rst_space=TRUE;
|
||
I64 arg1,arg2;
|
||
|
||
MenuPush(
|
||
"File {"
|
||
" Abort(,CH_SHIFT_ESC);"
|
||
" Exit(,CH_ESC);"
|
||
"}"
|
||
"Play {"
|
||
" Restart(,'\n');"
|
||
" Flap(,CH_SPACE);"
|
||
"}"
|
||
);
|
||
|
||
PopUpOk("Use $$GREEN$$<SPACE>$$FG$$ to flap.\nHold down to glide.");
|
||
|
||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||
Fs->text_attr=LTGRAY<<4+WHITE;
|
||
WinBorder(ON);
|
||
WinHorz(1,TEXT_COLS/2);
|
||
WinVert(2,TEXT_ROWS/2);
|
||
DocCursor;
|
||
DocClear;
|
||
Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
|
||
Init;
|
||
Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
|
||
Fs->draw_it=&DrawIt;
|
||
try {
|
||
while (TRUE) {
|
||
switch (GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_KEY_UP)) {
|
||
case MSG_KEY_DOWN:
|
||
switch (arg1) {
|
||
case CH_SPACE:
|
||
if (rst_space) {
|
||
flap_down=TRUE;
|
||
rst_space=FALSE;
|
||
}
|
||
break;
|
||
case '\n':
|
||
CleanUp;
|
||
Init;
|
||
break;
|
||
case CH_SHIFT_ESC:
|
||
case CH_ESC:
|
||
goto bl_done;
|
||
}
|
||
break;
|
||
case MSG_KEY_UP:
|
||
switch (arg1) {
|
||
case CH_SPACE:
|
||
flap_up=TRUE;
|
||
rst_space=TRUE;
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
bl_done:
|
||
GetMsg(,,1<<MSG_KEY_UP);
|
||
} catch
|
||
PutExcept;
|
||
SettingsPop;
|
||
CleanUp;
|
||
MenuPop;
|
||
RegWrite("TempleOS/FlapBat","F64 best_score=%5.4f;\n",best_score);
|
||
}
|
||
|
||
FlapBat;
|
||
|