#define THRUST 100 Bool blast_off; CMass m1, //Bottom of rocket m2; //Top of rocket CSpring s; #define ROCKET_HEIGHT 40 #define GROUND_Y (GR_HEIGHT-3*FONT_HEIGHT) <1>/* Graphics Not Rendered in HTML */ /* Graphics Not Rendered in HTML */ CDC *dc2; U0 DrawIt(CTask *task,CDC *dc) { I64 i,x,y,cx=GR_WIDTH/2,cy=GROUND_Y; Bool engine_on; F64 nozzle_angle,theta=Arg(m2.x-m1.x,m2.y-m1.y); Sprite3(dc,0,GROUND_Y,0,<2>); if (Bt(kbd.down_bitmap,SC_CURSOR_UP)) { nozzle_angle=0; engine_on=TRUE; } else if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) { nozzle_angle=pi/8; engine_on=TRUE; } else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) { nozzle_angle=-pi/8; engine_on=TRUE; } else engine_on=FALSE; if (engine_on) { x=m1.x-10*Cos(theta+nozzle_angle); y=m1.y-10*Sin(theta+nozzle_angle); for (i=0;i<6;i++) { if ((i^winmgr.updates)&1) dc->color=YELLOW; else dc->color=RED; GrLine(dc,cx+(m1.x+i*Cos(theta-pi/2)),cy-(m1.y+i*Sin(theta-pi/2)),cx+x,cy-y); GrLine(dc,cx+(m1.x+i*Cos(theta+pi/2)),cy-(m1.y+i*Sin(theta+pi/2)),cx+x,cy-y); } for (i=0;i<10;i++) { switch (RandU16&3) { case 0: dc2->color=WHITE; break; case 1: dc2->color=LTGRAY; break; case 2: dc2->color=DKGRAY; break; case 3: dc2->color=BLACK; break; } GrPlot(dc2,cx+(x+RandU16%12-6),cy-(y+RandU16%12-6)); } Snd(22); } else Snd; Sprite3ZB(dc,cx+(m1.x+m2.x)/2,cy-(m1.y+m2.y)/2,0,<1>,-theta); } U0 MyDerivative(CMathODE *,F64,COrder2D3 *,COrder2D3 *) { Bool engine_on; F64 nozzle_angle,theta=Arg(m2.state->x-m1.state->x,m2.state->y-m1.state->y); if (Bt(kbd.down_bitmap,SC_CURSOR_UP)) { nozzle_angle=0; engine_on=TRUE; } else if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) { nozzle_angle=pi/8; engine_on=TRUE; } else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) { nozzle_angle=-pi/8; engine_on=TRUE; } else engine_on=FALSE; if (engine_on) { m1.DstateDt->DxDt+=THRUST*Cos(theta+nozzle_angle); m1.DstateDt->DyDt+=THRUST*Sin(theta+nozzle_angle); } if (blast_off) { m1.DstateDt->DyDt-=25; //Gravity m2.DstateDt->DyDt-=25; } } U0 Init() { DocClear; "$BG,LTCYAN$$GREEN$Up, Left, Right$FG$%h*c",ToI64(GROUND_Y/FONT_HEIGHT),'\n'; blast_off=FALSE; //We don't clear que links. MemSet(&m1.start,0,offset(CMass.end)-offset(CMass.start)); m1.y=0; MemSet(&m2.start,0,offset(CMass.end)-offset(CMass.start)); m2.y=ROCKET_HEIGHT; MemSet(&s.start,0,offset(CSpring.end)-offset(CSpring.start)); s.end1=&m1; s.end2=&m2; s.rest_len=ROCKET_HEIGHT; s.const=10000; DCFill; } U0 TaskEndCB() { DCFill; SndTaskEndCB; } U0 Rocket() { CMathODE *ode=ODENew(0,1e-2,ODEF_HAS_MASSES); SettingsPush; //See SettingsPush Fs->text_attr=YELLOW<<4+BLUE; MenuPush( "File {" " Abort(,CH_SHIFT_ESC);" " Exit(,CH_ESC);" "}" "Play {" " Restart(,'\n');" " Up(,,SC_CURSOR_UP);" " UpLeft(,,SC_CURSOR_LEFT);" " UpRight(,,SC_CURSOR_RIGHT);" "}" ); AutoComplete; WinBorder; WinMax; DocCursor; DocClear; dc2=DCAlias; Fs->task_end_cb=&TaskEndCB; ode->derive=&MyDerivative; ode->drag_v2=0.002; ode->drag_v3=0.00001; ode->acceleration_limit=5e3; Init; QueIns(&m1,ode->last_mass); QueIns(&m2,ode->last_mass); QueIns(&s,ode->last_spring); QueIns(ode,Fs->last_ode); Fs->draw_it=&DrawIt; try { GetKey; blast_off=TRUE; while (TRUE) { switch (GetChar(,FALSE)) { case '\n': Init; GetKey; blast_off=TRUE; break; case CH_ESC: case CH_SHIFT_ESC: goto rk_done; } } rk_done: } catch PutExcept; QueRem(ode); ODEDel(ode); DocClear; SettingsPop; DCFill; DCDel(dc2); MenuPop; } Rocket;