class Enemy { Vector2D m_LastPosition; Vector2D m_Position; Vector2D m_Direction; float m_DistanceTravelled; int m_TravelledCounter; int m_GridSquareX; int m_GridSquareY; float m_Width; float m_Height; float m_HalfWidth; float m_HalfHeight; boolean m_Visible; int m_ExcitedCounter; int m_FrozenCounter; int m_State; //0 - normal //1 - excited //2 - frozen void Initialize() { m_Position = new Vector2D(); m_Position.x = 20.f; m_Position.y = 80.f; m_LastPosition = new Vector2D(); m_LastPosition.Set( m_Position.x, m_Position.y ); m_Direction = new Vector2D(); m_Direction.x = 1.f; m_Direction.y = 0.f; m_DistanceTravelled = 0.f; m_TravelledCounter = 30; m_Width = 12.f; m_Height = 12.f; m_HalfWidth = m_Width / 2.f; m_HalfHeight = m_Height / 2.f; m_Visible = true; } void Update() { m_LastPosition.x = m_Position.x; m_LastPosition.y = m_Position.y; float tempPosX = m_Position.x; float tempPosY = m_Position.y; //update state if( m_State == 1 ) { tempPosX += m_Direction.x; tempPosY += m_Direction.y; --m_ExcitedCounter; if( m_ExcitedCounter <= 0 ) { m_ExcitedCounter = 0; m_State = 0; } } else if( m_State == 2 ) { --m_FrozenCounter; if( m_FrozenCounter <= 0 ) { m_FrozenCounter = 0; m_State = 0; } return; } //update position tempPosX += m_Direction.x; tempPosY += m_Direction.y; //cap if( tempPosX < 0.f ) { tempPosX = 0.f; m_Direction.x = -m_Direction.x; } else if( tempPosX > (float)SCREEN_WIDTH ) { tempPosX = (float)SCREEN_WIDTH; m_Direction.x = -m_Direction.x; } if( tempPosY < 0.f ) { tempPosY = 0.f; m_Direction.y = -m_Direction.y; } else if( tempPosY > (float)SCREEN_HEIGHT ) { tempPosY = (float)SCREEN_HEIGHT; m_Direction.y = -m_Direction.y; } //compute projected grid square int curCellIndexX = (int)(tempPosX / GRID.m_CellWidth); int curCellIndexY = (int)(tempPosY / GRID.m_CellWidth); curCellIndexX = CapInt( curCellIndexX, 0, GRID.m_NumCellsX - 1 ); curCellIndexY = CapInt( curCellIndexY, 0, GRID.m_NumCellsY - 1 ); m_GridSquareX = curCellIndexX; m_GridSquareY = curCellIndexY; if( GRID.m_Cells[ curCellIndexY * GRID.m_NumCellsX + curCellIndexX ].m_Wall || GRID.m_Cells[ curCellIndexY * GRID.m_NumCellsX + curCellIndexX ].m_FakeWall ) { m_Direction.Negative(); } else { m_Position.x = tempPosX; m_Position.y = tempPosY; } //if we've travelled farther than our magic number to create a new sound, do so --m_TravelledCounter; Vector2D travelled = new Vector2D( m_LastPosition.x - m_Position.x, m_LastPosition.y - m_Position.y ); m_DistanceTravelled += travelled.MagnitudeSquared(); if( m_DistanceTravelled > 20.f && m_TravelledCounter > 0 ) { m_TravelledCounter = 30; m_DistanceTravelled = 0.f; SOUND_MANAGER.AddSoundBurst( m_Position.x, m_Position.y, 100, 0 ); } //check to see if we hit a player int i; for( i = 0; i < NUM_PLAYERS; ++i ) { Vector2D toPlayer = new Vector2D(); toPlayer.Set( m_Position.x - PLAYER[i].m_Position.x, m_Position.y - PLAYER[i].m_Position.y ); if( toPlayer.MagnitudeSquared() < 10.f ) { PLAYER[i].ResetToHome(); } } m_Direction.Normalize(); } void Draw() { //only draw invisible enemies if we're Scream if( !m_Visible && CURRENT_PLAYER != 2 ) { return; } //only draw if we're in viewing distance //Vector2D thisPlayerToCurrent = new Vector2D( PLAYER[CURRENT_PLAYER].m_Position.x - m_Position.x, // PLAYER[CURRENT_PLAYER].m_Position.y - m_Position.y ); Vector2D thisPlayerToCurrent = new Vector2D( PLAYER[0].m_Position.x - m_Position.x, PLAYER[0].m_Position.y - m_Position.y ); float sight = PLAYER[0].m_Sight; //if( CURRENT_PLAYER == 2 ) //{ // sight *= 8; //} if( !DRAW_ALL && thisPlayerToCurrent.MagnitudeSquared() > sight ) { return; } int redComponent = 0; if( CURRENT_PLAYER == 2 ) { redComponent = 128; } stroke( redComponent, 0, 255 - redComponent ); fill( redComponent, 0, 255 - redComponent ); switch( m_State ) { case 1: { line( m_Position.x - 7.5f, m_Position.y, m_Position.x + 7.5f, m_Position.y ); line( m_Position.x, m_Position.y - 7.5f, m_Position.x, m_Position.y + 7.5f ); line( m_Position.x - 7.5f, m_Position.y - 7.5f, m_Position.x + 7.5f, m_Position.y + 7.5f ); line( m_Position.x - 7.5f, m_Position.y + 7.5f, m_Position.x + 7.5f, m_Position.y - 7.5f ); } case 0: { ellipse( m_Position.x, m_Position.y, m_Width, m_Height ); line( m_Position.x, m_Position.y, m_Position.x + (m_Direction.x * 8.5f), m_Position.y + (m_Direction.y * 8.5f) ); } break; case 2: { fill( redComponent, 0, 255 - redComponent, (150.f-(float)m_FrozenCounter)/150.f * 255.f ); ellipse( m_Position.x, m_Position.y, m_Width, m_Height ); } break; } } void SetFrozen() { m_FrozenCounter = 150; m_State = 2; } void SetExcited() { if( m_State != 2 ) { m_ExcitedCounter = 120; m_State = 1; } } };