CONTROL.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:43k
源码类别:
Windows编程
开发平台:
Visual C++
- /*==========================================================================
- *
- * Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
- *
- * File: control.cpp
- *
- ***************************************************************************/
- // Includes....
- #include "rm.h"
- #include "control.h"
- #include "directx.h"
- // Defines....
- #define MOVE_NORMAL D3DVAL(10)
- #define MOVE_FAST D3DVAL(20)
- #define MIN_DIST_TO_OPPONENT D3DVAL(100)
- #define PLAYER_MOVE_FORWARD VK_UP
- #define PLAYER_MOVE_BACKWARD VK_DOWN
- #define PLAYER_BLOCK VK_CONTROL
- #define PLAYER_ATTACK VK_SPACE
- #define CAM_BOTH_IN_VIEW VK_F1
- #define CAM_OVER_THE_SHOULDER VK_F2
- #define CAM_PILOT VK_F3
- #define NUM_BOB_FRAMES D3DVAL(30)
- #define NUM_DEAD_FRAMES D3DVAL(66)
- #define NUM_PUNCH_FRAMES D3DVAL(29)
- #define NUM_BEEN_HIT_FRAMES D3DVAL(14)
- #define NUM_BLOCKING_FRAMES D3DVAL(16)
- #define NUM_VICTORY_FRAMES D3DVAL(55)
- #define BOB_START D3DVAL(1)
- #define DEAD_START D3DVAL(94)
- #define DEAD_HIT_GROUND D3DVAL(115)
- #define PUNCH_START D3DVAL(31)
- #define PUNCH_ARM_COCKED D3DVAL(50)
- #define BLOCK_START D3DVAL(77)
- #define BEEN_HIT_START D3DVAL(62)
- #define HEAD_RETURNING D3DVAL(68)
- #define VICTORY_START D3DVAL(161)
- #define EDGE_LEFT D3DVAL(-600)
- #define EDGE_RIGHT D3DVAL(600)
- // Globals....
- // States
- AppState g_appState = DOING_INTRO;
- PlayerState g_oppState = CAUTIOUS;
- CameraState g_camState = BOTH_IN_VIEW;
- PlayerActionState g_player1State = BOBBING;
- PlayerActionState g_player2State = BOBBING;
- AnimArgs g_player1AnimArgs;
- AnimArgs g_player2AnimArgs;
- BOOL g_bPlayer1Attacking = FALSE;
- BOOL g_bPlayer1Blocking = FALSE;
- DWORD g_player1health = 100;
- DWORD g_player2health = 100;
- // Timed lengths for each animation in milliseconds
- #define BOB_TIME_MS D3DVAL(500)
- #define PUNCH_TIME_MS D3DVAL(600)
- #define BLOCK_TIME_MS D3DVAL(500)
- #define HIT_TIME_MS D3DVAL(500)
- #define DEAD_TIME_MS D3DVAL(4000)
- #define VICTORY_TIME_MS D3DVAL(3000)
- // Timing deltas, used for scaling animation to frame rate
- D3DVALUE g_bobDelta = NUM_BOB_FRAMES / BOB_TIME_MS;
- D3DVALUE g_attackDelta = NUM_PUNCH_FRAMES / PUNCH_TIME_MS;
- D3DVALUE g_blockDelta = NUM_BLOCKING_FRAMES / BLOCK_TIME_MS;
- D3DVALUE g_hitDelta = NUM_BEEN_HIT_FRAMES / HIT_TIME_MS;
- D3DVALUE g_deadDelta = NUM_DEAD_FRAMES / DEAD_TIME_MS;
- D3DVALUE g_victoryDelta = NUM_DEAD_FRAMES / DEAD_TIME_MS;
- // Externals....
- extern LPDIRECT3DRM g_lpD3DRM;
- extern LPDIRECT3DRMFRAME g_lpScene;
- extern LPDIRECT3DRMFRAME g_lpCamera;
- extern LPDIRECT3DRMFRAME g_lpPlayer1;
- extern LPDIRECT3DRMFRAME g_lpPlayer1HeadFrame;
- extern LPDIRECT3DRMFRAME g_lpPlayer2;
- extern LPDIRECT3DRMFRAME g_lpPlayer2HeadFrame;
- extern LPDIRECT3DRMFRAME g_lpTmp;
- extern LPDIRECT3DRMANIMATION g_lpAnim;
- extern LPDIRECT3DRMMESHBUILDER g_lpRedDebris;
- extern LPDIRECT3DRMMESHBUILDER g_lpBlueDebris;
- extern Debris g_debris[NUM_DEBRIS];
- extern LPDIRECTSOUND3DLISTENER g_lpDs3dListener; // Defined in DIRECTX.CPP
- //----------------------------------------------------------------------
- //
- // Function : IsKeyDown()
- //
- // Purpose : Returns TRUE if specified key is being pressed
- //
- //----------------------------------------------------------------------
- BOOL IsKeyDown(int virtKeyCode)
- {
- if (GetAsyncKeyState(virtKeyCode) & 0x8000) return TRUE;
- return FALSE;
- }
- //----------------------------------------------------------------------
- //
- // Function : Player1AnimationCallback()
- //
- // Purpose : Animation call back for player 1
- //
- //----------------------------------------------------------------------
- void CDECL Player1AnimationCallback(LPDIRECT3DRMFRAME obj, void* arg, D3DVALUE delta)
- {
- D3DVALUE time = g_player1AnimArgs.time;
- D3DVECTOR player1pos;
- D3DVECTOR player2pos;
- // Booleans to help with sound playing
- static BOOL bHitGround = FALSE;
- static BOOL bPlayedWhoosh = FALSE;
- // Get the players positions
- g_lpPlayer1->GetPosition(g_lpScene, &player1pos);
- g_lpPlayer2->GetPosition(g_lpScene, &player2pos);
- // Compute distance between players
- D3DVALUE curDist = player2pos.z - player1pos.z;
- // Do something based upon the state of player 1
- switch (g_player1State)
- {
- case BOBBING :
- {
- // Forward the bobbing animation time
- g_player1AnimArgs.lpAnimSet->SetTime(time);
- time += (g_bobDelta * delta);
- // Reset if animation has ended
- if (time > BOB_START + NUM_BOB_FRAMES) time = BOB_START;
- // Record the new time
- g_player1AnimArgs.time = time;
- }
- break;
- case PUNCHING :
- {
- // Forward the punching animation time
- g_player1AnimArgs.lpAnimSet->SetTime(time);
- time += (g_attackDelta * delta);
- // Play a whoosh sound if player 1's arm has gone back and is about to punch
- if ((time > PUNCH_ARM_COCKED) && (!bPlayedWhoosh))
- {
- // Play the whoosh
- PlaySoundDS(rand() % 2 == 0 ? WHOOSH1 : WHOOSH2,player1pos);
- bPlayedWhoosh = TRUE;
- }
- // If the punch has played, see if we hit the opponent
- if (time > PUNCH_START + NUM_PUNCH_FRAMES)
- {
- // Reset player 1's state to BOBBING
- time = BOB_START;
- g_player1State = BOBBING;
- bPlayedWhoosh = FALSE;
- // Play a servo sound
- PlaySoundDS(SERVO_DOWN_1,player1pos);
- // Now, decide whether we have hit the other player
- if (curDist < MIN_DIST_TO_OPPONENT + D3DVAL(20))
- {
- // The opponent may be blocking
- if ((g_player2State == BLOCKING) &&
- (g_player2AnimArgs.time > BLOCK_START + (NUM_BLOCKING_FRAMES / D3DVAL(2))))
- {
- // The opponent blocked the punch, so play the block sound
- PlaySoundDS(BLOCK1 + (rand() % 3),player2pos);
- break;
- }
- // We're within the striking distance
- if (g_player2health == 0) return;
- // Add some debris into the scene to register a hit and play a sound
- D3DVECTOR debrisOrg = player1pos;
- D3DVECTOR debrisVel = { D3DVAL(0), D3DVAL(0), D3DVAL(-10) };
- debrisOrg.x += D3DVAL(40);
- debrisOrg.y += D3DVAL(40);
- debrisOrg.z += D3DVAL(90);
- // Add some debris
- AddDebris(debrisOrg, debrisVel, g_lpRedDebris);
- // Decrease the opponents health
- if (g_player2health > 0) g_player2health -= 10;
- if (g_player2health == 0)
- {
- // The opponent has died!
- g_player2State = DEAD;
- g_player2AnimArgs.time = DEAD_START;
- g_player2AnimArgs.lpAnimSet->SetTime(DEAD_START);
- PlaySoundDS(HEAD_SPRING,player2pos);
- // And the player has victory!
- g_player1State = VICTORY;
- g_player1AnimArgs.time = VICTORY_START;
- g_player1AnimArgs.lpAnimSet->SetTime(VICTORY_START);
- PlaySoundDS(VICTORY_YEAH,player1pos);
- return;
- }
- // Play a punch sound
- PlaySoundDS(rand() % 2 == 0 ? PLAYER1_PUNCH1 : PLAYER1_PUNCH2,player2pos);
- // Recalculate the power bars
- RecalcPowerBars(g_player1health, g_player2health);
- // Make sure we force the camera to the correct place
- PositionCamera();
- // Setup the opponents animation and state
- g_player2State = BEEN_HIT;
- g_player2AnimArgs.time = BEEN_HIT_START;
- g_player2AnimArgs.lpAnimSet->SetTime(BEEN_HIT_START);
- // What should the opponent do?
- if (rand() % 10 < 2)
- {
- // Make the opponent defensive
- g_oppState = DEFENSIVE;
- }
- // Play the ouch sound
- PlaySoundDS(PLAYER2_OUCH,player1pos);
- }
- }
- // Record the new animation time
- g_player1AnimArgs.time = time;
- }
- break;
- case BLOCKING :
- {
- // Forward the blocking animation time
- g_player1AnimArgs.lpAnimSet->SetTime(time);
- // Hold the block up if CTRL is held down
- if (GetAsyncKeyState(PLAYER_BLOCK) & 0x8000)
- {
- if (time < BLOCK_START + (NUM_BLOCKING_FRAMES / 2)) time += (g_blockDelta * delta);
- }
- else
- {
- time += (g_blockDelta * delta);
- }
- // Reset player 1's state to BOBBING if the animation has ended
- if (time > BLOCK_START + NUM_BLOCKING_FRAMES)
- {
- time = BOB_START;
- g_player1State = BOBBING;
- }
- // Record the new animation time
- g_player1AnimArgs.time = time;
- }
- break;
- case BEEN_HIT :
- {
- // Forward the been hit animation time
- g_player1AnimArgs.lpAnimSet->SetTime(time);
- time += (g_hitDelta * delta);
- if (player1pos.z > EDGE_LEFT) g_lpPlayer1->SetPosition(g_lpScene, player1pos.x, player1pos.y, player1pos.z - D3DVAL(5));
- PositionCamera();
- // Reset player 1's state to BOBBING if the animation has ended
- if (time > BEEN_HIT_START + NUM_BEEN_HIT_FRAMES)
- {
- time = BOB_START;
- g_player1State = BOBBING;
- }
- // Record the new animation time
- g_player1AnimArgs.time = time;
- }
- break;
- case DEAD :
- {
- // Forward the death animation time
- g_player1AnimArgs.lpAnimSet->SetTime(time);
- time += (g_deadDelta * delta);
- // Play a crash sound if the animation has passes the DEAD_HIT_GROUND frame
- if ((time > DEAD_HIT_GROUND) && (!bHitGround))
- {
- bHitGround = TRUE;
- PlaySoundDS(BLOCK3,player1pos);
- }
- // Reset player 1's state to BOBBING if the animation has ended
- if (time > DEAD_START + NUM_DEAD_FRAMES)
- {
- time = BOB_START;
- g_player1State = BOBBING;
- g_player1health = 100;
- bHitGround = FALSE;
- RecalcPowerBars(g_player1health, g_player2health);
- }
- // Record the new animation time
- g_player1AnimArgs.time = time;
- // Position the camera correctly
- PositionCamera();
- }
- break;
- case VICTORY :
- {
- // Forward the victory animation time
- g_player1AnimArgs.lpAnimSet->SetTime(time);
- time += (g_victoryDelta * delta);
- if (time > VICTORY_START + NUM_VICTORY_FRAMES)
- {
- time = BOB_START;
- g_player1State = BOBBING;
- }
- g_player1AnimArgs.time = time;
- PositionCamera();
- }
- break;
- }
- }
- //----------------------------------------------------------------------
- //
- // Function : Player2AnimationCallback()
- //
- // Purpose : Animation call back for player 2
- //
- //----------------------------------------------------------------------
- void CDECL Player2AnimationCallback(LPDIRECT3DRMFRAME obj, void* arg, D3DVALUE delta)
- {
- D3DVALUE time = g_player2AnimArgs.time;
- D3DVECTOR player1pos;
- D3DVECTOR player2pos;
- // Booleans to help with sound playing
- static BOOL bHitGround = FALSE;
- static BOOL bPlayedWhoosh = FALSE;
- // Get the players positions
- g_lpPlayer1->GetPosition(g_lpScene, &player1pos);
- g_lpPlayer2->GetPosition(g_lpScene, &player2pos);
- // Compute distance between players
- D3DVALUE curDist = player2pos.z - player1pos.z;
- // Do something based upon the state of player 1
- switch (g_player2State)
- {
- case BOBBING :
- {
- // Forward the bobbing animation time
- g_player2AnimArgs.lpAnimSet->SetTime(time);
- time += (g_bobDelta * delta);
- // Reset if animation has ended
- if (time > BOB_START + NUM_BOB_FRAMES) time = BOB_START;
- // Record the new time
- g_player2AnimArgs.time = time;
- }
- break;
- case PUNCHING :
- {
- // Forward the punching animation time
- g_player2AnimArgs.lpAnimSet->SetTime(time);
- time += (g_attackDelta * delta);
- // Play a whoosh sound if player 2's arm has gone back and is about to punch
- if ((time > PUNCH_ARM_COCKED) && (!bPlayedWhoosh))
- {
- // Play the whoosh
- PlaySoundDS(rand() % 2 == 0 ? WHOOSH1 : WHOOSH2,player2pos);
- bPlayedWhoosh = TRUE;
- }
- // If the punch has played, see if we hit the opponent
- if (time > PUNCH_START + NUM_PUNCH_FRAMES)
- {
- time = BOB_START;
- g_player2State = BOBBING;
- bPlayedWhoosh = FALSE;
- // Play a servo sound
- PlaySoundDS(SERVO_DOWN_2,player2pos);
- // Now, decide whether we have hit the other player
- if (curDist < MIN_DIST_TO_OPPONENT + D3DVAL(20))
- {
- // The opponent may be blocking
- if ((g_player1State == BLOCKING) &&
- (g_player1AnimArgs.time > BLOCK_START + (NUM_BLOCKING_FRAMES / D3DVAL(2))))
- {
- // The opponent blocked the punch, so play the block sound
- PlaySoundDS(BLOCK1 + (rand() % 3),player1pos);
- break;
- }
- // We're within the striking distance
- if (g_player1health <= 0) return;
- // We're within the striking distance
- // Add some debris into the scene to register a hit and play a sound
- D3DVECTOR debrisOrg = player1pos;
- D3DVECTOR debrisVel = { D3DVAL(0), D3DVAL(0), D3DVAL(10) };
- debrisOrg.x += D3DVAL(-40);
- debrisOrg.y += D3DVAL(40);
- debrisOrg.z += D3DVAL(-10);
- // Add some debris
- AddDebris(debrisOrg, debrisVel, g_lpBlueDebris);
- // Play a punch sound
- PlaySoundDS(rand() % 2 == 0 ? PLAYER2_PUNCH1 : PLAYER2_PUNCH2,player1pos);
- // Decrease the opponents health
- if (g_player1health > 0) g_player1health -= 10;
- if (g_player1health == 0)
- {
- // The player has died!
- g_player1State = DEAD;
- g_player1AnimArgs.time = DEAD_START;
- g_player1AnimArgs.lpAnimSet->SetTime(DEAD_START);
- PlaySoundDS(HEAD_SPRING,player1pos);
- // And the opponent has victory!
- g_player2State = VICTORY;
- g_player2AnimArgs.time = VICTORY_START;
- g_player2AnimArgs.lpAnimSet->SetTime(VICTORY_START);
- // The crowd is not happy....
- PlaySoundDS(VICTORY_BOO,player2pos);
- return;
- }
- // Recalculate the power bars
- RecalcPowerBars(g_player1health, g_player2health);
- // Force a camera positional update
- PositionCamera();
- if (g_player1State != BEEN_HIT)
- {
- // Change player 1's state to BEEN_HIT,
- g_player1State = BEEN_HIT;
- // And set the animation time
- g_player1AnimArgs.time = BEEN_HIT_START;
- g_player1AnimArgs.lpAnimSet->SetTime(BEEN_HIT_START);
- }
- // Play the ouch sound
- PlaySoundDS(PLAYER1_OUCH,player1pos);
- }
- }
- // Record the new animation time
- g_player2AnimArgs.time = time;
- }
- break;
- case BEEN_HIT :
- {
- // Forward the been hit animation time
- g_player2AnimArgs.lpAnimSet->SetTime(time);
- time += (g_hitDelta * delta);
- // Move the player
- if (player2pos.z < EDGE_RIGHT) g_lpPlayer2->SetPosition(g_lpScene, player2pos.x, player2pos.y, player2pos.z + D3DVAL(5));
- // Force a camera position update
- PositionCamera();
- // Reset to BOBBING if animation has ended
- if (time > BEEN_HIT_START + NUM_BEEN_HIT_FRAMES)
- {
- time = BOB_START;
- g_player2State = BOBBING;
- }
- // Record the new animation time
- g_player2AnimArgs.time = time;
- }
- break;
- case BLOCKING :
- {
- // Forward the blocking animation time
- g_player2AnimArgs.lpAnimSet->SetTime(time);
- time += (g_blockDelta * delta);
- // Reset to BOBBING if animation has ended
- if (time > BLOCK_START + NUM_BLOCKING_FRAMES)
- {
- time = BOB_START;
- g_player2State = BOBBING;
- g_oppState = AGGRESSIVE;
- }
- // Record the new animation time
- g_player2AnimArgs.time = time;
- }
- break;
- case DEAD :
- {
- // Forward the death animation time
- g_player2AnimArgs.lpAnimSet->SetTime(time);
- time += (g_deadDelta * delta);
- // Play the BLOCK3 sound when the opponent hits the ground
- if ((time > DEAD_HIT_GROUND) && (!bHitGround))
- {
- bHitGround = TRUE;
- PlaySoundDS(BLOCK3,player2pos);
- }
- // Reset to BOBBING if the animation has ended
- if (time > DEAD_START + NUM_DEAD_FRAMES)
- {
- time = BOB_START;
- g_player2State = BOBBING;
- g_player2health = 100;
- bHitGround = FALSE;
- // Recalculate the power bars
- RecalcPowerBars(g_player1health, g_player2health);
- }
- // Record the new animation time
- g_player2AnimArgs.time = time;
- // Force a camera position update
- PositionCamera();
- }
- break;
- case VICTORY :
- {
- // Forward the victory animation time
- g_player2AnimArgs.lpAnimSet->SetTime(time);
- time += (g_victoryDelta * delta);
- if (time > VICTORY_START + NUM_VICTORY_FRAMES)
- {
- time = BOB_START;
- g_player2State = BOBBING;
- }
- // Record the new animation time
- g_player2AnimArgs.time = time;
- // Force a camera position update
- PositionCamera();
- }
- break;
- }
- }
- //----------------------------------------------------------------------
- //
- // Function : CheckInputAndUpdate()
- //
- // Purpose : Checks input, updates scene, moves player(s)
- //
- //----------------------------------------------------------------------
- void CheckInputAndUpdate()
- {
- D3DVECTOR player1pos;
- D3DVECTOR player2pos;
- D3DVECTOR camPos;
- // Run intro
- if (g_appState == DOING_INTRO)
- {
- RunIntro();
- return;
- }
- // Transition camera
- if (g_appState == BETWEEN_CAM_VIEWS)
- {
- TransitionCamera();
- return;
- }
- // Get the players positions
- g_lpPlayer1->GetPosition(g_lpScene, &player1pos);
- g_lpPlayer2->GetPosition(g_lpScene, &player2pos);
- // Get the camera's position
- g_lpCamera->GetPosition(g_lpScene, &camPos);
- // Calculate distance between players
- D3DVALUE curDist = player2pos.z - player1pos.z;
- // Move player forward
- if ((IsKeyDown(PLAYER_MOVE_FORWARD)) && (g_player1State != VICTORY) && (g_player1State != DEAD))
- {
- // Make sure the player can only move so close to the opponent
- if (curDist > MIN_DIST_TO_OPPONENT)
- {
- // Move the player
- g_lpPlayer1->SetPosition(g_lpScene, player1pos.x, player1pos.y, player1pos.z + MOVE_NORMAL);
- // Force a camera position update
- PositionCamera();
- // Play a servo sound
- PlaySoundDS(SERVO_UP_3,player1pos);
- // Play a walk sound
- PlaySoundDS(PLAYER1_WALK,player1pos);
- }
- }
- // Move player backward
- if ((IsKeyDown(PLAYER_MOVE_BACKWARD)) && (g_player1State != VICTORY) && (g_player1State != DEAD))
- {
- // Make sure the player can't run off the arena
- if (player1pos.z > EDGE_LEFT)
- {
- // Move the player
- g_lpPlayer1->SetPosition(g_lpScene, player1pos.x, player1pos.y, player1pos.z - MOVE_NORMAL);
- // Force a camera position update
- PositionCamera();
- // Play a servo sound
- PlaySoundDS(SERVO_UP_3,player1pos);
- // Play a walk sound
- PlaySoundDS(PLAYER1_WALK,player1pos);
- }
- }
- // Initiate a player attack
- if ((!g_bPlayer1Attacking) && (!g_bPlayer1Blocking) && (IsKeyDown(PLAYER_ATTACK)))
- {
- if ((g_player1State != PUNCHING) && (g_player1State != DEAD) && (g_player1State != VICTORY))
- {
- // Set the player state to punching
- g_player1State = PUNCHING;
- // Set up the correct time for the animation
- g_player1AnimArgs.time = D3DVAL(PUNCH_START);
- g_player1AnimArgs.lpAnimSet->SetTime(D3DVAL(PUNCH_START));
- g_bPlayer1Attacking = TRUE;
- // Play a servo sound
- PlaySoundDS(SERVO_UP_1,player1pos);
- }
- }
- // Reset the attacking flag if the PLAYER_ATTACK key is not pressed anymore
- if ((g_bPlayer1Attacking) && (!IsKeyDown(PLAYER_ATTACK)))
- {
- g_bPlayer1Attacking = FALSE;
- }
- // Initiate a player block
- if ((!g_bPlayer1Blocking) && (!g_bPlayer1Attacking) && (IsKeyDown(PLAYER_BLOCK)))
- {
- if ((g_player1State != BLOCKING) && (g_player1State != DEAD) && (g_player1State != VICTORY))
- {
- // Set the player state to blocking
- g_player1State = BLOCKING;
- // Set up the correct time for the animation
- g_player1AnimArgs.time = D3DVAL(BLOCK_START);
- g_player1AnimArgs.lpAnimSet->SetTime(D3DVAL(BLOCK_START));
- // Don't allow any more blocking
- g_bPlayer1Blocking = TRUE;
- // Play a servo sound
- PlaySoundDS(SERVO_UP_1,player1pos);
- }
- }
- // Reset the blocking flag if the PLAYER_BLOCK key is no longer held down
- if ((g_bPlayer1Blocking) && (!IsKeyDown(PLAYER_BLOCK)))
- {
- g_bPlayer1Blocking = FALSE;
- }
- // Transition to the BOTH_IN_VIEW camera view
- if ((IsKeyDown(CAM_BOTH_IN_VIEW)) && (g_camState != BOTH_IN_VIEW))
- {
- // Create transition animation
- if (!FAILED(g_lpD3DRM->CreateAnimation(&g_lpAnim)))
- {
- // Setup the animation options
- g_lpAnim->SetOptions(D3DRMANIMATION_OPEN |
- D3DRMANIMATION_LINEARPOSITION |
- D3DRMANIMATION_POSITION);
- // Make midway vector between both players, this is what the camera will focus on
- D3DVECTOR vMidPoint;
- vMidPoint.x = 0.0f;
- vMidPoint.y = 0.0f;
- vMidPoint.z = (player1pos.z + player2pos.z) / D3DVAL(2);
- // Calculate vector that will keep both players in sight
- D3DVECTOR vNewCam;
- vNewCam.x = (float)abs((int)player2pos.z - (int)player1pos.z) + D3DVAL(300);
- vNewCam.y = camPos.y;
- vNewCam.z = vMidPoint.z;
- // Add the keyframes to the animation
- g_lpAnim->AddPositionKey(D3DVAL(0), camPos.x, camPos.y, camPos.z);
- g_lpAnim->AddPositionKey(D3DVAL(1), vNewCam.x, vNewCam.y, vNewCam.z);
- // Setup the initial position
- g_lpTmp->SetPosition(g_lpScene, vMidPoint.x, vMidPoint.y, vMidPoint.z);
- // And attach the camera to the animation
- g_lpAnim->SetFrame(g_lpCamera);
- g_appState = BETWEEN_CAM_VIEWS;
- }
- else
- {
- // Create animation failed so just set the camera position
- g_lpCamera->SetPosition(g_lpScene, D3DVAL(200), D3DVAL(100), player1pos.z + MOVE_NORMAL - D3DVAL(400));
- g_lpCamera->LookAt(g_lpPlayer2, g_lpScene, D3DRMCONSTRAIN_Z);
- PositionCamera();
- }
- g_camState = BOTH_IN_VIEW;
- }
- // Transition to the OVER_SHOULDER camera view
- if ((IsKeyDown(CAM_OVER_THE_SHOULDER)) && (g_camState != OVER_SHOULDER))
- {
- if (!FAILED(g_lpD3DRM->CreateAnimation(&g_lpAnim)))
- {
- // Setup the animation options
- g_lpAnim->SetOptions(D3DRMANIMATION_OPEN |
- D3DRMANIMATION_LINEARPOSITION |
- D3DRMANIMATION_POSITION);
- // Add the keyframes to the animation
- g_lpAnim->AddPositionKey(D3DVAL(0), camPos.x, camPos.y, camPos.z);
- g_lpAnim->AddPositionKey(D3DVAL(1), D3DVAL(200), D3DVAL(100), player1pos.z - D3DVAL(300));
- // Setup the initial position
- g_lpTmp->SetPosition(g_lpScene, player2pos.x, player2pos.y, player2pos.z);
- // And attach the camera to the animation
- g_lpAnim->SetFrame(g_lpCamera);
- g_appState = BETWEEN_CAM_VIEWS;
- }
- else
- {
- // Create animation failed so just set the camera position
- PositionCamera();
- }
- g_camState = OVER_SHOULDER;
- }
- // Transition to the PILOT_VIEW camera view
- if ((IsKeyDown(CAM_PILOT)) && (g_camState != PILOT_VIEW))
- {
- PositionCamera();
- g_camState = PILOT_VIEW;
- }
- // Update the opponent
- UpdateOpponent();
- // Update any debris in the world
- UpdateDebris();
- }
- //----------------------------------------------------------------------
- //
- // Function : UpdateOpponent()
- //
- // Purpose : Updates opponent
- //
- //----------------------------------------------------------------------
- void UpdateOpponent()
- {
- D3DVECTOR player1pos;
- D3DVECTOR player2pos;
- if (g_player2State != BOBBING) return;
- // Random value to determine what the opponent should do based upon its state
- int r = rand() % 100;
- // Get the players positions
- g_lpPlayer1->GetPosition(g_lpScene, &player1pos);
- g_lpPlayer2->GetPosition(g_lpScene, &player2pos);
- // Calculate distance betweens players
- D3DVALUE curDist = player2pos.z - player1pos.z;
- // There is always a chance to block the player
- if ((r < 15) && (g_player1State == PUNCHING) && (g_player2State == BOBBING))
- {
- // Set the opponents state to BLOCKING ans start the animation
- g_player2State = BLOCKING;
- g_player2AnimArgs.time = BLOCK_START;
- g_player2AnimArgs.lpAnimSet->SetTime(BLOCK_START);
- // Play a servo sound
- PlaySoundDS(SERVO_UP_2,player2pos);
- return;
- }
- switch (g_oppState)
- {
- case DEFENSIVE:
- {
- // Decide whether to move opponent backwards
- if (r < 25)
- {
- // Move the opponent backwards
- g_lpPlayer2->SetPosition(g_lpScene, player2pos.x, player2pos.y, player2pos.z + MOVE_NORMAL);
- // Play a walk sound
- PlaySoundDS(PLAYER2_WALK,player2pos);
- // Play a servo sound
- PlaySoundDS(SERVO_DOWN_3,player2pos);
- }
- PositionCamera();
- // Decide whether to go from DEFENSIVE to cautious
- if (r < 10) g_oppState = CAUTIOUS;
- }
- break;
- case CAUTIOUS:
- {
- // Decide whether to go from CAUTIOUS to AGGRESSIVE
- if (r < 5)
- {
- // Make the opponent become aggresive
- g_oppState = AGGRESSIVE;
- }
- }
- break;
- case AGGRESSIVE:
- {
- // Decide whether to move the opponent towards the player
- if (r < 50)
- {
- // Move the opponent towards the player
- if (curDist > MIN_DIST_TO_OPPONENT)
- {
- g_lpPlayer2->SetPosition(g_lpScene, player2pos.x, player2pos.y, player2pos.z - MOVE_NORMAL);
- PositionCamera();
- // Play a walk sound
- PlaySoundDS(PLAYER2_WALK,player2pos);
- // Play a servo sound
- PlaySoundDS(SERVO_DOWN_3,player2pos);
- }
- }
- // Decide whether or not to attack the player
- if ((r < 15) && (g_player2State == BOBBING) &&
- (g_player1State != DEAD) && (curDist < MIN_DIST_TO_OPPONENT + D3DVAL(50)))
- {
- // Set the opponent's state to PUNCHING
- g_player2State = PUNCHING;
- g_player2AnimArgs.time = PUNCH_START;
- g_player2AnimArgs.lpAnimSet->SetTime(PUNCH_START);
- // Play a servo sound
- PlaySoundDS(SERVO_UP_2,player2pos);
- }
- // Decide whether or not to move the opponent backwards out of the way if the player
- // is punching
- if ((g_player1State == PUNCHING) && (r > 50) && (g_player2State == BOBBING) && (curDist < MIN_DIST_TO_OPPONENT + 50))
- {
- // Move the opponent out of the way, making sure its still in the arena
- if (player2pos.z < EDGE_RIGHT)
- {
- g_lpPlayer2->SetPosition(g_lpScene, player2pos.x, player2pos.y, player2pos.z + D3DVAL(5));
- // Play a servo sound
- PlaySoundDS(SERVO_DOWN_3,player1pos);
- }
- }
- }
- break;
- }
- }
- //----------------------------------------------------------------------
- //
- // Function : RunIntro()
- //
- // Purpose : Moves camera along path
- //
- //----------------------------------------------------------------------
- void RunIntro()
- {
- static D3DVALUE time = D3DVAL(0.0f);
- D3DVECTOR d3dvPos; // D3DVECTOR used for 3D position of sound
- d3dvPos.x = D3DVAL(0); // set the sound at (0,0,0)..
- d3dvPos.y = D3DVAL(0);
- d3dvPos.z = D3DVAL(0);
- // Play the intro sound
- if (time == D3DVAL(0.0f))
- {
- PlaySoundDS(INTRO,d3dvPos);
- PlaySoundDS(CROWD_LOOP,d3dvPos, DSBPLAY_LOOPING);
- SetTimer(NULL,NULL,10000,(TIMERPROC)PlayRandomWave);
- }
- // Foward the intro animation
- time += D3DVAL(0.04);
- // Set the animation time
- g_lpAnim->SetTime(time);
- // Always look at the origin of the g_lpScene frame
- g_lpCamera->LookAt(g_lpTmp, g_lpScene, D3DRMCONSTRAIN_Z);
- // If time has exceeded 1.0 the intro is done, and we can start the demo
- if (time >= D3DVAL(1.0f))
- {
- g_appState = PLAYING_DEMO;
- g_lpAnim->Release();
- g_lpAnim = NULL;
- PositionCamera();
- }
- }
- //----------------------------------------------------------------------
- //
- // Function : PostionCamera()
- //
- // Purpose : Positions camera based upon camera state
- //
- //----------------------------------------------------------------------
- void PositionCamera()
- {
- D3DVECTOR player1pos;
- D3DVECTOR player2pos;
- D3DVECTOR camPos;
- // Don't position the camera if we are transitioning between camera views
- if (g_appState == BETWEEN_CAM_VIEWS) return;
- // Get the players positions
- g_lpPlayer1->GetPosition(g_lpScene, &player1pos);
- g_lpPlayer2->GetPosition(g_lpScene, &player2pos);
- // Get the camera's position
- g_lpCamera->GetPosition(g_lpScene, &camPos);
- switch (g_camState)
- {
- case OVER_SHOULDER:
- {
- // Position the camera such that it looks over the shoulder of the player and
- // keeps the opponent in view
- g_lpCamera->SetPosition(g_lpScene, camPos.x, camPos.y, D3DVAL(player1pos.z) + MOVE_NORMAL - 300);
- g_lpCamera->LookAt(g_lpPlayer2, g_lpScene, D3DRMCONSTRAIN_Z);
- if (g_lpDs3dListener)
- {
- // Set the listener position to where the camera is
- g_lpDs3dListener->SetPosition(camPos.x, camPos.y, D3DVAL(player1pos.z) + MOVE_NORMAL - 300,DS3D_DEFERRED);
- // Change listener's orientation vector
- g_lpDs3dListener->SetOrientation(D3DVAL(0),D3DVAL(0),D3DVAL(1),D3DVAL(0),D3DVAL(1),D3DVAL(0),DS3D_DEFERRED);
- }
- }
- break;
- case BOTH_IN_VIEW:
- {
- // Position the camera such that it looks at both players all the time
- // Make midway point, this is what the camera will focus on
- D3DVECTOR vMidPoint;
- vMidPoint.x = 0.0f;
- vMidPoint.y = 0.0f;
- vMidPoint.z = (player1pos.z + player2pos.z) / D3DVAL(2);
- // Calculate vector that will keep both players in sight
- D3DVECTOR vNewCam;
- vNewCam.x = (float)abs((int)player2pos.z - (int)player1pos.z) + D3DVAL(300);
- vNewCam.y = camPos.y;
- vNewCam.z = vMidPoint.z;
- g_lpCamera->SetPosition(g_lpScene, vNewCam.x, vNewCam.y, vNewCam.z);
- g_lpTmp->SetPosition(g_lpScene, vMidPoint.x, vMidPoint.y, vMidPoint.z);
- g_lpCamera->LookAt(g_lpTmp, g_lpScene, D3DRMCONSTRAIN_Z);
- if (g_lpDs3dListener)
- {
- // Set the listener position to where the camera is
- g_lpDs3dListener->SetPosition(vNewCam.x, vNewCam.y, vNewCam.z,DS3D_DEFERRED);
- // Change listener's orientation vector
- g_lpDs3dListener->SetOrientation(-D3DVAL(1),D3DVAL(0),D3DVAL(0),D3DVAL(0),D3DVAL(1),D3DVAL(0),DS3D_DEFERRED);
- }
- }
- break;
- case PILOT_VIEW:
- {
- // Position the camera such that it looks through the eyes of the player
- // and fixes on the origin of the head frame of the opponent
- g_lpCamera->SetPosition(g_lpPlayer1HeadFrame, D3DVAL(0), D3DVAL(-10), D3DVAL(0));
- g_lpTmp->SetPosition(g_lpPlayer2HeadFrame, D3DVAL(0), D3DVAL(-10), D3DVAL(0));
- g_lpCamera->LookAt(g_lpTmp, g_lpScene, D3DRMCONSTRAIN_Z);
- if (g_lpDs3dListener)
- {
- // Set the listener position to where the camera is
- g_lpDs3dListener->SetPosition(player1pos.x, D3DVAL(0), player1pos.z,DS3D_DEFERRED);
- // Change listener's orientation vector
- g_lpDs3dListener->SetOrientation(D3DVAL(0),D3DVAL(0),D3DVAL(1),D3DVAL(0),D3DVAL(1),D3DVAL(0),DS3D_DEFERRED);
- }
- }
- break;
- }
- // Commit the changes to the listener's orientation and position..
- if (g_lpDs3dListener)
- g_lpDs3dListener->CommitDeferredSettings();
- }
- //----------------------------------------------------------------------
- //
- // Function : TransitionCamera()
- //
- // Purpose : Positions camera based upon camera state
- //
- //----------------------------------------------------------------------
- void TransitionCamera()
- {
- static D3DVALUE time = D3DVAL(0.0f);
- // Forward the transition animation time
- time += D3DVAL(0.04);
- // Set the time for the transitional animation
- g_lpAnim->SetTime(time);
- // Look at the g_lpScene frame
- g_lpCamera->LookAt(g_lpTmp, g_lpScene, D3DRMCONSTRAIN_Z);
- // If the animation has ended, run the demo
- if (time >= D3DVAL(1.0f))
- {
- g_appState = PLAYING_DEMO;
- g_lpAnim->Release();
- g_lpAnim = NULL;
- time = D3DVAL(0);
- PositionCamera();
- }
- // Update debris so any debris in the scene doesn't just sit there doing nothing
- UpdateDebris();
- }
- //----------------------------------------------------------------------
- //
- // Function : AddDebris()
- //
- // Purpose : Adds some debris to the scene
- //
- //----------------------------------------------------------------------
- void AddDebris(D3DVECTOR vOrg, D3DVECTOR vVel, LPDIRECT3DRMMESHBUILDER pDebris)
- {
- // vOrg is the origin of the debris, find first open spot and add 5 bits of debris
- int count = 0;
- for (int i = 0; i < NUM_DEBRIS; i ++)
- {
- // Find some debris that is not in use yet
- if (!g_debris[i].m_bInUse)
- {
- // Add some debris
- g_debris[i].m_pFrame->AddVisual(pDebris);
- g_debris[i].m_pFrame->SetPosition(g_lpScene, vOrg.x, vOrg.y, vOrg.z);
- g_debris[i].m_pFrame->SetRotation(g_lpScene, D3DVAL(0.5), D3DVAL(0.5), D3DVAL(0.5), D3DVAL(0.5));
- g_debris[i].m_life = 0;
- // Setup velocity and acceleration
- g_debris[i].m_vel.x = D3DVAL(-10 + (rand() % 20)) + vVel.x;
- g_debris[i].m_vel.y = D3DVAL(8) + D3DVAL(rand() % 10) + vVel.y;
- g_debris[i].m_vel.z = D3DVAL(-10 + (rand() % 20)) + vVel.z;
- g_debris[i].m_acc.x = D3DVAL(0);
- g_debris[i].m_acc.y = D3DVAL(-2);
- g_debris[i].m_acc.z = D3DVAL(0);
- // This piece of debris is now in use
- g_debris[i].m_bInUse = TRUE;
- g_debris[i].m_pMeshBuilder = pDebris;
- count ++;
- }
- // Return if we've added NUM_HIT_DEBRIS bits of debris
- if (count == NUM_HIT_DEBRIS) return;
- }
- }
- //----------------------------------------------------------------------
- //
- // Function : UpdateDebris()
- //
- // Purpose : Updates debris
- //
- //----------------------------------------------------------------------
- void UpdateDebris()
- {
- D3DVECTOR vPos;
- // Go through the array of debris and update any debris that is in use
- for (int i = 0; i < NUM_DEBRIS; i ++)
- {
- if (g_debris[i].m_bInUse)
- {
- // If the debris's life has not yet expired
- if (g_debris[i].m_life < DEBRIS_LIFE)
- {
- // Move the debris
- g_debris[i].m_pFrame->GetPosition(g_lpScene, &vPos);
- g_debris[i].m_vel.x += g_debris[i].m_acc.x;
- g_debris[i].m_vel.y += g_debris[i].m_acc.y;
- g_debris[i].m_vel.z += g_debris[i].m_acc.z;
- vPos.x += g_debris[i].m_vel.x;
- vPos.y += g_debris[i].m_vel.y;
- vPos.z += g_debris[i].m_vel.z;
- // Check to see whether the debris is below the floor
- if (vPos.y < D3DVAL(-60))
- {
- // Bounce the debris
- vPos.y = D3DVAL(-60);
- g_debris[i].m_vel.y = -g_debris[i].m_vel.y / D3DVAL(1.5);
- }
- // Update the position of the debris
- g_debris[i].m_pFrame->SetPosition(g_lpScene, vPos.x, vPos.y, vPos.z);
- }
- else
- {
- // Remove the debris from the world
- g_debris[i].m_pFrame->DeleteVisual(g_debris[i].m_pMeshBuilder);
- g_debris[i].m_bInUse = FALSE;
- }
- // Age the debris
- g_debris[i].m_life ++;
- }
- }
- }