ZealOS/src/Demo/Games/BomberGolf.ZC
2023-11-12 10:40:40 -05:00

446 lines
No EOL
24 KiB
HolyC
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

RegDefault("ZealOS/BomberGolf", "I64 best_score=99999;\n");
RegExe("ZealOS/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_count, key_count;
#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_count, key_count, best_score);
if (!target_count && 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_count--;
}
}
QueueRemove(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;
QueueInsert(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_count)
Sound(Freq2Ona(100 + 60 * Clamp(0.1 * (1.0 + Abs(Wrap(Θf - Θ, -π))) ` 4.0, -3, 3)));
else if (key_count < best_score)
{
best_score = key_count;
Sleep(150);
Sound(74);
Sleep(150);
Sound;
Sleep(150);
Sound(74);
Sleep(150);
Sound;
}
else
Sound;
}
Θ += 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;
QueueInit(&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_count = 0;
target_count = TARGETS_NUM;
}
U0 CleanUp()
{
QueueDel(&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;
PaletteSetLight(FALSE);
Fs->animate_task = Spawn(&AnimateTask, Fs, "Animate",, Fs);
Fs->draw_it = &DrawIt;
Init;
try
{
while (TRUE)
switch (KeyGet(&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_count++;
Θf += 1.0 / (Abs(Wrap(Θf - Θ, -π)) + 2 * π);
break;
case SC_CURSOR_RIGHT:
key_count++;
Θf -= 1.0 / (Abs(Wrap(Θf - Θ, -π)) + 2 * π);
break;
}
break;
case CH_SPACE:
key_count++;
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("ZealOS/BomberGolf", "I64 best_score=%d;\n", best_score);
}
BomberGolf;
                                    
                            
                    
                        
      
     

   

     

  
  


   

   


   

      
      
      


       
      


        
                   

            

                                                                         °        





     





     

     
        

           

           

           
    
    

           

           

        
     

     





     





              δ   %,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
ó   ±   .#                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        r   °                  





             





             

             
                

                   

                   

                   
           
         
       
          

           
                                                                                                                    
   °   #                       





                     





                     

                     
                        

                           

                           

                          
                    
              
                 
                

                  
                                                                                                                                                            j       S!                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ±                                                                                                                                                                                    ±                                                                                                                                                                                                      ±