@startuml

!theme plain
top to bottom direction
skinparam linetype ortho

class Audio {
  + Audio(): 
  - playSound(String): void
  + jump(): void
  + point(): void
  + hit(): void
}
class Bird {
  + Bird(int, int): 
  - isAlive: boolean
  + renderBird(Graphics): void
  + jump(): void
  + killBird(): void
  + menuFloat(): void
  + inGameBorders(): void
  - animateBird(Graphics, double): void
  + setGameStartPos(): void
   isAlive: boolean
}
class FlappyBird {
  + FlappyBird(): 
  + actionPerformed(ActionEvent): void
  + main(String[]): void
}
class GamePanel {
  + GamePanel(): 
  - gameState: GameState
  # clickedPoint: Point
  + keyReleased(KeyEvent): void
  + mouseEntered(MouseEvent): void
  + keyPressed(KeyEvent): void
  + mousePressed(MouseEvent): void
  + paintComponent(Graphics): void
  + keyTyped(KeyEvent): void
  + mouseClicked(MouseEvent): void
  + mouseReleased(MouseEvent): void
  + isTouching(Rectangle): boolean
  + addNotify(): void
  + mouseExited(MouseEvent): void
   gameState: GameState
   clickedPoint: Point
}
class GameState {
  + GameState(GamePanel): 
  + prepareScreen(Graphics): void
  + renderGameState(Graphics): void
  + handleMouseEvent(MouseEvent): void
  + handleKeyboardEvent(KeyEvent): void
  + restart(): void
  + drawBase(Graphics): void
}
class HasPosition {
  + HasPosition(int, int): 
  # y: int
  # x: int
   y: int
   x: int
}
class Highscore {
  + Highscore(): 
  + bestScore(): int
   newBest: int
}
class MenuState {
  + MenuState(GamePanel): 
  + handleKeyboardEvent(KeyEvent): void
  # drawMenu(Graphics): void
  + drawCentered(String, int, int, int, Graphics): void
  + handleMouseEvent(MouseEvent): void
  + renderGameState(Graphics): void
  + openReviewUrl(): void
}
class Pipe {
  + Pipe(String): 
  + move(): void
  + reset(): void
  + collide(Bird): boolean
   y: int
}
class PlayState {
  + PlayState(GamePanel): 
  + drawScore(Graphics, int, boolean, int, int): void
  + startGameScreen(Graphics): void
  + pipeHandler(Graphics): void
  + handleMouseEvent(MouseEvent): void
  + gameOver(Graphics): void
  + renderGameState(Graphics): void
  + handleKeyboardEvent(KeyEvent): void
}
class Sprites {
  + Sprites(): 
  - putTexture(String, int, int, int, int, int, int): void
  - resize(BufferedImage): BufferedImage
   gameTextures: HashMap<String, Texture>
}
class Texture {
  + Texture(BufferedImage, int, int): 
  - image: BufferedImage
  - rect: Rectangle
   image: BufferedImage
   rect: Rectangle
}

Bird         -[#000082,plain]-^  HasPosition 
FlappyBird   -[#595959,dashed]->  Audio       : "«create»"
FlappyBird  "1" *-[#595959,plain]-> "audio\n1" Audio       
FlappyBird   -[#595959,dashed]->  GamePanel   : "«create»"
FlappyBird  "1" *-[#595959,plain]-> "game\n1" GamePanel   
FlappyBird   -[#595959,dashed]->  Sprites     : "«create»"
FlappyBird  "1" *-[#595959,plain]-> "textures\n*" Texture     
GamePanel   "1" *-[#595959,plain]-> "gameState\n1" GameState   
GamePanel    -[#595959,dashed]->  MenuState   : "«create»"
GameState    -[#595959,dashed]->  Bird        : "«create»"
GameState   "1" *-[#595959,plain]-> "gameBird\n1" Bird        
GameState   "1" *-[#595959,plain]-> "gamePanel\n1" GamePanel   
GameState   "1" *-[#595959,plain]-> "pipes\n*" Pipe        
MenuState    -[#000082,plain]-^  GameState   
MenuState    -[#595959,dashed]->  PlayState   : "«create»"
Pipe         -[#000082,plain]-^  HasPosition 
PlayState    -[#000082,plain]-^  GameState   
PlayState    -[#595959,dashed]->  Highscore   : "«create»"
PlayState   "1" *-[#595959,plain]-> "highscore\n1" Highscore   
PlayState    -[#595959,dashed]->  Pipe        : "«create»"
Sprites     "1" *-[#595959,plain]-> "textures\n*" Texture     
Sprites      -[#595959,dashed]->  Texture     : "«create»"
Texture      -[#000082,plain]-^  HasPosition 
@enduml
