RegDefault("ZealOS/ZoneOut", "F64 best_score=9999;\n"); RegExe("ZealOS/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 SCREEN_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 = SCREEN_SCALE / 2 * *x / zz; *y = SCREEN_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 < SCREEN_SCALE / 2 * SCREEN_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; QueueInsert(tmpo, shots.last); } U0 MoveUs(F64 theta) { us.x += 0.1 * SCREEN_SCALE * Cos(theta); us.z += 0.1 * SCREEN_SCALE * Sin(theta); } U0 AnimateTask(I64) { I64 i; Obj *tmpo, *tmpo1; while (TRUE) { for (i = 0; i < THEM_NUM; i++) { them[i].x += SCREEN_SCALE / 32 * Cos(them[i].theta); them[i].z += SCREEN_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) { QueueRemove(tmpo); Free(tmpo); } else { tmpo->x += 0.25 * SCREEN_SCALE *Cos(tmpo->theta); tmpo->z += 0.25 * SCREEN_SCALE * Sin(tmpo->theta); } tmpo = tmpo1; } Sleep(20); } } U0 Init() { I64 i; DocClear; "$BG, LTCYAN$%h12c", '\n'; QueueInit(&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() { QueueDel(&shots, TRUE); } U0 SongTask(I64) {//Randomly generate (by God :-) Fs->task_end_cb = &SoundTaskEndCB; MusicSettingsReset; while (TRUE) { Play("5sD4B5D4B5qEsG4B5G4B5eD4GsB5F4B5FeD4A5qFG"); Play("5sD4B5D4B5qEsG4B5G4B5eD4GsB5F4B5FeD4A5qFG"); Play("5eGDsFGFGqDE4eB5E4sG5D4G5DqF4sGAGA"); Play("5eGDsFGFGqDE4eB5E4sG5D4G5DqF4sGAGA"); } } U0 ZoneOut() { I64 sc; PopUpOk( "Terry refused 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 (KeyGet(&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("ZealOS/ZoneOut", "F64 best_score=%5.4f;\n", best_score); } ZoneOut;