/*$WW,1$
$FG,2$This game measures your response time. You swing at the last possible fraction of a second.
I went overboard using the differential equation solver in this example. It's more like gravitational bodies.
$FG,4$GrElem$FG,2$ collision detection is used.
$WW,0$$FG$*/
#define OBJ_BASE 0
#define NUM_OBJECTS 5
#define A_TRANSITION -1
#define A_INACTIVE 0
#define A_ACTIVE 1
class Object
{
I4 active;
I4 type;
U1 *img;
double mass,radius;
U8 collision_time;
};
Order2D3 *ms;
Object *objs;
I8 score,total_score,num_scores,best_score;
$PI,"",1$
$PI,"",2$
void DrawIt(TssStruct *tss)
{
I8 i,cx=(tss->win_pixel_right-tss->win_pixel_left)>>1,
cy=(tss->win_pixel_bottom-tss->win_pixel_top)>>1;
I1 buf[128];
double average=total_score,best=best_score/10.0;
if (num_scores)
average/=num_scores;
else
average/=10.0;
if (best_score==MAX_I8)
best=0;
GrBitMap *base=GrAlias(grbase2,tss);
ClearWinText(tss);
for (i=0;i9) {
base->color=RED;
GrText(base,0,0,"Hit a key for a new round.");
} else {
base->color=BLACK;
GrText(base,0,0,"Hit a key at the last possible moment.");
}
GrText(base,0,FONT_HEIGHT*2,buf);
GrDel(base);
}
void MyDerivative(Ode *ode,double t,Order2D3 *state,Order2D3 *DstateDt)
{
I8 i,j;
double dx,dy,d,d1,dd,f;
nounusedwarn ode,t;
MemSet(DstateDt,0,sizeof(Order2D3)*NUM_OBJECTS);
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;
}
}
}
}
}
void CheckCollisions()
{
I8 i,j;
double d,d1,dd,dx,dy;
GrBitMap *b;
for (i=0;icolor=WHITE;
GrBox(b,0,0,64,64);
GrElemsPlot(b,32,32,0,objs[i].img);
b->bkcolor=ROP_COLLISION+WHITE;
GrElemsPlot(b,ms[j].x-ms[i].x+32,ms[j].x-ms[i].y+32,0,objs[j].img);
if (b->collision_cnt>0) {
objs[i].collision_time=objs[j].collision_time=GetTimeStamp;
objs[i].active=objs[j].active=A_INACTIVE;
}
GrDel(b);
}
}
}
}
}
for (i=0;i",1$;
ms[1+num_balls].x=-300;
ms[1+num_balls].y=0;
ms[1+num_balls].DxDt=RandU4%500;
ms[1+num_balls].DyDt=-(RandU4%20)+10;
objs[1+num_balls].mass=RandU4%10000+1;
if (Abs(ms[1+num_balls].DyDt)>5.0)
objs[1+num_balls].mass+=RandU4%100000+10000;
if (Abs(ms[1+num_balls].DyDt)>8.0)
objs[1+num_balls].mass+=RandU4%100000+10000;
objs[1+num_balls].radius=8.0;
objs[1+num_balls].active=A_ACTIVE;
objs[1+num_balls++].img=$IB,"",2$;
if (RandU4%5==0) {
ms[1+num_balls].x=300;
ms[1+num_balls].y=0;
ms[1+num_balls].DxDt=-(RandU4%500);
ms[1+num_balls].DyDt=-(RandU4%20)+10;
objs[1+num_balls].mass=RandU4%10000+1;
if (Abs(ms[1+num_balls].DyDt)>5.0)
objs[1+num_balls].mass+=RandU4%100000+10000;
if (Abs(ms[1+num_balls].DyDt)>8.0)
objs[1+num_balls].mass+=RandU4%100000+10000;
objs[1+num_balls].radius=8.0;
objs[1+num_balls].active=A_ACTIVE;
objs[1+num_balls++].img=$IB,"",2$;
}
if (RandU4%5==0) {
ms[1+num_balls].y=-300;
ms[1+num_balls].x=0;
ms[1+num_balls].DyDt=RandU4%500;
ms[1+num_balls].DxDt=-(RandU4%20)+10;
objs[1+num_balls].mass=RandU4%10000+1;
if (Abs(ms[1+num_balls].DxDt)>5.0)
objs[1+num_balls].mass+=RandU4%100000+10000;
if (Abs(ms[1+num_balls].DyDt)>8.0)
objs[1+num_balls].mass+=RandU4%100000+10000;
objs[1+num_balls].radius=8.0;
objs[1+num_balls].active=A_ACTIVE;
objs[1+num_balls++].img=$IB,"",2$;
}
if (RandU4%5==0) {
ms[1+num_balls].y=300;
ms[1+num_balls].x=0;
ms[1+num_balls].DyDt=-(RandU4%500);
ms[1+num_balls].DxDt=-(RandU4%20)+10;
objs[1+num_balls].mass=RandU4%10000+1;
if (Abs(ms[1+num_balls].DxDt)>5.0)
objs[1+num_balls].mass+=RandU4%100000+10000;
if (Abs(ms[1+num_balls].DyDt)>8.0)
objs[1+num_balls].mass+=RandU4%100000+10000;
objs[1+num_balls].radius=8.0;
objs[1+num_balls].active=A_ACTIVE;
objs[1+num_balls++].img=$IB,"",2$;
}
}
$FG,4$//This routine is called when the task in charge of
//playing the background music is killed. It turns off
//the sound and ends the task with $FG,2$Exit$FG,2$. $FG$
void SongEndTsk()
{
Sound(0);
Exit;
}
void SongTsk()
{
$FG,4$//This establishes a function which will be called when
//this task is killed.$FG$
Fs->end_task_cb=&SongEndTsk;
ResetMusicSettings;
while (TRUE)
Play("qRe2G32G3etCADqBqBe2G3RetCAReFGqRe2G32G3etCADqBqBe2G3RetCAReFGsRGRGqGeFGqEsCGCGetDAFqCqAsRGRGqGeFGqEsCGCGetDAFqCqA");
}
void Swing()
{
I8 ch,key_time;
void *old_update=Fs->update_win;
Ode *ode=OdeNew(NUM_OBJECTS*6);
BoolU4 old_preempt=Preempt(OFF);
BoolU4 old_border=WinBorder(OFF);
BoolU4 old_mute=music_mute;
TssStruct *song_tss=Spawn(&SongTsk,"Swing Song",Fs);
WinMax;
objs=MAlloc(sizeof(Object)*NUM_OBJECTS);
ode->derivative=&MyDerivative;
ode->tolerance_start=.01;
ms=ode->state;
InitObjs;
InsQue(ode,Fs->last_ode);
Fs->update_win=&DrawIt;
score=0;
num_scores=0;
total_score=0;
best_score=MAX_I8;
do {
FlushMsgs;
InitObjs;
ch=0;
while (!ch && !objs[OBJ_BASE].collision_time) {
CheckCollisions;
SwapInNext;
ScanKey(&ch);
}
if (ch!=CH_CTRLQ && ch!=CH_ESC) {
if (objs[OBJ_BASE].collision_time) {
music_mute=TRUE;
Sound(0);
Beep;
Beep;
music_mute=old_mute;
score=time_stamp_freq; //penalty
} else {
key_time=kbd_evt_time;
while (!ScanKey(&ch) &&
!objs[OBJ_BASE].collision_time) {
CheckCollisions;
SwapInNext;
}
score=GetTimeStamp-key_time;
}
total_score+=score;
num_scores++;
if (num_scores>9) {
music_mute=TRUE;
Sound(2000);
Sleep(1000);
Sound(0);
music_mute=old_mute;
if (total_scoreupdate_win=old_update;
RemQue(ode);
OdeDel(ode);
Free(objs);
WinBorder(old_border);
Preempt(old_preempt);
}
Swing;
h óÿÿÿòÿÿÿ ÷ÿÿÿöÿÿÿ
ûÿÿÿúÿÿÿ ÿÿÿÿþÿÿÿ ‰
ûÿÿÿúÿÿÿ þÿÿÿ ùÿÿÿ
üÿÿÿ ýÿÿÿ ýÿÿÿ