$BG,0$ $SP,"",1$ $SP,"",2$ $SP,"",3$ $SP,"",4$ $SP,"",5$ $SP,"",6$ $SP,"",7$ $SP,"",8$ $SP,"",9$ $SP,"",10$ $SP,"",11$ $SP,"",12$ $SP,"",13$ $SP,"",14$ $BG$ #define CMD_NULL 0 #define CMD_SPIN_LEFT 1 #define CMD_SPIN_RIGHT 2 #define CMD_THRUST 3 #define CMD_FIRE 4 #define CMD_GAME_OVER 5 I64 cmd_code=CMD_NULL; #define NUM_STARS 100 I64 stars_x[NUM_STARS],stars_y[NUM_STARS]; Bool bounce; #define OT_SHIP 1 #define OT_CARGO 2 #define OT_BULLET 3 #define OT_TINY_ROCK 4 #define OT_SMALL_ROCK 5 #define OT_MEDIUM_ROCK 6 #define OT_LARGE_ROCK 7 #define A_TRANSITION -1 #define A_INACTIVE 0 #define A_ACTIVE 1 class Order2D2é { F64 x,y,é; F64 DxDt,DyDt,DéDt; }; class Obj { I32 active; I32 type; U8 *img; F64 mass,radius; F64 timeout; }; #define NUM_OBJECTS 256 CMathODE *ode; Order2D2é *o_state; Obj *objs; U0 ObjInit(I64 i, I64 type) { objs[i].active=A_ACTIVE; objs[i].timeout=0; objs[i].type=type; switch (type) { case OT_SHIP: if (bounce) objs[i].img=$IB,"",1$; else objs[i].img=$IB,"",3$; objs[i].radius=15; break; case OT_CARGO: objs[i].img=$IB,"",14$; objs[i].radius=30; break; case OT_BULLET: objs[i].img=$IB,"",15$; objs[i].radius=7; break; case OT_TINY_ROCK: if (i&1) objs[i].img=$IB,"",5$; else objs[i].img=$IB,"",6$; objs[i].radius=5; break; case OT_SMALL_ROCK: if (i&1) objs[i].img=$IB,"",16$; else objs[i].img=$IB,"",8$; objs[i].radius=11; break; case OT_MEDIUM_ROCK: if (i&1) objs[i].img=$IB,"",17$; else objs[i].img=$IB,"",10$; objs[i].radius=20; break; case OT_LARGE_ROCK: if (i&1) objs[i].img=$IB,"",18$; else objs[i].img=$IB,"",12$; objs[i].radius=26; break; } objs[i].mass=objs[i].radius*objs[i].radius*objs[i].radius; } I64 ObjAlloc(I64 type) { I64 i; for (i=0;itext_attr=BLACK<<4+WHITE; dc->color=WHITE; for (i=0;iGR_WIDTH) { x%=GR_WIDTH; o_state[i].x=x; } if (y<0) { y=GR_HEIGHT-AbsI64(y)%GR_HEIGHT; o_state[i].y=y; } else if (y>GR_HEIGHT) { y%=GR_HEIGHT; o_state[i].y=y; } switch (objs[i].type) { case OT_SHIP: if (bounce) { if (cmd_code==CMD_THRUST && RandU16&0x8000) SpritePlotRotZ3b(dc,x,y,0,$IB,"",2$,o_state[i].é); else SpritePlotRotZ3b(dc,x,y,0,$IB,"",1$,o_state[i].é); } else { if (cmd_code==CMD_THRUST && RandU16&0x8000) SpritePlotRotZ3b(dc,x,y,0,$IB,"",4$,o_state[i].é); else SpritePlotRotZ3b(dc,x,y,0,$IB,"",3$,o_state[i].é); } break; case OT_BULLET: case OT_TINY_ROCK: case OT_SMALL_ROCK: case OT_MEDIUM_ROCK: case OT_LARGE_ROCK: case OT_CARGO: SpritePlotRotZ3b(dc,x,y,0,objs[i].img,o_state[i].é); break; } } } } dc->color=WHITE; GrPutS(dc,0,0,"Escort the cargo ship."); } U0 Init() { I64 i,j; cmd_code=CMD_NULL; for (i=0;i1000000.0) f=1000000.0; } } else f=-2.5*objs[i].mass*objs[j].mass/(dd+1.0); DstateDt[i].DxDt+=f*dx/objs[i].mass; DstateDt[i].DyDt+=f*dy/objs[i].mass; } } } } switch (cmd_code) { case CMD_SPIN_LEFT: DstateDt[0].DéDt-=10.0; break; case CMD_SPIN_RIGHT: DstateDt[0].DéDt+=10.0; break; case CMD_THRUST: DstateDt[0].DxDt+=100.0*Cos(state[0].é-ã/2.0); DstateDt[0].DyDt+=100.0*Sin(state[0].é-ã/2.0); break; } DstateDt[1].DxDt+=2.0*Cos(state[1].é-ã/2.0); DstateDt[1].DyDt+=2.0*Sin(state[1].é-ã/2.0); } U0 Collision(I64 i,I64 j) { I64 i2; switch (objs[i].type) { case OT_SHIP: if (!bounce) { cmd_code=CMD_GAME_OVER; objs[i].active=A_INACTIVE; } break; case OT_CARGO: cmd_code=CMD_GAME_OVER; objs[i].active=A_INACTIVE; break; case OT_TINY_ROCK: if (objs[j].type==OT_BULLET && !bounce) objs[i].active=A_INACTIVE; break; case OT_BULLET: if (!bounce) objs[i].active=A_INACTIVE; break; case OT_SMALL_ROCK: case OT_MEDIUM_ROCK: i2=ObjAlloc(objs[i].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[i].x+objs[i2].radius+2.0; o_state[i2].y=o_state[i].y; o_state[i2].é=o_state[i].é; o_state[i2].DxDt=o_state[i].DxDt; o_state[i2].DyDt=o_state[i].DyDt; o_state[i2].DéDt=o_state[i].DéDt; i2=ObjAlloc(objs[i].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[i].x-objs[i2].radius-2.0; o_state[i2].y=o_state[i].y; o_state[i2].é=o_state[i].é; o_state[i2].DxDt=o_state[i].DxDt; o_state[i2].DyDt=o_state[i].DyDt; o_state[i2].DéDt=o_state[i].DéDt; objs[i].active=A_INACTIVE; break; case OT_LARGE_ROCK: i2=ObjAlloc(objs[i].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[i].x+objs[i2].radius+4.0; o_state[i2].y=o_state[i].y+objs[i2].radius+4.0; o_state[i2].é=o_state[i].é; o_state[i2].DxDt=o_state[i].DxDt; o_state[i2].DyDt=o_state[i].DyDt; o_state[i2].DéDt=o_state[i].DéDt; i2=ObjAlloc(objs[i].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[i].x-objs[i2].radius-4.0; o_state[i2].y=o_state[i].y-objs[i2].radius-4.0; o_state[i2].é=o_state[i].é; o_state[i2].DxDt=o_state[i].DxDt; o_state[i2].DyDt=o_state[i].DyDt; o_state[i2].DéDt=o_state[i].DéDt; i2=ObjAlloc(objs[i].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[i].x-objs[i2].radius-4.0; o_state[i2].y=o_state[i].y+objs[i2].radius+4.0; o_state[i2].é=o_state[i].é; o_state[i2].DxDt=o_state[i].DxDt; o_state[i2].DyDt=o_state[i].DyDt; o_state[i2].DéDt=o_state[i].DéDt; i2=ObjAlloc(objs[i].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[i].x+objs[i2].radius+4.0; o_state[i2].y=o_state[i].y-objs[i2].radius-4.0; o_state[i2].é=o_state[i].é; o_state[i2].DxDt=o_state[i].DxDt; o_state[i2].DyDt=o_state[i].DyDt; o_state[i2].DéDt=o_state[i].DéDt; objs[i].active=A_INACTIVE; break; } switch (objs[j].type) { case OT_SHIP: if (!bounce) { cmd_code=CMD_GAME_OVER; objs[j].active=A_INACTIVE; } break; case OT_CARGO: cmd_code=CMD_GAME_OVER; objs[j].active=A_INACTIVE; break; case OT_TINY_ROCK: if (objs[i].type==OT_BULLET && !bounce) objs[j].active=A_INACTIVE; break; case OT_BULLET: if (!bounce) objs[j].active=A_INACTIVE; break; case OT_SMALL_ROCK: case OT_MEDIUM_ROCK: i2=ObjAlloc(objs[j].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[j].x+objs[i2].radius+2.0; o_state[i2].y=o_state[j].y; o_state[i2].é=o_state[j].é; o_state[i2].DxDt=o_state[j].DxDt; o_state[i2].DyDt=o_state[j].DyDt; o_state[i2].DéDt=o_state[j].DéDt; i2=ObjAlloc(objs[j].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[j].x-objs[i2].radius-2.0; o_state[i2].y=o_state[j].y; o_state[i2].é=o_state[j].é; o_state[i2].DxDt=o_state[j].DxDt; o_state[i2].DyDt=o_state[j].DyDt; o_state[i2].DéDt=o_state[j].DéDt; objs[j].active=A_INACTIVE; break; case OT_LARGE_ROCK: i2=ObjAlloc(objs[j].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[j].x+objs[i2].radius+4.0; o_state[i2].y=o_state[j].y+objs[i2].radius+4.0; o_state[i2].é=o_state[j].é; o_state[i2].DxDt=o_state[j].DxDt; o_state[i2].DyDt=o_state[j].DyDt; o_state[i2].DéDt=o_state[j].DéDt; i2=ObjAlloc(objs[j].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[j].x-objs[i2].radius-4.0; o_state[i2].y=o_state[j].y-objs[i2].radius-4.0; o_state[i2].é=o_state[j].é; o_state[i2].DxDt=o_state[j].DxDt; o_state[i2].DyDt=o_state[j].DyDt; o_state[i2].DéDt=o_state[j].DéDt; i2=ObjAlloc(objs[j].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[j].x-objs[i2].radius-4.0; o_state[i2].y=o_state[j].y+objs[i2].radius+4.0; o_state[i2].é=o_state[j].é; o_state[i2].DxDt=o_state[j].DxDt; o_state[i2].DyDt=o_state[j].DyDt; o_state[i2].DéDt=o_state[j].DéDt; i2=ObjAlloc(objs[j].type-1); objs[i2].active=A_TRANSITION; o_state[i2].x=o_state[j].x+objs[i2].radius+4.0; o_state[i2].y=o_state[j].y-objs[i2].radius-4.0; o_state[i2].é=o_state[j].é; o_state[i2].DxDt=o_state[j].DxDt; o_state[i2].DyDt=o_state[j].DyDt; o_state[i2].DéDt=o_state[j].DéDt; objs[j].active=A_INACTIVE; break; } } U0 CheckCollisions() { I64 i,j; F64 d,d1,dd,dx,dy; CDC *dc; for (i=0;icolor=ROP_COLLISION; dc->bkcolor=BLACK; SpritePlotRotZ3b(dc,o_state[j].x-o_state[i].x+32, o_state[j].y-o_state[i].y+32,0, objs[j].img,o_state[j].é); if (dc->collision_cnt>0) Collision(i,j); DCDel(dc); } } } } } for (i=0;iMUZZLE_VELOCITY*5.0) Auto(" "); } } U0 SongTask(I64) { //Song by Terry A. Davis Fs->task_end_cb=&SndTaskEndCB; MusicSettingsRst; while (TRUE) { Play("W13eGGsGGeGGGe.GeCDsEDeCBAe.AeG"); Play("GsGGeGGGe.GeFEsDEeDCBe.AeFD"); Play("EDFDEDECDCECDCsGGeG"); Play("GG2hG3sGGeGGG2hG"); } } U0 Rocks() { I64 ch,sc,msg_code; CMenuEntry *tempse; PopUpOk( "I refuse to rip-off the original\n" "so this is intentionally unplayable\n" "and included for demonstration\n" "purposes.\n\n" "Write games, don't play them.\n"); SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$ Fs->song_task=Spawn(&SongTask,NULL,"Song",Fs); Preempt(OFF), WinBorder; WordStat; MenuPush( "File {" " Abort(,CH_SHIFT_ESC);" " Exit(,CH_ESC);" "}" "Play {" " Restart(,'\n');" " Fire(,CH_SPACE);" " Fwd(,,SC_CURSOR_UP);" " Left(,,SC_CURSOR_LEFT);" " Right(,,SC_CURSOR_RIGHT);" " ToggleBounce(,'b');" "}" ); tempse=MenuEntryFind(Fs->cur_menu,"Play/ToggleBounce"); tempse->checked=bounce=TRUE; ode=ODENew(NUM_OBJECTS*6,0.01); ode->derivative=&MyDerivative; ode->min_tolerance=0.001*ode->max_tolerance; o_state=ode->state; objs=MAlloc(NUM_OBJECTS*sizeof(Obj)); WinMax; Init; QueIns(ode,Fs->last_ode); DocCursor; DocClear; Fs->draw_it=&DrawIt; try { while (TRUE) { while (msg_code=ScanMsg(&ch,&sc,1<cur_menu,"Play/ToggleBounce"); tempse->checked=bounce=!bounce; break; } else //MSG_KEY_UP cmd_code=CMD_NULL; } CheckCollisions; CheckCrazy; if (cmd_code==CMD_GAME_OVER) { Sleep(1000); Init; } WinMgrSync; //msgs are only qued by winmngr } rk_done: GetMsg(,,1<