From 47ec2337a423ee6b9c869c53d6ed95402aee7f8c Mon Sep 17 00:00:00 2001 From: Nilstrieb Date: Sat, 12 Dec 2020 12:37:13 +0100 Subject: [PATCH] coordinates change --- src/main/java/core/Master.java | 19 +++- .../java/core/{ => physics}/Collidable.java | 2 +- src/main/java/objects/GameObject.java | 97 +++++++++++++++--- src/main/java/objects/ships/BattleShip.java | 17 +-- src/main/java/objects/ships/Turret.java | 3 +- src/main/java/objects/world/Wall.java | 8 +- target/classes/core/Master.class | Bin 4214 -> 4410 bytes target/classes/objects/GameObject.class | Bin 1723 -> 2835 bytes target/classes/objects/ships/BattleShip.class | Bin 2936 -> 2526 bytes 9 files changed, 108 insertions(+), 38 deletions(-) rename src/main/java/core/{ => physics}/Collidable.java (60%) diff --git a/src/main/java/core/Master.java b/src/main/java/core/Master.java index c4e77e9..06042e7 100644 --- a/src/main/java/core/Master.java +++ b/src/main/java/core/Master.java @@ -17,6 +17,19 @@ import java.util.ArrayList; */ public class Master extends JPanel { + /** + * The ratio of height to width. + */ + public static double SCREEN_RATIO = 16f / 9f; + + /** + * The height of the relative coordinates shown on the screen. + */ + public static final double SCREEN_Y_COORDINATES = 100d; + + @Deprecated + public static final double SCREEN_X_COORDINATES = 100d * SCREEN_RATIO; + /** * All GameObjects that exist */ @@ -41,9 +54,9 @@ public class Master extends JPanel { BattleShip battleShip = new BattleShip(Color.DARK_GRAY); BattleShip bs = new BattleShip(70, 10, 5, 80, Color.GREEN); - for (int i = 0; i < 10; i++) { + /*for (int i = 0; i < 10; i++) { bs.addTurret(new Turret(bs, 25, 10 * i + 1, 50, i % 5)); - } + }*/ objects.add(bs); objects.add(battleShip); @@ -57,7 +70,6 @@ public class Master extends JPanel { */ private void doDrawing(Graphics g) { - //TODO w/h fields int w, h; if (getWidth() * 9 > getHeight() * 16) { h = getHeight(); @@ -85,6 +97,7 @@ public class Master extends JPanel { */ public void debugPos(Vector2D pos){ create(new DebugPos(pos, new Vector2D(10, 10))); + System.out.println(pos); } /** diff --git a/src/main/java/core/Collidable.java b/src/main/java/core/physics/Collidable.java similarity index 60% rename from src/main/java/core/Collidable.java rename to src/main/java/core/physics/Collidable.java index 7b14855..3336ffb 100644 --- a/src/main/java/core/Collidable.java +++ b/src/main/java/core/physics/Collidable.java @@ -1,4 +1,4 @@ -package core; +package core.physics; public interface Collidable { diff --git a/src/main/java/objects/GameObject.java b/src/main/java/objects/GameObject.java index 6e2ae52..33cb6ab 100644 --- a/src/main/java/objects/GameObject.java +++ b/src/main/java/objects/GameObject.java @@ -4,6 +4,8 @@ import core.Master; import core.Vector2D; import java.awt.*; +import java.util.function.Consumer; +import java.util.function.Function; /** * The GameObject class is the superclass of every GameObject that can be displayed on screen. It has the 2 @@ -19,6 +21,8 @@ public abstract class GameObject { protected Vector2D velocity; + protected Color mainColor; + public GameObject(double x, double y, double xSize, double ySize) { this(new Vector2D(x, y), new Vector2D(xSize, ySize)); } @@ -27,37 +31,104 @@ public abstract class GameObject { this.position = position; this.size = size; this.velocity = new Vector2D(); + mainColor = Color.BLACK; } + /** + *

The draw method is called every frame after the {@link #update(Master)} by the master object on each object. Everything + * about drawing should be handled here in this method.

+ *

No general calculations should be made in this method. The game should be able to work just + * fine even without this method being called.

+ *

This function is NOT intended to be called manually.

+ * @param g2d The {@code Graphics2D} object given by the master + * @param w The width of the screen + * @param master The master object itself + */ public abstract void draw(Graphics2D g2d, int w, Master master); + + /** + *

The update method is called every frame before the {@link #draw(Graphics2D, int, Master)} method by the master object on each object. Everything + * that is needed for the game to work should be here in this method.

+ *

No drawing should be made in this method. The {@code debug} method can be called on the master.

+ *

This function is NOT intended to be called manually.

+ * @param master The master object itself + */ public abstract void update(Master master); + /** + * A simple method to move the object to a Vector2D. This method should be called instead of doing it manually. + * @param target The target position + */ public void moveTo(Vector2D target){ this.position = target; } + /** + * This method draws a rectangle at the current position and size + * @param g2d The Graphics2D object provided by the master + * @param w The width of the screen + */ + public void drawRect(Graphics2D g2d, int w){ + this.w = w; + h = (int) (this.w / Master.SCREEN_RATIO); + int xAbs = (int) getWorldCoords(position.x, true); + int yAbs = (int) getWorldCoords(position.y, false); + int sizeXAbs = (int) getWorldCoordsSize(size.x, true); + int sizeYAbs = (int) getWorldCoordsSize(size.y, false); + + g2d.setPaint(mainColor); + g2d.fillRect(xAbs, yAbs, sizeXAbs, sizeYAbs); + } + + /** + * This method draws a rounded rectangle at the current position and size + * @param g2d The Graphics2D object provided by the master + * @param w The width of the screen + * @param arcW The arc width of the rectangle + * @param arcH The arc height of the rectangle + */ + public void drawRoundRect(Graphics2D g2d, int w, int arcW, int arcH){ + this.w = w; + h = (int) (w / Master.SCREEN_RATIO); + int xAbs = (int) getWorldCoords(position.x, true); + int yAbs = (int) getWorldCoords(position.y, false); + int sizeXAbs = (int) getWorldCoordsSize(size.x, true); + int sizeYAbs = (int) getWorldCoordsSize(size.y, false); + + g2d.setPaint(mainColor); + g2d.fillRoundRect(xAbs, yAbs, sizeXAbs, sizeYAbs, arcW, arcH); + } + + public double getWorldCoords(double value, boolean isX){ + if (isX){ + return (value / (Master.SCREEN_Y_COORDINATES * Master.SCREEN_RATIO) * w); + } else { + return (value / Master.SCREEN_Y_COORDINATES * h); + } + } + + public double getWorldCoordsSize(double value, boolean isX){ + if (isX){ + return (value / Master.SCREEN_Y_COORDINATES * w); + } else { + return (value / Master.SCREEN_Y_COORDINATES * h); + } + } + public double getMapCoords(double value, boolean isX){ if (isX){ - return (position.x + value / 100 * size.x); + return (position.x + value / 100d * size.x); } else { - return (position.y + value / 100 * size.y); + return (position.y + value / 100d * size.y); } } public double getMapCoordsSize(double value, boolean useX){ if (useX){ - return (value / 100 * size.x); + return (value / 100d * size.x); } else { - return (value / 100 * size.y); - } - } - - public double getWorldCoords(double value, boolean isX){ - if (isX){ - return (value / 100 * w); - } else { - return (value / 100 * h); + return (value / 100d * size.y); } } @@ -66,6 +137,6 @@ public abstract class GameObject { } public int getWorldCoordsFromLocalSize(double value, boolean useX){ - return (int) getWorldCoords(getMapCoordsSize(value, useX), useX); + return (int) getWorldCoordsSize(getMapCoordsSize(value, useX), useX); } } diff --git a/src/main/java/objects/ships/BattleShip.java b/src/main/java/objects/ships/BattleShip.java index 107f4aa..cbcb6b2 100644 --- a/src/main/java/objects/ships/BattleShip.java +++ b/src/main/java/objects/ships/BattleShip.java @@ -11,16 +11,14 @@ import java.util.ArrayList; */ public class BattleShip extends GameObject { - private Color mainColor; private ArrayList turrets; public BattleShip(Color mainColor) { - super(20, 20, 5, 40); - turrets = new ArrayList<>(); - turrets.add(new Turret(this, 25, 25, 50, 3)); + this(20, 20, 5, 40, mainColor); + //TODO child x coords 100 not 100*16/9 + turrets.add(new Turret(this, 100*16/9d/4, 25, 50, 3)); //turrets.add(new Turret(this, 25, 10, 50, 2)); //turrets.add(new Turret(this, 25, 70, 50, 2)); - this.mainColor = mainColor; } public BattleShip(double x, double y, double xSize, double ySize, Color mainColor) { @@ -31,15 +29,8 @@ public class BattleShip extends GameObject { @Override public void draw(Graphics2D g2d, int w, Master master) { - this.w = w; - h = w/16*9; - g2d.setPaint(mainColor); - int xAbs = (int) getWorldCoords(position.x, true); - int yAbs = (int) getWorldCoords(position.y, false); - int sizeXAbs = (int) getWorldCoords(size.x, true); - int sizeYAbs = (int) getWorldCoords(size.y, false); - g2d.fillRoundRect(xAbs, yAbs, sizeXAbs, sizeYAbs, w/10, w/10); + drawRoundRect(g2d, w, w/10, w/10); turrets.forEach((turret -> turret.draw(g2d, w, master))); } diff --git a/src/main/java/objects/ships/Turret.java b/src/main/java/objects/ships/Turret.java index c115c15..9689e57 100644 --- a/src/main/java/objects/ships/Turret.java +++ b/src/main/java/objects/ships/Turret.java @@ -43,7 +43,6 @@ public class Turret extends GameObject { @Override public void draw(Graphics2D g2d, int w, Master master) { - //TODO draw should be draw only for better everything h = w / 16 * 9; g2d.setPaint(mainColor); int xAbs = battleShip.getWorldCoordsFromLocal(position.x, true); @@ -75,6 +74,8 @@ public class Turret extends GameObject { } } g2d.rotate(-rotation, xCenterAbs, yCenterAbs); + + g2d.setStroke(new BasicStroke()); } @Override diff --git a/src/main/java/objects/world/Wall.java b/src/main/java/objects/world/Wall.java index 5b2e1a9..4ea16d0 100644 --- a/src/main/java/objects/world/Wall.java +++ b/src/main/java/objects/world/Wall.java @@ -13,13 +13,7 @@ public class Wall extends GameObject { @Override public void draw(Graphics2D g2d, int w, Master master) { - int xAbs = (int) getWorldCoords(position.x, true); - int yAbs = (int) getWorldCoords(position.y, false); - int sizeXAbs = (int) getWorldCoords(size.x, true); - int sizeYAbs = (int) getWorldCoords(size.y, false); - - g2d.setPaint(Color.BLACK); - g2d.fillRect(xAbs, yAbs, sizeXAbs, sizeYAbs); + drawRect(g2d, w); } @Override diff --git a/target/classes/core/Master.class b/target/classes/core/Master.class index 271caab6719584ec06627decb0636fdd1761cc89..933f4377d861b9745d131ef818883bc901c3c6d6 100644 GIT binary patch delta 2346 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 R22h|dGQ4GY&+w5!5&!}b*UJC^ delta 2102 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 Z;2_y;3^sk}2KNv&7~*tBh6=EgDgkkD_Tm5l literal 1723 zcmX^0Z`VEs1_mnze|82YMh4#G{GwF-u+-#|{30V4E(S&h79Ivx1~x_pHk-`6%o00B z238Fh7tJs(1`Y;Jb_OnxEH@*AP<~QYYH~@jzI$SBsy~>`$e^g_uoD3WcLOcw@3?hsS90mEsnI)O|d5jGFXvTq* ziSaOqgOsrpXI7iQGB7g8@-WCT$TKo9RxmO!y0AG! zGJpX{N|}d21uRtw(yhkBpw6Jd$iP_6$iV0c64Bye&<2ZSfPz7nhe3})pOJwlJ+;I) zvA{V$zbK^`98OW1E+7SlJPbx41$^nLCE@u+IVlh&ASn|b22+rf0J7fT%&JsI26hb> z7f?tuGO#%3r=)`Xo0*sDSDKrYS`?C)l#|NHAmo#uoR|}qSdx)n z7#Y|~3sMqGQW+TppplC#mz!Uf8j{b*AOw|zr6Y*WlEk9))DlJp*0RK$(o{wU=FH*< zMh3lkm4W>cqiIu^Ofsw(S zfq@|(lmi$T7$miJGcZP~Yi?&?1~DX9CD^w!FmGpI-^jqgz{Fs|z`(%8z{J47AkHAc zAi-eCz`$U_zzWjHV8vh!PIHo=l*qsc7E@u6XJ7`iY#8LB>TDV08Q2*Z8CV&(p_XSb zFoRV|X>DiV(bC?^AgHCYl|dBjlTNxw~wu^yHkz!zBkY?aykYV6skYxbb2y%%6 z#1yzoq(He0>=G$ZMq*%MVPvpluxDUkVPtS%aAaU$U}SJ&aE7|Vj)4j6Gd8db5H>>m ztHQv_pbGY{7(^A^7B&VK1`!5E21ZcEftpp%z{bGBz`$T2JCi|DYYT(m76uu05e9{P ztt||qTNq@rlh;E;m5@Z0vXj>{FfcHKLzxfk7fl8h1}z3D1|6`?5dRs#Z8l(VWsnE^ z&w#;=!JUDb!2_(HQHp^PloO$j$!A~zJ4QivCW9c7eKOhWk$6hk=$0EYurL@g2r-x- zS*`%LTmf#m0)r>AzZ3k(drT3YI|+Zc3Yw=o#>t%0XvHgLE(BH6$Tw}BUK d125DDMg|{T1{-5F*p;BckT7Fp@C7@`4*)c$4GRDO diff --git a/target/classes/objects/ships/BattleShip.class b/target/classes/objects/ships/BattleShip.class index 961b066fbdfa7207d6f7b34f97b05eb8eea3bdf6..34aa79b63f2c71a51d0d279dd78500548e9541bc 100644 GIT binary patch delta 1283 zcmew%c2Ah=)W2Q(7#J9=7%C@nX-%9Y&CX_%nU`5&H#vqyii?whgMp8SfuBKO;%XH} zp@|nHmE9~J_gOsdV{@=%00TA$PcY5E#URKa#lyhOAU&CxQB6^nL5`h4o`*q!L6MO` zI4iL%QNOe#Ge_UCs3@`0C$qR@vLU0K8yABzg9R$iS?j83uBkHV=aigYM)=MtM0d1`Y;&9tHyjLq-PP zl%mA)p#0Ljl%Uk)5=I7TjmiBiqWqqoo|<7o3=9m$JPalbrjute1#rkRnDa1LFj!9h z#AL{24HCCuWYE!=yq8H=PmsZmhryn~fsui&v>+w1B$bgtK*J|FzbIATH?g=Rwa6Oe zDnSM(9tLLym&qN>*SHuf7#SE{7#SEVCzr7p$TOBRGBA2FGO*=>)iW~iqG;dzkcE?x zFNKRCl_8CtA)SXIgCTSC4^|dN#_Y*|*`y6~L7vLvVTfah7hs6wXJaS?2^8@##4yA% zGVplj<)s!m=Oh*vrxvp_lrl1?PBvguWoBn6pIpeUThGCu%)r3F$iM`OKn6wzR|W1_m815e7yuVisXw)!xp)uC;}McQ=Dzq?QPS zun2>w2!lA=b_U693^L&x!6tzso{xc)b; zfFg;35o|3F)Y=vXP6jRp1_l`|bxjFY3HI#_N?N-aWFxmTsBdN9)sp1g%Akd?Mu>rh zfq_ASfr~+sL6kv?L7G7tY?U1Y8^{c}O)?C=41NrZV6l3C20yUtWEcV%{1{llf`JTv z4D4W*4udWOCj%oW=Acf>V_*YYBd4V;BO}0-1H#)F^gzL&Eu*`O!H9uj8-p3bQ4qf? zFz_)bGRQJ0fgPj;F#+VDda&Q+7=jpr!7h?x2w?~X2aOy<7(+M%GXoQkWn1q5Cp|82iUiuWXl0Iotc4| uApx8y6B&}ANl-bNftewTA%`KK0m3R^$Y&^KU|`^4U}Pv^C}XH#kOTk#r>|!K delta 1674 zcmca7{6mcE)W2Q(7#J9=7^Y6-(wgkgDC)&#lbM%UV#mn9uHoY1;-VSG&cMgWAe@z0 zmZ)D^l9{9LSX7i)>62Mp!o|SLAi%@G%^=9gz^tJe#>pVeAi~Zd%EKVWAkN4jG4X-K z#3~g=$%*qNr7Ri1fX%@ZOfzsXNHEBQ^eRlet;Wa8pv1$V%%H-^z?_(pGFgF5oI46+ zni>y-I)ldKHb!{^5Lb(bL7PE`k%6(Ck%7?@B%;T|pbr+w;9@XjFk)vg=3y{lFlA&A zp8SwWxSo-Lqd2uBATcwqgpom5!w2k%#PSk-u#h#x$>ux^77Uh*3>*dd#hE3U`FV^C z{65L~MXCB>smUezMMf^xoD9|sHtY;R zA#}1mlOb0)NIZg(K}TaU7n3fB1Va=LLo`FoH)91;w1JPh#+36rlfU6T+8$1Wm7 zobz+?i>x)nCU0dnnEaMmQi-L)F{zl5fu#~maTI4(rA8o_k&a2ln^{;m8TlHx7#bOx z*cqC67+M%wH%qg!Ffz7JR$!CX>jZ^J7Y{=fL$v@yDL)%SFG!$|hoOR@l97SOGcPZ- z$T=smxHz?#onhkSOg1f+$&3tglXKYQ>KPf>eDd?NOA8nj8H5=)7#J9s7??nb0n8F( z5NBXyNCdN!7}yyY8Mqme85kK-7#JAp8Mqmk7#J9=wL};g!H8Lefpt3ryVh<7-pK6? z{974>w6-t^?PidO)DmHk0wWo=?F@3;7!<>`w6`*-Ze*wj*_X<|z#zuJ%D})N#2~;R z%plDm!eGiE&S1qL!H@=)1KY!p&X564)Yf44F@jx_33W{i11AF)0|SGMmb#_{s{}im zJ0v;5*1>EOVqjrlV320us%Ma45M_{MkY>1d>V(JVU44e#%pm>KkiIIna100|gS~6Q1G__;|1abs8Gqy75YHMv_ zP~FC0pry5?p22JjgB8m*28TW~7A>tUAg&8Dn9B;{y2EAJpj@adyS6BcD61%&D7%aR zR}KhoWAFk6x3-M#E(SjahHVT%8^Q4g3SBL5*eEfuGAJ_$FsLv{FsL%9GpI3`)ibCw zxH4!kgfM6_WH4wmlr!jn!yyRba(FmYFyt`gg2SN#R5XAizJei-A)kSnL7gFxp@2b$ zfrY`0!HJ=eL5G2r!Ii<7p@>0;fsG-AL4~21K?j_8q8VZ!VZ-1CPG$@Y^?YDA?_vl; zb1@g#3IhgS21Bre#K3$$xP$n>mV?qj2}3E=P$#INTwpUnsSFVU5c5nJI2lZl%;Tzu z8_2~_#!$|{D8L2EHBbYspa!yOYi(nQL>R^f4haJ!gV?~%0i{khxH(k})lhQ+7+Amw zjzd>VT4x(WEW)H*h*8>LqqHE3z(EZ%iUSKT|B+88<*x)~s>9)@m)eg*~xE(S)12@I1MrZ7kX0BPO^2mk;8