@startuml https://www.plantuml.com/plantuml/uml/D8b9_sj8003lxulCoVj7WiISfkqBiIzS_3Hj2K5eX4y_ymvpg4DL_RFWVCRhk__rLuFnjFpzyxFl---fpuS_zNSnld_-bvy_l0o5SmSqKDotRuPu67KBvizQ2AA4KaO-Zc0yrW05au1e0M-oz4RDM19z7rgBSoQVQXkiyCnu_d7s6rpTwZ51Zkz6C4S2V4b3tKRKcckzJi4ezbMc4DgGGPjDmijOtNLgbQFBBH9NHc_OAyczawNUxKIzU4V_L7Wg3emdwto8OP7j_F1I9OvkiCYkWKbJ3eXCFU6e6K0Y61Y_RglcqAawJbq0SnLb9-YRY07qMPQ7cu9aAVCP2HiWGY-EpS3PIIbU3R5H43lCYkgmt0Vwd7Jwewjy-hnZIOFPbf1KllOHE9arw2S7LQxj0t3lI2d73f8p9nBuHlxl-vVRtcvhec6nQsv8FWrfm-bfFKCgojiWl8dYD2Sq3DxiPTYS87fXCvS6uv5bxhuvtl6oJKxZrc9Ac-BYMFCxs3gqodlBnZFpTGh2Vl94QPBuQ5eSsj-RTTklQoYq0jnWeooUML4TeiAe40V1iKqJv5VwTM4bS9KYaidgUO8amMywfreYrk9fsn-QJZ9Y3SZaimC6fdHYqJZRGHPEfMrUY-nBYJwMNKIgI7QxN1GqPVMJVQvnDbmRlit7oLjmUQ_6FFJ0kmhnWtk6hJzQHnltvYYNgOkaXojtHPRr2wticUa5m_bTASrPFx7Usobxr-9-9Hf3Ir-1n3zl7_pWqU4dlF8w7BCh0T2JnrxX6srM2SdLotsXhCK8b5GQiQD6Fa6WoXIAeaht2RFasHltWRmp5yqV8ubfF3LMjuCR2JBVrw8NlgYym8RFVltwjxSgwd7RXi7l_XL4zd0fBcTWh-umxBgYsm73MZG1zd2u1zbY4dMob8bKUqRG_pxPiWmByz9cmFeKywFuaP_8K3UmzVK7RBWmeaKwYGOJKduWE1S0ZHP42Um1W3kmDQ7xY8ugU3iuwF6f67otq5X3x7p3rgrVZ1ZvcXgdQbodo1IOJdXprPbxhIToOrdjksroEHeyduk-86KOtRwNzNOaFSSeVvA2SKtMkmOh87RA73PGbgNbO-0OAI0f3vw90hwhjSUNMXaifML6-PBncQiU1O3gdnL18xGcY4cX2CGti1FkW4opcuz8lFXqyoC8WH-Df5btobIPQayQMpISUIUz012xzb6HgdKGMrkhKPY8FeToVHkAZ6QNcv-Kv6CE7L4TZfnZgZrKyEwX5GSSns0-1SzLFBk1JJTzHkPeZPqCEjzPPJWqCAE_bKvyIkrMzAlY6MMNE79TjtIqTl5SSTq0f3QWb5tUYzIQyoN5rmhEixxspP-BIV_7dDk_l78EzRVDcnAy4JrfzyCsT4CZM_FZcF9CB5WrdyEP1nE-JOE1AO-QCaMKNdM_YnRNF5Zz9wL6Fpvj8C9_f5BpAO69wxqmqhOZuzhuz9bYliHJz387DcCPGUEUmUxpmg62cIvGeGkx-zt3ptti3Rn77QHRGqTree3aeMMP3UV5vLI19oHOu9YDsdzbI8FpzInn4VxY3GWZuPNN6hcOBSJWcRRXD2WzUcaTZczKunrPbxOIH92EbhVM6rd1yFD6wUJ2ziJTl_WuH8L8ofUUmrOe4uPfmLVtMW8uYdfyMbYBYJNxdsIxpg6sGaOhpcAMSlrY39rllFJsfTkA1S0vRVjysITh-Nr8g_qhDdkte2AjqA5Zg-zNS7S7grQORfMgkZmZ8HC7kN5Emg1i6-iGNYiwQT7DvYGwHhmVcDdxcVc-z5HEYXV6vZVSSzvZwfaJj70voYXMGaUf5xjCo4EP2H5IHdj8iRFtKkRX8M2aNGTyASCrZroutP_GID_glm40 ' Subject namespace Subject.js { class Subject{ - observers: Objects[] + constructor() + subscribe(observer: Object) + unsubscribe(observer: Object) + unsubscribeAll() + notifySubscribers(source: string) } interface Observer{ +update(source: string, ...others) } Subject .. Observer #blue;line.dotted;text:blue : notifySubscribers calls update } ' Targets namespace Target.js { class Target extends Subject.js.Subject implements Subject.js.Observer{ -visible: boolean -x: number -y: number -width: number -height: number -img: PImage +constructor(x:number, ,y:number, width:number) +getPoints(): number +draw() +isHit(x:number, y:number): boolean +shoot(x:number, y:number) +update(source: string, ...others) } class TeddyTarget extends Target { +constructor(x:number, y:number, width:number) +getPoints(): number } class DuckTarget extends Target{ +constructor(x:number, y:number, width:number) +getPoints(): number } class SquirrelTarget extends Target{ +constructor(x:number, y:number, width:number) +getPoints(): number } class TargetFactory{ +{static}getInstance(): TargetFactory +getTargetsByName(targetNames: string[], targetWidth:number, y:number) +getRandomTargets(numTargets:number, targetWidth:number, y:number) } note left of TargetFactory : getInstance is STATIC ' Relationships TargetFactory .. TeddyTarget #blue;line.dotted;text:blue : uses TargetFactory .. DuckTarget #blue;line.dotted;text:blue : uses TargetFactory .. SquirrelTarget #blue;line.dotted;text:blue : uses } ' Gun and Bullet namespace Gun.js { class Gun extends Subject.js.Subject { -cursor: PImage -shotSound: SoundFile -emptySound: SoundFile -totShots: number -remainingShots: number -bullets: Bullet[] +constructor(totShots:number) +draw() +reload() +getRemainingShots():number +shoot() } class Bullet { -x:number -y:number -visible: boolean -img:PImage +constructor(x:number, y:number) +draw() } Gun "1" -- "many" Bullet #blue;line.dotted;text:blue : contains } ' Score Display namespace ScoreDisplay.js { class ScoreDisplay implements Subject.js.Observer{ -img: PImage -shotLeft: number -score: number +constructor(initialBullets:number) +draw() +resetScore() +addScore(scoreToAdd:number) +setBullets(numBullets:number) +update(source: string, ...others) } } @enduml