void Player::Update() { if(Events::Instance->IsKey(KeyCode::Key_Left)) { MoveToLeft(); } else if(Events::Instance->IsKey(KeyCode::Key_Right)) { MoveToRight(); } if(Events::Instance->IsKeyDown(KeyCode::Key_Space)) { FireMissile(); } for(unsigned int i = 0; i < m_listOfMissiles.size(); i++) { m_listOfMissiles[i]->Update(); } if(m_collisionObject->GetCollisionData() != NULL) { LoseLife(); } }
//Calculate new angle and position given starting angle and position when timer started, elapsed time and keystate when last changed. void MoveCamera(Point3d *cameraPos, Point3d *cameraAngle, Point3d baselinePos, float baselineAngle, unsigned int elapsed, int keys) { float distance; if(blocked) SetMotors(0,0); switch (keys & (KEY_RIGHT_BACK+KEY_RIGHT_FORWARD+KEY_LEFT_BACK+KEY_LEFT_FORWARD)) { case KEY_RIGHT_BACK+KEY_LEFT_FORWARD: { //rotate right if (blocked) { blocked=false; CloseMotors(); } cameraAngle->y=baselineAngle + (PI * 2.0 * elapsed) / rotateSleep; } break; case KEY_RIGHT_FORWARD+KEY_LEFT_BACK: { //rotate left if (blocked) { blocked=false; CloseMotors(); } cameraAngle->y=baselineAngle - (PI * 2.0 * elapsed) / rotateSleep; } break; case KEY_RIGHT_FORWARD: { //one wheel rotate left if (blocked) { blocked=false; CloseMotors(); } cameraAngle->y=baselineAngle - (PI * elapsed) / rotateSleep; } break; case KEY_LEFT_FORWARD: { //one wheel rotate right if (blocked) { blocked=false; CloseMotors(); } cameraAngle->y=baselineAngle + (PI * elapsed) / rotateSleep; } break; case KEY_RIGHT_BACK: { //one wheel rotate left if (blocked) { blocked=false; CloseMotors(); } cameraAngle->y=baselineAngle + (PI * elapsed) / rotateSleep; } break; case KEY_LEFT_BACK: { //one wheel rotate left if (blocked) { blocked=false; CloseMotors(); } cameraAngle->y=baselineAngle - (PI * elapsed) / rotateSleep; } break; case KEY_RIGHT_FORWARD+KEY_LEFT_FORWARD: { //forward //First, check if anything is in our way int ob = LineHitsObject(*cameraPos, *cameraAngle); if (ob != 0) { //something's in the way, calculate the distance to it Point3d offset = SubtractPoint(world.objects[ob].centre, *cameraPos); distance = qsqrt(offset.x * offset.x + offset.z * offset.z); //if we're too close, stop engines and refuse to proceed if (distance < 30 && !blocked) { if (world.objects[ob].colour.R==255 && world.objects[ob].colour.G==0 && world.objects[ob].colour.B==0) { //it's a barrel - red barrels always explode in FPSs! LoseLife("Beware barrels!"); } else { OpenMotors(); SetMotors(0,0); PlaySound(SOUND_HIT); blocked=true; } break; } } if (blocked) { blocked=false; CloseMotors(); } distance=(20.0 * elapsed)/FORWARDSLEEP; cameraPos->x=baselinePos.x + (distance * qsin(baselineAngle)); cameraPos->z=baselinePos.z + (distance * qcos(baselineAngle)); }; break; case KEY_RIGHT_BACK+KEY_LEFT_BACK: { //backwards //First, check if anything is in our way Point3d dir=*cameraAngle; dir.y=ClipAngle(dir.y+PI); int ob = LineHitsObject(*cameraPos, dir); if (ob != 0) { //something's in the way, calculate the distance to it Point3d offset = SubtractPoint(world.objects[ob].centre, *cameraPos); distance = qsqrt(offset.x * offset.x + offset.z * offset.z); //if we're too close, stop engines and refuse to proceed if (distance < 30 && !blocked) { if (world.objects[ob].colour.R==255 && world.objects[ob].colour.G==0 && world.objects[ob].colour.B==0) { //it's a barrel - red barrels always explode in FPSs! LoseLife("Beware barrel!s"); } else { OpenMotors(); SetMotors(0,0); PlaySound(SOUND_HIT); blocked=true; } break; } } if (blocked) { blocked=false; CloseMotors(); } distance=(20.0 * elapsed)/FORWARDSLEEP; cameraPos->x=baselinePos.x - (distance * qsin(baselineAngle)); cameraPos->z=baselinePos.z - (distance * qcos(baselineAngle)); }; } //normalise ret to 0..2PI cameraAngle->y = ClipAngle(cameraAngle->y); }
//Handle tank movement void MoveTank() { Point3d playerOffset = SubtractPoint(cameraPos, world.objects[tankObjectIndex].centre); double angleToPlayer; if (playerOffset.x == 0.0) { angleToPlayer = ((playerOffset.z < 0.0) ? PI / 2.0 : 0.0); } else { angleToPlayer = qatan((double)playerOffset.x / (double)playerOffset.z); if (playerOffset.x < 0.0) angleToPlayer += PI; } angleToPlayer = ClipAngle(angleToPlayer); double distanceToPlayer = qsqrt(playerOffset.x * playerOffset.x + playerOffset.z * playerOffset.z); double angleOffset = ClipAngle(world.objects[tankObjectIndex].heading.y - angleToPlayer); /* DrawText(5,35,"X:%d, Z:%d",(int)(playerOffset.x),(int)(playerOffset.z)); DrawText(5,50,"AO:%d, AP:%d",(int)(180.0/PI*angleOffset),(int)(180.0/PI*angleToPlayer)); DrawText(5,65,"DI:%d, Atan:%d",(int)(distanceToPlayer),(int)(1000.0 * qatan((double)playerOffset.x / (double)playerOffset.z))); */ switch(behaviourType) { case 0: { //move forward MoveObject(&(world.objects[tankObjectIndex]), CreatePoint(2.0 * qsin(world.objects[tankObjectIndex].heading.y), 0.0, 2.0 * qcos(world.objects[tankObjectIndex].heading.y))); } break; case 1: { //rotate right RotateObjectYAxis(&(world.objects[tankObjectIndex]), 5.0 * PI * 2.0 /360.0); } break; case 2: { //rotate left RotateObjectYAxis(&(world.objects[tankObjectIndex]), -5.0 * PI * 2.0 /360.0); } break; case 3: { //hunt! if (angleOffset > PI/4.0 && angleOffset < 7.0 * PI / 4.0) { //if not pointing roughly at player, turn towards player RotateObjectYAxis(&(world.objects[tankObjectIndex]), PI / 180.0 * (angleOffset < PI ? -5.0 : 5.0)); } else if (distanceToPlayer > 75.0) { //if pointing roughly at player but far away, move forward MoveObject(&(world.objects[tankObjectIndex]), CreatePoint(2.0 * qsin(world.objects[tankObjectIndex].heading.y), 0.0, 2.0 * qcos(world.objects[tankObjectIndex].heading.y))); } else if (angleOffset < PI / 180.0 * 5.0 || angleOffset > PI / 180.0 * 355.0) { //turn more finely RotateObjectYAxis(&(world.objects[tankObjectIndex]), PI / 180.0 * (angleOffset < PI ? -1.0 : 1.0)); } else { //if pointing roughly at player and close, turn towards player RotateObjectYAxis(&(world.objects[tankObjectIndex]), PI / 180.0 * (angleOffset < PI ? -5.0 : 5.0)); } } } playerOffset = SubtractPoint(cameraPos, world.objects[tankObjectIndex].centre); if (playerOffset.x == 0.0) { angleToPlayer = ((playerOffset.z < 0.0) ? PI / 2.0 : 0.0); } else { angleToPlayer = qatan((double)playerOffset.x / (double)playerOffset.z); if (playerOffset.x < 0.0) angleToPlayer += PI; } angleToPlayer = ClipAngle(angleToPlayer); distanceToPlayer = qsqrt(playerOffset.x * playerOffset.x + playerOffset.z * playerOffset.z); angleOffset = ClipAngle(world.objects[tankObjectIndex].heading.y - angleToPlayer); if (angleOffset < PI / 180.0 * 5.0 || angleOffset > PI / 180.0 * 355.0) { //if pointing at player, fire PlaySound(SOUND_SHOOT); //Hit if close enough angle if (angleOffset < PI / 180.0 * 2.0 || angleOffset > PI / 180.0 * 358.0) { LoseLife("You got shot!"); } else { //Missed - pick a new behaviour ChooseBehaviour(); } } }