Merging hitbox-drawing and dev. Adding BufferedImage to Entity. Refactoring Entity parsing in to the Project and download ListGUI

This commit is contained in:
2024-11-18 15:29:14 +03:00
3 changed files with 60 additions and 35 deletions

View File

@ -44,7 +44,6 @@ public class ListGUI extends JPanel {
JButton addListElementEntity;
JButton removeListElementEntity;
JButton addPicEntity;
String pathImage;
JList list;
JScrollPane scroll;
ActionListener removeEntity;
@ -93,8 +92,8 @@ public class ListGUI extends JPanel {
}
//ТУТ МОЖЕТ БЫТЬ ТРАБЛ Т,К, СОЗДАНИЕ ХИТБОКСА - ХАРДКОД. Он может быть не только Rectangle
public void addListElement(String name,String solid) throws DuplicateEntryException {
public void addListElement(String name, String solid) throws DuplicateEntryException {
// плейсхолдеры для новых хитбоксов и дроубоксов, иначе всё валится с NPE
Hitbox hitbox = new Hitbox();
Drawbox drawbox = new Drawbox();
@ -108,13 +107,15 @@ public class ListGUI extends JPanel {
}
public void updateList() {
String[] nameList = createNameList();
testModel.removeAllElements();
for (String name : nameList)
testModel.addElement(name);
pathImage = Project.getInstance().getXMLPath();
createImageMap(nameList);
for (Entity e: Project.getInstance()) {
testModel.addElement(e.getName());
// Create and store JList items icons in a map to prevent their unneccessary re-creation
iconMap.put(e.getName(), createListIconFromSprite( e.getImage() ));
}
list.updateUI();
}
@ -137,7 +138,7 @@ public class ListGUI extends JPanel {
}
private final float iconMaxWidth = 40, iconMaxHeight = 40;
public Icon imageScaling(BufferedImage image) {
private Icon createListIconFromSprite(BufferedImage image) {
CustomIcon icon = null;
try {
int imageWidth = image.getWidth(), imageHeight = image.getHeight();
@ -185,14 +186,6 @@ public class ListGUI extends JPanel {
}
}
private void createImageMap(String[] nameList) {
for (int i = 0; i < nameList.length; i++) {
String name = nameList[i];
BufferedImage image = Project.getInstance().loadImageByName(name);
iconMap.put(name, imageScaling(image));
}
}
private JButton createButton(int width,int height,ActionListener listener,String pathImage) {
JButton button = new JButton(new ImageIcon(pathImage));
button.setSize(110, 46);

View File

@ -8,11 +8,14 @@ public class Entity {
private Hitbox thisHitbox;
private String type;
private BufferedImage thisImage;
//private
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);
setImage(sprite); // updates entity width and height, should be called before creating hitbox
thisHitbox = new Hitbox(hitbox);
thisHitbox.setOwnerEntity(this);
}
@ -44,10 +47,6 @@ public class Entity {
thisHitbox = outHitbox;
};
public void setImage(BufferedImage outImage) {
thisImage = outImage;
};
public String getName() {
return thisName;
};
@ -60,9 +59,19 @@ public class Entity {
return thisHitbox;
};
/** @return BufferedImage object or null if an image is not set */
public BufferedImage getImage() {
return thisImage;
};
}
/** NOTE: Image setter updates entity width and height */
public void setImage(BufferedImage sprite) {
this.thisImage = sprite;
if(sprite != null) {
width = sprite.getHeight();
height = sprite.getHeight();
}
}
public void PrintEntity() {
System.out.println("---------------------");
@ -71,4 +80,20 @@ public class Entity {
this.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

@ -132,6 +132,7 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
factory = DocumentBuilderFactory.newInstance();
builder = factory.newDocumentBuilder();
document = builder.parse(new File(path+fileName));
// TODO: remove this from Project, it should not know SHIT about MainGUI
if(Launcher.getMainGUI() != null) // at the first program launch, main gui creates list gui before static link to main gui is set
Launcher.getMainGUI().setTitle("Hitbox/Drawbox Editor: " + path + fileName);
// Получение списка всех элементов objecttype внутри корневого элемента (getDocumentElement возвращает ROOT элемент XML файла).
@ -144,14 +145,18 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
}
}
// эта колбаса парсит сущности из XML в программные объекты внутри модели, является частью внутренней кухни так что обычно её не нужно трогать
private void parsingElementXMLtoElementList(String entityName,Node objecttype) {
private void parsingElementXMLtoElementList(String entityName, Node objecttype) {
String newDrawbox = null;
String newHitbox = null;
String type = null;
BufferedImage sprite = null;
Element element = (Element)objecttype;
NodeList propertyElements = element.getElementsByTagName("property");
if(propertyElements!=null) {
if(propertyElements != null) {
// do not lazy load images here - Hitbox parser needs real image sizes
sprite = loadImageByName(entityName);
for(int i = 0; i < propertyElements.getLength(); i++) {
Element property = (Element)propertyElements.item(i);
String propertyName = property.getAttribute("name");
@ -168,7 +173,8 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
break;
}
}
Entity e = new Entity(entityName,newDrawbox,newHitbox);
Entity e = new Entity(entityName, newDrawbox, newHitbox, sprite);
e.setType(type);
listEntity.add(e);
}
@ -179,9 +185,6 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
* XML-файл. Возвращает null если изображение не найдено.
* */
public BufferedImage loadImageByName(String name) {
//TODO: сделать кеширование - не дело подгружать одну и ту же картинку по десять раз!
String path = Project.getInstance().getXMLPath();
String extension = "png";
// TODO: изображения следует подгружать в отдельном потоке!
@ -210,6 +213,9 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
if(getEntityByName(e.getName()) != null)
throw new DuplicateEntryException("The entity with the name '" + e.getName() + "' already exists!");
//TODO: move image loading to AddListElementEntityListener and make it lazy
e.setImage(loadImageByName(e.getName()));
listEntity.add(e);
Element objecttypeElement = document.createElement("objecttype");
@ -366,8 +372,9 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
return null;
}
//https://stackoverflow.com/a/64659614/6929164
public static void stripEmptyElements(Node node)
// https://stackoverflow.com/a/64659614/6929164
// new empty lines will appear on every XML save without this function
private static void stripEmptyElements(Node node)
{
NodeList children = node.getChildNodes();
for(int i = 0; i < children.getLength(); ++i) {