RegDefault("ZealOS/DunGen", "F64 best_score=9999;\n"); RegExe("ZealOS/DunGen"); //Set snap to 4 and width to 4 //if you edit this map. //Don't forget to change the //starting pos. <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 */ <7>/* Graphics Not Rendered in HTML */ <8>/* Graphics Not Rendered in HTML */ <9>/* Graphics Not Rendered in HTML */ <10>/* Graphics Not Rendered in HTML */ //These are indexed by color #. //See COLORS. U8 *tiles1[16]={NULL, <7> , <5> , NULL, NULL, NULL, NULL, NULL, <6> , NULL, NULL, NULL, NULL, NULL, NULL, NULL}; U8 *tiles2[16]={NULL, <8> , <5> , NULL, NULL, NULL, NULL, NULL, <6> , NULL, NULL, NULL, NULL, NULL, NULL, NULL}; #define SCREEN_SCALE 24 #define SCREEN_WIDTH 24 #define SCREEN_HEIGHT 24 I64 screen_x, screen_y; #define MAP_SCALE 4 I64 map_width, map_height; U8 *map = NULL; I64 man_x, man_y, man_dx, man_dy; Bool man_attack; F64 man_attack_t0; #define MONSTERS_NUM 10 I64 monsters_left; class Monster { I64 x, y, dx, dy; Bool dead, pad[7]; } monsters[MONSTERS_NUM]; F64 t0, tf; #define LOS_SCALE 4 Bool LOSPlot(U8 *, I64 x, I64 y, I64) { if (!map[(y / LOS_SCALE) * map_width + (x / LOS_SCALE)]) return FALSE; else return TRUE; } Bool LOS(I64 x1, I64 y1, I64 x2, I64 y2) {//Line of sight return Line(NULL, x1 * LOS_SCALE + LOS_SCALE / 2, y1 * LOS_SCALE + LOS_SCALE / 2, 0, x2 * LOS_SCALE + LOS_SCALE / 2, y2 * LOS_SCALE + LOS_SCALE / 2, 0, &LOSPlot); } U0 DrawIt(CTask *task, CDC *dc) { CDC *dc_t = DCAlias(gr.dc2, task); I64 i, x, y, xx, yy, x1, y1, z1, color, cx = task->pix_width / 2, cy = task->pix_height / 2; CD3I32 poly[4]; U8 **_tiles; F64 tt; Monster *tmpm; if (Blink(5)) _tiles = tiles1; else _tiles = tiles2; Mat4x4RotX(dc_t->r, 60 * 2 * pi / 360); Mat4x4RotZ(dc_t->r, 15 * 2 * pi / 360); DCMat4x4Set(dc_t, dc_t->r); dc_t->x = task->pix_width / 2; dc_t->y = task->pix_height / 2; dc_t->flags |= DCF_TRANSFORMATION; //You could make it much more efficient //if you did it like ::/Demo/Games/BigGuns.ZC //with a CDC. for (y = -SCREEN_HEIGHT / 2; y < SCREEN_HEIGHT / 2; y++) { yy = y + screen_y; if (0 <= yy < map_height) for (x = -SCREEN_WIDTH / 2; x < SCREEN_WIDTH / 2; x++) { xx = x + screen_x; if (0 <= xx < map_width) { if ((color = map[yy * map_width + xx]) && LOS(xx, yy, man_x, man_y)) { if (_tiles[color]) { x1 = x * SCREEN_SCALE; y1 = y * SCREEN_SCALE; z1 = 0; DCTransform(dc_t, &x1, &y1, &z1); Sprite3(dc, x1, y1, z1, _tiles[color]); } else {//If no tile defined, do solid color. poly[0].x = x * SCREEN_SCALE; poly[0].y = y * SCREEN_SCALE; poly[0].z = 0; poly[1].x = (x + 1) * SCREEN_SCALE - 1; poly[1].y = y * SCREEN_SCALE; poly[1].z = 0; poly[2].x = (x + 1) * SCREEN_SCALE; poly[2].y = (y + 1) * SCREEN_SCALE - 1; poly[2].z = 0; poly[3].x = x * SCREEN_SCALE - 1; poly[3].y = (y + 1) * SCREEN_SCALE - 1; poly[3].z = 0; dc_t->color = color; GrFillPoly3(dc_t, 4, poly); } } } } } for (y = -SCREEN_HEIGHT / 2; y < SCREEN_HEIGHT / 2; y++) { yy = y + screen_y; if (0 <= yy < map_height) for (x = -SCREEN_WIDTH / 2; x < SCREEN_WIDTH / 2; x++) { xx = x + screen_x; if (0 <= xx < map_width) { if (!map[yy * map_width + xx]) { if (yy + 1 < map_height && LOS(xx, yy + 1, man_x, man_y)) { x1 = x * SCREEN_SCALE; y1 = y * SCREEN_SCALE; z1 = 0; DCTransform(dc_t, &x1, &y1, &z1); Sprite3(dc, x1, y1, z1, <9>); } if (xx + 1 < map_width && LOS(xx + 1, yy, man_x, man_y)) { x1 = x * SCREEN_SCALE; y1 = y * SCREEN_SCALE; z1 = 0; DCTransform(dc_t, &x1, &y1, &z1); Sprite3(dc, x1, y1, z1, <10>); } } } } } for (i = 0, tmpm = monsters; i < MONSTERS_NUM; i++, tmpm++) if (!tmpm->dead && LOS(tmpm->x, tmpm->y, man_x, man_y)) { x1 = (tmpm->x - screen_x) * SCREEN_SCALE + SCREEN_SCALE / 2; y1 = (tmpm->y - screen_y) * SCREEN_SCALE + SCREEN_SCALE / 2; z1 = 0; DCTransform(dc_t, &x1, &y1, &z1); if (tmpm->dx < 0) { dc->flags |= DCF_SYMMETRY|DCF_JUST_MIRROR; DCSymmetrySet(dc, x1, y1, x1, y1 + 1); } else dc->flags &= ~(DCF_SYMMETRY | DCF_JUST_MIRROR); Sprite3(dc, x1, y1, z1, <4>); } x1 = (man_x - screen_x) * SCREEN_SCALE + SCREEN_SCALE / 2; y1 = (man_y - screen_y) * SCREEN_SCALE + SCREEN_SCALE / 2; z1 = 0; if (tS - man_attack_t0 < 0.2) { x1 += Tri(tS - man_attack_t0, 0.2) * SCREEN_SCALE * man_dx; y1 += Tri(tS - man_attack_t0, 0.2) * SCREEN_SCALE * man_dy; if (man_dy != 1) y1 -= Saw(tS - man_attack_t0, 0.2) * SCREEN_SCALE; } DCTransform(dc_t, &x1, &y1, &z1); if (man_dx < 0) { dc->flags |= DCF_SYMMETRY | DCF_JUST_MIRROR; DCSymmetrySet(dc, x1, y1, x1, y1 + 1); } else dc->flags &= ~(DCF_SYMMETRY | DCF_JUST_MIRROR); if (tS - man_attack_t0 < 0.2) Sprite3(dc, x1, y1, z1, <3>); else Sprite3(dc, x1, y1, z1, <2>); DCDel(dc_t); if (tf) { dc->color = LTRED; if (Blink) GrPrint(dc, cx - (FONT_WIDTH * 14) / 2, cy - FONT_HEIGHT / 2, "Game Completed"); tt = tf; } else { dc->color = LTGREEN; tt = tS; } GrPrint(dc, 0, 0, "Enemy:%d Time:%3.2f Best:%3.2f", monsters_left, tt - t0, best_score); } U0 Attack() { I64 i; Monster *tmpm; man_attack_t0 = tS; Noise(100, 53, 74); for (i = 0, tmpm = monsters; i < MONSTERS_NUM; i++, tmpm++) { if (!tmpm->dead && man_x + man_dx == tmpm->x && man_y + man_dy == tmpm->y) { tmpm->dead = TRUE; if (!--monsters_left) { tf = tS; if (tf - t0 < best_score) best_score = tf - t0; } } } } U0 Init() { I64 i, x, y; CDC *dc; Monster *tmpm; dc = Sprite2DC(<1>); map_width = dc->width / MAP_SCALE; map_height = dc->height / MAP_SCALE; Free(map); map = MAlloc(map_width * map_height * sizeof(U8)); for (y = 0; y < map_height; y++) for (x = 0; x < map_width; x++) map[y * map_width + x] = GrPeek(dc, x * MAP_SCALE, y * MAP_SCALE); DCDel(dc); man_attack_t0 = 0; man_attack = FALSE; man_x = 0; man_y = 4; man_dx = 0; man_dy = 0; screen_x = 0; screen_y = 0; for (i = 0, tmpm = monsters; i < MONSTERS_NUM; i++, tmpm++) { tmpm->dead = FALSE; tmpm->dx = 0; tmpm->dy = 0; do { tmpm->x = RandU64 % (map_width - 2) + 1; tmpm->y = RandU64 % (map_height - 2) + 1; } while (!map[(tmpm->y) * map_width + tmpm->x]); } monsters_left = MONSTERS_NUM; tf = 0; t0 = tS; } U0 CleanUp() { Free(map); map = NULL; } U0 AnimateTask(I64) { I64 i, x, y, dx, dy; Monster *tmpm; while (TRUE) { for (i = 0, tmpm = monsters; i < MONSTERS_NUM; i++, tmpm++) if (!tmpm->dead) { dx = RandU16 % 3 - 1; dy = RandU16 % 3 - 1; x = tmpm->x + dx; y = tmpm->y + dy; if (0 <= x < map_width && 0 <= y < map_height && map[y * map_width + x]) { tmpm->x = x; tmpm->y = y; tmpm->dx = dx; tmpm->dy = dy; } } Sleep(1000); } } U0 DunGen() { I64 ch, sc; MenuPush( "File {" " Abort(,CH_SHIFT_ESC);" " Exit(,CH_ESC);" "}" "Play {" " Restart(,'\n');" " Up(,,SC_CURSOR_UP);" " Down(,,SC_CURSOR_DOWN);" " Left(,,SC_CURSOR_LEFT);" " Right(,,SC_CURSOR_RIGHT);" " Attack(,CH_SPACE);" "}" ); SettingsPush; //See SettingsPush Fs->text_attr = BLACK << 4 + WHITE; AutoComplete; WinBorder; WinMax; DocCursor; DocClear; Init; PaletteSetLight(FALSE); Fs->animate_task = Spawn(&AnimateTask, NULL, "Animate",, Fs); Fs->draw_it = &DrawIt; try { while (TRUE) { switch (MessageGet(&ch, &sc, 1 << MESSAGE_KEY_DOWN | 1 << MESSAGE_KEY_UP)) { case MESSAGE_KEY_DOWN: switch (ch) { case '\n': Init; break; case CH_SPACE: man_attack = TRUE; break; case CH_ESC: case CH_SHIFT_ESC: goto dg_done; case 0: switch (sc.u8[0]) { case SC_CURSOR_RIGHT: if (man_attack) { man_dx = 1; man_dy = 0; Attack; } else if (man_x + 1 < map_width && map[man_y * map_width + (man_x + 1)] == DKGRAY) { man_x++; if (man_x - screen_x > SCREEN_WIDTH / 2 - 3) { screen_x += SCREEN_WIDTH / 2; if (screen_x + SCREEN_WIDTH / 2 > map_width) screen_x = map_width - SCREEN_WIDTH / 2; } } break; case SC_CURSOR_LEFT: if (man_attack) { man_dx = -1; man_dy = 0; Attack; } else if (man_x - 1 >= 0 && map[man_y * map_width + (man_x - 1)] == DKGRAY) { man_x--; if (man_x - screen_x < -SCREEN_WIDTH / 2 + 3) { screen_x -= SCREEN_WIDTH / 2; if (screen_x - SCREEN_WIDTH / 2 < 0) screen_x = SCREEN_WIDTH / 2; } } break; case SC_CURSOR_UP: if (man_attack) { man_dx = 0; man_dy = -1; Attack; } else if (man_y - 1 >= 0 && map[(man_y - 1) * map_width + man_x] == DKGRAY) { man_y--; if (man_y - screen_y < -SCREEN_HEIGHT / 2 + 3) { screen_y -= SCREEN_HEIGHT / 2; if (screen_y - SCREEN_HEIGHT / 2 < 0) screen_y = SCREEN_HEIGHT / 2; } } break; case SC_CURSOR_DOWN: if (man_attack) { man_dx = 0; man_dy = 1; Attack; } else if (man_y + 1 < map_height && map[(man_y + 1) * map_width + man_x] == DKGRAY) { man_y++; if (man_y - screen_y > SCREEN_HEIGHT / 2 - 3) { screen_y += SCREEN_HEIGHT / 2; if (screen_y + SCREEN_HEIGHT / 2 > map_height) screen_y = map_height - SCREEN_HEIGHT / 2; } } break; } } break; case MESSAGE_KEY_UP: if (ch == CH_SPACE) man_attack = FALSE; break; } } dg_done: MessageGet(,, 1 << MESSAGE_KEY_UP); } catch PutExcept; SettingsPop; CleanUp; MenuPop; RegWrite("ZealOS/DunGen", "F64 best_score=%5.4f;\n", best_score); } DunGen;