@startuml skinparam linetype ortho package utils { class PathFinder { static List findPath(Board, TileVec2, TileVec2) } } package viewer { class Viewer { Game Stage void main(String[]) void eventLoop(ApplicationContext) void renderFrame(Graphics2D,ApplicationContext) } } package context { class Context { Context(Stage,List,GraphicsContext) final Stage final List final GraphicsContext } class GraphicsContext { final Graphics2D final ScreenInfo paintCircle(Color, Vec2, float) paintSquare(Color, Vec2, float, float) } class InputHandler { private final ApplicationContext InputHandler(ApplicationContext) List getEvents() } class ScreenManager { private final ApplicationContext private final Graphics2D ScreenManager(ApplicationContext,Graphics2D) GraphicsContext clearScreen() } class Game { final GameController int index final List Game(GameController,List) } } package event { interface Event interface InputEvent implements Event interface GameEvent implements Event class DropBombEvent implements InputEvent class AddBombEvent implements InputEvent { final TileVec2 AddBombEvent(TileVec2) TileVec2 getTile() } class MoveRobotEvent implements InputEvent { final TileVec2 MoveRobotEvent(TileVec2) TileVec2 getTile() } class ConfirmEvent implements InputEvent class ExplosionEvent implements GameEvent { Block source Body source } } package board { class Board { Board(width, height) BlockType getBlockTypeAt(TileVec2) BlockType setBlockTypeAt(TileVec2, BlockType) } class BoardParser { static Board parse(File) } class BoardValidator { static bool validate(Board) } class BoardConverter { static Board worldToBoard(List) static List boardToWorld(Board) } class TileVec2 { static final int TILE_DIM static TileVec2 fromVec2(Vec2) Vec2 TileVec2(col, row) Vec2 toPixelPos() } } package model { enum BlockType { FREE WALL TRASH GARBAGE ROBOT BOMB } class BlockFactory { Block build(BlockType, Vec2) } abstract class Block { List Block(Vec2) Vec2 getPosition() void setPosition(Vec2) List update(Context) } abstract class StaticBlock extends Block class WallBlock extends StaticBlock class TrashBlock extends StaticBlock class BombBlock extends StaticBlock class GarbageBlock extends Block class RobotBlock extends Block class Stage { StageController List Stage(Board) List getBlocks() List update(Context) bool isCleared() } } package controller { interface Controller { List update(Context) } abstract class BlockController implements Controller { Block Controller(Block) Block getBlock() } class BlockControllerFactory { BlockController build(Block) } class GameController implements Controller class StageController implements Controller abstract class PhysicsController extends BlockController abstract class DisplayController extends BlockController class WallPhysicsController extends PhysicsController class WallDisplayController extends DisplayController class TrashPhysicsController extends PhysicsController class TrashDisplayController extends DisplayController class GarbagePhysicsController extends PhysicsController class GarbageDisplayController extends DisplayController class RobotPhysicsController extends PhysicsController { List path } class RobotDisplayController extends DisplayController class BombPhysicsController extends PhysicsController class BombDisplayController extends DisplayController } RobotPhysicsController --> PathFinder RobotPhysicsController --> BoardConverter Stage --> BoardConverter PhysicsController --() JBox2D Zen5 ()-- Viewer viewer --> context viewer --> model context --> event model --> controller board --> model @enduml