#include "stdafx.h" /* ----------------------------------------------------------------------------- File: Player.cpp Desc: Object that accepts pad input, knocks down ColorArrows that were stepped on, and keeps score for the player. Copyright (c) 2001 Chris Danford. All rights reserved. ----------------------------------------------------------------------------- */ #include "ScreenDimensions.h" #include "Math.h" // for fabs() #include "Player.h" #include "RageUtil.h" //const float STEP_DOWN_TIME = 0.05f; const int SCORE_ADD_PERFECT = 700; const int SCORE_ADD_GREAT = 400; const int SCORE_ADD_GOOD = 200; const int SCORE_ADD_BOO = 100; const float LIFE_PERFECT = 0.015f; const float LIFE_GREAT = 0.008f; const float LIFE_GOOD = 0.000f; const float LIFE_BOO = -0.015f; const float LIFE_MISS = -0.060f; const int ARROW_SIZE = 64; const float ARROW_X_OFFSET[6] = { ARROW_SIZE*-2.5, ARROW_SIZE*-1.5, ARROW_SIZE*-0.5, ARROW_SIZE* 0.5, ARROW_SIZE* 1.5, ARROW_SIZE* 2.5 }; const float GRAY_ARROW_Y = ARROW_SIZE * 1.5; const float GRAY_ARROW_POP_UP_TIME = 0.30f; const float ARROW_GAP = 70; const int NUM_FRAMES_IN_COLOR_ARROW_SPRITE = 12; const CString SPRITE_COLOR_ARROW = "Sprites\\Color Arrow.sprite"; const CString SPRITE_GRAY_ARROW = "Sprites\\Gray Arrow.sprite"; const float JUDGEMENT_DISPLAY_TIME = 1.0f; const CString JUDGEMENT_SPRITE = "Sprites\\Judgement.sprite"; const float JUDGEMENT_Y = CENTER_Y; const CString FONT_COMBO = "Fonts\\Font - Arial Bold numbers 30px.font"; const float COMBO_TWEEN_TIME = 0.5f; const CString COMBO_SPRITE = "Sprites\\Combo.sprite"; const float COMBO_Y = (CENTER_Y+60); const int LIEFMETER_NUM_PILLS = 17; const CString LIFEMETER_FRAME_SPRITE= "Sprites\\Life Meter Frame.sprite"; const CString LIFEMETER_PILLS_SPRITE= "Sprites\\Life Meter Pills.sprite"; const float LIFEMETER_Y = 30; const float LIFEMETER_PILLS_Y = LIFEMETER_Y+2; const float PILL_OFFSET_Y[LIEFMETER_NUM_PILLS] = { 0.3f, 0.7f, 1.0f, 0.7f, 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f // kind of a sin wave }; const CString FONT_SCORE = "Fonts\\Font - Arial Bold numbers 30px.font"; const CString SCORE_FRAME_TEXTURE = "Textures\\Score Frame 1x1.png"; const float SCORE_Y = SCREEN_HEIGHT - 40; Player::Player() { m_iCurCombo = 0; m_iMaxCombo = 0; m_fLifePercentage = 0.50f; m_fScore = 0.0f; // init step elements for( int i=0; i mapStepToRotation; // arrow facing left is rotation 0 mapStepToRotation[STEP_PAD1_LEFT] = 0; mapStepToRotation[STEP_PAD1_UPLEFT] = D3DX_PI/4.0f; mapStepToRotation[STEP_PAD1_DOWN] = -D3DX_PI/2.0f; mapStepToRotation[STEP_PAD1_UP] = D3DX_PI/2.0f; mapStepToRotation[STEP_PAD1_UPRIGHT]= D3DX_PI*3.0f/4.0f; mapStepToRotation[STEP_PAD1_RIGHT] = D3DX_PI; mapStepToRotation[STEP_PAD2_LEFT] = mapStepToRotation[STEP_PAD1_LEFT]; mapStepToRotation[STEP_PAD2_UPLEFT] = mapStepToRotation[STEP_PAD1_UPLEFT]; mapStepToRotation[STEP_PAD2_DOWN] = mapStepToRotation[STEP_PAD1_DOWN]; mapStepToRotation[STEP_PAD2_UP] = mapStepToRotation[STEP_PAD1_UP]; mapStepToRotation[STEP_PAD2_UPRIGHT]= mapStepToRotation[STEP_PAD1_UPRIGHT]; mapStepToRotation[STEP_PAD2_RIGHT] = mapStepToRotation[STEP_PAD1_RIGHT]; switch( GAMEINFO->m_GameMode ) { case single4: case versus4: m_iNumColumns = 4; // LEFT, DOWN, UP, RIGHT m_StepToColumnNumber[STEP_PAD1_LEFT] = 0; m_StepToColumnNumber[STEP_PAD1_DOWN] = 1; m_StepToColumnNumber[STEP_PAD1_UP] = 2; m_StepToColumnNumber[STEP_PAD1_RIGHT] = 3; m_ColumnNumberToStep[0] = STEP_PAD1_LEFT; m_ColumnNumberToStep[1] = STEP_PAD1_DOWN; m_ColumnNumberToStep[2] = STEP_PAD1_UP; m_ColumnNumberToStep[3] = STEP_PAD1_RIGHT; m_ColumnToRotation[0] = mapStepToRotation[STEP_PAD1_LEFT]; m_ColumnToRotation[1] = mapStepToRotation[STEP_PAD1_DOWN]; m_ColumnToRotation[2] = mapStepToRotation[STEP_PAD1_UP]; m_ColumnToRotation[3] = mapStepToRotation[STEP_PAD1_RIGHT]; break; case single6: m_iNumColumns = 6; // LEFT, UP+LEFT, DOWN, UP, UP+RIGHT, RIGHT m_StepToColumnNumber[STEP_PAD1_LEFT] = 0; m_StepToColumnNumber[STEP_PAD1_UPLEFT] = 1; m_StepToColumnNumber[STEP_PAD1_DOWN] = 2; m_StepToColumnNumber[STEP_PAD1_UP] = 3; m_StepToColumnNumber[STEP_PAD1_UPRIGHT] = 4; m_StepToColumnNumber[STEP_PAD1_RIGHT] = 5; m_ColumnNumberToStep[0] = STEP_PAD1_LEFT; m_ColumnNumberToStep[1] = STEP_PAD1_UPLEFT; m_ColumnNumberToStep[2] = STEP_PAD1_DOWN; m_ColumnNumberToStep[3] = STEP_PAD1_UP; m_ColumnNumberToStep[4] = STEP_PAD1_UPRIGHT; m_ColumnNumberToStep[5] = STEP_PAD1_RIGHT; m_ColumnToRotation[0] = mapStepToRotation[STEP_PAD1_LEFT]; m_ColumnToRotation[1] = mapStepToRotation[STEP_PAD1_UPLEFT]; m_ColumnToRotation[2] = mapStepToRotation[STEP_PAD1_DOWN]; m_ColumnToRotation[3] = mapStepToRotation[STEP_PAD1_UP]; m_ColumnToRotation[4] = mapStepToRotation[STEP_PAD1_UPRIGHT]; m_ColumnToRotation[5] = mapStepToRotation[STEP_PAD1_RIGHT]; break; case double4: m_iNumColumns = 8; // 1_LEFT, 1_DOWN, 1_UP, 1_RIGHT, 2_LEFT, 2_DOWN, 2_UP, 2_RIGHT m_StepToColumnNumber[STEP_PAD1_LEFT] = 0; m_StepToColumnNumber[STEP_PAD1_DOWN] = 1; m_StepToColumnNumber[STEP_PAD1_UP] = 2; m_StepToColumnNumber[STEP_PAD1_RIGHT] = 3; m_StepToColumnNumber[STEP_PAD2_LEFT] = 4; m_StepToColumnNumber[STEP_PAD2_DOWN] = 5; m_StepToColumnNumber[STEP_PAD2_UP] = 6; m_StepToColumnNumber[STEP_PAD2_RIGHT] = 7; m_ColumnNumberToStep[0] = STEP_PAD1_LEFT; m_ColumnNumberToStep[1] = STEP_PAD1_DOWN; m_ColumnNumberToStep[2] = STEP_PAD1_UP; m_ColumnNumberToStep[3] = STEP_PAD1_RIGHT; m_ColumnNumberToStep[4] = STEP_PAD2_LEFT; m_ColumnNumberToStep[5] = STEP_PAD2_DOWN; m_ColumnNumberToStep[6] = STEP_PAD2_UP; m_ColumnNumberToStep[7] = STEP_PAD2_RIGHT; m_ColumnToRotation[0] = mapStepToRotation[STEP_PAD1_LEFT]; m_ColumnToRotation[1] = mapStepToRotation[STEP_PAD1_DOWN]; m_ColumnToRotation[2] = mapStepToRotation[STEP_PAD1_UP]; m_ColumnToRotation[3] = mapStepToRotation[STEP_PAD1_RIGHT]; m_ColumnToRotation[4] = mapStepToRotation[STEP_PAD2_LEFT]; m_ColumnToRotation[5] = mapStepToRotation[STEP_PAD2_DOWN]; m_ColumnToRotation[6] = mapStepToRotation[STEP_PAD2_UP]; m_ColumnToRotation[7] = mapStepToRotation[STEP_PAD2_RIGHT]; break; } for( int c=0; c < MAX_NUM_COLUMNS; c++ ) { // gray arrows m_sprGrayArrow[c].LoadFromSpriteFile( SPRITE_GRAY_ARROW ); m_sprGrayArrow[c].SetRotation( m_ColumnToRotation[c] ); m_sprGrayArrowGhost[c].LoadFromSpriteFile( SPRITE_GRAY_ARROW ); m_sprGrayArrowGhost[c].SetRotation( m_ColumnToRotation[c] ); m_sprGrayArrowGhost[c].StopAnimating(); m_sprGrayArrowGhost[c].SetState( 1 ); m_sprGrayArrowGhost[c].SetColor( D3DXCOLOR(1,1,1,0) ); // color arrows m_sprColorArrow[c].LoadFromSpriteFile( SPRITE_COLOR_ARROW ); m_sprColorArrow[c].StopAnimating(); m_sprColorArrow[c].SetRotation( m_ColumnToRotation[c] ); } // judgement m_fJudgementDisplayCountdown = 0; m_sprJudgement.LoadFromSpriteFile( JUDGEMENT_SPRITE ); // combo m_bComboVisible = FALSE; m_sprCombo.LoadFromSpriteFile( COMBO_SPRITE ); m_textComboNum.LoadFromFontName( "Arial Bold" ); m_textComboNum.SetText( "" ); // life meter m_sprLifeMeterFrame.LoadFromSpriteFile( LIFEMETER_FRAME_SPRITE ); m_sprLifeMeterPills.LoadFromSpriteFile( LIFEMETER_PILLS_SPRITE ); // score m_sprScoreFrame.LoadFromTexture( SCORE_FRAME_TEXTURE ); m_textScoreNum.LoadFromFontName( "Arial Bold" ); m_textScoreNum.SetText( " " ); SetX( CENTER_X ); } void Player::SetX( int iX ) { m_iArrowsCenterX = iX; SetGrayArrowsX(iX); SetColorArrowsX(iX); SetJudgementX(iX); SetComboX(iX); SetScoreX(iX); SetLifeMeterX(iX); } void Player::SetSteps( const Steps& newSteps ) { for( int i=0; i 0 ) { SetJudgement( miss ); m_iCurCombo = 0; SetCombo( 0 ); for( int i=0; i 0.0 ) m_fJudgementDisplayCountdown -= fDeltaTime; m_sprJudgement.Update( fDeltaTime ); } void Player::DrawJudgement() { if( m_fJudgementDisplayCountdown > 0.0 ) m_sprJudgement.Draw(); } void Player::SetJudgement( StepScore score ) { //RageLog( "Judgement::SetJudgement()" ); switch( score ) { case perfect: m_sprJudgement.SetState( 0 ); break; case great: m_sprJudgement.SetState( 1 ); break; case good: m_sprJudgement.SetState( 2 ); break; case boo: m_sprJudgement.SetState( 3 ); break; case miss: m_sprJudgement.SetState( 4 ); break; } m_fJudgementDisplayCountdown = JUDGEMENT_DISPLAY_TIME; m_sprJudgement.SetZoom( 1.5f ); m_sprJudgement.TweenTo( JUDGEMENT_DISPLAY_TIME/2.0, m_sprJudgement.GetX(), m_sprJudgement.GetY() ); } void Player::SetComboX( int iNewX ) { m_sprCombo.SetXY( iNewX+40, COMBO_Y ); m_textComboNum.SetXY( iNewX-50, COMBO_Y ); } void Player::UpdateCombo( const float &fDeltaTime ) { m_sprCombo.Update( fDeltaTime ); m_textComboNum.Update( fDeltaTime ); } void Player::DrawCombo() { if( m_bComboVisible ) { m_textComboNum.Draw(); m_sprCombo.Draw(); } } void Player::SetCombo( int iNewCombo ) { // new max combo if( iNewCombo > m_iMaxCombo ) m_iMaxCombo = iNewCombo; m_iCurCombo = iNewCombo; if( iNewCombo <= 4 ) { m_bComboVisible = FALSE; } else { m_bComboVisible = TRUE; m_textComboNum.SetText( ssprintf("%d", iNewCombo) ); m_textComboNum.SetZoom( 1.0f + iNewCombo/200.0f ); m_textComboNum.TweenTo( COMBO_TWEEN_TIME, m_textComboNum.GetX(), m_textComboNum.GetY() ); } } void Player::SetLifeMeterX( int iNewX ) { m_sprLifeMeterFrame.SetXY( iNewX, LIFEMETER_Y ); m_sprLifeMeterPills.SetXY( iNewX, LIFEMETER_PILLS_Y ); } void Player::UpdateLifeMeter( const float &fDeltaTime ) { m_sprLifeMeterFrame.Update( fDeltaTime ); m_sprLifeMeterPills.Update( fDeltaTime ); } void Player::DrawLifeMeter( float fSongBeat ) { float fBeatPercentage = fSongBeat - (int)fSongBeat; int iOffsetStart = roundf( LIEFMETER_NUM_PILLS*fBeatPercentage ); m_sprLifeMeterFrame.Draw(); float iX = m_sprLifeMeterFrame.GetLeftEdge() + 27; int iNumPills = (int)(m_sprLifeMeterPills.GetNumStates() * m_fLifePercentage); int iPillWidth = m_sprLifeMeterPills.GetZoomedWidth(); for( int i=0; i