From 0545adee2ad3cade1641d1f0fee5e874a6fb3abc Mon Sep 17 00:00:00 2001 From: Fp_Sviat Date: Fri, 3 Apr 2026 17:59:08 +0300 Subject: [PATCH] Ready to draw and save round hitboxes. It is necessary to complete the correct loading of round hitbox data --- res/objecttypes.xml | 17 ++++---- src/gui/EditableCanvas.java | 1 + .../render/HitboxCircleRenderingFunction.java | 41 +++++++++++++++---- src/model/HitboxCircle.java | 31 ++++++++++---- 4 files changed, 68 insertions(+), 22 deletions(-) diff --git a/res/objecttypes.xml b/res/objecttypes.xml index 4a9bb6b..5326079 100644 --- a/res/objecttypes.xml +++ b/res/objecttypes.xml @@ -1,12 +1,15 @@ - - - - - + + + + + + + - + + @@ -22,4 +25,4 @@ - \ No newline at end of file + diff --git a/src/gui/EditableCanvas.java b/src/gui/EditableCanvas.java index d275dc2..f29e267 100644 --- a/src/gui/EditableCanvas.java +++ b/src/gui/EditableCanvas.java @@ -34,6 +34,7 @@ public class EditableCanvas extends JPanel implements MouseListener, MouseMotion hitboxCircleRenderFunct = new HitboxCircleRenderingFunction(); drawboxRectengleRenderFunct.subscribe(Project.getInstance()); // подписка: Project получит данные ввиде обьекта Event, содержащий данные drawbox при отрисовке последней точки из 4-х. hitboxRectengleRenderFunct.subscribe(Project.getInstance()); + hitboxCircleRenderFunct.subscribe(Project.getInstance()); addMouseListener(this); addMouseMotionListener(this); } diff --git a/src/gui/render/HitboxCircleRenderingFunction.java b/src/gui/render/HitboxCircleRenderingFunction.java index db99c8e..63c3b3f 100644 --- a/src/gui/render/HitboxCircleRenderingFunction.java +++ b/src/gui/render/HitboxCircleRenderingFunction.java @@ -2,7 +2,11 @@ package gui.render; import java.awt.Graphics2D; import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; +import events.EntityHitboxChangedEvent; +import events.EntityHitboxChangedListener; import model.Entity; import model.HitboxCircle; import model.Point; @@ -10,8 +14,9 @@ import model.Point; public class HitboxCircleRenderingFunction implements ShapeRenderingFunction { Point firstIsoPoint = null; Point currentIsoPoint = new Point(0,0); - int currentRadius=0; + int currentDiametrX=0; Entity entity; + private List listeners = new ArrayList<>(); public void setEntityInHitboxCircle(Entity e) { entity = e; @@ -21,12 +26,11 @@ public class HitboxCircleRenderingFunction implements ShapeRenderingFunction { public void drawing(Graphics2D g) { HitboxCircle nowHitbox = (HitboxCircle)entity.getHitbox(); if(nowHitbox.getRadius()!=0) { - g.drawOval((int)nowHitbox.getCurrentRefPoint().x, (int)nowHitbox.getCurrentRefPoint().y, (int)nowHitbox.getRadius()*4, (int)(nowHitbox.getRadius()*2)); + g.drawOval((int)nowHitbox.getCurrentRefPoint().x, (int)(nowHitbox.getCurrentRefPoint().y-(nowHitbox.getDiametrY()/2)), (int)nowHitbox.getDiametrX(), (int)(nowHitbox.getDiametrY())); }else if(firstIsoPoint != null) { - currentRadius = Math.abs((int)firstIsoPoint.x-(int)currentIsoPoint.x); - g.drawOval((int)firstIsoPoint.x, (int)firstIsoPoint.y, currentRadius, currentRadius/2); + currentDiametrX = Math.abs((int)firstIsoPoint.x-(int)currentIsoPoint.x); + g.drawOval((int)firstIsoPoint.x, (int)(firstIsoPoint.y-currentDiametrX/4), currentDiametrX, currentDiametrX/2); } - } @Override @@ -35,9 +39,16 @@ public class HitboxCircleRenderingFunction implements ShapeRenderingFunction { if(nowHitbox.getRadius()==0 && firstIsoPoint == null) { firstIsoPoint = new Point(e.getX(), e.getY()); }else if(nowHitbox.getRadius()==0 && firstIsoPoint != null) { + //Формула высчитывания радиуса из диаметров circle. + nowHitbox.getCurrentRefPoint().setXY(firstIsoPoint.x, firstIsoPoint.y); + nowHitbox.setDiametrXY(Math.abs(firstIsoPoint.x-e.getX()),Math.abs((firstIsoPoint.x-e.getX())/2)); + System.out.println("X = "+nowHitbox.getDiametrX()+ "Y = "+nowHitbox.getDiametrY()); + float temp = (float)Math.sqrt(2); + nowHitbox.setRadius((nowHitbox.getDiametrY()/2)*temp); // высчитываем в параметры хитбокссеркла нужный радиус и текущую реф поинт. // Не забываем высчитать реф поинт хитбокса относительно текущей. // после чего вызываем listPointsToString и нотифай, который отправляет данные на сохранение + notifySubscribers(); } } @@ -50,16 +61,32 @@ public class HitboxCircleRenderingFunction implements ShapeRenderingFunction { public void functionClearHitboxJButton() { HitboxCircle nowHitbox = (HitboxCircle)entity.getHitbox(); - } @Override public void functionClearJButton() { firstIsoPoint = null; currentIsoPoint = new Point(0,0); - currentRadius = 0; + currentDiametrX = 0; HitboxCircle nowhitbox = (HitboxCircle)entity.getHitbox(); nowhitbox.setRadius(0); System.err.println("radius: "+nowhitbox.getRadius()); } + + public void subscribe(EntityHitboxChangedListener listener) { + listeners.add(listener); + } + + public void unsubscribe(EntityHitboxChangedListener listener) { + listeners.remove(listener); + } + + private void notifySubscribers() { + for (EntityHitboxChangedListener listener : listeners) { + listener.hitboxChanged( + new EntityHitboxChangedEvent(entity.getHitbox(), entity) + ); + } + } + } diff --git a/src/model/HitboxCircle.java b/src/model/HitboxCircle.java index e1abfbf..96076e4 100644 --- a/src/model/HitboxCircle.java +++ b/src/model/HitboxCircle.java @@ -2,7 +2,9 @@ package model; public class HitboxCircle extends Hitbox { private float radiusHitbox; + private float diametrX,diametrY; Point cartesianCenterImagePoint= new Point(0,0); + //currentRefPoint - точка хранящая изометрические(экранные) коорды, от которой рисуется овал private Point currentRefPoint= new Point(0,0); public HitboxCircle(String[] dataHitbox, Entity owner){ super(dataHitbox[0]); @@ -15,24 +17,37 @@ public class HitboxCircle extends Hitbox { radiusHitbox = 0; } private void parseStringToCircleHitbox(String[] informations) { - cartesianCenterImagePoint = isometricToCartesian(owner.getImage().getWidth(),owner.getImage().getHeight(),cartesianCenterImagePoint); referencePoint.x = Float.parseFloat(informations[1]); referencePoint.y = Float.parseFloat(informations[2]); - currentRefPoint = cartesianToIsometric(cartesianCenterImagePoint.x-referencePoint.x,cartesianCenterImagePoint.y-referencePoint.y,currentRefPoint); - float chisloPizdec = (float)Math.sqrt(2); - radiusHitbox = Float.parseFloat(informations[3])/chisloPizdec; - currentRefPoint.x -=radiusHitbox; - currentRefPoint.y -=radiusHitbox*2; + currentRefPoint.x = owner.getImage().getWidth()/2+referencePoint.x; + currentRefPoint.y = owner.getImage().getHeight()+referencePoint.y; + radiusHitbox = Float.parseFloat(informations[3]); } @Override public String listPointsToString() { - return "Circle"+referencePoint.x+referencePoint.x+" "+referencePoint.y+" "+radiusHitbox; + Point cartesianCenterRefPoint = new Point(0, 0); + cartesianCenterImagePoint = isometricToCartesian(owner.getImage().getWidth()/2,owner.getImage().getHeight(),cartesianCenterImagePoint); + cartesianCenterRefPoint = isometricToCartesian(currentRefPoint.x+diametrY,currentRefPoint.y+(diametrY/2),cartesianCenterRefPoint); + System.out.println(""); + referencePoint.x = (cartesianCenterRefPoint.x - cartesianCenterImagePoint.x) * (-1); + referencePoint.y = (cartesianCenterRefPoint.y - cartesianCenterImagePoint.y) * (-1); + return "Circle "+(int)referencePoint.x+" "+(int)referencePoint.y+" "+(int)radiusHitbox; } public float getRadius() { return radiusHitbox; } - public void setRadius(int radius) { + public void setDiametrXY(float diametrX, float diametrY) { + this.diametrX = diametrX; + this.diametrY = diametrY; + } + public float getDiametrX() { + return diametrX; + } + public float getDiametrY() { + return diametrY; + } + public void setRadius(float radius) { radiusHitbox = radius; } public Point getCurrentRefPoint() {