Compare commits

..

10 Commits

29 changed files with 801 additions and 447 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-19">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-22">
<attributes>
<attribute name="module" value="true"/>
</attributes>

View File

@ -1,8 +1,9 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=15
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=22
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=15
org.eclipse.jdt.core.compiler.compliance=22
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@ -11,4 +12,4 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=15
org.eclipse.jdt.core.compiler.source=22

BIN
res/.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

BIN
res/NewName.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

BIN
res/newtest.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View File

@ -1,23 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<objecttypes>
<objecttype name="misato" color="#a0a0a4">
<property name="class" type="string" default="Solid"/>
<property name="drawbox" type="string" default="2 1 254 1 254 338 2 336"/>
<property name="hitbox" type="string" default="Circle 4 6 24"/>
<objecttype color="#a0a0a4" name="misato">
<property default="Solid" name="class" type="string"/>
<property default="22 10 232 3 264 199 5 198 " name="drawbox" type="string"/>
<property default="Circle 4 6 24" name="hitbox" type="string"/>
</objecttype>
<objecttype name="starlight" color="#a0a0a4">
<property name="class" type="string" default="Solid"/>
<property name="drawbox" type="string" default="2 1 253 1 254 468 2 490"/>
<property name="hitbox" type="string" default="Rectangle 0 0 76 119"/>
<objecttype color="#a0a0a4" name="starlight">
<property default="Solid" name="class" type="string"/>
<property default="2 1 253 1 254 468 2 490" name="drawbox" type="string"/>
<property default="Rectangle 0 0 76 119" name="hitbox" type="string"/>
</objecttype>
<objecttype name="tavern" color="#a0a0a4">
<property name="class" type="string" default="Solid"/>
<property name="drawbox" type="string" default="3 2 252 1 253 605 6 608"/>
<property name="hitbox" type="string" default="Rectangle 0 0 96 98"/>
<objecttype color="#a0a0a4" name="tavern">
<property default="Solid" name="class" type="string"/>
<property default="3 2 252 1 253 605 6 608" name="drawbox" type="string"/>
<property default="Rectangle 0 0 96 98" name="hitbox" type="string"/>
</objecttype>
<objecttype name="TopHome" color="#a0a0a4">
<property name="class" type="string" default="Solid"/>
<property name="drawbox" type="string" default="3 2 252 1 253 605 6 608"/>
<property name="hitbox" type="string" default="Rectangle 0 0 96 98"/>
<objecttype color="#a0a0a4" name="TopHome">
<property default="Solid" name="class" type="string"/>
<property default="3 2 252 1 253 605 6 608" name="drawbox" type="string"/>
<property default="Rectangle 0 0 96 98" name="hitbox" type="string"/>
</objecttype>
<objecttype color="000000" name="newtest">
<property default="solid" name="class" type="string"/>
<property default="0 0 0 0 0 0 0 0" name="drawbox" type="string"/>
<property default="Rectangle 0 0 0 0" name="hitbox" type="string"/>
</objecttype>
</objecttypes>

View File

@ -0,0 +1,18 @@
package events;
import model.Entity;
import model.Hitbox;
/*
* Structure-like class no getters
*/
public class EntityHitboxChangedEvent {
public Hitbox hitbox;
//storing entity object instead of just entity name will allow to get entity data without extra calls
public Entity owner;
public EntityHitboxChangedEvent(Hitbox hitbox, Entity owner) {
this.hitbox = hitbox;
this.owner = owner;
}
}

View File

@ -0,0 +1,7 @@
package events;
public interface EntityHitboxChangedListener {
void hitboxChanged(EntityHitboxChangedEvent event);
}

View File

@ -1,5 +1,6 @@
package gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
@ -16,143 +17,48 @@ import javax.swing.JTabbedPane;
import events.EntityDrawboxChangedEvent;
import events.EntityDrawboxChangedListener;
import gui.render.DrawboxRectengleRenderingFunction;
import model.Drawbox;
import model.Point;
import repository.Project;
public class DrawboxEditor extends Editable {
private List<Point> drawboxPoints;
private List<Point> basePoints;
Logger logger = Logger.getLogger("gui.DrawboxRectangleEditor");
Point currentPoint = new Point(0, 0);
private List<EntityDrawboxChangedListener> listeners = new ArrayList<>();
DrawboxEditor(ListGUI listGUI) {
super(listGUI);
//Если будет ошибка, попробовать в Editable прокинуть canvas, как сделано с ListGUI
canvas = new EditableCanvas(entity, image);
add(canvas,BorderLayout.CENTER);
canvas.setBackground(Color.GRAY);
canvas.setDrawboxRectengleRenderingFunction();
canvas.setVisible(true);
logger.setLevel(Level.CONFIG);
}
@Override
public void drawing(Graphics2D g) {
Drawbox drawbox = entity.getDrawbox();
drawboxPoints = drawbox.getDrawboxlistPoints();
basePoints = drawbox.getbaseListPoints();
logger.finest("drawbox point size: "+ drawboxPoints.size());
for(Point p: drawboxPoints)
logger.finest("DrawBoxPoint: ["+ p.x + ":"+p.y+"]");
for(Point p: basePoints)
logger.finest("BasePoint: ["+ p.x + ":"+p.y+"]");
if(drawboxPoints.size() >= 1 && drawboxPoints.size() < 4) {
Point lastPoint = drawboxPoints.get(drawboxPoints.size()-1);
g.drawLine((int)lastPoint.x, (int)lastPoint.y, (int)currentPoint.x, (int)currentPoint.y);
for(int i = 0; i < drawboxPoints.size()-1;i++) {
int x1 = (int)drawboxPoints.get(i).x;
int y1 = (int)drawboxPoints.get(i).y;
int x2 = (int)drawboxPoints.get(i+1).x;
int y2 = (int)drawboxPoints.get(i+1).y;
g.drawLine(x1, y1, x2, y2);
}
} else {
for(int i = 0; i < drawboxPoints.size();i++) {
int x1 = (int)drawboxPoints.get(i % drawboxPoints.size()).x;
int y1 = (int)drawboxPoints.get(i % drawboxPoints.size()).y;
int x2 = (int)drawboxPoints.get((i+1) % drawboxPoints.size()).x;
int y2 = (int)drawboxPoints.get((i+1) % drawboxPoints.size()).y;
g.drawLine(x1, y1, x2, y2);
}
// ОТРИСОВКА ОСНОВАНИЯ
g.setColor(Color.BLUE);
for(int i = 0; i < basePoints.size()-1;i++) {
int x1 = (int)basePoints.get(i).x;
int y1 = (int)basePoints.get(i).y;
int x2 = (int)basePoints.get(i+1).x;
int y2 = (int)basePoints.get(i+1).y;
g.drawLine(x1, y1+3, x2, y2+3);
}
}
}
@Override
public void saveDataInEntity() {
entity.setDrawbox(new Drawbox(drawboxPoints));
}
@Override
public void mousePressed(MouseEvent e) {
if(drawboxPoints.size() < 4) {
Point p = new Point(e.getX(), e.getY());
drawboxPoints.add(p);
if(drawboxPoints.size() == 4) {
sortingDrawboxPoints();
saveDataInEntity();
//при выборе 4-й точки и формировании данных drawbox, уведомляем всех подписчит
if(listeners!=null) {
notifySubscribers();
}
}
}
}
/*Точки должны идти в определенном порядке:
* левая верхняя точка, правая верхняя, нижняя правая, нижняя левая;
* Обе нижние точки, т.е. 3 и 4 являются основанием - хардкод.
* P.s. возможно это не критично, и в сторе предусмотрено, что бы они сортировались,
* но на данном этапе на всякий случай стоит так поступить*/
private void sortingDrawboxPoints() {
//окей, это написано плохо, но... Похуй, пляшем)
Collections.sort(
drawboxPoints,
(point1, point2) -> Float.compare(point1.y, point2.y)
);
if(drawboxPoints.get(0).x>drawboxPoints.get(1).x) {
Collections.swap(drawboxPoints, 0, 1);
}
if(drawboxPoints.get(2).x<drawboxPoints.get(3).x) {
Collections.swap(drawboxPoints, 2, 3);
}
/*Багтест, проверка очередности построения точек
*
* System.out.println("_______________");
int i = 0;
for (Point point : drawboxPoints) {
System.out.println("Point["+i+"]: ("+point.x+" ; "+point.y+");");
i++;
}*/
}
@Override
public void mouseMoved(MouseEvent e) {
currentPoint.x = e.getX();
currentPoint.y = e.getY();
repaint();
}
public void subscribe(EntityDrawboxChangedListener listener) {
listeners.add(listener);
}
public void unsubscribe(EntityDrawboxChangedListener listener) {
listeners.remove(listener);
}
public void clearPoints(){
private void notifySubscribers() {
for (EntityDrawboxChangedListener listener : listeners) {
listener.drawboxChanged(
new EntityDrawboxChangedEvent(entity.getDrawbox(), entity)
);
}
}
// эта штука очищает точки при нажатии универскальной кнопки очистки в Main GUI. Это следует рефакторнуть и вместо передачи события сюда,
// обрабатывать его прямо в Main GUI(лямбдой) вызывая отсюда только метод в духе clearPoints()
@Override
/*@Override
public void actionPerformed(ActionEvent e) {
JTabbedPane parent = (JTabbedPane) getParent();
if(parent.getSelectedComponent() == this){
@ -162,6 +68,7 @@ public class DrawboxEditor extends Editable {
repaint();
}
}
}
}*/
}

View File

@ -1,5 +1,6 @@
package gui;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionListener;
@ -10,6 +11,8 @@ import java.awt.image.BufferedImage;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.event.ListSelectionEvent;
@ -18,13 +21,13 @@ import javax.swing.event.ListSelectionListener;
import model.Entity;
import repository.Project;
public abstract class Editable extends JPanel implements MouseListener, MouseMotionListener, ListSelectionListener, ActionListener {
public abstract class Editable extends JPanel implements MouseListener, MouseMotionListener, ListSelectionListener {
protected ListGUI listGUI;
protected Entity entity;
protected String selectedEntityName;
protected BufferedImage image;
JPanel drawPanel;
EditableCanvas canvas;
private static Logger logger = Logger.getLogger("gui.Editable");
@ -40,16 +43,7 @@ public abstract class Editable extends JPanel implements MouseListener, MouseMot
}
//Абстрактные методы
public abstract void drawing(Graphics2D g);
public abstract void saveDataInEntity();
//методы родительского класса Editable
//get,set для name
public String getName() {
return selectedEntityName;
}
@ -58,19 +52,11 @@ public abstract class Editable extends JPanel implements MouseListener, MouseMot
this.selectedEntityName = name;
}
//заполнить текущую сущность по имени.
public void setEntityByName(String name) throws Exception {
entity = Project.getInstance().getEntityByName(name);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
if(entity != null) {
drawing((Graphics2D)g);
}
}
// из mouse motion listener'a
@Override
@ -104,8 +90,21 @@ public abstract class Editable extends JPanel implements MouseListener, MouseMot
}
image = Project.getInstance().loadImageByName(selectedEntityName);
//TODO: if(image == null) вызов FileChooser'a и выбор изображения
this.repaint();
//canvas.repaint();
System.out.println(" Edit image = " + image);
System.out.println("---");
System.out.println(" Canvas image = " + image);
}
}
private JButton createButton(String text,ActionListener listener,String pathImage) {
JButton button = new JButton(new ImageIcon(pathImage));
button.addActionListener(listener);
button.setContentAreaFilled(false);
button.setFocusPainted(false);
button.setPreferredSize(new Dimension(72, 38));
return button;
}
}

View File

@ -0,0 +1,96 @@
package gui;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import gui.render.DrawboxRectengleRenderingFunction;
import gui.render.ShapeRenderingFunction;
import model.Entity;
import repository.Project;
public class EditableCanvas extends JPanel implements MouseListener, MouseMotionListener, ListSelectionListener {
DrawboxRectengleRenderingFunction drawboxRectengleRenderFunct;
ShapeRenderingFunction renderingFunction;
Entity entity;
BufferedImage image;
public EditableCanvas(Entity entity, BufferedImage image) {
this.entity = entity;
this.image = image;
drawboxRectengleRenderFunct = new DrawboxRectengleRenderingFunction(entity);
drawboxRectengleRenderFunct.subscribe(Project.getInstance()); // подписка: Project получит данные ввиде обьекта Event, содержащий данные drawbox при отрисовке последней точки из 4-х.
//hitboxPanel.subscribe(Project.getInstance());
}
public void drawing(Graphics2D g) {
if(renderingFunction!=null) {
renderingFunction.drawing(g);
}
}
public void setDrawboxRectengleRenderingFunction() {
renderingFunction = drawboxRectengleRenderFunct;
}
@Override
public void mouseMoved(MouseEvent e) {
if(renderingFunction!=null) {
renderingFunction.mouseMoved(e);
}
}
@Override
public void mouseClicked(MouseEvent e) {
if(renderingFunction!=null) {
renderingFunction.mouseClicked(e);
}
}
@Override
public void mousePressed(MouseEvent e) {
if(renderingFunction!=null) {
renderingFunction.mousePressed(e);
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
if(entity != null) {
drawing((Graphics2D)g);
}
}
@Override
public void mouseDragged(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void valueChanged(ListSelectionEvent e) {
//this.repaint();
//System.out.println(" Canvas image = " + image);
}
}

122
src/gui/HitboxEditor.java Normal file
View File

@ -0,0 +1,122 @@
package gui;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTabbedPane;
import events.EntityDrawboxChangedEvent;
import events.EntityDrawboxChangedListener;
import events.EntityHitboxChangedEvent;
import events.EntityHitboxChangedListener;
import model.Hitbox;
import model.Point;
public class HitboxEditor extends Editable {
Point firstIsoPoint = null;
Point currentIsoPoint = new Point(0,0);
Point firstCartesianPoint = new Point(0,0), currentCartesianPoint = new Point(0,0);
private List<EntityHitboxChangedListener> listeners = new ArrayList<>();
HitboxEditor(ListGUI listGUI) {
super(listGUI);
}
//@Override
//public void drawing(Graphics2D g) {
/*Hitbox nowHitbox = entity.getHitbox();
//if(firstIsoPoint != null) {
int x1,y1,x2,y2;
int size = nowHitbox.getListPointsIso().size();
for(int i = 0; i < size;i++) {
x1 = (int)nowHitbox.getListPointsIso().get(i % size).x;
y1 = (int)nowHitbox.getListPointsIso().get(i % size).y;
x2 = (int)nowHitbox.getListPointsIso().get((i+1) % size).x;
y2 = (int)nowHitbox.getListPointsIso().get((i+1) % size).y;
g.drawLine(x1, y1, x2, y2);
}
x1 = (int)nowHitbox.getListPointsIso().get(0).x;
y1 = (int)nowHitbox.getListPointsIso().get(0).y;
x2 = (int)nowHitbox.getListPointsIso().get(3).x;
y2 = (int)nowHitbox.getListPointsIso().get(3).y;
g.drawLine(x1, y1, x2, y2);
//}
*/
//}
@Override
public void mouseClicked(MouseEvent e) {
if(firstIsoPoint == null) {
firstIsoPoint = new Point(currentIsoPoint.x,currentIsoPoint.y);
//System.out.println("firstPoint("+firstIsoPoint.x+";"+firstIsoPoint.y+");");
firstCartesianPoint = Hitbox.isometricToCartesian(firstIsoPoint.x, firstIsoPoint.y,firstCartesianPoint);
}else{
/*
* В данном месте при нажатии закрепляющей точки, необходимо вызывать функцию,
* которая будет формировать из текущих декартовых координат:
* 1. Точку старта и ширину с высотой.
* 2. Так же необходимо реализовать слушатель сохранения новых хитбоксов в дерево.
*
* */
repaint();
}
}
@Override
public void mouseMoved(MouseEvent e) {
/*currentIsoPoint.x = e.getX();
currentIsoPoint.y = e.getY();
if(entity!=null) {
Hitbox nowHitbox = entity.getHitbox();
if(firstIsoPoint != null) {
//System.out.println("firstPoint("+firstIsoPoint.x+";"+firstIsoPoint.y+");");
currentCartesianPoint = Hitbox.isometricToCartesian(currentIsoPoint.x, currentIsoPoint.y, currentCartesianPoint);
nowHitbox.getListPointsCartesian().get(0).setXY(firstCartesianPoint.x, firstCartesianPoint.y);
nowHitbox.getListPointsCartesian().get(1).setXY(currentCartesianPoint.x, firstCartesianPoint.y);
nowHitbox.getListPointsCartesian().get(2).setXY(currentCartesianPoint.x, currentCartesianPoint.y);
nowHitbox.getListPointsCartesian().get(3).setXY(firstCartesianPoint.x, currentCartesianPoint.y);
nowHitbox.convertCartesianPointsToIso();
repaint();
}
}*/
}
public void subscribe(EntityHitboxChangedListener listener) {
listeners.add(listener);
}
public void unsubscribe(EntityHitboxChangedListener listener) {
listeners.remove(listener);
}
//НАДО ДОБАВИТЬ ЧТО БЫ ПОД КОНЕЦ РИСОВАНИЯ ХИТБОКСА ОНО ВЫЗЫВАЛО ФУНКЦИЮ И ВСЕ СОХРАНЯЛО.
//СОХРАНЕНИЕ УЖЕ РЕАЛИЗОВАНО.
//НО НЕ ДОБАВЛЕН ВЫЗОВ ФУНКЦИИ И НЕ ОФОРМЛЕНА ПОДПИСКА
//UPD: вроде подписку оформил в MainGUI;
private void notifySubscribers() {
for (EntityHitboxChangedListener listener : listeners) {
listener.hitboxChanged(
new EntityHitboxChangedEvent(entity.getHitbox(), entity)
);
}
}
//это старая очистка которая пока убрана. В будущем будет убрана вовсе, после рефакторинга.
/*@Override
public void actionPerformed(ActionEvent e) {
JTabbedPane parent = (JTabbedPane) getParent();
if(parent.getSelectedComponent() == this){
if(entity != null) {
firstIsoPoint = null;
currentIsoPoint.setXY(0,0);
repaint();
}
}
}*/
}

View File

@ -1,53 +0,0 @@
package gui;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class HitboxRectangleEditor extends Editable {
HitboxRectangleEditor(ListGUI listGUI) {
super(listGUI);
// TODO Auto-generated constructor stub
}
@Override
public void drawing(Graphics2D g) {
// TODO Auto-generated method stub
}
@Override
public void saveDataInEntity() {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}

View File

@ -1,14 +1,14 @@
package gui;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -35,23 +35,23 @@ import listeners.RemoveListElementEntityListener;
import model.Drawbox;
import model.Entity;
import model.Hitbox;
import model.Point;
import repository.Project;
public class ListGUI extends JPanel {
private Map<String, Icon> iconMap = new HashMap<>();
JButton addListElementEntity;
JButton removeListElementEntity;
JButton addPicEntity;
JList list;
JScrollPane scroll;
ActionListener removeEntity;
ActionListener addEntity;
DefaultListModel<String> testModel;
JPanel gridButtonBar = new JPanel(new GridLayout(1, 2, 5, 0));
private static Logger logger = Logger.getLogger("gui.ListGUI");
public ListGUI() {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(223,638));
try {
Project.getInstance().load();
} catch (SAXException | IOException | ParserConfigurationException e) {
@ -60,24 +60,21 @@ public class ListGUI extends JPanel {
JOptionPane.showMessageDialog(this, "Parser exception, cause: "+e);
}
String[] nameList = createNameList();
testModel = new DefaultListModel<>();
list = new JList(testModel);
list.setCellRenderer(new ListEntityRenderer());
addEntity = new CreateFrameAddElementListener(this);
removeEntity = new RemoveListElementEntityListener(this);
scroll = new JScrollPane(list);
scroll.setSize(new Dimension(223, 638));
scroll.setLocation(5, 5);
this.add(scroll);
add(scroll,BorderLayout.CENTER);
list.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
addListElementEntity = createButton(5,645, addEntity,"res/addbutton.png");
removeListElementEntity = createButton(117,645,removeEntity,"res/deletebutton.png");
addListElementEntity = createButton(addEntity,"res/addbutton.png");
removeListElementEntity = createButton(removeEntity,"res/deletebutton.png");
add(gridButtonBar,BorderLayout.SOUTH);
/// ЧТОБЫ ОТКЛЮЧИТЬ ИЗБЫТОЧНЫЙ ВЫВОД В КОНСОЛЬ - НУЖНО СМЕНИТЬ УРОВЕНЬ ЛОГГИРОВАНИЯ В СТРОКЕ НИЖЕ
logger.setLevel(Level.FINEST);
@ -90,15 +87,9 @@ public class ListGUI extends JPanel {
return (String) list.getSelectedValue();
}
public void addListElement(String name, String solid) throws DuplicateEntryException {
// плейсхолдеры для новых хитбоксов и дроубоксов, иначе всё валится с NPE
List<Point> hitboxPoints = new LinkedList<Point>();
List<Point> drawboxPoints = new LinkedList<Point>();
Hitbox hitbox = new Hitbox("Rectangle", hitboxPoints);
Drawbox drawbox = new Drawbox(drawboxPoints);
// а тут уже создание новой сущности
Entity e = new Entity(name, hitbox, drawbox);
public void addListElement(String name, String solid) throws DuplicateEntryException {
Entity e = new Entity(name);
e.setType(solid);
logger.finer("Entity \""+name+"\" was created.");
Project.getInstance().addEntity(e);
@ -185,14 +176,13 @@ public class ListGUI extends JPanel {
}
}
private JButton createButton(int width,int height,ActionListener listener,String pathImage) {
private JButton createButton(ActionListener listener,String pathImage) {
JButton button = new JButton(new ImageIcon(pathImage));
button.setSize(110, 46);
button.setLocation(width, height);
button.setPreferredSize(new Dimension(100, 50));
button.addActionListener(listener);
button.setContentAreaFilled(false);
button.setFocusPainted(false);
this.add(button);
gridButtonBar.add(button);
return button;
}

View File

@ -1,119 +1,88 @@
package gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import listeners.OpenXMLFileButtonListener;
import repository.Project;
public class MainGUI extends JFrame{
JPanel gridButtonBar = new JPanel(new GridLayout(1, 3, 5, 0));
JPanel TopButtonBar = new JPanel(new FlowLayout(FlowLayout.LEFT));
ListGUI list;
ActionListener OpenXMLFileButtonListener;
JButton openXMLJButton;
JButton saveXMLJButton;
JButton clearLinesJButton;
public static JTabbedPane editorPane;
public static JTabbedPane hitdrawPane;
List <Editable> listEditorPanel = new ArrayList<Editable>();
DrawboxEditor drawBoxPanel;
HitboxCircleEditor hitboxCirclePanel;
HitboxRectangleEditor hitboxRectanglePanel;
HitboxPoligonEditor hitboxPoligonPanel;
HitboxEditor hitboxPanel;
public MainGUI() {
setTitle("Hitbox/Drawbox Editor");
setLayout(null);
setSize(1200,780);
setLocationRelativeTo(null);
setResizable(false);
setSize(1000,650);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setMinimumSize(new Dimension(800,600));
list = new ListGUI();
this.add(list);
list.setLayout(null);
list.setSize(230, 691);
list.setLocation(0, 47);
add(list,BorderLayout.WEST);
list.setVisible(true);
drawBoxPanel = new DrawboxEditor(list);
hitboxCirclePanel = new HitboxCircleEditor(list);
hitboxRectanglePanel = new HitboxRectangleEditor(list);
hitboxPoligonPanel = new HitboxPoligonEditor(list);
listEditorPanel.add(drawBoxPanel);
listEditorPanel.add(hitboxCirclePanel);
listEditorPanel.add(hitboxRectanglePanel);
listEditorPanel.add(hitboxPoligonPanel);
hitboxPanel = new HitboxEditor(list);
list.registerJListListener(drawBoxPanel);
list.registerJListListener(hitboxCirclePanel);
list.registerJListListener(hitboxPoligonPanel);
list.registerJListListener(hitboxRectanglePanel);
list.registerJListListener(hitboxPanel);
OpenXMLFileButtonListener = new OpenXMLFileButtonListener(list);
openXMLJButton = createButton("XML",5,5, OpenXMLFileButtonListener,"res/xml.png");
saveXMLJButton = createButton("Save",80,5,(e)-> Project.getInstance().writeXML(),"res/download.png");
clearLinesJButton = createButton("Clear lines",155,5,null,"res/destroy.png");
openXMLJButton = createButton("XML", OpenXMLFileButtonListener,"res/xml.png");
saveXMLJButton = createButton("Save",(e)-> Project.getInstance().writeXML(),"res/download.png");
clearLinesJButton = createButton("Clear lines",null,"res/destroy.png");
clearLinesJButton.addActionListener(drawBoxPanel);
clearLinesJButton.addActionListener(hitboxCirclePanel);
clearLinesJButton.addActionListener(hitboxPoligonPanel);
clearLinesJButton.addActionListener(hitboxRectanglePanel);
gridButtonBar.add(openXMLJButton);
gridButtonBar.add(saveXMLJButton);
//gridButtonBar.add(clearLinesJButton);
TopButtonBar.add(gridButtonBar);
TopButtonBar.setBorder(BorderFactory.createLoweredBevelBorder());
add(TopButtonBar,BorderLayout.NORTH);
repaint();
//clearLinesJButton.addActionListener(drawBoxPanel); - ранее регистрировались слушатели для кнопки очистки.
//clearLinesJButton.addActionListener(hitboxPanel);
this.add(editorPane = createPane(editorPane, 230, 50));
editorPane.addTab("Hitbox", hitdrawPane = createPane(hitdrawPane,10, 10));
editorPane = new JTabbedPane();
editorPane.setVisible(true);
add(editorPane,BorderLayout.CENTER);
editorPane.addTab("Hitbox", hitboxPanel);
editorPane.addTab("Drawbox", drawBoxPanel);
hitdrawPane.addTab(null, new ImageIcon("res/square.png"),hitboxRectanglePanel, null);
hitdrawPane.addTab(null, new ImageIcon("res/circle.png"),hitboxCirclePanel, null);
hitdrawPane.addTab(null, new ImageIcon("res/formless.png"),hitboxPoligonPanel, null);
hitdrawPane.setTabPlacement(JTabbedPane.LEFT);
//Оформление подписок к издателям.
drawBoxPanel.subscribe(Project.getInstance()); // подписка: Project получит данные ввиде обьекта Event, содержащий аднные drawbox при отрисовке последней точки из 4-х.
repaint();
}
@Override
public void paint(Graphics g){
super.paint(g);
g.drawLine(0, 72, 1200, 72);
}
public JTabbedPane createPane(JTabbedPane pane, int x, int y) {
pane = new JTabbedPane();
pane.setSize(new Dimension(950, 688));
pane.setLocation(new Point(x, y));
pane.setVisible(true);
return pane;
}
private JButton createButton(String text,int width,int height,ActionListener listener,String pathImage) {
private JButton createButton(String text,ActionListener listener,String pathImage) {
JButton button = new JButton(new ImageIcon(pathImage));
button.setSize(68, 34);
button.setLocation(width, height);
button.addActionListener(listener);
button.setContentAreaFilled(false);
button.setFocusPainted(false);
this.add(button);
button.setPreferredSize(new Dimension(72, 38));
return button;
}
}

View File

@ -0,0 +1,150 @@
package gui.render;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import events.EntityDrawboxChangedEvent;
import events.EntityDrawboxChangedListener;
import model.Drawbox;
import model.Entity;
import model.Point;
public class DrawboxRectengleRenderingFunction implements ShapeRenderingFunction {
private List<Point> drawboxPoints;
private List<Point> basePoints;
Point currentPoint = new Point(0, 0);
private List<EntityDrawboxChangedListener> listeners = new ArrayList<>();
Entity entity;
Logger logger = Logger.getLogger("gui.DrawboxRectangleEditor");
public DrawboxRectengleRenderingFunction(Entity entity) {
this.entity = entity;
}
@Override
public void drawing(Graphics2D g) {
Drawbox drawbox = entity.getDrawbox();
drawboxPoints = drawbox.getDrawboxlistPoints();
basePoints = drawbox.getbaseListPoints();
logger.finest("drawbox point size: "+ drawboxPoints.size());
for(Point p: drawboxPoints)
logger.finest("DrawBoxPoint: ["+ p.x + ":"+p.y+"]");
for(Point p: basePoints)
logger.finest("BasePoint: ["+ p.x + ":"+p.y+"]");
if(drawboxPoints.size() >= 1 && drawboxPoints.size() < 4) {
Point lastPoint = drawboxPoints.get(drawboxPoints.size()-1);
g.drawLine((int)lastPoint.x, (int)lastPoint.y, (int)currentPoint.x, (int)currentPoint.y);
for(int i = 0; i < drawboxPoints.size()-1;i++) {
int x1 = (int)drawboxPoints.get(i).x;
int y1 = (int)drawboxPoints.get(i).y;
int x2 = (int)drawboxPoints.get(i+1).x;
int y2 = (int)drawboxPoints.get(i+1).y;
g.drawLine(x1, y1, x2, y2);
}
} else {
for(int i = 0; i < drawboxPoints.size();i++) {
int x1 = (int)drawboxPoints.get(i % drawboxPoints.size()).x;
int y1 = (int)drawboxPoints.get(i % drawboxPoints.size()).y;
int x2 = (int)drawboxPoints.get((i+1) % drawboxPoints.size()).x;
int y2 = (int)drawboxPoints.get((i+1) % drawboxPoints.size()).y;
g.drawLine(x1, y1, x2, y2);
}
// ОТРИСОВКА ОСНОВАНИЯ
g.setColor(Color.BLUE);
for(int i = 0; i < basePoints.size()-1;i++) {
int x1 = (int)basePoints.get(i).x;
int y1 = (int)basePoints.get(i).y;
int x2 = (int)basePoints.get(i+1).x;
int y2 = (int)basePoints.get(i+1).y;
g.drawLine(x1, y1+3, x2, y2+3);
}
}
}
@Override
public void mousePressed(MouseEvent e) {
if(drawboxPoints.size() < 4) {
Point p = new Point(e.getX(), e.getY());
drawboxPoints.add(p);
if(drawboxPoints.size() == 4) {
sortingDrawboxPoints();
saveDataInEntity();
//при выборе 4-й точки и формировании данных drawbox, уведомляем всех подписчит
if(listeners!=null) {
notifySubscribers();
}
}
}
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseMoved(MouseEvent e) {
currentPoint.x = e.getX();
currentPoint.y = e.getY();
}
/*Точки должны идти в определенном порядке:
* левая верхняя точка, правая верхняя, нижняя правая, нижняя левая;
* Обе нижние точки, т.е. 3 и 4 являются основанием - хардкод.
* P.s. возможно это не критично, и в сторе предусмотрено, что бы они сортировались,
* но на данном этапе на всякий случай стоит так поступить*/
private void sortingDrawboxPoints() {
//окей, это написано плохо, но... Похуй, пляшем)
Collections.sort(
drawboxPoints,
(point1, point2) -> Float.compare(point1.y, point2.y)
);
if(drawboxPoints.get(0).x>drawboxPoints.get(1).x) {
Collections.swap(drawboxPoints, 0, 1);
}
if(drawboxPoints.get(2).x<drawboxPoints.get(3).x) {
Collections.swap(drawboxPoints, 2, 3);
}
/*Багтест, проверка очередности построения точек
*
* System.out.println("_______________");
int i = 0;
for (Point point : drawboxPoints) {
System.out.println("Point["+i+"]: ("+point.x+" ; "+point.y+");");
i++;
}*/
}
public void subscribe(EntityDrawboxChangedListener listener) {
listeners.add(listener);
}
public void unsubscribe(EntityDrawboxChangedListener listener) {
listeners.remove(listener);
}
//
private void notifySubscribers() {
for (EntityDrawboxChangedListener listener : listeners) {
listener.drawboxChanged(
new EntityDrawboxChangedEvent(entity.getDrawbox(), entity)
);
}
}
public void saveDataInEntity() {
entity.setDrawbox(new Drawbox(drawboxPoints));
}
}

View File

@ -1,18 +1,9 @@
package gui;
package gui.render;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
public class HitboxCircleEditor extends Editable {
HitboxCircleEditor(ListGUI listGUI) {
super(listGUI);
// TODO Auto-generated constructor stub
}
public class HitboxCircleRenderingFunction implements ShapeRenderingFunction {
@Override
public void drawing(Graphics2D g) {
@ -21,7 +12,7 @@ public class HitboxCircleEditor extends Editable {
}
@Override
public void saveDataInEntity() {
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@ -38,10 +29,4 @@ public class HitboxCircleEditor extends Editable {
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}

View File

@ -1,19 +1,9 @@
package gui;
package gui.render;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
public class HitboxPoligonEditor extends Editable {
HitboxPoligonEditor(ListGUI listGUI) {
super(listGUI);
// TODO Auto-generated constructor stub
}
public class HitboxRectengleRenderingFunction implements ShapeRenderingFunction {
@Override
public void drawing(Graphics2D g) {
@ -22,7 +12,7 @@ public class HitboxPoligonEditor extends Editable {
}
@Override
public void saveDataInEntity() {
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@ -39,10 +29,4 @@ public class HitboxPoligonEditor extends Editable {
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,12 @@
package gui.render;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
public interface ShapeRenderingFunction {
void drawing(Graphics2D g);
public void mousePressed(MouseEvent e);
public void mouseClicked(MouseEvent e);
public void mouseMoved(MouseEvent e);
//private void notifySubscribers() ?? надо ли? подумать
}

View File

@ -4,8 +4,12 @@ import java.util.ArrayList;
import java.util.List;
public class Drawbox {
private List<Point> drawboxlistPoints ;//для прямоугольника дравбокса.
private List<Point> baseListPoints ;//2 точки для линии основания
private List<Point> drawboxlistPoints = new ArrayList<Point>();//для прямоугольника дравбокса.
private List<Point> baseListPoints = new ArrayList<Point>();//2 точки для линии основания
public Drawbox(){
}
public Drawbox(List<Point> drawboxlistPoints){
this.drawboxlistPoints = new ArrayList<Point>(drawboxlistPoints) ;
@ -15,8 +19,6 @@ public class Drawbox {
public Drawbox(String informationDrawbox){
if(informationDrawbox!= null) {
drawboxlistPoints = new ArrayList<Point>();
baseListPoints = new ArrayList<Point>();
String[] informations = informationDrawbox.split(" ");
parseStringToDrawbox(informations);
createBasePoint();
@ -44,9 +46,12 @@ public class Drawbox {
}
}
}
//Возвращает все точки дравбокса через пробел.
@Override
/* @Override
public String toString() {
}
*/
//Возвращает все точки дравбокса через пробел.
public String listPointsToString() {
String stringDrawbox="";
for (Point point : drawboxlistPoints) {
stringDrawbox+=((int)point.x)+" "+((int)point.y)+" "; //(int) because it is for XML
@ -54,6 +59,7 @@ public class Drawbox {
return stringDrawbox;
}
public List<Point> getDrawboxlistPoints() {
return drawboxlistPoints;
}

View File

@ -7,18 +7,29 @@ public class Entity {
private Drawbox thisDrawbox;
private Hitbox thisHitbox;
private String type;
private BufferedImage sprite;
private BufferedImage thisImage;
private int width = 0;
private int height = 0;
public Entity(String name,String drawbox,String hitbox) {
public Entity(String name, String drawbox, String hitbox, BufferedImage sprite) {
thisName = new String(name);
thisDrawbox = new Drawbox(drawbox);
thisHitbox = new Hitbox(hitbox);
setImage(sprite); // updates entity width and height, should be called before creating hitbox
if(hitbox != null) {
String[] dataHitbox = hitbox.split(" ");
System.out.println("Создается обьект /"+name+"/. Shape Hitbox = /"+dataHitbox[0]+"/. Размер dataHitbox = /"+dataHitbox.length+"/.");
if(dataHitbox[0].equals("Rectangle")) {
thisHitbox = new HitboxRectangle(dataHitbox,this);
}else if(dataHitbox[0].equals("Circle")) {
thisHitbox = new HitboxCircle(dataHitbox,this);
}
public Entity(String name, Hitbox hitbox, Drawbox drawbox) {
}
}
// при добавлении новой сущности по умолчанию создается у нее прямоугольный хитбокс
public Entity(String name) {
this.thisName = name;
this.thisHitbox = hitbox;
this.thisDrawbox = drawbox;
this.thisHitbox = new HitboxRectangle("Rectangle",this);
this.thisDrawbox = new Drawbox();
}
public void setName(String outName) {
@ -53,24 +64,41 @@ public class Entity {
return thisHitbox;
};
public Drawbox getThisDrawbox() {
return thisDrawbox;
}
/** @return BufferedImage object or null if an image is not set */
public BufferedImage getImage() {
return sprite;
return thisImage;
}
/** NOTE: Image setter updates entity width and height */
public void setImage(BufferedImage sprite) {
this.sprite = sprite;
this.thisImage = sprite;
if(sprite != null) {
width = sprite.getHeight();
height = sprite.getHeight();
}
}
public void PrintEntity() {
System.out.println("---------------------");
System.out.println("Name: "+thisName);
this.thisDrawbox.printToConsole();
this.thisHitbox.printToConsole();
thisDrawbox.printToConsole();
thisHitbox.printToConsole();
System.out.println("---------------------");
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}

View File

@ -3,82 +3,87 @@ package model;
import java.util.ArrayList;
import java.util.List;
public class Hitbox {
private String shape = null;// shape - Форма хитбокса. Понадобится при написании сохранения. Один из параметров в xml-file.
private List<Point> listPoints = null;//для прямоугольника - 4 точки. Для круга - надо посмотреть.
public abstract class Hitbox {
String shape = null;// shape - Форма хитбокса. Понадобится при написании сохранения. Один из параметров в xml-file.
Point referencePoint = new Point(0, 0); //Точка отсчета хитбокса, от нее рассчитывается высота+ширина/радиус(при круге) хитбокса.
Entity owner;
public Hitbox(String shape,List<Point> listPoints){
public Hitbox(){
}
//Либо так передавать shape, либо создать setShape. Но по сути shape определяется при создании обьекта, и тогда set - предоставление не нужных возможностей.
public Hitbox(String shape){
this.shape = new String(shape);
this.listPoints = new ArrayList<Point>(listPoints) ;
}
public Hitbox(String informationHitbox){
//informationHitbox - default="Rectangle 0 0 96 98"
//Предварительно, я бы сказал что вообще этот конструктор бесполезен и его можно удалить,
// т.к. Hitbox конструктор вызывается из дочерних элементов, а они уже владеют всей необходимой инфой, и entity owner задают сами
// кстати забавно. сейчас устанавливается entity через serOwnerEntity, но как будто этот метод тоже излишек, ведь владелец хитбокса только один.
//Но нет. у нас может быть хитбокс создан программно раньше entity, помню было такое где то, так что этот метод еще обоснован.
public Hitbox(String informationHitbox, Entity owner){
if(informationHitbox!= null) {
listPoints = new ArrayList<Point>();
setOwnerEntity(owner);
String[] informations = informationHitbox.split(" ");
//в 0-м индексе всегда идет название фигуры.Так сделан наш xml.
shape = new String(informations[0]);
//заполняем лист точками. Пока что делаю тупо и топорно. Хардкод. Потом можно переделать.
if(shape.equals("Rectangle")) {
parseStringToRectangleHitbox(informations);
}else if(shape.equals("Circle")) {
parseStringToCircleHitbox(informations);
}
}
}
private void parseStringToRectangleHitbox(String[] informations) {
//составляем точки по которым строится прямоугольник, и запихиваем их в лист с точками
for(int i = 1;i<informations.length;i+=2) {
float x = Float.parseFloat(informations[i]);
float y = Float.parseFloat(informations[i+1]);
Point point = new Point(x, y);
listPoints.add(point);
}
}
private void parseStringToCircleHitbox(String[] informations) {
//ЭТО ХАРДКОД.ДА.Но в данном случае, имхо, разумный(в каком то смысле).
//первая точка где строится круг
float x1 = Float.parseFloat(informations[1]);
float y1 = Float.parseFloat(informations[2]);
Point point1 = new Point(x1, y1);
//вторая точка x2 - диаметр, а y2 = 0, потому что нам на него пофиг.
//Просто же не создавать для круга новый класс хитбокса? Нет. Так что так.
float x2 = Float.parseFloat(informations[3]);
Point point2 = new Point(x2, 0);
listPoints.add(point2);
public abstract String listPointsToString();
/**
* @param result - Point object to store the result
* @return x and y converted to isometic coords
* */
public static Point cartesianToIsometric(float cartX, float cartY, Point result) {
result.x = cartX - cartY;
result.y = (cartX + cartY) / 2;
return result;
}
public void addPoint(Point point) {
listPoints.add(point);
/**
* @param result - Point object to store the result
* @return x and y converted to cartesian coords
* */
public static Point isometricToCartesian(float x, float y, Point result) {
result.x = (2 * y + x) / 2;
result.y = (2 * y - x) / 2;
return result;
}
public void setOwnerEntity(Entity owner) {
this.owner = owner;
}
public Entity getOwnerEntity() {
return owner;
}
public void clearPoints() {
listPoints.clear();
}
public String getShape() {
return shape;
}
public List<Point> getListPoints() {
return listPoints;
}
//not the same as toString()! the latter is for XML while printToConsole() is for console
public void printToConsole() {
System.out.println();
/*System.out.println();
System.out.println("|||Hitbox:");
if(shape!=null&&listPoints!=null) {
System.out.println("shape: " + shape);
for(Point point: listPoints) {
if(shape!=null&&listPointsCartesian!=null) {
System.out.println("Shape: " + shape);
System.out.println("Cartesian: ");
for(Point point: listPointsCartesian) {
System.out.print("("+point.x+";"+point.y+") ");
System.out.println("");
}
System.out.println();
System.out.println("-----------");
System.out.println("Iso: ");
for(Point point: listPointsIso){
System.out.print("("+point.x+";"+point.y+") ");
System.out.println("");
}
System.out.println(" ");
}else {
System.out.println("null");
}
}*/
}
//дописать функцию возвращения listPonts и shape(форма), если будет нужно.
// так же при написании функции возвращения нужных координат, надо их сделать целочисленными.

View File

@ -0,0 +1,26 @@
package model;
public class HitboxCircle extends Hitbox {
private float radiusHitbox;
public HitboxCircle(String[] dataHitbox, Entity owner){
super(dataHitbox[0]);
setOwnerEntity(owner);
parseStringToCircleHitbox(dataHitbox);
}
public HitboxCircle(String shape, Entity owner){
super(shape);
setOwnerEntity(owner);
radiusHitbox = 0;
}
private void parseStringToCircleHitbox(String[] informations) {
referencePoint.x = Float.parseFloat(informations[1]);
referencePoint.y = Float.parseFloat(informations[2]);
radiusHitbox = Float.parseFloat(informations[3]);
}
@Override
public String listPointsToString() {
return "Circle"+referencePoint.x+referencePoint.x+" "+referencePoint.y+" "+radiusHitbox;
}
}

View File

@ -0,0 +1,94 @@
package model;
import java.util.ArrayList;
import java.util.List;
public class HitboxRectangle extends Hitbox {
private List<Point> listPointsIso = new ArrayList<Point>();
private List<Point> listPointsCartesian = new ArrayList<Point>();
private float widthHitbox = 0,heightHitbox = 0; // Ширина и высота хитбокса в декартовых координатах.
public HitboxRectangle(String shape, Entity owner){
super(shape);
setOwnerEntity(owner);
initListsPoints();
}
public HitboxRectangle(String shape,List<Point> listPointsIso,List<Point> listPointsCartesian){
super(shape);
this.listPointsIso = listPointsIso;
this.listPointsCartesian = listPointsCartesian;
initListsPoints();
}
//informationHitbox - default="Rectangle 0 0 96 98"
public HitboxRectangle(String[] dataHitbox, Entity owner){
super(dataHitbox[0]);
setOwnerEntity(owner);
initListsPoints();
//в 0-м индексе всегда идет название фигуры.Так сделан наш xml.
parseStringToRectangleHitbox(dataHitbox);
createCartesianPointsFromWidthAndHeigh();
convertCartesianPointsToIso();
printToConsole();
}
private void initListsPoints() {
if(listPointsIso.size()<1) {
for(int i=0;i<4;i++) {
listPointsIso.add(new Point(0,0));
}
}
if(listPointsCartesian.size()<1) {
for(int i=0;i<4;i++) {
listPointsCartesian.add(new Point(0,0));
}
}
}
private void parseStringToRectangleHitbox(String[] dataHitbox) {
referencePoint.x = Float.parseFloat(dataHitbox[1]);
referencePoint.y = Float.parseFloat(dataHitbox[2]);
widthHitbox = Float.parseFloat(dataHitbox[3]);
heightHitbox = Float.parseFloat(dataHitbox[4]);
}
//тут не правильно реализована функция, т.к. до сих пор нигде не используется. Надо переделать будет.
public void convertIsoPointsToCartesian() {
Point isoPoint;
for (int i = 0 ; i<4;i++) {
isoPoint = listPointsIso.get(i);
cartesianToIsometric(isoPoint.x,isoPoint.y,listPointsCartesian.get(i));
}
}
//+++++++
public void convertCartesianPointsToIso() {
Point cartesianPoint;
for (int i = 0 ; i<4;i++) {
cartesianPoint = listPointsCartesian.get(i);
cartesianToIsometric(cartesianPoint.x,cartesianPoint.y,listPointsIso.get(i));
}
}
//+++++++
private void createCartesianPointsFromWidthAndHeigh(){
Point refIsoPoint = new Point(owner.getWidth()/2+referencePoint.x,owner.getHeight()+referencePoint.y);
Point refCartesianPoint = isometricToCartesian(refIsoPoint.x,refIsoPoint.y,new Point(0,0));
listPointsCartesian.clear();
listPointsCartesian.add(new Point(refCartesianPoint.x-widthHitbox,refCartesianPoint.y));
listPointsCartesian.add(new Point(refCartesianPoint.x,refCartesianPoint.y));
listPointsCartesian.add(new Point(refCartesianPoint.x,refCartesianPoint.y-heightHitbox));
listPointsCartesian.add(new Point(refCartesianPoint.x-widthHitbox,refCartesianPoint.y-heightHitbox));
}
public List<Point> getListPointsIso() {
return listPointsIso;
}
public List<Point> getListPointsCartesian() {
return listPointsCartesian;
}
@Override
public String listPointsToString() {
return "Rectangle "+referencePoint.x+" "+referencePoint.y+" "+widthHitbox+" "+heightHitbox;
}
}

View File

@ -1,25 +0,0 @@
package model;
public class IsometricCoordsConverter {
/**
* @param result - Point object to store the result
* @return x and y converted to isometic coords
* */
public static Point cartesianToIsometric(float cartX, float cartY, Point result) {
result.x = cartX - cartY;
result.y = (cartX + cartY) / 2;
return result;
}
/**
* @param result - Point object to store the result
* @return x and y converted to cartesian coords
* */
public static Point isometricToCartesian(float x, float y, Point result) {
result.x = (2 * y + x) / 2;
result.y = (2 * y - x) / 2;
return result;
}
}

View File

@ -8,4 +8,8 @@ public class Point {
x = mainX;
y = mainY;
}
public void setXY(float x, float y){
this.x = x;
this.y = y;
}
}

View File

@ -32,6 +32,8 @@ import org.xml.sax.SAXException;
import events.EntityDrawboxChangedEvent;
import events.EntityDrawboxChangedListener;
import events.EntityHitboxChangedEvent;
import events.EntityHitboxChangedListener;
import exception.DuplicateEntryException;
import launch.Launcher;
import model.Entity;
@ -41,7 +43,7 @@ import model.Entity;
* Класс данных, который оперирует их сохранением, загрузкой, и хранением в памяти.
* ВАЖНО: данный класс хранит так же актуальную копию XML-представления файла
* */
public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
public class Project implements Iterable<Entity>, EntityDrawboxChangedListener, EntityHitboxChangedListener {
/**
* Путь к XML по-умолчанию.
@ -125,7 +127,7 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
}
/**
* Загружает типы сущностей из файла с заданным именем и расположением.<br>
* Загружает типы сущностей из файла с заданным именем и расположением.<br>0
* */
public void load() throws SAXException, IOException, ParserConfigurationException {
listEntity.clear();
@ -174,9 +176,8 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
}
}
Entity e = new Entity(entityName, newDrawbox, newHitbox);
Entity e = new Entity(entityName, newDrawbox, newHitbox, sprite);
e.setType(type);
e.setImage(sprite);
listEntity.add(e);
}
}
@ -194,6 +195,7 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
if (!imageFile.exists())
throw new FileNotFoundException();
BufferedImage image = ImageIO.read(imageFile);
return image;
} catch (FileNotFoundException fe) {
logger.warning("Image file \""+path+name+'.'+extension+"\" is not found!");
@ -237,14 +239,14 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
Element drawboxProperty = document.createElement("property");
drawboxProperty.setAttribute("name", "drawbox");
drawboxProperty.setAttribute("type", "string");
drawboxProperty.setAttribute("default", ""); // empty, because on creation there is no drawbox yet
drawboxProperty.setAttribute("default", "0 0 0 0 0 0 0 0"); // empty, because on creation there is no drawbox yet
objecttypeElement.appendChild(drawboxProperty);
// format: <property name="hitbox" type="string" default="HITBOX_TYPE OFFSET_X OFFSET_Y SIZE"/>
Element hitboxProperty = document.createElement("property");
hitboxProperty.setAttribute("name", "hitbox");
hitboxProperty.setAttribute("type", "string");
hitboxProperty.setAttribute("default", ""); // empty, no hitbox yet
hitboxProperty.setAttribute("default", "Rectangle 0 0 0 0"); // empty, no hitbox yet
objecttypeElement.appendChild(hitboxProperty);
//printXMlToConsole(); //DEBUG!
@ -355,7 +357,27 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
//we have hitbox, drawbox and class, gotta set the right one
Element propertyElement = ((Element)properties.item(i));
if (propertyElement.getAttribute("name").equals("drawbox")) {
propertyElement.setAttribute("default", event.owner.getDrawbox().toString());
propertyElement.setAttribute("default", event.owner.getDrawbox().listPointsToString());
}
}
}
}
/**
* Получение события при отрисовке нового Hitbox, для изменения XML-дерева.
* Объект event хранит в себе ссылку на новый объект Hitbox и объект entity, для которой он был создан.
* */
@Override
public void hitboxChanged(EntityHitboxChangedEvent event) {
String entityName = event.owner.getName();
Node entityToUpdate = getEntityXMLNodeByName(entityName);
NodeList properties = entityToUpdate.getChildNodes();
for(int i = 0; i < properties.getLength(); i++) {
if(properties.item(i) instanceof Element) { // ignoring #text nodes
//we have hitbox, drawbox and class, gotta set the right one
Element propertyElement = ((Element)properties.item(i));
if (propertyElement.getAttribute("name").equals("hitbox")) {
propertyElement.setAttribute("default", event.owner.getHitbox().listPointsToString());
}
}
}
@ -388,6 +410,8 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
stripEmptyElements(child);
}
}
}
//в момент окончания рисования, в зависимости в какой мы рисуем вкладке хитбокса,
//в зависимости от того в какой панельке(jpanel)и подклассе интерфейса Editable