//These are the coordinates of the player. I64 x = 0, y = GR_HEIGHT / 2; /*This is a FIFO (first-in first-out) data structure which keeps track of bullets. When a new bullet is fired, the bullets_in val is increased by one. When a bullet expires, the bullets_out value is increased by one. The in and out values loop-around, back to the start of the arrays. It is known as a ring-buffer. */ #define BULLETS_NUM 32 I64 bullets_in = 0, bullets_out = 0, bx[BULLETS_NUM], by[BULLETS_NUM]; //This is a fifo which keeps track of the bad guys. #define DEAD_NUM 32 I64 dead_in = 0, dead_out = 0, gx[DEAD_NUM], gy[DEAD_NUM]; Bool g_dead[DEAD_NUM]; /*This is a sprite created and edited by pressing <CTRL-r>. When created, they are assigned a num. Press <CTRL-t>, to see the hidden DolDoc place holder for the sprite. The text in quotes can be set to whatever you want or nothing, but the ending num can't be changed. It is controled by the editor. */ <1>/* Graphics Not Rendered in HTML */ <2>/* Graphics Not Rendered in HTML */ <3>/* Graphics Not Rendered in HTML */ //Called by the Window Mgr system task 60fps. //The task arg is the task owning the window. U0 DrawIt(CTask *task, CDC *dc) { I64 i, j; //<CTRL-t> now to see the DolDoc place holder //where the sprite num is encoded. $IB...$ stands //for "insert pointer to binary object". Sprite3(dc, x, y, 0, <1>); i = bullets_out; while (i != bullets_in) { j = i++ & (BULLETS_NUM - 1); GrLine(dc, bx[j], by[j], bx[j] - 2, by[j]); } i = dead_out; while (i != dead_in) { j = i++ & (BULLETS_NUM - 1); if (!g_dead[j]) { if (gx[j] % 10 > 4) Sprite3(dc, gx[j], gy[j], 0, <2>); else Sprite3(dc, gx[j], gy[j], 0, <3>); } } dc->color = BLACK; GrPrint(dc, 0, 0, "If you aspire to making games,"); GrPrint(dc, 0, FONT_HEIGHT, "you must learn to make-up rules."); } U0 SongTask(I64) {//Randomly generate (by God :-) Fs->task_end_cb = &SoundTaskEndCB; MusicSettingsReset; while (TRUE) { Play("5qDqDsDCDC4etB5C4B5qCqCqCqCqDqDsDCDC4etB5C4B5qCqCqCqCqCqCsCCCCetCCBeBBeBBqBqBqCqCsCCCCetCCBeBBeBBqBqB"); } } U0 TheDead() { I64 i, j, i1, j1, k = 0, sc = 0, ch = 0, message_code, arg1, arg2; Bool gun_on = FALSE; MenuPush( "File {" " Abort(,CH_SHIFT_ESC);" " Exit(,CH_ESC);" "}" "Play {" " Fire(,CH_SPACE);" " Up(,,SC_CURSOR_UP);" " Down(,,SC_CURSOR_DOWN);" "}" ); SettingsPush; //See SettingsPush AutoComplete; WinBorder; WinMax; DocCursor; DocClear; Fs->song_task = Spawn(&SongTask, NULL, "Song",, Fs); Fs->draw_it = &DrawIt; try { do { if (message_code = MessageScan(&arg1, &arg2, 1 << MESSAGE_KEY_DOWN | 1 << MESSAGE_KEY_UP)) { //With keyboard messages, the two message args //are the scan code and ascii value for the key. sc = arg2; ch = arg1; if (message_code == MESSAGE_KEY_DOWN) { //The low byte of the scan code identifies the key. if (sc.u8[0] == SC_CURSOR_DOWN) { y += 10; if (y > GR_HEIGHT - 30) y = GR_HEIGHT - 30; } else if (sc.u8[0] == SC_CURSOR_UP) { y -= 10; if (y < 0) y = 0; } else if (sc.u8[0] == SC_CURSOR_RIGHT || ch == CH_SPACE) gun_on = TRUE; } else if (message_code == MESSAGE_KEY_UP) { if (sc.u8[0] == SC_CURSOR_RIGHT || ch == CH_SPACE) gun_on = FALSE; } } i = bullets_out; while (i != bullets_in) { j = i++ & (BULLETS_NUM - 1); bx[j] += 5; if (bx[j] > GR_WIDTH) bullets_out++; else { i1 = dead_out; while (i1 != dead_in) { j1 = i1++ & (DEAD_NUM - 1); if (gy[j1] <= by[j] <= gy[j1] + 38 && gx[j1] <= bx[j] <= gx[j1] + 40) g_dead[j1] = TRUE; } } } if (gun_on) { j = bullets_in & (BULLETS_NUM - 1); bx[j] = x + 32; by[j] = y + 14; bullets_in++; } //Runs one out of four passes through this loop. if (!(k % 4)) { i = dead_out; while (i != dead_in) { j = i++ &(DEAD_NUM - 1); gx[j] -= 1; if (gx[j] < 25) dead_out++; } } //Runs one out of 150 passes through this loop. if (!(k % 150)) { j = dead_in & (DEAD_NUM - 1); gx[j] = GR_WIDTH - 30; gy[j] = RandU32 % (GR_HEIGHT - 50) + 25; g_dead[j] = FALSE; dead_in++; } k++; Sleep(10); //Swap this task out for 10 miliseconds. } while (ch != CH_ESC && ch != CH_SHIFT_ESC); } catch PutExcept; SettingsPop; MenuPop; } TheDead; //Run program when #included