📄 main.cpp
字号:
}
// Evade
if(Units[i].Evade)
{
u = Units[0].vPosition;
d = u - Units[i].vPosition;
w = VRotate2D(-Units[i].fOrientation, d);
if(w.x < 0) m = 1;
if(w.x > 0) m = -1;
Fs.x += m*_STEERINGFORCE;
}
// apply accumulated steering force
Units[i].Fa = Fs;
Units[i].Pa = Pfs;
// end Flock AI
}
void UpdateSimulation(void)
{
double dt = _TIMESTEP;
int i;
Vector u;
bool kill = false;
// initialize the back buffer
if(FrameCounter >= _RENDER_FRAME_COUNT)
ClearBackBuffer();
// Update player controlled unit:
Units[0].SetThrusters(false, false, 1);
Units[0].SetThrusters(false, false, 1);
if (IsKeyDown(VK_RIGHT))
Units[0].SetThrusters(true, false, 0.5);
if (IsKeyDown(VK_LEFT))
Units[0].SetThrusters(false, true, 0.5);
if (IsKeyDown('0'))
DamageRate = 0.0;
if (IsKeyDown('1'))
DamageRate = 0.2;
if (IsKeyDown('2'))
DamageRate = 0.4;
if (IsKeyDown('3'))
DamageRate = 0.6;
if (IsKeyDown('4'))
DamageRate = 0.8;
if (IsKeyDown('5'))
DamageRate = 1.0;
if (IsKeyDown('6'))
DamageRate = 1.2;
if (IsKeyDown('7'))
DamageRate = 1.4;
if (IsKeyDown('8'))
DamageRate = 1.6;
if (IsKeyDown('9'))
DamageRate = 1000.0;
Units[0].UpdateBodyEuler(dt);
if(FrameCounter >= _RENDER_FRAME_COUNT)
DrawCraft(Units[0], RGB(0, 255, 0));
if(Units[0].vPosition.x > _WINWIDTH) Units[0].vPosition.x = 0;
if(Units[0].vPosition.x < 0) Units[0].vPosition.x = _WINWIDTH;
if(Units[0].vPosition.y > _WINHEIGHT) Units[0].vPosition.y = 0;
if(Units[0].vPosition.y < 0) Units[0].vPosition.y = _WINHEIGHT;
// calc number of enemy units currently engaging the target
Vector d;
Units[0].NumFriends = 0;
for(i=1; i<_MAX_NUM_UNITS; i++)
{
d = Units[i].vPosition - Units[0].vPosition;
if(d.Magnitude() <= (Units[0].fLength * _CRITICAL_RADIUS_FACTOR))
Units[0].NumFriends++;
}
// deduct hit points from target
if(Units[0].NumFriends > 0)
{
Units[0].HitPoints -= 0.2 * Units[0].NumFriends;
if(Units[0].HitPoints < 0)
{
Units[0].vPosition.x = _WINWIDTH/2;
Units[0].vPosition.y = _WINHEIGHT/2;
Units[0].HitPoints = _MAXHITPOINTS;
kill = true;
}
} else {
//Units[0].HitPoints += 1;
//if(Units[0].HitPoints > _MAXHITPOINTS) Units[0].HitPoints = _MAXHITPOINTS;
}
// update computer controlled units:
for(i=1; i<_MAX_NUM_UNITS; i++)
{
u = Units[0].vPosition - Units[i].vPosition;
if(kill)
{
if((u.Magnitude() <= (Units[0].fLength * _CRITICAL_RADIUS_FACTOR)) /*&& (Units[i].Command != 2)*/)
{
ReTrainTheBrain(i, 0.9, 0.1, 0.1, 0.1);
Units[i].HitPoints += _MAXHITPOINTS/4.0f;
if(Units[i].HitPoints > _MAXHITPOINTS) Units[i].HitPoints = _MAXHITPOINTS;
}
}
// handle enemy hitpoints, and learning if required
if(u.Magnitude() <= (Units[0].fLength * _CRITICAL_RADIUS_FACTOR))
{
Units[i].HitPoints -= DamageRate;
if((Units[i].HitPoints < 0))
{
Units[i].vPosition.x = GetRandomNumber(_WINWIDTH/2-_SPAWN_AREA_R, _WINWIDTH/2+_SPAWN_AREA_R, false);
Units[i].vPosition.y = GetRandomNumber(_WINHEIGHT/2-_SPAWN_AREA_R, _WINHEIGHT/2+_SPAWN_AREA_R, false);
Units[i].HitPoints = _MAXHITPOINTS/2.0;
// if(Units[i].Command == 0)
ReTrainTheBrain(i, 0.1, 0.1, 0.9, 0.1);
}
} else {
Units[i].HitPoints+=0.01;
if(Units[i].HitPoints > _MAXHITPOINTS) Units[i].HitPoints = _MAXHITPOINTS;
/* if((Units[i].HitPoints < 0))
{
Units[i].vPosition.x = GetRandomNumber(_WINWIDTH/2-_SPAWN_AREA_R, _WINWIDTH/2+_SPAWN_AREA_R, false);
Units[i].vPosition.y = GetRandomNumber(_WINHEIGHT/2-_SPAWN_AREA_R, _WINHEIGHT/2+_SPAWN_AREA_R, false);
Units[i].HitPoints = _MAXHITPOINTS/2;
if (Units[i].Command != 0)
ReTrainTheBrain(i, 0.9, 0.1, 0.1, 0.1);
}*/
}
// get a new command
Units[i].Inputs[0] = Units[i].NumFriends/_MAX_NUM_UNITS;
Units[i].Inputs[1] = (double) (Units[i].HitPoints/_MAXHITPOINTS);
Units[i].Inputs[2] = (Units[0].NumFriends>0 ? 1:0);
Units[i].Inputs[3] = (u.Magnitude()/800.0f);
TheBrain.SetInput(0, Units[i].Inputs[0]);
TheBrain.SetInput(1, Units[i].Inputs[1]);
TheBrain.SetInput(2, Units[i].Inputs[2]);
TheBrain.SetInput(3, Units[i].Inputs[3]);
TheBrain.FeedForward();
Units[i].Command = TheBrain.GetMaxOutputID();
switch(Units[i].Command)
{
case 0:
Units[i].Chase = true;
Units[i].Flock = false;
Units[i].Evade = false;
Units[i].Wander = false;
break;
case 1:
Units[i].Chase = false;
Units[i].Flock = true;
Units[i].Evade = false;
Units[i].Wander = false;
break;
case 2:
Units[i].Chase = false;
Units[i].Flock = false;
Units[i].Evade = true;
Units[i].Wander = false;
break;
/*case 3:
Units[i].Chase = false;
Units[i].Flock = false;
Units[i].Evade = true;
Units[i].Wander = true;
break;*/
}
DoUnitAI(i);
Units[i].UpdateBodyEuler(dt);
if(FrameCounter >= _RENDER_FRAME_COUNT)
{
if(Units[i].Command == 0)
DrawCraft(Units[i], RGB(255,0,0));
else if(Units[i].Command == 1)
DrawCraft(Units[i], RGB(0,0,255));
else if(Units[i].Command == 2)
DrawCraft(Units[i], RGB(128,128,0));
else
DrawCraft(Units[i], RGB(0,128,128));
}
if(Units[i].vPosition.x > _WINWIDTH) Units[i].vPosition.x = 0;
if(Units[i].vPosition.x < 0) Units[i].vPosition.x = _WINWIDTH;
if(Units[i].vPosition.y > _WINHEIGHT) Units[i].vPosition.y = 0;
if(Units[i].vPosition.y < 0) Units[i].vPosition.y = _WINHEIGHT;
} // end i-loop
kill = false;
if(FrameCounter >= _RENDER_FRAME_COUNT) {
CopyBackBufferToWindow();
FrameCounter = 0;
} else
FrameCounter++;
}
void DrawCraft(RigidBody2D craft, COLORREF clr)
{
Vector vList[5];
double wd, lg;
int i;
Vector v1;
wd = craft.fWidth;
lg = craft.fLength;
vList[0].y = lg/2; vList[0].x = wd/2;
vList[1].y = -lg/2; vList[1].x = wd/2;
vList[2].y = -lg/2; vList[2].x = -wd/2;
vList[3].y = lg/2; vList[3].x = -wd/2;
vList[4].y = lg/2*1.5; vList[4].x = 0;
for(i=0; i<5; i++)
{
v1 = VRotate2D(craft.fOrientation, vList[i]);
vList[i] = v1 + craft.vPosition;
}
DrawLine(vList[0].x, vList[0].y, vList[1].x, vList[1].y, 2, clr);
DrawLine(vList[1].x, vList[1].y, vList[2].x, vList[2].y, 2, clr);
DrawLine(vList[2].x, vList[2].y, vList[3].x, vList[3].y, 2, clr);
DrawLine(vList[3].x, vList[3].y, vList[4].x, vList[4].y, 2, clr);
DrawLine(vList[4].x, vList[4].y, vList[0].x, vList[0].y, 2, clr);
if(ShowVectors)
{
Vector v, u;
double f = 0.025;
// Show velocity vectors in green
DrawLine(craft.vPosition.x, craft.vPosition.y, craft.vPosition.x+craft.vVelocity.x, craft.vPosition.y+craft.vVelocity.y, 3, RGB(0,255,0));
// Show force vectors in black
// thrust vector
v.x = 0;
v.y = craft.ThrustForce*f;
v = VRotate2D(craft.fOrientation, v);
u.x = craft.CT.x;
u.y = craft.CT.y;
u = VRotate2D(craft.fOrientation, u);
DrawLine(craft.vPosition.x+u.x, craft.vPosition.y+u.y, craft.vPosition.x + u.x + v.x, craft.vPosition.y + u.y + v.y, 1, RGB(0,0,0));
// port steering force
v.x = craft.PThrust.x*f;
v.y = craft.PThrust.y*f;
v = VRotate2D(craft.fOrientation, v);
u.x = craft.CPT.x;
u.y = craft.CPT.y;
u = VRotate2D(craft.fOrientation, u);
DrawLine(craft.vPosition.x+u.x, craft.vPosition.y+u.y, craft.vPosition.x + u.x + v.x, craft.vPosition.y + u.y + v.y, 1, RGB(0,0,0));
// stbd steering force
v.x = craft.SThrust.x*f;
v.y = craft.SThrust.y*f;
v = VRotate2D(craft.fOrientation, v);
u.x = craft.CST.x;
u.y = craft.CST.y;
u = VRotate2D(craft.fOrientation, u);
DrawLine(craft.vPosition.x+u.x, craft.vPosition.y+u.y, craft.vPosition.x + u.x + v.x, craft.vPosition.y + u.y + v.y, 1, RGB(0,0,0));
// applied force
v.x = craft.Fa.x*f;
v.y = craft.Fa.y*f;
v = VRotate2D(craft.fOrientation, v);
u.x = craft.Pa.x;
u.y = craft.Pa.y;
u = VRotate2D(craft.fOrientation, u);
DrawLine(craft.vPosition.x+u.x, craft.vPosition.y+u.y, craft.vPosition.x + u.x + v.x, craft.vPosition.y + u.y + v.y, 1, RGB(0,0,0));
}
}
int GetRandomNumber(int min, int max, bool seed)
{
int number;
if(seed)
srand( (unsigned)time( NULL ) );
number = (((abs(rand())%(max-min+1))+min));
if(number>max)
number = max;
if(number<min)
number = min;
return number;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -