/*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 */ RegDft("TempleOS/BlackDiamond","I64 best_score=9999;\n"); RegExe("TempleOS/BlackDiamond"); #define MAP_HEIGHT 3000 #define OBJS_NUM 128 I64 x,y,scrn_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]-scrn_top_y-0.85*DC_WOLF_HEIGHT,dc_wolf); DCDel(dc_wolf); if (0<=(obj_y[i]-scrn_top_y)<GR_HEIGHT) obj_x[i]+=3*SignI64(x-obj_x[i]); } U0 DrawMan(CDC *dc) { if(dc->collision_cnt) Sprite3(dc,x,y-scrn_top_y,0,<2>); //Red man else Sprite3(dc,x,y-scrn_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]-scrn_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]-scrn_top_y,0,imgs[obj_types[i]]); } dc->collision_cnt=0; dc->color=ROP_COLLISION; dc->bkcolor=WHITE; Sprite3(dc,x,y-scrn_top_y,0,<1>); if (!game_over) { if(dc->collision_cnt) { Snd(58); penalty++; //Time is irregular. Scoring is imperfect. 30fps more or less. } else Snd; } 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]-scrn_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; } QSortI64(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; Fs->draw_it=&DrawIt; Init; try { while (TRUE) { bd_restart: MemCpy(obj_x,obj_saved_x,sizeof(obj_x)); //Wolves move. We must reset the MemCpy(obj_y,obj_saved_y,sizeof(obj_y)); //wolves if running same game. game_over=FALSE; scrn_top_y=0; x=Fs->pix_width>>1; y=0; penalty=0; while (TRUE) { if (ScanKey(&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 (scrn_top_y>0||y>0) {//Animate going back to top. scrn_top_y=MaxI64(0,scrn_top_y-4); y=MaxI64(0,y-4); x+=SignI64(Fs->pix_width>>1-x); Sleep(1); } Snd; goto bd_restart; } //Don't want keystrokes building-up in the buf. FlushMsgs; } if (!game_over) { y+=2; scrn_top_y++; if (y-scrn_top_y>Fs->pix_height) {//Animate scrolling scrn. while (y-scrn_top_y>Fs->pix_height>>1) { scrn_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("TempleOS/BlackDiamond","I64 best_score=%d;\n",best_score); } BlackDiamond; //Start game when #included.