/*Sprites were created with <CTRL-r> and can be edited by moving the cursor on top and pressing <CTRL-r>. <CTRL-t> to see the num of the sprite and <CTRL-t> again to get back. Nums are assigned by the editor. */ <1>/* Graphics Not Rendered in HTML */ <2>/* Graphics Not Rendered in HTML */ <3>/* Graphics Not Rendered in HTML */ <4>/* Graphics Not Rendered in HTML */ <5>/* Graphics Not Rendered in HTML */ <6>/* Graphics Not Rendered in HTML */ //See ::/Doc/Credits.DD. <7>/* Graphics Not Rendered in HTML */ <8>/* Graphics Not Rendered in HTML */ <9>/* Graphics Not Rendered in HTML */ RegDefault("ZealOS/BlackDiamond", "I64 best_score=9999;\n"); RegExe("ZealOS/BlackDiamond"); #define MAP_HEIGHT 3000 #define OBJS_NUM 128 I64 x, y, screen_top_y, penalty, chair_lift_num; I64 obj_x[OBJS_NUM], obj_y[OBJS_NUM], obj_types[OBJS_NUM], obj_saved_x[OBJS_NUM], obj_saved_y[OBJS_NUM]; Bool game_over; #define T_TREE 0 #define T_LITTLE_ROCK 1 #define T_BIG_ROCK 2 #define T_WOLF 3 #define T_CHAIR_LIFT 4 U8 *imgs[5] = {<3>, <4>, <5>, <6>, <9>}; #define DC_WOLF_WIDTH 48 #define DC_WOLF_HEIGHT 38 U0 DrawRunningWolf(CDC *dc, I64 i) {//Draw wolf on small DC so bottom gets clipped looking like sunk into snow. //Then, copy onto main DC. U8 *tmps; CDC *dc_wolf = DCNew(DC_WOLF_WIDTH, DC_WOLF_HEIGHT); DCFill(dc_wolf); if (x < obj_x[i]) { dc_wolf->flags |= DCF_SYMMETRY | DCF_TRANSFORMATION | DCF_JUST_MIRROR; DCSymmetrySet(dc_wolf, DC_WOLF_WIDTH / 2, 0, DC_WOLF_WIDTH / 2, 1); } if (tS % 1.0 < 0.5) tmps = <6>; else tmps = <7>; Sprite3ZB(dc_wolf, DC_WOLF_WIDTH / 2, 0.85 * DC_WOLF_HEIGHT, 0, tmps, 0.4 * Sin(7 * tS)); GrBlot(dc, obj_x[i] - DC_WOLF_WIDTH / 2, obj_y[i] - screen_top_y - 0.85 * DC_WOLF_HEIGHT, dc_wolf); DCDel(dc_wolf); if (0 <= (obj_y[i] - screen_top_y) < GR_HEIGHT) obj_x[i] += 3 * SignI64(x - obj_x[i]); } U0 DrawMan(CDC *dc) { if (dc->collision_count) Sprite3(dc, x, y - screen_top_y, 0, <2>); //Red man else Sprite3(dc, x, y - screen_top_y, 0, <1>); //Normal man } #define WIRE_HEIGHT 595 #define WIRE_WIDTH 121 #define WIRE_DIP 800 #define PULLY_WIDTH 13 U0 DrawUpperChairLift(CDC *dc) { I64 i = chair_lift_num, x, x1, y = obj_y[i] - screen_top_y - WIRE_HEIGHT, y1; Sprite3(dc, obj_x[i], y + 13, 0, <8>); dc->thick = 2; for (x = -WIRE_WIDTH / 2; x < GR_WIDTH + WIRE_WIDTH / 2; x += 2) { //Pen width is 2, step 2. x1 = x - obj_x[i]; y1 = y - WIRE_DIP / 2 + Cosh(Ln(WIRE_DIP) + (Abs(x1) - PULLY_WIDTH) / 10000.0) + 0.1 * x1; if (!(-PULLY_WIDTH < x1 < PULLY_WIDTH)) { GrPlot3(dc, x - WIRE_WIDTH / 2, y1, 0); GrPlot3(dc, x + WIRE_WIDTH / 2, y1, 0); } } dc->thick = 1; } U0 DrawIt(CTask *, CDC *dc) { I64 i; Bool man_drawn = FALSE; for (i = 0; i < OBJS_NUM; i++) if (obj_y[i] - 32 <= y <= obj_y[i]) { if (obj_types[i] == T_WOLF && AbsI64(x - obj_x[i]) > 3) DrawRunningWolf(dc, i); else Sprite3(dc, obj_x[i], obj_y[i] - screen_top_y, 0, imgs[obj_types[i]]); } dc->collision_count = 0; dc->color = ROP_COLLISION; dc->bkcolor = WHITE; Sprite3(dc, x, y - screen_top_y, 0, <1>); if (!game_over) { if (dc->collision_count) { Sound(58); penalty++; //Time is irregular. Scoring is imperfect. 60fps more or less. } else Sound; } dc->color = ROP_EQU; for (i = 0; i < OBJS_NUM; i++) { if (!man_drawn && obj_y[i] >= y) { DrawMan(dc); man_drawn = TRUE; } if (obj_types[i] == T_WOLF && AbsI64(x - obj_x[i]) > 3) DrawRunningWolf(dc, i); else Sprite3(dc, obj_x[i], obj_y[i] - screen_top_y, 0, imgs[obj_types[i]]); } if (!man_drawn) DrawMan(dc); DrawUpperChairLift(dc); dc->color = BLACK; GrPrint(dc, 0, 0, "Penalty:%d Best:%d", penalty, best_score); if (game_over && Blink) { dc->color = RED; GrPrint(dc, (Fs->pix_width - 9 * FONT_WIDTH) / 2, (Fs->pix_height - FONT_HEIGHT) / 2, "Game Over"); } } I64 Compare(I64 e1, I64 e2) { return e1 - e2; } U0 Init() { I64 i, j; for (i = 0; i < OBJS_NUM; i++) { obj_saved_y[i] = RandU32 % MAP_HEIGHT; obj_saved_x[i] = RandU32 % GR_WIDTH; j = RandU16; if (j & 7) obj_types[i] = T_TREE; else if (j & 31) obj_types[i] = T_LITTLE_ROCK; else if (j & 63) obj_types[i] = T_BIG_ROCK; else obj_types[i] = T_WOLF; } QuickSortI64(obj_saved_y, OBJS_NUM, &Compare); //Break associations. Doesn't matter. chair_lift_num = RandU16 % OBJS_NUM; obj_types[chair_lift_num] = T_CHAIR_LIFT; } U0 BlackDiamond() { I64 ch, sc; MenuPush( "File {" " New(,'\n');" " Restart(,CH_SPACE);" " Abort(,CH_SHIFT_ESC);" " Exit(,CH_ESC);" "}" "Play {" " Up(,,SC_CURSOR_UP);" " Down(,,SC_CURSOR_DOWN);" " Left(,,SC_CURSOR_LEFT);" " Right(,,SC_CURSOR_RIGHT);" "}" ); SettingsPush; //See SettingsPush AutoComplete; WinBorder; WinMax; DocCursor; DocClear; PaletteSetLight(FALSE); Fs->draw_it = &DrawIt; Init; try { while (TRUE) { bd_restart: MemCopy(obj_x, obj_saved_x, sizeof(obj_x)); //Wolves move. We must reset the MemCopy(obj_y, obj_saved_y, sizeof(obj_y)); //wolves if running same game. game_over = FALSE; screen_top_y = 0; x = Fs->pix_width >> 1; y = 0; penalty = 0; while (TRUE) { if (KeyScan(&ch, &sc)) { switch (ch) { case 0: if (!game_over) switch (sc.u8[0]) { case SC_CURSOR_RIGHT: x += 10; if (x >= Fs->pix_width) x -= Fs->pix_width; break; case SC_CURSOR_LEFT: x -= 10; if (x < 0) x += Fs->pix_width; break; case SC_CURSOR_UP: y -= 10; break; case SC_CURSOR_DOWN: y += 10; break; } break; case CH_ESC: case CH_SHIFT_ESC: goto bd_done; case '\n': Init; goto bd_restart; case CH_SPACE: game_over = TRUE; while (screen_top_y > 0 || y > 0) {//Animate going back to top. screen_top_y = MaxI64(0, screen_top_y - 4); y = MaxI64(0, y - 4); x += SignI64(Fs->pix_width >> 1 - x); Sleep(1); } Sound; goto bd_restart; } //Don't want keystrokes building-up in the buf. FlushMessages; } if (!game_over) { y += 2; screen_top_y++; if (y - screen_top_y > Fs->pix_height) {//Animate scrolling screen. while (y - screen_top_y > Fs->pix_height >> 1) { screen_top_y += 2; Sleep(1); } } if (y >= MAP_HEIGHT) { game_over = TRUE; Beep; if (penalty <= best_score) { best_score = penalty; Beep; } } } Sleep(10); } } bd_done: } catch PutExcept; SettingsPop; MenuPop; RegWrite("ZealOS/BlackDiamond", "I64 best_score=%d;\n", best_score); } BlackDiamond; //Start game when #included.