Translated project in Scala (but the path finder seems to be broken)
This commit is contained in:
parent
40e0a92f9e
commit
58509e0d5b
24
compile.sh
24
compile.sh
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
chmod +x lib/*.jar
|
|
||||||
rm -rf tmp
|
|
||||||
mkdir tmp
|
|
||||||
javac -cp src/main/java:lib/gson-2.8.6.jar:lib/jopt-simple-6.0-alpha-3.jar \
|
|
||||||
-target 1.9 -source 1.9 \
|
|
||||||
-d tmp --module-path src/main/java \
|
|
||||||
src/main/java/fr/ynerant/leveleditor/api/editor/*.java \
|
|
||||||
src/main/java/fr/ynerant/leveleditor/client/main/*.java \
|
|
||||||
src/main/java/fr/ynerant/leveleditor/editor/*.java \
|
|
||||||
src/main/java/fr/ynerant/leveleditor/frame/*.java \
|
|
||||||
src/main/java/fr/ynerant/leveleditor/game/*.java \
|
|
||||||
src/main/java/fr/ynerant/leveleditor/game/mobs/*.java \
|
|
||||||
src/main/java/fr/ynerant/leveleditor/game/towers/*.java
|
|
||||||
cp -r src/main/resources/* tmp/
|
|
||||||
unzip lib/gson-2.8.6.jar -x META-INF/MANIFEST.MF -d tmp
|
|
||||||
unzip lib/jopt-simple-6.0-alpha-3.jar -x META-INF/MANIFEST.MF -d tmp
|
|
||||||
cd tmp
|
|
||||||
zip -r TheGame.jar *
|
|
||||||
mv TheGame.jar ../
|
|
||||||
cd ..
|
|
||||||
rm -rf tmp
|
|
||||||
chmod +x TheGame.jar
|
|
||||||
echo "Successfully compiled to \"TheGame.jar\". To run: \"java -jar TheGame.jar\"".
|
|
|
@ -1,52 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.api.editor;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.Sprite;
|
|
||||||
|
|
||||||
public class Case {
|
|
||||||
private int x;
|
|
||||||
private int y;
|
|
||||||
private Sprite couche1;
|
|
||||||
private Sprite couche2;
|
|
||||||
private Sprite couche3;
|
|
||||||
private Collision collision;
|
|
||||||
|
|
||||||
public static Case create(int posX, int posY, Sprite couche1, Sprite couche2, Sprite couche3, Collision collision) {
|
|
||||||
Case c = new Case();
|
|
||||||
c.x = posX;
|
|
||||||
c.y = posY;
|
|
||||||
c.couche1 = couche1;
|
|
||||||
c.couche2 = couche2;
|
|
||||||
c.couche3 = couche3;
|
|
||||||
c.collision = collision;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPosX() {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPosY() {
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Sprite getCoucheOne() {
|
|
||||||
return couche1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Sprite getCoucheTwo() {
|
|
||||||
return couche2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Sprite getCoucheThree() {
|
|
||||||
return couche3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collision getCollision() {
|
|
||||||
return collision;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "{Case x=" + x + " y=" + y + " couche1=" + couche1 + " couche2=" + couche2 + " couche3=" + couche3 + " collision=" + collision.name().toUpperCase() + "}\n";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.api.editor;
|
|
||||||
|
|
||||||
public enum Collision {
|
|
||||||
FULL, PARTIAL, ANY
|
|
||||||
}
|
|
|
@ -1,162 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.api.editor;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import fr.ynerant.leveleditor.editor.Map;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.*;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
import java.util.zip.GZIPOutputStream;
|
|
||||||
|
|
||||||
public class EditorAPI {
|
|
||||||
private static File LAST_FILE;
|
|
||||||
|
|
||||||
public static RawMap toRawMap(int width, int height) {
|
|
||||||
List<RawCase> cases = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int y = 1; y < height; y += 16) {
|
|
||||||
for (int x = 1; x < width; x += 16) {
|
|
||||||
RawCase c = RawCase.create(x / 16, y / 16, RawSprite.BLANK, RawSprite.BLANK, RawSprite.BLANK, Collision.ANY);
|
|
||||||
cases.add(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return RawMap.create(cases, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Gson createGson() {
|
|
||||||
GsonBuilder builder = new GsonBuilder();
|
|
||||||
|
|
||||||
builder.enableComplexMapKeySerialization();
|
|
||||||
builder.serializeNulls();
|
|
||||||
builder.setPrettyPrinting();
|
|
||||||
|
|
||||||
return builder.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JFileChooser createJFC() {
|
|
||||||
JFileChooser jfc = new JFileChooser();
|
|
||||||
|
|
||||||
jfc.setFileFilter(new FileNameExtensionFilter("Fichiers monde (*.gmap, *.dat)", "gmap", "dat"));
|
|
||||||
jfc.setFileHidingEnabled(true);
|
|
||||||
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
|
||||||
File dir = new File("maps");
|
|
||||||
assert dir.mkdirs();
|
|
||||||
jfc.setCurrentDirectory(dir);
|
|
||||||
|
|
||||||
return jfc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void saveAs(RawMap map) {
|
|
||||||
JFileChooser jfc = createJFC();
|
|
||||||
File file;
|
|
||||||
jfc.showSaveDialog(null);
|
|
||||||
file = jfc.getSelectedFile();
|
|
||||||
|
|
||||||
if (file == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!file.getName().toLowerCase().endsWith(".gmap") && !file.getName().toLowerCase().endsWith(".dat")) {
|
|
||||||
file = new File(file.getParentFile(), file.getName() + ".gmap");
|
|
||||||
}
|
|
||||||
|
|
||||||
LAST_FILE = file;
|
|
||||||
|
|
||||||
save(file, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void save(RawMap map) {
|
|
||||||
if (LAST_FILE != null)
|
|
||||||
save(LAST_FILE, map);
|
|
||||||
else
|
|
||||||
saveAs(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void save(File file, RawMap map) {
|
|
||||||
String json = createGson().toJson(map);
|
|
||||||
|
|
||||||
try {
|
|
||||||
assert file.createNewFile();
|
|
||||||
BufferedOutputStream bos = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(file)));
|
|
||||||
|
|
||||||
bos.write(json.getBytes(StandardCharsets.UTF_8));
|
|
||||||
|
|
||||||
bos.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map open() {
|
|
||||||
JFileChooser jfc = createJFC();
|
|
||||||
File file;
|
|
||||||
|
|
||||||
jfc.showOpenDialog(null);
|
|
||||||
file = jfc.getSelectedFile();
|
|
||||||
|
|
||||||
if (file == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
LAST_FILE = file;
|
|
||||||
|
|
||||||
return open(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RawMap getRawMap(File f) {
|
|
||||||
String json = null;
|
|
||||||
try {
|
|
||||||
GZIPInputStream gis = new GZIPInputStream(new BufferedInputStream(new FileInputStream(f)));
|
|
||||||
byte[] bytes = new byte[512 * 1024];
|
|
||||||
int count;
|
|
||||||
StringBuilder text = new StringBuilder();
|
|
||||||
while ((count = gis.read(bytes)) != -1) {
|
|
||||||
text.append(new String(bytes, 0, count, StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
gis.close();
|
|
||||||
|
|
||||||
json = text.toString();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return createGson().fromJson(json, RawMap.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map open(File f) {
|
|
||||||
return open(getRawMap(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map open(RawMap map) {
|
|
||||||
if (map.getFont() == null) {
|
|
||||||
int baseWidth = map.getWidth();
|
|
||||||
int baseHeight = map.getHeight();
|
|
||||||
int width = baseWidth + (baseWidth / 16) + 1;
|
|
||||||
int height = baseHeight + (baseHeight / 16) + 1;
|
|
||||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
Graphics2D g = image.createGraphics();
|
|
||||||
g.setColor(Color.white);
|
|
||||||
g.fillRect(0, 0, width, height);
|
|
||||||
g.setColor(Color.black);
|
|
||||||
g.drawLine(0, 0, width, 0);
|
|
||||||
g.drawLine(0, 0, 0, height);
|
|
||||||
for (int x = 17; x <= width; x += 17) {
|
|
||||||
g.drawLine(x, 0, x, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = 17; y <= height; y += 17) {
|
|
||||||
g.drawLine(0, y, width, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
map.setFont(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Map(map);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.api.editor;
|
|
||||||
|
|
||||||
public class RawCase {
|
|
||||||
private int x;
|
|
||||||
private int y;
|
|
||||||
private RawSprite couche1;
|
|
||||||
private RawSprite couche2;
|
|
||||||
private RawSprite couche3;
|
|
||||||
private Collision collision;
|
|
||||||
|
|
||||||
public static RawCase create(int posX, int posY, RawSprite couche1, RawSprite couche2, RawSprite couche3, Collision collision) {
|
|
||||||
RawCase c = new RawCase();
|
|
||||||
c.x = posX;
|
|
||||||
c.y = posY;
|
|
||||||
c.couche1 = couche1;
|
|
||||||
c.couche2 = couche2;
|
|
||||||
c.couche3 = couche3;
|
|
||||||
c.collision = collision;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RawCase create(Case c) {
|
|
||||||
RawCase raw = new RawCase();
|
|
||||||
raw.x = c.getPosX();
|
|
||||||
raw.y = c.getPosY();
|
|
||||||
raw.couche1 = RawSprite.create(c.getCoucheOne());
|
|
||||||
raw.couche2 = RawSprite.create(c.getCoucheTwo());
|
|
||||||
raw.couche3 = RawSprite.create(c.getCoucheThree());
|
|
||||||
raw.collision = c.getCollision();
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPosX() {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPosY() {
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RawSprite getCoucheOne() {
|
|
||||||
return couche1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RawSprite getCoucheTwo() {
|
|
||||||
return couche2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RawSprite getCoucheThree() {
|
|
||||||
return couche3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collision getCollision() {
|
|
||||||
return collision;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCollision(Collision collision) {
|
|
||||||
this.collision = collision;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.api.editor;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.editor.Map;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class RawMap {
|
|
||||||
private List<RawCase> cases;
|
|
||||||
private java.util.Map<Integer, RawCase> cases_map;
|
|
||||||
private int width;
|
|
||||||
private int height;
|
|
||||||
private transient BufferedImage font;
|
|
||||||
|
|
||||||
public static RawMap create(List<RawCase> cases, int width, int height) {
|
|
||||||
RawMap rm = new RawMap();
|
|
||||||
rm.cases = cases;
|
|
||||||
rm.width = width;
|
|
||||||
rm.height = height;
|
|
||||||
return rm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RawMap create(Map map) {
|
|
||||||
RawMap raw = new RawMap();
|
|
||||||
raw.width = map.getWidth();
|
|
||||||
raw.height = map.getHeight();
|
|
||||||
raw.cases = new ArrayList<>();
|
|
||||||
for (Case c : map.getAllCases()) {
|
|
||||||
RawCase rc = RawCase.create(c);
|
|
||||||
raw.cases.add(rc);
|
|
||||||
}
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<RawCase> getCases() {
|
|
||||||
return cases;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RawCase getCase(int x, int y) {
|
|
||||||
if (cases_map == null) {
|
|
||||||
cases_map = new HashMap<>();
|
|
||||||
for (RawCase c : getCases())
|
|
||||||
cases_map.put(c.getPosY() * width + c.getPosX(), c);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cases_map.get(y * getWidth() + x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<RawCase> getNeighbours(RawCase c) {
|
|
||||||
List<RawCase> list = new ArrayList<>();
|
|
||||||
list.add(getCase(c.getPosX() - 1, c.getPosY()));
|
|
||||||
list.add(getCase(c.getPosX(), c.getPosY() - 1));
|
|
||||||
list.add(getCase(c.getPosX() + 1, c.getPosY()));
|
|
||||||
list.add(getCase(c.getPosX(), c.getPosY() + 1));
|
|
||||||
return list.stream().filter(_c -> _c != null && _c.getCollision() == Collision.ANY).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWidth() {
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHeight() {
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BufferedImage getFont() {
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFont(BufferedImage font) {
|
|
||||||
this.font = font;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.api.editor;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.Sprite;
|
|
||||||
|
|
||||||
public class RawSprite {
|
|
||||||
public static transient final RawSprite BLANK = new RawSprite();
|
|
||||||
private String category = "blank";
|
|
||||||
private int index = 0;
|
|
||||||
|
|
||||||
public static RawSprite create(Sprite spr) {
|
|
||||||
RawSprite raw = new RawSprite();
|
|
||||||
raw.category = spr.getCategory().getName();
|
|
||||||
raw.index = spr.getIndex();
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCategory() {
|
|
||||||
return category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIndex() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
/**
|
|
||||||
* @author ÿnérant
|
|
||||||
*/
|
|
||||||
package fr.ynerant.leveleditor.api.editor;
|
|
|
@ -1,33 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.api.editor.sprites;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Category {
|
|
||||||
private List<Sprite> sprites;
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private Category() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Category create(String name, List<Sprite> sprites) {
|
|
||||||
Category c = new Category();
|
|
||||||
|
|
||||||
c.name = name;
|
|
||||||
c.sprites = sprites;
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Sprite> getSprites() {
|
|
||||||
return sprites;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.api.editor.sprites;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class Sprite {
|
|
||||||
public static final Sprite BLANK = new Sprite(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB), Category.create("blank", new ArrayList<>()), 0);
|
|
||||||
|
|
||||||
static {
|
|
||||||
Graphics2D g = BLANK.getImage().createGraphics();
|
|
||||||
g.setComposite(AlphaComposite.Clear);
|
|
||||||
g.setColor(new Color(0, true));
|
|
||||||
g.fillRect(0, 0, 16, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Category cat;
|
|
||||||
private final BufferedImage img;
|
|
||||||
private final int index;
|
|
||||||
|
|
||||||
public Sprite(BufferedImage img, Category cat, int index) {
|
|
||||||
this.img = img;
|
|
||||||
this.cat = cat;
|
|
||||||
this.index = index;
|
|
||||||
|
|
||||||
if (!this.cat.getSprites().contains(this))
|
|
||||||
this.cat.getSprites().add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BufferedImage getImage() {
|
|
||||||
return this.img;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Category getCategory() {
|
|
||||||
return cat;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIndex() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return cat.hashCode() ^ getIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (!(o instanceof Sprite))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Sprite other = (Sprite) o;
|
|
||||||
|
|
||||||
return hashCode() == other.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "{Sprite img=" + img + " cat=" + cat.getName() + "}";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.api.editor.sprites;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import fr.ynerant.leveleditor.client.main.Main;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.*;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.jar.JarEntry;
|
|
||||||
import java.util.jar.JarFile;
|
|
||||||
|
|
||||||
public class SpriteRegister {
|
|
||||||
private static Map<String, List<List<Double>>> nameToCoords;
|
|
||||||
private static final Map<String, Category> sprites = new HashMap<>();
|
|
||||||
|
|
||||||
public static void unpack() throws IOException {
|
|
||||||
if (Main.isInDevelopmentMode()) {
|
|
||||||
try {
|
|
||||||
File dir = new File(SpriteRegister.class.getResource("/assets").toURI()).getParentFile();
|
|
||||||
unpackDir(dir);
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
String path = URLDecoder.decode(SpriteRegister.class.getProtectionDomain().getCodeSource().getLocation().getPath());
|
|
||||||
File jarFile = new File(path);
|
|
||||||
|
|
||||||
if (jarFile.isFile()) {
|
|
||||||
JarFile jar = new JarFile(jarFile);
|
|
||||||
Enumeration<JarEntry> entries = jar.entries();
|
|
||||||
while (entries.hasMoreElements()) {
|
|
||||||
JarEntry je = entries.nextElement();
|
|
||||||
String name = je.getName();
|
|
||||||
if (name.startsWith("assets/")) {
|
|
||||||
File f = new File(name);
|
|
||||||
if (name.endsWith("/")) {
|
|
||||||
if (!f.mkdirs() && !f.isDirectory())
|
|
||||||
throw new IOException("Unable to make dir: " + f);
|
|
||||||
}
|
|
||||||
else if (!f.isFile())
|
|
||||||
Files.copy(jar.getInputStream(je), Paths.get(f.toURI()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jar.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void unpackDir(File dir) throws IOException {
|
|
||||||
for (File f : Objects.requireNonNull(dir.listFiles())) {
|
|
||||||
if (f.isDirectory()) {
|
|
||||||
unpackDir(f);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String path = f.getAbsolutePath().substring(f.getAbsolutePath().indexOf(File.separatorChar + "assets") + 1);
|
|
||||||
File local = new File(path);
|
|
||||||
assert local.getParentFile().mkdirs();
|
|
||||||
assert !local.exists() || local.delete();
|
|
||||||
Files.copy(Paths.get(f.toURI()), Paths.get(local.toURI()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static void refreshAllSprites() {
|
|
||||||
if (nameToCoords != null && !nameToCoords.isEmpty() && !sprites.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File assetsDir = new File("assets");
|
|
||||||
List<String> assets = new ArrayList<>();
|
|
||||||
|
|
||||||
for (File dir : Objects.requireNonNull(assetsDir.listFiles())) {
|
|
||||||
assets.add(dir.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String asset : assets) {
|
|
||||||
try {
|
|
||||||
File f = new File(assetsDir.getAbsolutePath() + "/" + asset + "/textures/sprites");
|
|
||||||
assert f.mkdirs();
|
|
||||||
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(f, "sprites.json"))));
|
|
||||||
nameToCoords = new Gson().fromJson(br, Map.class);
|
|
||||||
br.close();
|
|
||||||
|
|
||||||
for (String key : nameToCoords.keySet()) {
|
|
||||||
try {
|
|
||||||
BufferedInputStream is = new BufferedInputStream(new FileInputStream(new File(f, key + ".png")));
|
|
||||||
BufferedImage img = ImageIO.read(is);
|
|
||||||
Category cat = Category.create(key, new ArrayList<>());
|
|
||||||
|
|
||||||
for (List<Double> list : nameToCoords.get(key)) {
|
|
||||||
int x = list.get(0).intValue();
|
|
||||||
int y = list.get(1).intValue();
|
|
||||||
BufferedImage child = img.getSubimage(x, y, 16, 16);
|
|
||||||
new Sprite(child, cat, nameToCoords.get(key).indexOf(list));
|
|
||||||
}
|
|
||||||
|
|
||||||
sprites.put(key, cat);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
System.err.println("Erreur lors de la lecture du sprite '" + key + "'");
|
|
||||||
t.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Category getCategory(String name) {
|
|
||||||
return sprites.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Category> getAllCategories() {
|
|
||||||
return new ArrayList<>(sprites.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,226 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.client.main;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.EditorAPI;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.RawMap;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister;
|
|
||||||
import fr.ynerant.leveleditor.frame.MainFrame;
|
|
||||||
import fr.ynerant.leveleditor.game.GameFrame;
|
|
||||||
import joptsimple.OptionParser;
|
|
||||||
import joptsimple.OptionSet;
|
|
||||||
import joptsimple.OptionSpec;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class principale qui lance le jeu
|
|
||||||
*
|
|
||||||
* @author ÿnérant
|
|
||||||
* @see #main(String...)
|
|
||||||
*/
|
|
||||||
public class Main {
|
|
||||||
/**
|
|
||||||
* Variable disant si le jeu est lancé en développement ou non.
|
|
||||||
*
|
|
||||||
* @see #isInDevelopmentMode()
|
|
||||||
* @see #main(String...)
|
|
||||||
* @since 0.1-aplha
|
|
||||||
*/
|
|
||||||
private static boolean DEV;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param args arguments du jeu. Possibilités :<br> <strong>--edit</strong> lancera un éditeur<br> <strong>--help</strong> lance l'aide affichant toutes les options possibles
|
|
||||||
* @see #launchEditMode()
|
|
||||||
* @since 0.1-alpha
|
|
||||||
*/
|
|
||||||
public static void main(String... args) {
|
|
||||||
System.setProperty("sun.java2d.noddraw", "true");
|
|
||||||
|
|
||||||
Locale.setDefault(Locale.FRANCE);
|
|
||||||
|
|
||||||
try {
|
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
new ExceptionInInitializerError("Erreur lors du changement de 'look and feel'").printStackTrace();
|
|
||||||
System.err.print("Caused by ");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
new File(Main.class.getResource("/assets").toURI());
|
|
||||||
DEV = true;
|
|
||||||
} catch (Throwable t) {
|
|
||||||
DEV = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkJava();
|
|
||||||
|
|
||||||
OptionParser parser = new OptionParser();
|
|
||||||
|
|
||||||
OptionSpec<String> edit = parser.accepts("edit", "Lancer l'\u00e9diteur de monde").withOptionalArg();
|
|
||||||
OptionSpec<String> help = parser.accepts("help", "Affiche ce menu d'aide").withOptionalArg().forHelp();
|
|
||||||
|
|
||||||
OptionSet set = parser.parse(args);
|
|
||||||
|
|
||||||
if (set.has(help)) {
|
|
||||||
try {
|
|
||||||
parser.printHelpOn(System.out);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
SpriteRegister.unpack();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
SpriteRegister.refreshAllSprites();
|
|
||||||
|
|
||||||
if (set.has(edit)) {
|
|
||||||
launchEditMode();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
launchFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkJava() {
|
|
||||||
if (GraphicsEnvironment.isHeadless()) {
|
|
||||||
HeadlessException ex = new HeadlessException("Impossible de lancer un jeu sans \u00e9cran !");
|
|
||||||
System.err.println("Cette application est un jeu, sans écran, elle aura du mal \u00e0 tourner ...");
|
|
||||||
ex.printStackTrace();
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Map.class.getDeclaredMethod("getOrDefault", Object.class, Object.class);
|
|
||||||
} catch (NoSuchMethodException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
JOptionPane.showMessageDialog(null, "<html>Cette application requiert <strong>Java 8</strong>.<br />La page de t\u00e9l\u00e9chargement va maintenant s'ouvrir.</html>");
|
|
||||||
JOptionPane.showMessageDialog(null, "<html>Si vous êtes certain que Java 8 est installé sur votre machine, assurez-vous qu'il n'y a pas de versions obsolètes de Java,<br />ou si vous êtes plus expérimentés si le path vers Java est bien défini vers la bonne version.</html>");
|
|
||||||
try {
|
|
||||||
if (Desktop.isDesktopSupported())
|
|
||||||
Desktop.getDesktop().browse(new URL("http://java.com/download").toURI());
|
|
||||||
else
|
|
||||||
JOptionPane.showMessageDialog(null, "<html>Votre machine ne supporte pas la classe Desktop, impossible d'ouvrir la page.<br />Rendez-vous y manuellement sur <a href=\"http://java.com/download\">http://java.com/download</a> pour installer Java.</html>");
|
|
||||||
} catch (IOException | URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lance la fenêtre principale
|
|
||||||
*
|
|
||||||
* @see #main(String...)
|
|
||||||
* @see #launchEditMode()
|
|
||||||
*/
|
|
||||||
private static void launchFrame() {
|
|
||||||
MainFrame.getInstance().setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Permet de lancer l'éditeur de carte
|
|
||||||
*
|
|
||||||
* @see #main(String...)
|
|
||||||
* @see #launchFrame()
|
|
||||||
* @since 0.1-aplha
|
|
||||||
*/
|
|
||||||
public static boolean launchEditMode() {
|
|
||||||
System.out.println("Lancement de l'\u00e9diteur de monde ...");
|
|
||||||
int baseWidth;
|
|
||||||
int baseHeight;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
String baseWidthStr = JOptionPane.showInputDialog(null, "Veuillez entrez le nombre de cases longueur de votre carte (0 pour annuler) :");
|
|
||||||
if (baseWidthStr == null)
|
|
||||||
return false;
|
|
||||||
baseWidth = Integer.parseInt(baseWidthStr) * 16;
|
|
||||||
if (baseWidth < 0)
|
|
||||||
throw new NumberFormatException();
|
|
||||||
if (baseWidth == 0)
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
String baseHeightStr = JOptionPane.showInputDialog("Veuillez entrez le nombre de cases hauteur de votre carte (0 pour annuler) :");
|
|
||||||
if (baseHeightStr == null)
|
|
||||||
return false;
|
|
||||||
baseHeight = Integer.parseInt(baseHeightStr) * 16;
|
|
||||||
if (baseHeight < 0)
|
|
||||||
throw new NumberFormatException();
|
|
||||||
if (baseHeight == 0)
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
width = baseWidth + (baseWidth / 16) + 1;
|
|
||||||
height = baseHeight + (baseHeight / 16) + 1;
|
|
||||||
|
|
||||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
Graphics2D g = image.createGraphics();
|
|
||||||
g.setColor(Color.white);
|
|
||||||
g.fillRect(0, 0, width, height);
|
|
||||||
g.setColor(Color.black);
|
|
||||||
g.drawLine(0, 0, width, 0);
|
|
||||||
g.drawLine(0, 0, 0, height);
|
|
||||||
for (int x = 17; x <= width; x += 17) {
|
|
||||||
g.drawLine(x, 0, x, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = 17; y <= height; y += 17) {
|
|
||||||
g.drawLine(0, y, width, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
RawMap rm = EditorAPI.toRawMap(baseWidth, baseHeight);
|
|
||||||
rm.setFont(image);
|
|
||||||
|
|
||||||
EditorAPI.open(rm);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean launchGameMode() {
|
|
||||||
System.out.println("Lancement du jeu ...");
|
|
||||||
JFileChooser jfc = EditorAPI.createJFC();
|
|
||||||
jfc.showOpenDialog(MainFrame.getInstance());
|
|
||||||
if (jfc.getSelectedFile() == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
RawMap map = EditorAPI.getRawMap(jfc.getSelectedFile());
|
|
||||||
|
|
||||||
new GameFrame(map);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accesseur disant si le jeu est lancé en développement ou non.
|
|
||||||
*
|
|
||||||
* @see #DEV
|
|
||||||
* @since 0.1-alpha
|
|
||||||
*/
|
|
||||||
public static boolean isInDevelopmentMode() {
|
|
||||||
return DEV;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
/**
|
|
||||||
* Ce package comprend uniquement la classe Main, qui lance l'application.
|
|
||||||
*
|
|
||||||
* @author ÿnérant
|
|
||||||
*/
|
|
||||||
package fr.ynerant.leveleditor.client.main;
|
|
|
@ -1,83 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.editor;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.Case;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.Collision;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
public class CollidPanel extends JPanel {
|
|
||||||
private static final long serialVersionUID = -138754019431984881L;
|
|
||||||
|
|
||||||
private final EditorFrame frame;
|
|
||||||
|
|
||||||
public CollidPanel(EditorFrame frame) {
|
|
||||||
super();
|
|
||||||
this.frame = frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map getMap() {
|
|
||||||
return frame.getMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
g.fillRect(0, 0, getWidth(), getHeight());
|
|
||||||
BufferedImage img = getMap().getFont();
|
|
||||||
int x = getWidth() / 2 - img.getWidth();
|
|
||||||
int y = getHeight() / 2 - img.getHeight();
|
|
||||||
int width = img.getWidth() * 2;
|
|
||||||
int height = img.getHeight() * 2;
|
|
||||||
g.drawImage(getMap().getFont(), x, y, width, height, null);
|
|
||||||
|
|
||||||
for (Case c : getMap().getAllCases()) {
|
|
||||||
if (isEmpty(c.getCoucheOne().getImage()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
g.drawImage(c.getCoucheOne().getImage(), x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
|
||||||
|
|
||||||
if (isEmpty(c.getCoucheTwo().getImage()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
g.drawImage(c.getCoucheTwo().getImage(), x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
|
||||||
|
|
||||||
if (isEmpty(c.getCoucheThree().getImage()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
g.drawImage(c.getCoucheThree().getImage(), x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Case c : getMap().getAllCases()) {
|
|
||||||
if (c.getCollision() != Collision.ANY) {
|
|
||||||
BufferedImage alpha = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
|
|
||||||
if (c.getCollision() == Collision.FULL) {
|
|
||||||
Graphics2D grap = alpha.createGraphics();
|
|
||||||
grap.setColor(new Color(0, 0, 0, 100));
|
|
||||||
grap.fillRect(0, 0, 16, 16);
|
|
||||||
grap.dispose();
|
|
||||||
} else if (c.getCollision() == Collision.PARTIAL) {
|
|
||||||
Graphics2D grap = alpha.createGraphics();
|
|
||||||
grap.setColor(new Color(255, 0, 255, 70));
|
|
||||||
grap.fillRect(0, 0, 16, 16);
|
|
||||||
grap.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
g.drawImage(alpha, x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isEmpty(BufferedImage image) {
|
|
||||||
int allrgba = 0;
|
|
||||||
|
|
||||||
for (int x = 0; x < image.getWidth(); ++x) {
|
|
||||||
for (int y = 0; y < image.getHeight(); ++y) {
|
|
||||||
allrgba += image.getRGB(x, y) + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return allrgba == 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,322 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.editor;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.EditorAPI;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.RawMap;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.Category;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.Sprite;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister;
|
|
||||||
import fr.ynerant.leveleditor.frame.listeners.*;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.event.ChangeEvent;
|
|
||||||
import javax.swing.event.ChangeListener;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class EditorFrame extends JFrame implements ChangeListener, ActionListener, WindowListener {
|
|
||||||
private static final long serialVersionUID = -2705122356101556462L;
|
|
||||||
|
|
||||||
private final Map map;
|
|
||||||
|
|
||||||
private final JMenuItem save = new JMenuItem("Sauvegarder");
|
|
||||||
private final JMenuItem saveAs = new JMenuItem("Sauvegarder sous ...");
|
|
||||||
private final JMenuItem exit = new JMenuItem("Quitter");
|
|
||||||
private final JRadioButtonMenuItem pen = new JRadioButtonMenuItem("Pinceau");
|
|
||||||
private final JRadioButtonMenuItem pot = new JRadioButtonMenuItem("Pot de peinture");
|
|
||||||
private final JTabbedPane tabs = new JTabbedPane();
|
|
||||||
private final CollidPanel tabColl;
|
|
||||||
private final MapPanel mapPanel;
|
|
||||||
private final JTabbedPane resources = new JTabbedPane();
|
|
||||||
private final JPanel couche1 = new JPanel();
|
|
||||||
private final JPanel couche2 = new JPanel();
|
|
||||||
private final JPanel couche3 = new JPanel();
|
|
||||||
final ButtonGroup group = new ButtonGroup();
|
|
||||||
private SpriteComp selectedSprite;
|
|
||||||
|
|
||||||
public EditorFrame(Map map) {
|
|
||||||
super("Level Editor");
|
|
||||||
this.map = map;
|
|
||||||
this.setSize(600, 600);
|
|
||||||
this.setPreferredSize(getSize());
|
|
||||||
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
|
||||||
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
|
|
||||||
this.setLocationRelativeTo(null);
|
|
||||||
this.addWindowListener(this);
|
|
||||||
JPanel content = new JPanel();
|
|
||||||
content.setLayout(new BorderLayout());
|
|
||||||
this.setContentPane(content);
|
|
||||||
this.setVisible(true);
|
|
||||||
this.setVisible(false);
|
|
||||||
|
|
||||||
JMenu fichier = new JMenu("Fichier");
|
|
||||||
fichier.setMnemonic(KeyEvent.VK_F + KeyEvent.ALT_DOWN_MASK);
|
|
||||||
|
|
||||||
JMenuItem nouveau = new JMenuItem("Nouveau");
|
|
||||||
nouveau.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_DOWN_MASK, true));
|
|
||||||
nouveau.addActionListener(new CreateMapListener());
|
|
||||||
fichier.add(nouveau);
|
|
||||||
|
|
||||||
JMenuItem open = new JMenuItem("Ouvrir");
|
|
||||||
open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK, true));
|
|
||||||
open.addActionListener(new OpenMapListener());
|
|
||||||
fichier.add(open);
|
|
||||||
|
|
||||||
fichier.addSeparator();
|
|
||||||
|
|
||||||
save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK, true));
|
|
||||||
save.addActionListener(this);
|
|
||||||
fichier.add(save);
|
|
||||||
|
|
||||||
saveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK, true));
|
|
||||||
saveAs.addActionListener(this);
|
|
||||||
fichier.add(saveAs);
|
|
||||||
|
|
||||||
fichier.addSeparator();
|
|
||||||
|
|
||||||
exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, KeyEvent.CTRL_DOWN_MASK, true));
|
|
||||||
exit.addActionListener(this);
|
|
||||||
fichier.add(exit);
|
|
||||||
|
|
||||||
JMenuBar menuBar = new JMenuBar();
|
|
||||||
menuBar.add(fichier);
|
|
||||||
|
|
||||||
pen.setSelected(true);
|
|
||||||
pen.addActionListener(this);
|
|
||||||
pot.addActionListener(this);
|
|
||||||
group.add(pen);
|
|
||||||
group.add(pot);
|
|
||||||
JMenu selectionMode = new JMenu("Mode de s\u00e9lection");
|
|
||||||
selectionMode.add(pen);
|
|
||||||
selectionMode.add(pot);
|
|
||||||
|
|
||||||
JMenu tools = new JMenu("Outils");
|
|
||||||
tools.setMnemonic(KeyEvent.VK_O + KeyEvent.ALT_DOWN_MASK);
|
|
||||||
|
|
||||||
tools.add(selectionMode);
|
|
||||||
|
|
||||||
menuBar.add(tools);
|
|
||||||
|
|
||||||
this.setJMenuBar(menuBar);
|
|
||||||
|
|
||||||
mapPanel = new MapPanel(this);
|
|
||||||
mapPanel.addMouseListener(new MapMouseListener(mapPanel, this));
|
|
||||||
mapPanel.addMouseMotionListener(new MapMouseListener(mapPanel, this));
|
|
||||||
|
|
||||||
tabColl = new CollidPanel(this);
|
|
||||||
tabColl.addMouseListener(new CollidMapMouseListener(tabColl, this));
|
|
||||||
tabColl.addMouseMotionListener(new CollidMapMouseListener(tabColl, this));
|
|
||||||
|
|
||||||
JScrollPane scrollMap = new JScrollPane(mapPanel);
|
|
||||||
scrollMap.getHorizontalScrollBar().setUnitIncrement(34);
|
|
||||||
scrollMap.getVerticalScrollBar().setUnitIncrement(34);
|
|
||||||
JScrollPane scrollCollidMap = new JScrollPane(tabColl);
|
|
||||||
scrollCollidMap.getHorizontalScrollBar().setUnitIncrement(34);
|
|
||||||
scrollCollidMap.getVerticalScrollBar().setUnitIncrement(34);
|
|
||||||
|
|
||||||
tabs.addTab("Carte", scrollMap);
|
|
||||||
JPanel tabEvents = new JPanel();
|
|
||||||
tabs.addTab("\u00c9vennments", new JScrollPane(tabEvents));
|
|
||||||
tabs.addTab("Collisions", scrollCollidMap);
|
|
||||||
tabs.addChangeListener(this);
|
|
||||||
|
|
||||||
content.add(tabs, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
couche1.setLayout(new WrapLayout(WrapLayout.LEFT));
|
|
||||||
couche2.setLayout(new WrapLayout(WrapLayout.LEFT));
|
|
||||||
couche3.setLayout(new WrapLayout(WrapLayout.LEFT));
|
|
||||||
|
|
||||||
JScrollPane scroll1 = new JScrollPane(couche1, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
|
||||||
JScrollPane scroll2 = new JScrollPane(couche2, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
|
||||||
JScrollPane scroll3 = new JScrollPane(couche3, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
|
||||||
|
|
||||||
scroll1.getHorizontalScrollBar().setMaximum(0);
|
|
||||||
scroll2.getHorizontalScrollBar().setMaximum(0);
|
|
||||||
scroll3.getHorizontalScrollBar().setMaximum(0);
|
|
||||||
|
|
||||||
resources.addTab("", new ImageIcon(new File("assets/leveleditor/textures/layer 1.png").getAbsolutePath()), scroll1);
|
|
||||||
resources.addTab("", new ImageIcon(new File("assets/leveleditor/textures/layer 2.png").getAbsolutePath()), scroll2);
|
|
||||||
resources.addTab("", new ImageIcon(new File("assets/leveleditor/textures/layer 3.png").getAbsolutePath()), scroll3);
|
|
||||||
resources.addChangeListener(this);
|
|
||||||
resources.setBackgroundAt(0, Color.white);
|
|
||||||
resources.setBackgroundAt(1, Color.white);
|
|
||||||
resources.setBackgroundAt(2, Color.white);
|
|
||||||
|
|
||||||
content.add(resources, BorderLayout.EAST);
|
|
||||||
|
|
||||||
resize();
|
|
||||||
|
|
||||||
drawResources();
|
|
||||||
|
|
||||||
revalidate();
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawResources() {
|
|
||||||
couche1.removeAll();
|
|
||||||
couche2.removeAll();
|
|
||||||
couche3.removeAll();
|
|
||||||
|
|
||||||
if (couche1.getComponents().length > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (couche1.getWidth() == 0 || couche2.getWidth() == 0 || couche3.getWidth() == 0) {
|
|
||||||
couche1.repaint();
|
|
||||||
couche2.repaint();
|
|
||||||
couche3.repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Category cat : SpriteRegister.getAllCategories()) {
|
|
||||||
for (Sprite spr : cat.getSprites()) {
|
|
||||||
SpriteComp sprc1 = new SpriteComp(spr, 0);
|
|
||||||
SpriteComp sprc2 = new SpriteComp(spr, 1);
|
|
||||||
SpriteComp sprc3 = new SpriteComp(spr, 2);
|
|
||||||
sprc1.addMouseListener(new SpriteMouseListener(sprc1, this));
|
|
||||||
sprc2.addMouseListener(new SpriteMouseListener(sprc2, this));
|
|
||||||
sprc3.addMouseListener(new SpriteMouseListener(sprc3, this));
|
|
||||||
couche1.add(sprc1);
|
|
||||||
couche2.add(sprc2);
|
|
||||||
couche3.add(sprc3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
couche1.revalidate();
|
|
||||||
couche2.revalidate();
|
|
||||||
couche3.revalidate();
|
|
||||||
couche1.repaint();
|
|
||||||
couche2.repaint();
|
|
||||||
couche3.repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resize() {
|
|
||||||
|
|
||||||
int cursorPos = ((JScrollPane) resources.getSelectedComponent()).getVerticalScrollBar().getValue();
|
|
||||||
tabs.setPreferredSize(new Dimension(getWidth(), getHeight() / 5));
|
|
||||||
tabs.setLocation(0, 0);
|
|
||||||
BufferedImage img = getMap().getFont();
|
|
||||||
int width = img.getWidth() * 2;
|
|
||||||
int height = img.getHeight() * 2;
|
|
||||||
mapPanel.setPreferredSize(new Dimension(width, height));
|
|
||||||
mapPanel.setLocation(0, getHeight() / 5);
|
|
||||||
tabColl.setPreferredSize(new Dimension(width, height));
|
|
||||||
tabColl.setLocation(0, getHeight() / 5);
|
|
||||||
resources.setPreferredSize(new Dimension(getWidth() / 4 - 15, getHeight() / 5 * 4 - 40));
|
|
||||||
resources.setLocation(getWidth() / 4 * 3, getHeight() / 5);
|
|
||||||
|
|
||||||
JScrollPane scroll1 = (JScrollPane) resources.getComponent(0);
|
|
||||||
JScrollPane scroll2 = (JScrollPane) resources.getComponent(1);
|
|
||||||
JScrollPane scroll3 = (JScrollPane) resources.getComponent(2);
|
|
||||||
|
|
||||||
scroll1.getHorizontalScrollBar().setMaximum(0);
|
|
||||||
scroll2.getHorizontalScrollBar().setMaximum(0);
|
|
||||||
scroll3.getHorizontalScrollBar().setMaximum(0);
|
|
||||||
|
|
||||||
drawResources();
|
|
||||||
|
|
||||||
((JScrollPane) resources.getSelectedComponent()).getVerticalScrollBar().setValue(cursorPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map getMap() {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SpriteComp getSelectedSprite() {
|
|
||||||
return selectedSprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSelectedSprite(SpriteComp sprite) {
|
|
||||||
this.selectedSprite = sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateChanged(ChangeEvent event) {
|
|
||||||
if (event.getSource() == resources) {
|
|
||||||
if (getSelectedLayerIndex() == 0) {
|
|
||||||
resources.setBackgroundAt(0, Color.white);
|
|
||||||
resources.setBackgroundAt(1, Color.white);
|
|
||||||
resources.setBackgroundAt(2, Color.white);
|
|
||||||
} else if (getSelectedLayerIndex() == 1) {
|
|
||||||
resources.setBackgroundAt(0, Color.black);
|
|
||||||
resources.setBackgroundAt(1, Color.white);
|
|
||||||
resources.setBackgroundAt(2, Color.white);
|
|
||||||
} else if (getSelectedLayerIndex() == 2) {
|
|
||||||
resources.setBackgroundAt(0, Color.black);
|
|
||||||
resources.setBackgroundAt(1, Color.black);
|
|
||||||
resources.setBackgroundAt(2, Color.white);
|
|
||||||
}
|
|
||||||
|
|
||||||
repaint();
|
|
||||||
} else if (event.getSource() == tabs) {
|
|
||||||
resources.setEnabled(tabs.getSelectedIndex() == 0);
|
|
||||||
couche1.setEnabled(resources.isEnabled());
|
|
||||||
couche2.setEnabled(resources.isEnabled());
|
|
||||||
couche3.setEnabled(resources.isEnabled());
|
|
||||||
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSelectedLayerIndex() {
|
|
||||||
return resources.getSelectedIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent event) {
|
|
||||||
if (event.getSource() == save) {
|
|
||||||
EditorAPI.save(RawMap.create(map));
|
|
||||||
} else if (event.getSource() == saveAs) {
|
|
||||||
EditorAPI.saveAs(RawMap.create(map));
|
|
||||||
} else if (event.getSource() == exit) {
|
|
||||||
int result = JOptionPane.showConfirmDialog(null, "Voulez-vous sauvegarder votre carte avant de quitter ? Toute modification sera perdue", "Confirmation", JOptionPane.YES_NO_CANCEL_OPTION);
|
|
||||||
|
|
||||||
if (result == 0)
|
|
||||||
save.doClick();
|
|
||||||
|
|
||||||
if (result != 2)
|
|
||||||
dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSelectedPaintingMode() {
|
|
||||||
return pen.isSelected() ? 0 : pot.isSelected() ? 1 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void windowActivated(WindowEvent event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void windowClosed(WindowEvent event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void windowClosing(WindowEvent event) {
|
|
||||||
int result = JOptionPane.showConfirmDialog(null, "Voulez-vous sauvegarder avant de quitter ?", "Confirmation", JOptionPane.YES_NO_CANCEL_OPTION);
|
|
||||||
|
|
||||||
if (result == 0) {
|
|
||||||
EditorAPI.save(RawMap.create(map));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != 2) {
|
|
||||||
dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void windowDeactivated(WindowEvent event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void windowDeiconified(WindowEvent event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void windowIconified(WindowEvent event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void windowOpened(WindowEvent event) {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.editor;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.Case;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.RawCase;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.RawMap;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Map {
|
|
||||||
@Deprecated
|
|
||||||
private static List<Case> cases;
|
|
||||||
private final EditorFrame frame;
|
|
||||||
private final int width;
|
|
||||||
private final int height;
|
|
||||||
private final java.util.Map<Integer, java.util.Map<Integer, Case>> casesMap = new HashMap<>();
|
|
||||||
private final transient BufferedImage font;
|
|
||||||
|
|
||||||
public Map(RawMap raw) {
|
|
||||||
cases = new ArrayList<>();
|
|
||||||
this.width = raw.getWidth();
|
|
||||||
this.height = raw.getHeight();
|
|
||||||
this.font = raw.getFont();
|
|
||||||
|
|
||||||
for (RawCase rc : raw.getCases()) {
|
|
||||||
cases.add(Case.create(rc.getPosX(), rc.getPosY(), SpriteRegister.getCategory(rc.getCoucheOne().getCategory()).getSprites().get(rc.getCoucheOne().getIndex()), SpriteRegister.getCategory(rc.getCoucheTwo().getCategory()).getSprites().get(rc.getCoucheTwo().getIndex()), SpriteRegister.getCategory(rc.getCoucheThree().getCategory()).getSprites().get(rc.getCoucheThree().getIndex()), rc.getCollision()));
|
|
||||||
}
|
|
||||||
|
|
||||||
reorganizeMap();
|
|
||||||
|
|
||||||
frame = new EditorFrame(this);
|
|
||||||
|
|
||||||
getFrame().setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EditorFrame getFrame() {
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWidth() {
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHeight() {
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Case getCase(int x, int y) {
|
|
||||||
return casesMap.getOrDefault(x, new HashMap<>()).get(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCase(int x, int y, Case c) {
|
|
||||||
casesMap.get(x).put(y, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BufferedImage getFont() {
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reorganizeMap() {
|
|
||||||
for (int i = 0; i < width; ++i) {
|
|
||||||
casesMap.put(i, new HashMap<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Case c : cases) {
|
|
||||||
setCase(c.getPosX(), c.getPosY(), c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Case> getAllCases() {
|
|
||||||
List<Case> list = new ArrayList<>();
|
|
||||||
|
|
||||||
for (java.util.Map<Integer, Case> l : casesMap.values()) {
|
|
||||||
list.addAll(l.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.editor;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.Case;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
|
|
||||||
public class MapPanel extends JPanel {
|
|
||||||
private static final long serialVersionUID = 2629019576253690557L;
|
|
||||||
|
|
||||||
private final EditorFrame frame;
|
|
||||||
|
|
||||||
public MapPanel(EditorFrame frame) {
|
|
||||||
super();
|
|
||||||
this.frame = frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map getMap() {
|
|
||||||
return frame.getMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
g.fillRect(0, 0, getWidth(), getHeight());
|
|
||||||
BufferedImage img = getMap().getFont();
|
|
||||||
int x = getWidth() / 2 - img.getWidth();
|
|
||||||
int y = getHeight() / 2 - img.getHeight();
|
|
||||||
int width = img.getWidth() * 2;
|
|
||||||
int height = img.getHeight() * 2;
|
|
||||||
g.drawImage(getMap().getFont(), x, y, width, height, null);
|
|
||||||
|
|
||||||
for (Case c : getMap().getAllCases()) {
|
|
||||||
// BufferedImage image;
|
|
||||||
|
|
||||||
if (!isEmpty(c.getCoucheOne().getImage())) {
|
|
||||||
g.drawImage(c.getCoucheOne().getImage(), x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
|
||||||
}
|
|
||||||
/* if (frame.getSelectedLayerIndex() != 0)
|
|
||||||
{
|
|
||||||
image = recalculateAplha(c.getCoucheOne().getImage(), 0);
|
|
||||||
g.drawImage(image, x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (!isEmpty(c.getCoucheTwo().getImage()) && frame.getSelectedLayerIndex() >= 1) {
|
|
||||||
g.drawImage(c.getCoucheTwo().getImage(), x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
|
||||||
}
|
|
||||||
/* if (frame.getSelectedLayerIndex() != 1)
|
|
||||||
{
|
|
||||||
image = recalculateAplha(c.getCoucheTwo().getImage(), 1);
|
|
||||||
g.drawImage(image, x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (!isEmpty(c.getCoucheThree().getImage()) && frame.getSelectedLayerIndex() == 2) {
|
|
||||||
g.drawImage(c.getCoucheThree().getImage(), x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
|
||||||
}
|
|
||||||
/* if (frame.getSelectedLayerIndex() != 2)
|
|
||||||
{
|
|
||||||
image = recalculateAplha(c.getCoucheThree().getImage(), 2);
|
|
||||||
g.drawImage(image, x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
|
||||||
private boolean isEmpty(BufferedImage image) {
|
|
||||||
int allrgba = 0;
|
|
||||||
|
|
||||||
for (int x = 0; x < image.getWidth(); ++x) {
|
|
||||||
for (int y = 0; y < image.getHeight(); ++y) {
|
|
||||||
allrgba += image.getRGB(x, y) + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return allrgba == 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.editor;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.Sprite;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
|
|
||||||
public class SpriteComp extends JComponent {
|
|
||||||
private static final long serialVersionUID = -6512257366877053285L;
|
|
||||||
|
|
||||||
private final Sprite sprite;
|
|
||||||
private final int couche;
|
|
||||||
private boolean selected;
|
|
||||||
|
|
||||||
public SpriteComp(Sprite sprite, int couche) {
|
|
||||||
super();
|
|
||||||
this.sprite = sprite;
|
|
||||||
this.couche = couche;
|
|
||||||
this.setMinimumSize(new Dimension(32, 32));
|
|
||||||
this.setMaximumSize(new Dimension(32, 32));
|
|
||||||
this.setPreferredSize(new Dimension(32, 32));
|
|
||||||
this.setSize(new Dimension(32, 32));
|
|
||||||
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Sprite getSprite() {
|
|
||||||
return sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCouche() {
|
|
||||||
return couche;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSelected() {
|
|
||||||
return selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSelected(boolean selected) {
|
|
||||||
this.selected = selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
super.paintComponent(g);
|
|
||||||
|
|
||||||
g.setColor(Color.white);
|
|
||||||
g.fillRect(0, 0, getWidth(), getHeight());
|
|
||||||
g.drawImage(sprite.getImage(), 0, 0, 32, 32, Color.white, null);
|
|
||||||
|
|
||||||
if (isSelected()) {
|
|
||||||
g.setColor(Color.black);
|
|
||||||
g.drawLine(0, 0, getWidth() - 1, 0);
|
|
||||||
g.drawLine(0, 0, 0, getHeight() - 1);
|
|
||||||
g.drawLine(0, getHeight() - 1, getWidth() - 1, getHeight() - 1);
|
|
||||||
g.drawLine(getWidth() - 1, 0, getWidth() - 1, getHeight() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.editor;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
|
|
||||||
public class WrapLayout extends FlowLayout {
|
|
||||||
private static final long serialVersionUID = 8777237960365591646L;
|
|
||||||
|
|
||||||
public WrapLayout(int align) {
|
|
||||||
super(align);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension preferredLayoutSize(Container target) {
|
|
||||||
return layoutSize(target, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension minimumLayoutSize(Container target) {
|
|
||||||
Dimension minimum = layoutSize(target, false);
|
|
||||||
minimum.width -= (getHgap() + 1);
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dimension layoutSize(Container target, boolean preferred) {
|
|
||||||
synchronized (target.getTreeLock()) {
|
|
||||||
int targetWidth = target.getSize().width;
|
|
||||||
|
|
||||||
if (targetWidth == 0)
|
|
||||||
targetWidth = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
int hgap = getHgap();
|
|
||||||
int vgap = getVgap();
|
|
||||||
Insets insets = target.getInsets();
|
|
||||||
int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
|
|
||||||
int maxWidth = targetWidth - horizontalInsetsAndGap;
|
|
||||||
|
|
||||||
Dimension dim = new Dimension(0, 0);
|
|
||||||
int rowWidth = 0;
|
|
||||||
int rowHeight = 0;
|
|
||||||
|
|
||||||
int nmembers = target.getComponentCount();
|
|
||||||
|
|
||||||
for (int i = 0; i < nmembers; i++) {
|
|
||||||
Component m = target.getComponent(i);
|
|
||||||
|
|
||||||
if (m.isVisible()) {
|
|
||||||
Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
|
|
||||||
|
|
||||||
if (rowWidth + d.width > maxWidth) {
|
|
||||||
addRow(dim, rowWidth, rowHeight);
|
|
||||||
rowWidth = 0;
|
|
||||||
rowHeight = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rowWidth != 0) {
|
|
||||||
rowWidth += hgap;
|
|
||||||
}
|
|
||||||
|
|
||||||
rowWidth += d.width;
|
|
||||||
rowHeight = Math.max(rowHeight, d.height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addRow(dim, rowWidth, rowHeight);
|
|
||||||
|
|
||||||
dim.width += horizontalInsetsAndGap;
|
|
||||||
dim.height += insets.top + insets.bottom + vgap * 2;
|
|
||||||
|
|
||||||
Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
|
|
||||||
if (scrollPane != null) {
|
|
||||||
dim.width -= (hgap + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dim;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addRow(Dimension dim, int rowWidth, int rowHeight) {
|
|
||||||
dim.width = Math.max(dim.width, rowWidth);
|
|
||||||
|
|
||||||
if (dim.height > 0) {
|
|
||||||
dim.height += getVgap();
|
|
||||||
}
|
|
||||||
|
|
||||||
dim.height += rowHeight;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,102 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.frame;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.client.main.Main;
|
|
||||||
import fr.ynerant.leveleditor.frame.listeners.ChangeLAFListener;
|
|
||||||
import fr.ynerant.leveleditor.frame.listeners.CreateMapListener;
|
|
||||||
import fr.ynerant.leveleditor.frame.listeners.OpenMapListener;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.KeyEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fenêtre principale du jeu
|
|
||||||
*
|
|
||||||
* @author ÿnérant
|
|
||||||
*/
|
|
||||||
public class MainFrame extends JFrame {
|
|
||||||
/**
|
|
||||||
* ID de série
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = -3168760121879418534L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instance unique principale
|
|
||||||
*
|
|
||||||
* @see #MainFrame()
|
|
||||||
* @see #getInstance()
|
|
||||||
*/
|
|
||||||
private static MainFrame INSTANCE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructeur
|
|
||||||
*
|
|
||||||
* @see Main#launchFrame()
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("JavadocReference")
|
|
||||||
private MainFrame() {
|
|
||||||
super();
|
|
||||||
System.out.println("Initialisation de la fen\u00eatre");
|
|
||||||
this.setTitle("Level Editor");
|
|
||||||
this.setPreferredSize(new Dimension(1000, 800));
|
|
||||||
this.setSize(800, 700);
|
|
||||||
this.setLocationRelativeTo(null);
|
|
||||||
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
|
|
||||||
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
|
|
||||||
JMenu fichier = new JMenu("Fichier");
|
|
||||||
fichier.setMnemonic(KeyEvent.VK_F + KeyEvent.ALT_DOWN_MASK);
|
|
||||||
JMenu display = new JMenu("Affichage");
|
|
||||||
display.setMnemonic(KeyEvent.VK_A + KeyEvent.ALT_DOWN_MASK);
|
|
||||||
|
|
||||||
JMenuItem createMap = new JMenuItem("Cr\u00e9er");
|
|
||||||
createMap.addActionListener(new CreateMapListener());
|
|
||||||
JMenu editMaps = new JMenu("Cartes");
|
|
||||||
editMaps.add(createMap);
|
|
||||||
JMenuItem openMap = new JMenuItem("Ouvrir");
|
|
||||||
openMap.addActionListener(new OpenMapListener());
|
|
||||||
editMaps.add(openMap);
|
|
||||||
|
|
||||||
fichier.add(editMaps);
|
|
||||||
|
|
||||||
JMenuItem systemLAF = new JMenuItem("Apparence syst\u00e8me");
|
|
||||||
systemLAF.addActionListener(new ChangeLAFListener(systemLAF, this));
|
|
||||||
JMenu changeLAF = new JMenu("Modfier l'apparence");
|
|
||||||
changeLAF.add(systemLAF);
|
|
||||||
JMenuItem javaLAF = new JMenuItem("Apparence Java");
|
|
||||||
javaLAF.addActionListener(new ChangeLAFListener(javaLAF, this));
|
|
||||||
changeLAF.add(javaLAF);
|
|
||||||
JMenuItem darkLAF = new JMenuItem("Apparence sombre");
|
|
||||||
darkLAF.addActionListener(new ChangeLAFListener(darkLAF, this));
|
|
||||||
changeLAF.add(darkLAF);
|
|
||||||
|
|
||||||
display.add(changeLAF);
|
|
||||||
|
|
||||||
JMenuBar menuBar = new JMenuBar();
|
|
||||||
menuBar.add(fichier);
|
|
||||||
menuBar.add(display);
|
|
||||||
|
|
||||||
this.setJMenuBar(menuBar);
|
|
||||||
|
|
||||||
JButton start = new JButton("Commencer la partie !");
|
|
||||||
start.addActionListener(actionEvent -> {
|
|
||||||
if (Main.launchGameMode())
|
|
||||||
getInstance().dispose();
|
|
||||||
});
|
|
||||||
this.setContentPane(start);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cet accesseur renvoie l'accesseur unique de la classe
|
|
||||||
*
|
|
||||||
* @return l'instance unique de la classe
|
|
||||||
* @see #INSTANCE
|
|
||||||
* @see #MainFrame()
|
|
||||||
*/
|
|
||||||
public static MainFrame getInstance() {
|
|
||||||
if (INSTANCE == null)
|
|
||||||
return INSTANCE = new MainFrame();
|
|
||||||
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.frame.listeners;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.frame.MainFrame;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
|
|
||||||
public class ChangeLAFListener implements ActionListener {
|
|
||||||
private final JMenuItem item;
|
|
||||||
private final JFrame frame;
|
|
||||||
|
|
||||||
public ChangeLAFListener(JMenuItem LAF, MainFrame f) {
|
|
||||||
this.item = LAF;
|
|
||||||
this.frame = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent event) {
|
|
||||||
if (item.getText().toLowerCase().contains("sys")) {
|
|
||||||
try {
|
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
new ExceptionInInitializerError("Erreur lors du changement de 'look and feel'").printStackTrace();
|
|
||||||
System.err.print("Caused by ");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
SwingUtilities.updateComponentTreeUI(frame);
|
|
||||||
} else if (item.getText().toLowerCase().contains("java")) {
|
|
||||||
try {
|
|
||||||
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
new ExceptionInInitializerError("Erreur lors du changement de 'look and feel'").printStackTrace();
|
|
||||||
System.err.print("Caused by ");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
SwingUtilities.updateComponentTreeUI(frame);
|
|
||||||
} else if (item.getText().toLowerCase().contains("sombre")) {
|
|
||||||
try {
|
|
||||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
|
|
||||||
} catch (Exception e) {
|
|
||||||
new ExceptionInInitializerError("Erreur lors du changement de 'look and feel'").printStackTrace();
|
|
||||||
System.err.print("Caused by ");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
SwingUtilities.updateComponentTreeUI(frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.frame.listeners;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.Case;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.Collision;
|
|
||||||
import fr.ynerant.leveleditor.editor.CollidPanel;
|
|
||||||
import fr.ynerant.leveleditor.editor.EditorFrame;
|
|
||||||
import fr.ynerant.leveleditor.editor.Map;
|
|
||||||
|
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
|
|
||||||
public class CollidMapMouseListener extends MouseAdapter {
|
|
||||||
private final EditorFrame frame;
|
|
||||||
private final CollidPanel panel;
|
|
||||||
|
|
||||||
public CollidMapMouseListener(CollidPanel panel, EditorFrame frame) {
|
|
||||||
this.frame = frame;
|
|
||||||
this.panel = panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EditorFrame getFrame() {
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent event) {
|
|
||||||
Map map = getFrame().getMap();
|
|
||||||
|
|
||||||
int x = panel.getWidth() / 2 - map.getFont().getWidth();
|
|
||||||
int y = panel.getHeight() / 2 - map.getFont().getHeight();
|
|
||||||
Case c;
|
|
||||||
|
|
||||||
if ((c = map.getCase((event.getX() - x + 2) / 34, (event.getY() - y + 2) / 34)) != null && event.getX() - x >= 2 && event.getY() - y >= 2) {
|
|
||||||
int colIndex = c.getCollision().ordinal();
|
|
||||||
int newColIndex = colIndex + 1;
|
|
||||||
if (newColIndex >= Collision.values().length)
|
|
||||||
newColIndex = 0;
|
|
||||||
Collision col = Collision.values()[newColIndex];
|
|
||||||
Case n = Case.create(c.getPosX(), c.getPosY(), c.getCoucheOne(), c.getCoucheTwo(), c.getCoucheThree(), col);
|
|
||||||
|
|
||||||
map.setCase((event.getX() - x + 2) / 34, (event.getY() - y + 2) / 34, n);
|
|
||||||
panel.repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.frame.listeners;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.client.main.Main;
|
|
||||||
import fr.ynerant.leveleditor.frame.MainFrame;
|
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ÿnérant
|
|
||||||
*/
|
|
||||||
public class CreateMapListener implements ActionListener {
|
|
||||||
/* !CodeTemplates.overridecomment.nonjd!
|
|
||||||
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent event) {
|
|
||||||
if (Main.launchEditMode())
|
|
||||||
MainFrame.getInstance().dispose();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.frame.listeners;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.Case;
|
|
||||||
import fr.ynerant.leveleditor.editor.EditorFrame;
|
|
||||||
import fr.ynerant.leveleditor.editor.Map;
|
|
||||||
import fr.ynerant.leveleditor.editor.MapPanel;
|
|
||||||
|
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
|
|
||||||
public class MapMouseListener extends MouseAdapter {
|
|
||||||
private final EditorFrame frame;
|
|
||||||
private final MapPanel panel;
|
|
||||||
|
|
||||||
public MapMouseListener(MapPanel panel, EditorFrame frame) {
|
|
||||||
this.frame = frame;
|
|
||||||
this.panel = panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EditorFrame getFrame() {
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(MouseEvent event) {
|
|
||||||
if (frame.getSelectedPaintingMode() == 0) {
|
|
||||||
Map map = getFrame().getMap();
|
|
||||||
|
|
||||||
int x = panel.getWidth() / 2 - map.getFont().getWidth();
|
|
||||||
int y = panel.getHeight() / 2 - map.getFont().getHeight();
|
|
||||||
Case c;
|
|
||||||
|
|
||||||
if ((c = map.getCase((event.getX() - x + 2) / 34, (event.getY() - y + 2) / 34)) != null && event.getX() - x >= 2 && event.getY() - y >= 2) {
|
|
||||||
if (getFrame().getSelectedSprite() != null) {
|
|
||||||
Case n;
|
|
||||||
|
|
||||||
switch (getFrame().getSelectedSprite().getCouche()) {
|
|
||||||
case 0:
|
|
||||||
n = Case.create(c.getPosX(), c.getPosY(), getFrame().getSelectedSprite().getSprite(), c.getCoucheTwo(), c.getCoucheThree(), c.getCollision());
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
n = Case.create(c.getPosX(), c.getPosY(), c.getCoucheOne(), getFrame().getSelectedSprite().getSprite(), c.getCoucheThree(), c.getCollision());
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
n = Case.create(c.getPosX(), c.getPosY(), c.getCoucheOne(), c.getCoucheTwo(), getFrame().getSelectedSprite().getSprite(), c.getCollision());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
n = c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
map.setCase(n.getPosX(), n.getPosY(), n);
|
|
||||||
panel.repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (frame.getSelectedPaintingMode() == 1) {
|
|
||||||
for (Case c : getFrame().getMap().getAllCases()) {
|
|
||||||
Map map = getFrame().getMap();
|
|
||||||
|
|
||||||
if (getFrame().getSelectedSprite() != null) {
|
|
||||||
if (getFrame().getSelectedSprite().getCouche() - 1 > getFrame().getSelectedLayerIndex())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Case n;
|
|
||||||
|
|
||||||
switch (getFrame().getSelectedSprite().getCouche()) {
|
|
||||||
case 0:
|
|
||||||
n = Case.create(c.getPosX(), c.getPosY(), getFrame().getSelectedSprite().getSprite(), c.getCoucheTwo(), c.getCoucheThree(), c.getCollision());
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
n = Case.create(c.getPosX(), c.getPosY(), c.getCoucheOne(), getFrame().getSelectedSprite().getSprite(), c.getCoucheThree(), c.getCollision());
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
n = Case.create(c.getPosX(), c.getPosY(), c.getCoucheOne(), c.getCoucheTwo(), getFrame().getSelectedSprite().getSprite(), c.getCollision());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
n = c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
map.setCase(n.getPosX(), n.getPosY(), n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panel.repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDragged(MouseEvent event) {
|
|
||||||
if (frame.getSelectedPaintingMode() == 0) {
|
|
||||||
mouseClicked(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.frame.listeners;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.EditorAPI;
|
|
||||||
import fr.ynerant.leveleditor.frame.MainFrame;
|
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
|
|
||||||
public class OpenMapListener implements ActionListener {
|
|
||||||
/* !CodeTemplates.overridecomment.nonjd!
|
|
||||||
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent event) {
|
|
||||||
if (EditorAPI.open() != null)
|
|
||||||
MainFrame.getInstance().dispose();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.frame.listeners;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.editor.EditorFrame;
|
|
||||||
import fr.ynerant.leveleditor.editor.SpriteComp;
|
|
||||||
|
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
|
|
||||||
public class SpriteMouseListener extends MouseAdapter {
|
|
||||||
private final SpriteComp sprite;
|
|
||||||
private final EditorFrame frame;
|
|
||||||
|
|
||||||
public SpriteMouseListener(SpriteComp sprc, EditorFrame frame) {
|
|
||||||
this.sprite = sprc;
|
|
||||||
this.frame = frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent event) {
|
|
||||||
if (frame.getSelectedSprite() != null) {
|
|
||||||
frame.getSelectedSprite().setSelected(false);
|
|
||||||
frame.getSelectedSprite().repaint();
|
|
||||||
}
|
|
||||||
frame.setSelectedSprite(sprite);
|
|
||||||
sprite.setSelected(true);
|
|
||||||
sprite.repaint();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,237 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.game;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.Collision;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.RawCase;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.RawMap;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.Sprite;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister;
|
|
||||||
import fr.ynerant.leveleditor.editor.CollidPanel;
|
|
||||||
import fr.ynerant.leveleditor.game.mobs.Mob;
|
|
||||||
import fr.ynerant.leveleditor.game.towers.AutoTower;
|
|
||||||
import fr.ynerant.leveleditor.game.towers.BasicTower;
|
|
||||||
import fr.ynerant.leveleditor.game.towers.NullTower;
|
|
||||||
import fr.ynerant.leveleditor.game.towers.Tower;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.event.MouseListener;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class GameFrame extends JFrame {
|
|
||||||
private final Random RANDOM = new Random();
|
|
||||||
private final RawMap map;
|
|
||||||
|
|
||||||
private int round = 0;
|
|
||||||
private int hp = 5;
|
|
||||||
private int reward = 20;
|
|
||||||
private final List<Mob> mobs = new ArrayList<>();
|
|
||||||
private final List<Tower> towers = new ArrayList<>();
|
|
||||||
|
|
||||||
private final JRadioButton basicTower;
|
|
||||||
private final JRadioButton nullTower;
|
|
||||||
private final JRadioButton autoTower;
|
|
||||||
private final JLabel waveLabel;
|
|
||||||
private final JLabel nbMobsLabel;
|
|
||||||
private final JLabel hpLabel;
|
|
||||||
private final JLabel rewardLabel;
|
|
||||||
private final JLabel winLabel;
|
|
||||||
|
|
||||||
public GameFrame(RawMap map) {
|
|
||||||
super("Jeu");
|
|
||||||
|
|
||||||
this.map = map;
|
|
||||||
this.setSize(600, 600);
|
|
||||||
this.setPreferredSize(getSize());
|
|
||||||
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
|
|
||||||
this.setLocationRelativeTo(null);
|
|
||||||
|
|
||||||
JPanel root = new JPanel();
|
|
||||||
root.setLayout(new BorderLayout());
|
|
||||||
this.setContentPane(root);
|
|
||||||
|
|
||||||
JPanel pane = new JPanel();
|
|
||||||
pane.setLayout(new GridLayout(8, 1));
|
|
||||||
root.add(pane, BorderLayout.SOUTH);
|
|
||||||
|
|
||||||
Grid grid = new Grid();
|
|
||||||
grid.setSize(map.getWidth(), map.getHeight());
|
|
||||||
grid.setPreferredSize(grid.getSize());
|
|
||||||
grid.setMinimumSize(grid.getSize());
|
|
||||||
grid.setMaximumSize(grid.getSize());
|
|
||||||
root.add(grid, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
ButtonGroup towerSelect = new ButtonGroup();
|
|
||||||
|
|
||||||
basicTower = new JRadioButton("Tour basique (" + new BasicTower(0, 0).getPrice() + " pièces)");
|
|
||||||
basicTower.setSelected(true);
|
|
||||||
towerSelect.add(basicTower);
|
|
||||||
pane.add(basicTower);
|
|
||||||
|
|
||||||
nullTower = new JRadioButton("Tour nulle (" + new NullTower(0, 0).getPrice() + " pièces)");
|
|
||||||
towerSelect.add(nullTower);
|
|
||||||
pane.add(nullTower);
|
|
||||||
|
|
||||||
autoTower = new JRadioButton("Tour automatique (" + new AutoTower(0, 0).getPrice() + " pièces)");
|
|
||||||
towerSelect.add(autoTower);
|
|
||||||
pane.add(autoTower);
|
|
||||||
|
|
||||||
waveLabel = new JLabel();
|
|
||||||
pane.add(waveLabel);
|
|
||||||
|
|
||||||
nbMobsLabel = new JLabel();
|
|
||||||
pane.add(nbMobsLabel);
|
|
||||||
|
|
||||||
hpLabel = new JLabel();
|
|
||||||
pane.add(hpLabel);
|
|
||||||
|
|
||||||
rewardLabel = new JLabel();
|
|
||||||
pane.add(rewardLabel);
|
|
||||||
|
|
||||||
winLabel = new JLabel();
|
|
||||||
pane.add(winLabel);
|
|
||||||
|
|
||||||
setVisible(true);
|
|
||||||
|
|
||||||
new Thread(() -> {
|
|
||||||
while (hp > 0 && (round < 4 || !mobs.isEmpty())) {
|
|
||||||
tick();
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(50L);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
public RawMap getMap() {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tick() {
|
|
||||||
if (mobs.isEmpty() && round < 4) {
|
|
||||||
++round;
|
|
||||||
int nb_mobs = round * (RANDOM.nextInt(16) + 1);
|
|
||||||
for (int i = 1; i <= nb_mobs; ++i) {
|
|
||||||
Mob mob = Mob.getRandomMob();
|
|
||||||
do
|
|
||||||
mob.move(RANDOM.nextInt(getMap().getWidth() / 16), RANDOM.nextInt(getMap().getHeight() / 16));
|
|
||||||
while (getMap().getCase(mob.getX(), mob.getY()).getCollision() != Collision.ANY);
|
|
||||||
getMap().getCase(mob.getX(), mob.getY()).setCollision(Collision.PARTIAL);
|
|
||||||
mobs.add(mob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Tower tower : towers) {
|
|
||||||
for (Mob mob : tower.filterDetectedMobs(mobs))
|
|
||||||
mob.hit(tower.getDamagePerShot());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Mob mob : new ArrayList<>(mobs)) {
|
|
||||||
getMap().getCase(mob.getX(), mob.getY()).setCollision(Collision.ANY);
|
|
||||||
mob.tick(this);
|
|
||||||
if (mob.getX() < 0 || mob.isDead()) {
|
|
||||||
mobs.remove(mob);
|
|
||||||
if (mob.getX() < 0) {
|
|
||||||
--hp;
|
|
||||||
if (hp == 0) {
|
|
||||||
winLabel.setForeground(Color.red);
|
|
||||||
winLabel.setText("Vous avez perdu !");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
reward += mob.getReward();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
getMap().getCase(mob.getX(), mob.getY()).setCollision(Collision.PARTIAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
waveLabel.setText("Vague " + round);
|
|
||||||
nbMobsLabel.setText(mobs.size() + " mob" + (mobs.size() > 1 ? "s" : "") + " restant" + (mobs.size() > 1 ? "s" : ""));
|
|
||||||
hpLabel.setText("Points de vie : " + hp);
|
|
||||||
rewardLabel.setText("Butin : " + reward);
|
|
||||||
|
|
||||||
if (round == 4 && mobs.isEmpty()) {
|
|
||||||
winLabel.setForeground(Color.green.darker());
|
|
||||||
winLabel.setText("Vous avez gagné !");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Grid extends JComponent implements MouseListener {
|
|
||||||
public Grid() {
|
|
||||||
addMouseListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void paintComponent(Graphics _g) {
|
|
||||||
Graphics2D g = (Graphics2D) _g;
|
|
||||||
|
|
||||||
if (getMap().getFont() != null)
|
|
||||||
g.drawImage(getMap().getFont(), null, null);
|
|
||||||
|
|
||||||
SpriteRegister.refreshAllSprites();
|
|
||||||
int SPRITE_SIZE = 32;
|
|
||||||
for (RawCase c : getMap().getCases()) {
|
|
||||||
Sprite s1 = SpriteRegister.getCategory(c.getCoucheOne().getCategory()).getSprites().get(c.getCoucheOne().getIndex());
|
|
||||||
Sprite s2 = SpriteRegister.getCategory(c.getCoucheTwo().getCategory()).getSprites().get(c.getCoucheTwo().getIndex());
|
|
||||||
Sprite s3 = SpriteRegister.getCategory(c.getCoucheThree().getCategory()).getSprites().get(c.getCoucheThree().getIndex());
|
|
||||||
g.drawImage(s1.getImage(), SPRITE_SIZE * c.getPosX(), SPRITE_SIZE * c.getPosY(), SPRITE_SIZE, SPRITE_SIZE, Color.white, null);
|
|
||||||
if (!CollidPanel.isEmpty(s2.getImage()))
|
|
||||||
g.drawImage(s2.getImage(), SPRITE_SIZE * c.getPosX(), SPRITE_SIZE * c.getPosY(), SPRITE_SIZE, SPRITE_SIZE, null, null);
|
|
||||||
if (!CollidPanel.isEmpty(s3.getImage()))
|
|
||||||
g.drawImage(s3.getImage(), SPRITE_SIZE * c.getPosX(), SPRITE_SIZE * c.getPosY(), SPRITE_SIZE, SPRITE_SIZE, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Mob mob : new ArrayList<>(mobs)) {
|
|
||||||
Sprite s = mob.getSprite();
|
|
||||||
g.drawImage(s.getImage(), SPRITE_SIZE * mob.getX(), SPRITE_SIZE * mob.getY(), SPRITE_SIZE, SPRITE_SIZE, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Tower tower : towers) {
|
|
||||||
Sprite s = tower.getSprite();
|
|
||||||
g.drawImage(s.getImage(), SPRITE_SIZE * tower.getX(), SPRITE_SIZE * tower.getY(), SPRITE_SIZE, SPRITE_SIZE, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(MouseEvent event) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mousePressed(MouseEvent event) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent event) {
|
|
||||||
int x = event.getX() / 32, y = event.getY() / 32;
|
|
||||||
Tower tower = basicTower.isSelected() ? new BasicTower(x, y) :
|
|
||||||
nullTower.isSelected() ? new NullTower(x, y) :
|
|
||||||
autoTower.isSelected() ? new AutoTower(x, y) :
|
|
||||||
null;
|
|
||||||
if (tower == null || tower.getPrice() > reward)
|
|
||||||
return;
|
|
||||||
|
|
||||||
RawCase c = getMap().getCase(x, y);
|
|
||||||
if (c == null || c.getCollision() != Collision.ANY)
|
|
||||||
return;
|
|
||||||
c.setCollision(Collision.FULL);
|
|
||||||
|
|
||||||
reward -= tower.getPrice();
|
|
||||||
towers.add(tower);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseEntered(MouseEvent event) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseExited(MouseEvent event) {}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,133 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.game.mobs;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.RawCase;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.Sprite;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister;
|
|
||||||
import fr.ynerant.leveleditor.game.GameFrame;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public abstract class Mob {
|
|
||||||
private static final Random RANDOM = new Random();
|
|
||||||
private Sprite sprite;
|
|
||||||
private int x;
|
|
||||||
private int y;
|
|
||||||
private int hp;
|
|
||||||
private long tickRemains;
|
|
||||||
|
|
||||||
public Mob() {
|
|
||||||
this.hp = getMaxHP();
|
|
||||||
this.tickRemains = getSlowness();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract int getMaxHP();
|
|
||||||
|
|
||||||
public abstract long getSlowness();
|
|
||||||
|
|
||||||
public abstract int getReward();
|
|
||||||
|
|
||||||
public abstract String getName();
|
|
||||||
|
|
||||||
public Sprite getSprite() {
|
|
||||||
if (sprite == null)
|
|
||||||
sprite = SpriteRegister.getCategory(getName()).getSprites().get(0);
|
|
||||||
return sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getX() {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getY() {
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void move(int x, int y) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHP() {
|
|
||||||
return hp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDead() {
|
|
||||||
return hp <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHP(int hp) {
|
|
||||||
this.hp = hp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hit(int damage) {
|
|
||||||
if (!isDead()) {
|
|
||||||
this.hp -= damage;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tick(GameFrame game) {
|
|
||||||
if (tickRemains > 0)
|
|
||||||
--tickRemains;
|
|
||||||
else {
|
|
||||||
tickRemains = getSlowness();
|
|
||||||
RawCase current = game.getMap().getCase(getX(), getY());
|
|
||||||
|
|
||||||
if (current.getPosX() == 0) {
|
|
||||||
move(-1, getY());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<RawCase> visited = new ArrayList<>();
|
|
||||||
Queue<RawCase> queue = new ArrayDeque<>();
|
|
||||||
Map<RawCase, RawCase> pred = new HashMap<>();
|
|
||||||
RawCase last = null;
|
|
||||||
queue.add(current);
|
|
||||||
while (!queue.isEmpty()) {
|
|
||||||
RawCase visiting = queue.poll();
|
|
||||||
visited.add(visiting);
|
|
||||||
for (RawCase neighbour : game.getMap().getNeighbours(visiting)) {
|
|
||||||
if (visited.contains(neighbour))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pred.put(neighbour, visiting);
|
|
||||||
queue.add(neighbour);
|
|
||||||
|
|
||||||
if (neighbour.getPosX() == 0) {
|
|
||||||
last = neighbour;
|
|
||||||
queue.clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last != null) {
|
|
||||||
while (pred.get(last) != current)
|
|
||||||
last = pred.get(last);
|
|
||||||
move(last.getPosX(), last.getPosY());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Mob{" +
|
|
||||||
"sprite=" + sprite +
|
|
||||||
", x=" + x +
|
|
||||||
", y=" + y +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Mob getRandomMob() {
|
|
||||||
switch (RANDOM.nextInt(3)) {
|
|
||||||
case 1:
|
|
||||||
return new Mob1();
|
|
||||||
case 2:
|
|
||||||
return new Mob2();
|
|
||||||
default:
|
|
||||||
return new MobCancer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.game.mobs;
|
|
||||||
|
|
||||||
public class Mob1 extends Mob {
|
|
||||||
@Override
|
|
||||||
public int getMaxHP() {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getSlowness() {
|
|
||||||
return 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getReward() {
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "mob1";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.game.mobs;
|
|
||||||
|
|
||||||
public class Mob2 extends Mob {
|
|
||||||
@Override
|
|
||||||
public int getMaxHP() {
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getSlowness() {
|
|
||||||
return 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getReward() {
|
|
||||||
return 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "mob2";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.game.mobs;
|
|
||||||
|
|
||||||
public class MobCancer extends Mob {
|
|
||||||
@Override
|
|
||||||
public int getMaxHP() {
|
|
||||||
return 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getSlowness() {
|
|
||||||
return 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getReward() {
|
|
||||||
return 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "mobcancer";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.game.towers;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.game.mobs.Mob;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class AutoTower extends Tower {
|
|
||||||
public AutoTower(int x, int y) {
|
|
||||||
super(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "autotower";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getDamagePerShot() {
|
|
||||||
return 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getPeriod() {
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPrice() {
|
|
||||||
return 142;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Collection<Mob> _filterDetectedMobs(Collection<Mob> mobs) {
|
|
||||||
return mobs;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.game.towers;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.game.mobs.Mob;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class BasicTower extends Tower {
|
|
||||||
public BasicTower(int x, int y) {
|
|
||||||
super(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "basictower";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getDamagePerShot() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getPeriod() {
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPrice() {
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Collection<Mob> _filterDetectedMobs(Collection<Mob> mobs) {
|
|
||||||
List<Mob> filtered = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Mob mob : mobs) {
|
|
||||||
if ((mob.getX() == getX() || mob.getY() == getY())
|
|
||||||
&& Math.abs(mob.getX() - getX()) <= 3 && Math.abs(mob.getY() - getY()) <= 3)
|
|
||||||
filtered.add(mob);
|
|
||||||
}
|
|
||||||
|
|
||||||
return filtered;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.game.towers;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.game.mobs.Mob;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class NullTower extends Tower {
|
|
||||||
public NullTower(int x, int y) {
|
|
||||||
super(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "nulltower";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getDamagePerShot() {
|
|
||||||
return Integer.MAX_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getPeriod() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPrice() {
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Collection<Mob> _filterDetectedMobs(Collection<Mob> mobs) {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package fr.ynerant.leveleditor.game.towers;
|
|
||||||
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.Sprite;
|
|
||||||
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister;
|
|
||||||
import fr.ynerant.leveleditor.game.mobs.Mob;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public abstract class Tower {
|
|
||||||
private final Sprite sprite;
|
|
||||||
private final int x;
|
|
||||||
private final int y;
|
|
||||||
private long remainingTicks;
|
|
||||||
|
|
||||||
public Tower(int x, int y) {
|
|
||||||
this.sprite = SpriteRegister.getCategory(getName()).getSprites().get(0);
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Random RANDOM = new Random();
|
|
||||||
|
|
||||||
public Sprite getSprite() {
|
|
||||||
return sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract String getName();
|
|
||||||
|
|
||||||
public abstract int getDamagePerShot();
|
|
||||||
|
|
||||||
public abstract long getPeriod();
|
|
||||||
|
|
||||||
public abstract int getPrice();
|
|
||||||
|
|
||||||
abstract Collection<Mob> _filterDetectedMobs(Collection<Mob> mobs);
|
|
||||||
|
|
||||||
public Collection<Mob> filterDetectedMobs(Collection<Mob> mobs) {
|
|
||||||
if (remainingTicks > 0) {
|
|
||||||
--remainingTicks;
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
remainingTicks = getPeriod();
|
|
||||||
return _filterDetectedMobs(mobs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getX() {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getY() {
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package fr.ynerant.leveleditor.api.editor
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.Collision.Collision
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.Sprite
|
||||||
|
|
||||||
|
|
||||||
|
object Case {
|
||||||
|
def create(posX: Int, posY: Int, couche1: Sprite, couche2: Sprite, couche3: Sprite, collision: Collision): Case = {
|
||||||
|
val c = new Case
|
||||||
|
c.x = posX
|
||||||
|
c.y = posY
|
||||||
|
c.couche1 = couche1
|
||||||
|
c.couche2 = couche2
|
||||||
|
c.couche3 = couche3
|
||||||
|
c.collision = collision
|
||||||
|
c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Case {
|
||||||
|
private var x = 0
|
||||||
|
private var y = 0
|
||||||
|
private var couche1 = null: Sprite
|
||||||
|
private var couche2 = null: Sprite
|
||||||
|
private var couche3 = null: Sprite
|
||||||
|
private var collision = null: Collision
|
||||||
|
|
||||||
|
def getPosX: Int = x
|
||||||
|
|
||||||
|
def getPosY: Int = y
|
||||||
|
|
||||||
|
def getCoucheOne: Sprite = couche1
|
||||||
|
|
||||||
|
def getCoucheTwo: Sprite = couche2
|
||||||
|
|
||||||
|
def getCoucheThree: Sprite = couche3
|
||||||
|
|
||||||
|
def getCollision: Collision = collision
|
||||||
|
|
||||||
|
override def toString: String = "{Case x=" + x + " y=" + y + " couche1=" + couche1 + " couche2=" + couche2 + " couche3=" + couche3 + " collision=" + collision.toString.toUpperCase + "}\n"
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package fr.ynerant.leveleditor.api.editor
|
||||||
|
|
||||||
|
object Collision extends Enumeration {
|
||||||
|
type Collision = Value
|
||||||
|
val FULL, PARTIAL, ANY = Value
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
package fr.ynerant.leveleditor.api.editor
|
||||||
|
|
||||||
|
import java.awt.Color
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.io._
|
||||||
|
import java.lang.reflect.Type
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.util
|
||||||
|
import java.util.zip.{GZIPInputStream, GZIPOutputStream}
|
||||||
|
|
||||||
|
import com.google.gson.{Gson, GsonBuilder, JsonDeserializationContext, JsonDeserializer, JsonElement, JsonPrimitive, JsonSerializationContext, JsonSerializer}
|
||||||
|
import fr.ynerant.leveleditor.api.editor.Collision.Collision
|
||||||
|
import fr.ynerant.leveleditor.editor.Map
|
||||||
|
import javax.swing.JFileChooser
|
||||||
|
import javax.swing.filechooser.FileNameExtensionFilter
|
||||||
|
|
||||||
|
object EditorAPI {
|
||||||
|
private var LAST_FILE = null: File
|
||||||
|
|
||||||
|
def toRawMap(width: Int, height: Int): RawMap = {
|
||||||
|
val cases = new util.ArrayList[RawCase]
|
||||||
|
var y = 1
|
||||||
|
while ( {
|
||||||
|
y < height
|
||||||
|
}) {
|
||||||
|
var x = 1
|
||||||
|
while ( {
|
||||||
|
x < width
|
||||||
|
}) {
|
||||||
|
val c = RawCase.create(x / 16, y / 16, RawSprite.BLANK, RawSprite.BLANK, RawSprite.BLANK, Collision.ANY)
|
||||||
|
cases.add(c)
|
||||||
|
|
||||||
|
x += 16
|
||||||
|
}
|
||||||
|
|
||||||
|
y += 16
|
||||||
|
}
|
||||||
|
RawMap.create(cases, width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
def createGson: Gson = {
|
||||||
|
val builder = new GsonBuilder
|
||||||
|
builder.registerTypeAdapter(classOf[Collision.Collision], new JsonDeserializer[Collision.Collision] {
|
||||||
|
override def deserialize(jsonElement: JsonElement, `type`: Type, jsonDeserializationContext: JsonDeserializationContext): Collision = Collision.withName(jsonElement.getAsString)
|
||||||
|
})
|
||||||
|
builder.registerTypeAdapter(classOf[Collision.Collision], new JsonSerializer[Collision.Collision] {
|
||||||
|
override def serialize(t: Collision, `type`: Type, jsonSerializationContext: JsonSerializationContext): JsonElement = new JsonPrimitive(t.toString)
|
||||||
|
})
|
||||||
|
builder.enableComplexMapKeySerialization
|
||||||
|
builder.serializeNulls
|
||||||
|
builder.setPrettyPrinting()
|
||||||
|
builder.create
|
||||||
|
}
|
||||||
|
|
||||||
|
def createJFC: JFileChooser = {
|
||||||
|
val jfc = new JFileChooser
|
||||||
|
jfc.setFileFilter(new FileNameExtensionFilter("Fichiers monde (*.gmap, *.dat)", "gmap", "dat"))
|
||||||
|
jfc.setFileHidingEnabled(true)
|
||||||
|
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY)
|
||||||
|
val dir = new File("maps")
|
||||||
|
assert(dir.isDirectory || dir.mkdirs)
|
||||||
|
jfc.setCurrentDirectory(dir)
|
||||||
|
jfc
|
||||||
|
}
|
||||||
|
|
||||||
|
def saveAs(map: RawMap): Unit = {
|
||||||
|
val jfc = createJFC
|
||||||
|
var file = null: File
|
||||||
|
jfc.showSaveDialog(null)
|
||||||
|
file = jfc.getSelectedFile
|
||||||
|
if (file == null) return
|
||||||
|
if (!file.getName.toLowerCase.endsWith(".gmap") && !file.getName.toLowerCase.endsWith(".dat")) file = new File(file.getParentFile, file.getName + ".gmap")
|
||||||
|
LAST_FILE = file
|
||||||
|
save(file, map)
|
||||||
|
}
|
||||||
|
|
||||||
|
def save(map: RawMap): Unit = {
|
||||||
|
if (LAST_FILE != null) save(LAST_FILE, map)
|
||||||
|
else saveAs(map)
|
||||||
|
}
|
||||||
|
|
||||||
|
def save(file: File, map: RawMap): Unit = {
|
||||||
|
val json = createGson.toJson(map)
|
||||||
|
try {
|
||||||
|
assert(file.createNewFile)
|
||||||
|
val bos = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(file)))
|
||||||
|
bos.write(json.getBytes(StandardCharsets.UTF_8))
|
||||||
|
bos.close()
|
||||||
|
} catch {
|
||||||
|
case ex: IOException =>
|
||||||
|
ex.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def open: Map = {
|
||||||
|
val jfc = createJFC
|
||||||
|
var file = null: File
|
||||||
|
jfc.showOpenDialog(null)
|
||||||
|
file = jfc.getSelectedFile
|
||||||
|
if (file == null) return null
|
||||||
|
LAST_FILE = file
|
||||||
|
open(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
def getRawMap(f: File): RawMap = {
|
||||||
|
var json = null: String
|
||||||
|
try {
|
||||||
|
val gis = new GZIPInputStream(new BufferedInputStream(new FileInputStream(f)))
|
||||||
|
val bytes = new Array[Byte](512 * 1024)
|
||||||
|
var count = 0
|
||||||
|
val text = new StringBuilder
|
||||||
|
while ( {
|
||||||
|
count = gis.read(bytes)
|
||||||
|
count != -1
|
||||||
|
}) text.append(new String(bytes, 0, count, StandardCharsets.UTF_8))
|
||||||
|
gis.close()
|
||||||
|
json = text.toString
|
||||||
|
} catch {
|
||||||
|
case e: IOException =>
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
createGson.fromJson(json, classOf[RawMap])
|
||||||
|
}
|
||||||
|
|
||||||
|
def open(f: File): Map = open(getRawMap(f))
|
||||||
|
|
||||||
|
def open(map: RawMap): Map = {
|
||||||
|
if (map.getFont == null) {
|
||||||
|
val baseWidth = map.getWidth
|
||||||
|
val baseHeight = map.getHeight
|
||||||
|
val width = baseWidth + (baseWidth / 16) + 1
|
||||||
|
val height = baseHeight + (baseHeight / 16) + 1
|
||||||
|
val image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)
|
||||||
|
val g = image.createGraphics
|
||||||
|
g.setColor(Color.white)
|
||||||
|
g.fillRect(0, 0, width, height)
|
||||||
|
g.setColor(Color.black)
|
||||||
|
g.drawLine(0, 0, width, 0)
|
||||||
|
g.drawLine(0, 0, 0, height)
|
||||||
|
var x = 17
|
||||||
|
while ( {
|
||||||
|
x <= width
|
||||||
|
}) {
|
||||||
|
g.drawLine(x, 0, x, height)
|
||||||
|
|
||||||
|
x += 17
|
||||||
|
}
|
||||||
|
var y = 17
|
||||||
|
while ( {
|
||||||
|
y <= height
|
||||||
|
}) {
|
||||||
|
g.drawLine(0, y, width, y)
|
||||||
|
|
||||||
|
y += 17
|
||||||
|
}
|
||||||
|
map.setFont(image)
|
||||||
|
}
|
||||||
|
new Map(map)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package fr.ynerant.leveleditor.api.editor
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.Collision.Collision
|
||||||
|
|
||||||
|
object RawCase {
|
||||||
|
def create(posX: Int, posY: Int, couche1: RawSprite, couche2: RawSprite, couche3: RawSprite, collision: Collision): RawCase = {
|
||||||
|
new RawCase(posX, posY, couche1, couche2, couche3, collision)
|
||||||
|
}
|
||||||
|
|
||||||
|
def create(c: Case): RawCase = {
|
||||||
|
new RawCase(c.getPosX, c.getPosY, RawSprite.create(c.getCoucheOne), RawSprite.create(c.getCoucheTwo), RawSprite.create(c.getCoucheThree), c.getCollision)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case class RawCase(var x: Int, var y: Int, var couche1: RawSprite, var couche2: RawSprite, var couche3: RawSprite, var collision: Collision) {
|
||||||
|
def getPosX: Int = x
|
||||||
|
|
||||||
|
def getPosY: Int = y
|
||||||
|
|
||||||
|
def getCoucheOne: RawSprite = couche1
|
||||||
|
|
||||||
|
def getCoucheTwo: RawSprite = couche2
|
||||||
|
|
||||||
|
def getCoucheThree: RawSprite = couche3
|
||||||
|
|
||||||
|
def getCollision: Collision = collision
|
||||||
|
|
||||||
|
def setCollision(collision: Collision): Unit = {
|
||||||
|
this.collision = collision
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package fr.ynerant.leveleditor.api.editor
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.editor.Map
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.util
|
||||||
|
import java.util.stream.Collectors
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
|
|
||||||
|
|
||||||
|
object RawMap {
|
||||||
|
def create(cases: util.List[RawCase], width: Int, height: Int): RawMap = {
|
||||||
|
new RawMap(cases, width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
def create(map: Map): RawMap = {
|
||||||
|
val raw = new RawMap(new util.ArrayList[RawCase], 0, 0)
|
||||||
|
raw.width = map.getWidth
|
||||||
|
raw.height = map.getHeight
|
||||||
|
raw.cases = new util.ArrayList[RawCase]
|
||||||
|
map.getAllCases.forEach(c => raw.cases.add(RawCase.create(c)))
|
||||||
|
raw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case class RawMap(var cases: util.List[RawCase], var width: Int, var height: Int) {
|
||||||
|
private var cases_map = null: util.HashMap[Integer, RawCase]
|
||||||
|
private var font = null: BufferedImage
|
||||||
|
|
||||||
|
def getCases: util.List[RawCase] = cases
|
||||||
|
|
||||||
|
def getCase(x: Int, y: Int): RawCase = {
|
||||||
|
if (cases_map == null) {
|
||||||
|
cases_map = new util.HashMap[Integer, RawCase]
|
||||||
|
getCases.forEach(c => cases_map.put(c.getPosY * width + c.getPosX, c))
|
||||||
|
}
|
||||||
|
cases_map.get(y * getWidth + x)
|
||||||
|
}
|
||||||
|
|
||||||
|
def getNeighbours(c: RawCase): util.Collection[RawCase] = {
|
||||||
|
val list = new util.ArrayList[RawCase]
|
||||||
|
list.add(getCase(c.getPosX - 1, c.getPosY))
|
||||||
|
list.add(getCase(c.getPosX, c.getPosY - 1))
|
||||||
|
list.add(getCase(c.getPosX + 1, c.getPosY))
|
||||||
|
list.add(getCase(c.getPosX, c.getPosY + 1))
|
||||||
|
list.stream.filter((_c: RawCase) => _c != null && (_c.getCollision == Collision.ANY)).collect(Collectors.toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
def getWidth: Int = width
|
||||||
|
|
||||||
|
def getHeight: Int = height
|
||||||
|
|
||||||
|
def getFont: BufferedImage = font
|
||||||
|
|
||||||
|
def setFont(font: BufferedImage): Unit = {
|
||||||
|
this.font = font
|
||||||
|
}
|
||||||
|
|
||||||
|
override def toString: String = new Gson().toJson(this)
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package fr.ynerant.leveleditor.api.editor
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.Sprite
|
||||||
|
|
||||||
|
|
||||||
|
object RawSprite {
|
||||||
|
val BLANK = new RawSprite("blank", 0)
|
||||||
|
|
||||||
|
def create(spr: Sprite): RawSprite = {
|
||||||
|
new RawSprite(spr.getCategory.getName, spr.getIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case class RawSprite(var category: String, protected var index: Int) {
|
||||||
|
if (category == null) category = "blank"
|
||||||
|
|
||||||
|
def getCategory: String = category
|
||||||
|
|
||||||
|
def getIndex: Int = index
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package fr.ynerant.leveleditor.api.editor.sprites
|
||||||
|
|
||||||
|
import java.util
|
||||||
|
|
||||||
|
object Category {
|
||||||
|
def create(name: String, sprites: util.List[Sprite]): Category = {
|
||||||
|
val c = new Category
|
||||||
|
c.name = name
|
||||||
|
c.sprites = sprites
|
||||||
|
c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Category private() {
|
||||||
|
private var sprites = null: util.List[Sprite]
|
||||||
|
private var name = null: String
|
||||||
|
|
||||||
|
def getName: String = name
|
||||||
|
|
||||||
|
def getSprites: util.List[Sprite] = sprites
|
||||||
|
|
||||||
|
override def toString: String = name
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package fr.ynerant.leveleditor.api.editor.sprites
|
||||||
|
|
||||||
|
import java.awt._
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.util
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
|
||||||
|
object Sprite {
|
||||||
|
val BLANK = new Sprite(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB), Category.create("blank", new util.ArrayList[Sprite]), 0)
|
||||||
|
|
||||||
|
val g: Graphics2D
|
||||||
|
= BLANK.getImage.createGraphics
|
||||||
|
g.setComposite(AlphaComposite.Clear)
|
||||||
|
g.setColor(new Color(0, true))
|
||||||
|
g.fillRect(0, 0, 16, 16)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Sprite(val img: BufferedImage, val cat: Category, val index: Int) {
|
||||||
|
if (!this.cat.getSprites.contains(this)) this.cat.getSprites.add(this)
|
||||||
|
|
||||||
|
def getImage: BufferedImage = this.img
|
||||||
|
|
||||||
|
def getCategory: Category = cat
|
||||||
|
|
||||||
|
def getIndex: Int = index
|
||||||
|
|
||||||
|
override def hashCode: Int = cat.hashCode ^ getIndex
|
||||||
|
|
||||||
|
override def equals(o: Any): Boolean = {
|
||||||
|
if (!o.isInstanceOf[Sprite]) return false
|
||||||
|
val other = o.asInstanceOf[Sprite]
|
||||||
|
hashCode == other.hashCode
|
||||||
|
}
|
||||||
|
|
||||||
|
override def toString: String = "{Sprite img=" + img + " cat=" + cat.getName + "}"
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package fr.ynerant.leveleditor.api.editor.sprites
|
||||||
|
|
||||||
|
import java.io.{BufferedInputStream, BufferedReader, File, FileInputStream, IOException, InputStreamReader}
|
||||||
|
import java.net.{URISyntaxException, URLDecoder}
|
||||||
|
import java.nio.file.{Files, Paths}
|
||||||
|
import java.util
|
||||||
|
import java.util.Objects
|
||||||
|
import java.util.jar.JarFile
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import javax.imageio.ImageIO
|
||||||
|
import fr.ynerant.leveleditor.client.main.Main
|
||||||
|
|
||||||
|
object SpriteRegister {
|
||||||
|
private var nameToCoords = null: util.Map[String, util.List[util.List[Double]]]
|
||||||
|
private val sprites = new util.HashMap[String, Category]
|
||||||
|
|
||||||
|
@throws[IOException]
|
||||||
|
def unpack(): Unit = {
|
||||||
|
if (Main.isInDevelopmentMode) try {
|
||||||
|
val dir = new File(getClass.getResource("/assets").toURI)
|
||||||
|
unpackDir(dir)
|
||||||
|
} catch {
|
||||||
|
case e: URISyntaxException =>
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
@SuppressWarnings(Array("deprecation")) val path = URLDecoder.decode(getClass.getProtectionDomain.getCodeSource.getLocation.getPath, "UTF-8")
|
||||||
|
val jarFile = new File(path)
|
||||||
|
if (jarFile.isFile) {
|
||||||
|
val jar = new JarFile(jarFile)
|
||||||
|
val entries = jar.entries
|
||||||
|
while ( {
|
||||||
|
entries.hasMoreElements
|
||||||
|
}) {
|
||||||
|
val je = entries.nextElement
|
||||||
|
val name = je.getName
|
||||||
|
if (name.startsWith("assets/")) {
|
||||||
|
val f = new File(name)
|
||||||
|
if (name.endsWith("/")) if (!f.mkdirs && !f.isDirectory) throw new IOException("Unable to make dir: " + f)
|
||||||
|
else if (!f.isFile) Files.copy(jar.getInputStream(je), Paths.get(f.toURI))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jar.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@throws[IOException]
|
||||||
|
private def unpackDir(dir: File): Unit = {
|
||||||
|
for (f <- Objects.requireNonNull(dir.listFiles)) {
|
||||||
|
if (f.isDirectory) {
|
||||||
|
unpackDir(f)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val path = f.getAbsolutePath.substring(f.getAbsolutePath.indexOf(File.separatorChar + "assets") + 1)
|
||||||
|
val local = new File(path)
|
||||||
|
assert(local.getParentFile.isDirectory || local.getParentFile.mkdirs)
|
||||||
|
assert(!local.exists || local.delete)
|
||||||
|
Files.copy(Paths.get(f.toURI), Paths.get(local.toURI))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings(Array("unchecked")) def refreshAllSprites(): Unit = {
|
||||||
|
if (nameToCoords != null && !nameToCoords.isEmpty && !sprites.isEmpty) return
|
||||||
|
val assetsDir = new File("assets")
|
||||||
|
val assets = new util.ArrayList[String]
|
||||||
|
for (dir <- Objects.requireNonNull(assetsDir.listFiles)) {
|
||||||
|
assets.add(dir.getName)
|
||||||
|
}
|
||||||
|
|
||||||
|
assets.forEach(asset => {
|
||||||
|
try {
|
||||||
|
val f = new File(assetsDir.getAbsolutePath + "/" + asset + "/textures/sprites")
|
||||||
|
assert(f.isDirectory || f.mkdirs)
|
||||||
|
val br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(f, "sprites.json"))))
|
||||||
|
nameToCoords = new Gson().fromJson(br, classOf[util.Map[_, _]])
|
||||||
|
br.close()
|
||||||
|
nameToCoords.keySet.forEach(key => {
|
||||||
|
try {
|
||||||
|
val is = new BufferedInputStream(new FileInputStream(new File(f, key + ".png")))
|
||||||
|
val img = ImageIO.read(is)
|
||||||
|
val cat = Category.create(key, new util.ArrayList[Sprite])
|
||||||
|
nameToCoords.get(key).forEach(list => {
|
||||||
|
val x = list.get(0).intValue
|
||||||
|
val y = list.get(1).intValue
|
||||||
|
val child = img.getSubimage(x, y, 16, 16)
|
||||||
|
new Sprite(child, cat, nameToCoords.get(key).indexOf(list))
|
||||||
|
})
|
||||||
|
sprites.put(key, cat)
|
||||||
|
} catch {
|
||||||
|
case t: Throwable =>
|
||||||
|
System.err.println("Erreur lors de la lecture du sprite '" + key + "'")
|
||||||
|
t.printStackTrace()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
case e: IOException =>
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
def getCategory(name: String): Category = sprites.get(name)
|
||||||
|
|
||||||
|
def getAllCategories = new util.ArrayList[Category](sprites.values)
|
||||||
|
}
|
|
@ -0,0 +1,185 @@
|
||||||
|
package fr.ynerant.leveleditor.client.main
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.EditorAPI
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister
|
||||||
|
import fr.ynerant.leveleditor.frame.MainFrame
|
||||||
|
import fr.ynerant.leveleditor.game.GameFrame
|
||||||
|
import javax.swing._
|
||||||
|
import java.awt._
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
import java.net.URISyntaxException
|
||||||
|
import java.net.URL
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.client.main.Main.DEV
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class principale qui lance le jeu
|
||||||
|
*
|
||||||
|
* @author ÿnérant
|
||||||
|
* @see #main(String...)
|
||||||
|
*/
|
||||||
|
object Main {
|
||||||
|
/**
|
||||||
|
* Variable disant si le jeu est lancé en développement ou non.
|
||||||
|
*
|
||||||
|
* @see #isInDevelopmentMode()
|
||||||
|
* @see #main(String...)
|
||||||
|
* @since 0.1-aplha
|
||||||
|
*/
|
||||||
|
private var DEV = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accesseur disant si le jeu est lancé en développement ou non.
|
||||||
|
*
|
||||||
|
* @see #DEV
|
||||||
|
* @since 0.1-alpha
|
||||||
|
*/
|
||||||
|
def isInDevelopmentMode: Boolean = DEV
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args arguments du jeu. Possibilités :<br> <strong>--edit</strong> lancera un éditeur<br> <strong>--help</strong> lance l'aide affichant toutes les options possibles
|
||||||
|
* @see #launchEditMode()
|
||||||
|
* @since 0.1-alpha
|
||||||
|
*/
|
||||||
|
def main(args: Array[String]): Unit = {
|
||||||
|
System.setProperty("sun.java2d.noddraw", "true")
|
||||||
|
Locale.setDefault(Locale.FRANCE)
|
||||||
|
try UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName)
|
||||||
|
catch {
|
||||||
|
case e: Exception =>
|
||||||
|
new ExceptionInInitializerError("Erreur lors du changement de 'look and feel'").printStackTrace()
|
||||||
|
System.err.print("Caused by ")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
new File(getClass.getResource("/assets").toURI)
|
||||||
|
DEV = true
|
||||||
|
} catch {
|
||||||
|
case t: Throwable =>
|
||||||
|
DEV = false
|
||||||
|
}
|
||||||
|
|
||||||
|
try SpriteRegister.unpack()
|
||||||
|
catch {
|
||||||
|
case e: IOException =>
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
SpriteRegister.refreshAllSprites()
|
||||||
|
|
||||||
|
launchFrame()
|
||||||
|
}
|
||||||
|
|
||||||
|
private def checkJava(): Unit = {
|
||||||
|
if (GraphicsEnvironment.isHeadless) {
|
||||||
|
val ex = new HeadlessException("Impossible de lancer un jeu sans \u00e9cran !")
|
||||||
|
System.err.println("Cette application est un jeu, sans écran, elle aura du mal \u00e0 tourner ...")
|
||||||
|
ex.printStackTrace()
|
||||||
|
System.exit(1)
|
||||||
|
}
|
||||||
|
try classOf[Map[_, _]].getDeclaredMethod("getOrDefault", classOf[Any], classOf[Any])
|
||||||
|
catch {
|
||||||
|
case ex: NoSuchMethodException =>
|
||||||
|
ex.printStackTrace()
|
||||||
|
JOptionPane.showMessageDialog(null, "<html>Cette application requiert <strong>Java 8</strong>.<br />La page de t\u00e9l\u00e9chargement va maintenant s'ouvrir.</html>")
|
||||||
|
JOptionPane.showMessageDialog(null, "<html>Si vous êtes certain que Java 8 est installé sur votre machine, assurez-vous qu'il n'y a pas de versions obsolètes de Java,<br />ou si vous êtes plus expérimentés si le path vers Java est bien défini vers la bonne version.</html>")
|
||||||
|
try if (Desktop.isDesktopSupported) Desktop.getDesktop.browse(new URL("http://java.com/download").toURI)
|
||||||
|
else JOptionPane.showMessageDialog(null, "<html>Votre machine ne supporte pas la classe Desktop, impossible d'ouvrir la page.<br />Rendez-vous y manuellement sur <a href=\"http://java.com/download\">http://java.com/download</a> pour installer Java.</html>")
|
||||||
|
catch {
|
||||||
|
case e@(_: IOException | _: URISyntaxException) =>
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
System.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lance la fenêtre principale
|
||||||
|
*
|
||||||
|
* @see #main(String...)
|
||||||
|
* @see #launchEditMode()
|
||||||
|
*/
|
||||||
|
private def launchFrame(): Unit = {
|
||||||
|
MainFrame.getInstance.setVisible(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permet de lancer l'éditeur de carte
|
||||||
|
*
|
||||||
|
* @see #main(String...)
|
||||||
|
* @see #launchFrame()
|
||||||
|
* @since 0.1-aplha
|
||||||
|
*/
|
||||||
|
def launchEditMode: Boolean = {
|
||||||
|
System.out.println("Lancement de l'\u00e9diteur de monde ...")
|
||||||
|
var baseWidth = 0
|
||||||
|
var baseHeight = 0
|
||||||
|
var width = 0
|
||||||
|
var height = 0
|
||||||
|
while (baseWidth <= 0) {
|
||||||
|
try {
|
||||||
|
val baseWidthStr = JOptionPane.showInputDialog(null, "Veuillez entrez le nombre de cases longueur de votre carte (0 pour annuler) :")
|
||||||
|
if (baseWidthStr == null) return false
|
||||||
|
baseWidth = baseWidthStr.toInt * 16
|
||||||
|
if (baseWidth < 0) throw new NumberFormatException
|
||||||
|
if (baseWidth == 0) return false
|
||||||
|
} catch {
|
||||||
|
case ignored: NumberFormatException =>
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (baseHeight <= 0) {
|
||||||
|
try {
|
||||||
|
val baseHeightStr = JOptionPane.showInputDialog("Veuillez entrez le nombre de cases hauteur de votre carte (0 pour annuler) :")
|
||||||
|
if (baseHeightStr == null) return false
|
||||||
|
baseHeight = baseHeightStr.toInt * 16
|
||||||
|
if (baseHeight < 0) throw new NumberFormatException
|
||||||
|
if (baseHeight == 0) return false
|
||||||
|
} catch {
|
||||||
|
case ignored: NumberFormatException =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
width = baseWidth + (baseWidth / 16) + 1
|
||||||
|
height = baseHeight + (baseHeight / 16) + 1
|
||||||
|
val image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)
|
||||||
|
val g = image.createGraphics
|
||||||
|
g.setColor(Color.white)
|
||||||
|
g.fillRect(0, 0, width, height)
|
||||||
|
g.setColor(Color.black)
|
||||||
|
g.drawLine(0, 0, width, 0)
|
||||||
|
g.drawLine(0, 0, 0, height)
|
||||||
|
var x = 17
|
||||||
|
while ( {
|
||||||
|
x <= width
|
||||||
|
}) {
|
||||||
|
g.drawLine(x, 0, x, height)
|
||||||
|
|
||||||
|
x += 17
|
||||||
|
}
|
||||||
|
var y = 17
|
||||||
|
while ( {
|
||||||
|
y <= height
|
||||||
|
}) {
|
||||||
|
g.drawLine(0, y, width, y)
|
||||||
|
|
||||||
|
y += 17
|
||||||
|
}
|
||||||
|
val rm = EditorAPI.toRawMap(baseWidth, baseHeight)
|
||||||
|
rm.setFont(image)
|
||||||
|
EditorAPI.open(rm)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
def launchGameMode: Boolean = {
|
||||||
|
println("Lancement du jeu ...")
|
||||||
|
val jfc = EditorAPI.createJFC
|
||||||
|
jfc.showOpenDialog(MainFrame.getInstance)
|
||||||
|
if (jfc.getSelectedFile == null) return false
|
||||||
|
val map = EditorAPI.getRawMap(jfc.getSelectedFile)
|
||||||
|
new GameFrame(map)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package fr.ynerant.leveleditor.editor
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.Collision
|
||||||
|
import javax.swing._
|
||||||
|
import java.awt._
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
|
||||||
|
|
||||||
|
@SerialVersionUID(-138754019431984881L)
|
||||||
|
object CollidPanel {
|
||||||
|
def isEmpty(image: BufferedImage): Boolean = {
|
||||||
|
var allrgba = 0
|
||||||
|
for (x <- 0 until image.getWidth) {
|
||||||
|
for (y <- 0 until image.getHeight) {
|
||||||
|
allrgba += image.getRGB(x, y) + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allrgba == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerialVersionUID(-138754019431984881L)
|
||||||
|
class CollidPanel(val frame: EditorFrame) extends JPanel {
|
||||||
|
def getMap: Map = frame.getMap
|
||||||
|
|
||||||
|
override def paintComponent(g: Graphics): Unit = {
|
||||||
|
g.fillRect(0, 0, getWidth, getHeight)
|
||||||
|
val img = getMap.getFont
|
||||||
|
val x = getWidth / 2 - img.getWidth
|
||||||
|
val y = getHeight / 2 - img.getHeight
|
||||||
|
val width = img.getWidth * 2
|
||||||
|
val height = img.getHeight * 2
|
||||||
|
g.drawImage(getMap.getFont, x, y, width, height, null)
|
||||||
|
getMap.getAllCases.forEach(c => {
|
||||||
|
if (!CollidPanel.isEmpty(c.getCoucheOne.getImage)) {
|
||||||
|
g.drawImage(c.getCoucheOne.getImage, x + c.getPosX * 34 + 2, y + c.getPosY * 34 + 2, 32, 32, null)
|
||||||
|
if (!CollidPanel.isEmpty(c.getCoucheTwo.getImage)) {
|
||||||
|
g.drawImage(c.getCoucheTwo.getImage, x + c.getPosX * 34 + 2, y + c.getPosY * 34 + 2, 32, 32, null)
|
||||||
|
if (!CollidPanel.isEmpty(c.getCoucheThree.getImage))
|
||||||
|
g.drawImage(c.getCoucheThree.getImage, x + c.getPosX * 34 + 2, y + c.getPosY * 34 + 2, 32, 32, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
getMap.getAllCases.forEach(c => {
|
||||||
|
if (c.getCollision ne Collision.ANY) {
|
||||||
|
val alpha = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB)
|
||||||
|
if (c.getCollision eq Collision.FULL) {
|
||||||
|
val grap = alpha.createGraphics
|
||||||
|
grap.setColor(new Color(0, 0, 0, 100))
|
||||||
|
grap.fillRect(0, 0, 16, 16)
|
||||||
|
grap.dispose()
|
||||||
|
}
|
||||||
|
else if (c.getCollision eq Collision.PARTIAL) {
|
||||||
|
val grap = alpha.createGraphics
|
||||||
|
grap.setColor(new Color(255, 0, 255, 70))
|
||||||
|
grap.fillRect(0, 0, 16, 16)
|
||||||
|
grap.dispose()
|
||||||
|
}
|
||||||
|
g.drawImage(alpha, x + c.getPosX * 34 + 2, y + c.getPosY * 34 + 2, 32, 32, null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,248 @@
|
||||||
|
package fr.ynerant.leveleditor.editor
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister
|
||||||
|
import fr.ynerant.leveleditor.frame.listeners._
|
||||||
|
import javax.swing._
|
||||||
|
import javax.swing.event.ChangeEvent
|
||||||
|
import javax.swing.event.ChangeListener
|
||||||
|
import java.awt._
|
||||||
|
import java.awt.event._
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.{EditorAPI, RawMap}
|
||||||
|
|
||||||
|
|
||||||
|
@SerialVersionUID(-2705122356101556462L)
|
||||||
|
class EditorFrame(val map: Map) extends JFrame("Level Editor") with ChangeListener with ActionListener with WindowListener {
|
||||||
|
final private val save = new JMenuItem("Sauvegarder")
|
||||||
|
final private val saveAs = new JMenuItem("Sauvegarder sous ...")
|
||||||
|
final private val exit = new JMenuItem("Quitter")
|
||||||
|
final private val pen = new JRadioButtonMenuItem("Pinceau")
|
||||||
|
final private val pot = new JRadioButtonMenuItem("Pot de peinture")
|
||||||
|
final private val tabs = new JTabbedPane
|
||||||
|
final private var tabColl = null: CollidPanel
|
||||||
|
final private var mapPanel = null: MapPanel
|
||||||
|
final private val resources = new JTabbedPane
|
||||||
|
final private val couche1 = new JPanel
|
||||||
|
final private val couche2 = new JPanel
|
||||||
|
final private val couche3 = new JPanel
|
||||||
|
final private[editor] val group = new ButtonGroup
|
||||||
|
private var selectedSprite = null: SpriteComp
|
||||||
|
|
||||||
|
this.setSize(600, 600)
|
||||||
|
this.setPreferredSize(getSize)
|
||||||
|
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE)
|
||||||
|
this.setExtendedState(Frame.MAXIMIZED_BOTH)
|
||||||
|
this.setLocationRelativeTo(null)
|
||||||
|
this.addWindowListener(this)
|
||||||
|
val content = new JPanel
|
||||||
|
content.setLayout(new BorderLayout)
|
||||||
|
this.setContentPane(content)
|
||||||
|
this.setVisible(true)
|
||||||
|
this.setVisible(false)
|
||||||
|
val fichier = new JMenu("Fichier")
|
||||||
|
fichier.setMnemonic(KeyEvent.VK_F + KeyEvent.VK_ALT)
|
||||||
|
val nouveau = new JMenuItem("Nouveau")
|
||||||
|
nouveau.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.VK_CONTROL, true))
|
||||||
|
nouveau.addActionListener(new CreateMapListener)
|
||||||
|
fichier.add(nouveau)
|
||||||
|
val open = new JMenuItem("Ouvrir")
|
||||||
|
open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.VK_CONTROL, true))
|
||||||
|
open.addActionListener(new OpenMapListener)
|
||||||
|
fichier.add(open)
|
||||||
|
fichier.addSeparator()
|
||||||
|
save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.VK_CONTROL, true))
|
||||||
|
save.addActionListener(this)
|
||||||
|
fichier.add(save)
|
||||||
|
saveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.VK_CONTROL + KeyEvent.VK_SHIFT, true))
|
||||||
|
saveAs.addActionListener(this)
|
||||||
|
fichier.add(saveAs)
|
||||||
|
fichier.addSeparator()
|
||||||
|
exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, KeyEvent.VK_CONTROL, true))
|
||||||
|
exit.addActionListener(this)
|
||||||
|
fichier.add(exit)
|
||||||
|
val bar: JMenuBar = new JMenuBar
|
||||||
|
bar.add(fichier)
|
||||||
|
pen.setSelected(true)
|
||||||
|
pen.addActionListener(this)
|
||||||
|
pot.addActionListener(this)
|
||||||
|
group.add(pen)
|
||||||
|
group.add(pot)
|
||||||
|
val selectionMode = new JMenu("Mode de s\u00e9lection")
|
||||||
|
selectionMode.add(pen)
|
||||||
|
selectionMode.add(pot)
|
||||||
|
val tools = new JMenu("Outils")
|
||||||
|
tools.setMnemonic(KeyEvent.VK_O + KeyEvent.VK_ALT)
|
||||||
|
tools.add(selectionMode)
|
||||||
|
bar.add(tools)
|
||||||
|
this.setJMenuBar(bar)
|
||||||
|
mapPanel = new MapPanel(this)
|
||||||
|
mapPanel.addMouseListener(new MapMouseListener(mapPanel, this))
|
||||||
|
mapPanel.addMouseMotionListener(new MapMouseListener(mapPanel, this))
|
||||||
|
tabColl = new CollidPanel(this)
|
||||||
|
tabColl.addMouseListener(new CollidMapMouseListener(tabColl, this))
|
||||||
|
tabColl.addMouseMotionListener(new CollidMapMouseListener(tabColl, this))
|
||||||
|
val scrollMap = new JScrollPane(mapPanel)
|
||||||
|
scrollMap.getHorizontalScrollBar.setUnitIncrement(34)
|
||||||
|
scrollMap.getVerticalScrollBar.setUnitIncrement(34)
|
||||||
|
val scrollCollidMap = new JScrollPane(tabColl)
|
||||||
|
scrollCollidMap.getHorizontalScrollBar.setUnitIncrement(34)
|
||||||
|
scrollCollidMap.getVerticalScrollBar.setUnitIncrement(34)
|
||||||
|
tabs.addTab("Carte", scrollMap)
|
||||||
|
val tabEvents = new JPanel
|
||||||
|
tabs.addTab("\u00c9vennments", new JScrollPane(tabEvents))
|
||||||
|
tabs.addTab("Collisions", scrollCollidMap)
|
||||||
|
tabs.addChangeListener(this)
|
||||||
|
content.add(tabs, BorderLayout.CENTER)
|
||||||
|
couche1.setLayout(new WrapLayout(FlowLayout.LEFT))
|
||||||
|
couche2.setLayout(new WrapLayout(FlowLayout.LEFT))
|
||||||
|
couche3.setLayout(new WrapLayout(FlowLayout.LEFT))
|
||||||
|
val scroll1 = new JScrollPane(couche1, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER)
|
||||||
|
val scroll2 = new JScrollPane(couche2, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER)
|
||||||
|
val scroll3 = new JScrollPane(couche3, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER)
|
||||||
|
scroll1.getHorizontalScrollBar.setMaximum(0)
|
||||||
|
scroll2.getHorizontalScrollBar.setMaximum(0)
|
||||||
|
scroll3.getHorizontalScrollBar.setMaximum(0)
|
||||||
|
resources.addTab("", new ImageIcon(new File("assets/leveleditor/textures/layer 1.png").getAbsolutePath), scroll1)
|
||||||
|
resources.addTab("", new ImageIcon(new File("assets/leveleditor/textures/layer 2.png").getAbsolutePath), scroll2)
|
||||||
|
resources.addTab("", new ImageIcon(new File("assets/leveleditor/textures/layer 3.png").getAbsolutePath), scroll3)
|
||||||
|
resources.addChangeListener(this)
|
||||||
|
resources.setBackgroundAt(0, Color.white)
|
||||||
|
resources.setBackgroundAt(1, Color.white)
|
||||||
|
resources.setBackgroundAt(2, Color.white)
|
||||||
|
content.add(resources, BorderLayout.EAST)
|
||||||
|
resize()
|
||||||
|
drawResources()
|
||||||
|
revalidate()
|
||||||
|
repaint()
|
||||||
|
|
||||||
|
private def drawResources(): Unit = {
|
||||||
|
couche1.removeAll()
|
||||||
|
couche2.removeAll()
|
||||||
|
couche3.removeAll()
|
||||||
|
if (couche1.getComponents.length > 0) return
|
||||||
|
if (couche1.getWidth == 0 || couche2.getWidth == 0 || couche3.getWidth == 0) {
|
||||||
|
couche1.repaint()
|
||||||
|
couche2.repaint()
|
||||||
|
couche3.repaint()
|
||||||
|
}
|
||||||
|
SpriteRegister.getAllCategories.forEach(cat => {
|
||||||
|
cat.getSprites.forEach(spr => {
|
||||||
|
val sprc1 = new SpriteComp(spr, 0)
|
||||||
|
val sprc2 = new SpriteComp(spr, 1)
|
||||||
|
val sprc3 = new SpriteComp(spr, 2)
|
||||||
|
sprc1.addMouseListener(new SpriteMouseListener(sprc1, this))
|
||||||
|
sprc2.addMouseListener(new SpriteMouseListener(sprc2, this))
|
||||||
|
sprc3.addMouseListener(new SpriteMouseListener(sprc3, this))
|
||||||
|
couche1.add(sprc1)
|
||||||
|
couche2.add(sprc2)
|
||||||
|
couche3.add(sprc3)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
couche1.revalidate()
|
||||||
|
couche2.revalidate()
|
||||||
|
couche3.revalidate()
|
||||||
|
couche1.repaint()
|
||||||
|
couche2.repaint()
|
||||||
|
couche3.repaint()
|
||||||
|
}
|
||||||
|
|
||||||
|
def resize(): Unit = {
|
||||||
|
val cursorPos = resources.getSelectedComponent.asInstanceOf[JScrollPane].getVerticalScrollBar.getValue
|
||||||
|
tabs.setPreferredSize(new Dimension(getWidth, getHeight / 5))
|
||||||
|
tabs.setLocation(0, 0)
|
||||||
|
val img = getMap.getFont
|
||||||
|
val width = img.getWidth * 2
|
||||||
|
val height = img.getHeight * 2
|
||||||
|
mapPanel.setPreferredSize(new Dimension(width, height))
|
||||||
|
mapPanel.setLocation(0, getHeight / 5)
|
||||||
|
tabColl.setPreferredSize(new Dimension(width, height))
|
||||||
|
tabColl.setLocation(0, getHeight / 5)
|
||||||
|
resources.setPreferredSize(new Dimension(getWidth / 4 - 15, getHeight / 5 * 4 - 40))
|
||||||
|
resources.setLocation(getWidth / 4 * 3, getHeight / 5)
|
||||||
|
val scroll1 = resources.getComponent(0).asInstanceOf[JScrollPane]
|
||||||
|
val scroll2 = resources.getComponent(1).asInstanceOf[JScrollPane]
|
||||||
|
val scroll3 = resources.getComponent(2).asInstanceOf[JScrollPane]
|
||||||
|
scroll1.getHorizontalScrollBar.setMaximum(0)
|
||||||
|
scroll2.getHorizontalScrollBar.setMaximum(0)
|
||||||
|
scroll3.getHorizontalScrollBar.setMaximum(0)
|
||||||
|
drawResources()
|
||||||
|
resources.getSelectedComponent.asInstanceOf[JScrollPane].getVerticalScrollBar.setValue(cursorPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
def getMap: Map = map
|
||||||
|
|
||||||
|
def getSelectedSprite: SpriteComp = selectedSprite
|
||||||
|
|
||||||
|
def setSelectedSprite(sprite: SpriteComp): Unit = {
|
||||||
|
this.selectedSprite = sprite
|
||||||
|
}
|
||||||
|
|
||||||
|
override def stateChanged(event: ChangeEvent): Unit = {
|
||||||
|
if (event.getSource eq resources) {
|
||||||
|
if (getSelectedLayerIndex == 0) {
|
||||||
|
resources.setBackgroundAt(0, Color.white)
|
||||||
|
resources.setBackgroundAt(1, Color.white)
|
||||||
|
resources.setBackgroundAt(2, Color.white)
|
||||||
|
}
|
||||||
|
else if (getSelectedLayerIndex == 1) {
|
||||||
|
resources.setBackgroundAt(0, Color.black)
|
||||||
|
resources.setBackgroundAt(1, Color.white)
|
||||||
|
resources.setBackgroundAt(2, Color.white)
|
||||||
|
}
|
||||||
|
else if (getSelectedLayerIndex == 2) {
|
||||||
|
resources.setBackgroundAt(0, Color.black)
|
||||||
|
resources.setBackgroundAt(1, Color.black)
|
||||||
|
resources.setBackgroundAt(2, Color.white)
|
||||||
|
}
|
||||||
|
repaint()
|
||||||
|
}
|
||||||
|
else if (event.getSource eq tabs) {
|
||||||
|
resources.setEnabled(tabs.getSelectedIndex == 0)
|
||||||
|
couche1.setEnabled(resources.isEnabled)
|
||||||
|
couche2.setEnabled(resources.isEnabled)
|
||||||
|
couche3.setEnabled(resources.isEnabled)
|
||||||
|
repaint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getSelectedLayerIndex: Int = resources.getSelectedIndex
|
||||||
|
|
||||||
|
override def actionPerformed(event: ActionEvent): Unit = {
|
||||||
|
if (event.getSource eq save) EditorAPI.save(RawMap.create(map))
|
||||||
|
else if (event.getSource eq saveAs) EditorAPI.saveAs(RawMap.create(map))
|
||||||
|
else if (event.getSource eq exit) {
|
||||||
|
val result = JOptionPane.showConfirmDialog(null, "Voulez-vous sauvegarder votre carte avant de quitter ? Toute modification sera perdue", "Confirmation", JOptionPane.YES_NO_CANCEL_OPTION)
|
||||||
|
if (result == 0) save.doClick()
|
||||||
|
if (result != 2) dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getSelectedPaintingMode: Int = if (pen.isSelected) 0
|
||||||
|
else if (pot.isSelected) 1
|
||||||
|
else -1
|
||||||
|
|
||||||
|
override def windowActivated(event: WindowEvent): Unit = {
|
||||||
|
}
|
||||||
|
|
||||||
|
override def windowClosed(event: WindowEvent): Unit = {
|
||||||
|
}
|
||||||
|
|
||||||
|
override def windowClosing(event: WindowEvent): Unit = {
|
||||||
|
val result = JOptionPane.showConfirmDialog(null, "Voulez-vous sauvegarder avant de quitter ?", "Confirmation", JOptionPane.YES_NO_CANCEL_OPTION)
|
||||||
|
if (result == 0) EditorAPI.save(RawMap.create(map))
|
||||||
|
if (result != 2) dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override def windowDeactivated(event: WindowEvent): Unit = {
|
||||||
|
}
|
||||||
|
|
||||||
|
override def windowDeiconified(event: WindowEvent): Unit = {
|
||||||
|
}
|
||||||
|
|
||||||
|
override def windowIconified(event: WindowEvent): Unit = {
|
||||||
|
}
|
||||||
|
|
||||||
|
override def windowOpened(event: WindowEvent): Unit = {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package fr.ynerant.leveleditor.editor
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.util
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.{Case, RawMap}
|
||||||
|
|
||||||
|
|
||||||
|
object Map {
|
||||||
|
private var cases = null: util.ArrayList[Case]
|
||||||
|
}
|
||||||
|
|
||||||
|
class Map(val raw: RawMap) {
|
||||||
|
final private var frame = null: EditorFrame
|
||||||
|
final private var width = 0
|
||||||
|
final private var height = 0
|
||||||
|
final private val casesMap = new util.HashMap[Integer, util.Map[Integer, Case]]
|
||||||
|
final private var font = null: BufferedImage
|
||||||
|
|
||||||
|
Map.cases = new util.ArrayList[Case]
|
||||||
|
this.width = raw.getWidth
|
||||||
|
this.height = raw.getHeight
|
||||||
|
this.font = raw.getFont
|
||||||
|
|
||||||
|
raw.getCases.forEach(rc =>
|
||||||
|
Map.cases.add(Case.create(rc.getPosX, rc.getPosY, SpriteRegister.getCategory(rc.getCoucheOne.getCategory).getSprites.get(rc.getCoucheOne.getIndex), SpriteRegister.getCategory(rc.getCoucheTwo.getCategory).getSprites.get(rc.getCoucheTwo.getIndex), SpriteRegister.getCategory(rc.getCoucheThree.getCategory).getSprites.get(rc.getCoucheThree.getIndex), rc.getCollision))
|
||||||
|
)
|
||||||
|
|
||||||
|
reorganizeMap()
|
||||||
|
frame = new EditorFrame(this)
|
||||||
|
getFrame.setVisible(true)
|
||||||
|
|
||||||
|
def getFrame: EditorFrame = frame
|
||||||
|
|
||||||
|
def getWidth: Int = width
|
||||||
|
|
||||||
|
def getHeight: Int = height
|
||||||
|
|
||||||
|
def getCase(x: Int, y: Int): Case = casesMap.getOrDefault(x, new util.HashMap[Integer, Case]).get(y)
|
||||||
|
|
||||||
|
def setCase(x: Int, y: Int, c: Case): Unit = {
|
||||||
|
casesMap.get(x).put(y, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
def getFont: BufferedImage = font
|
||||||
|
|
||||||
|
private def reorganizeMap(): Unit = {
|
||||||
|
for (i <- 0 until width) {
|
||||||
|
casesMap.put(i, new util.HashMap[Integer, Case])
|
||||||
|
}
|
||||||
|
Map.cases.forEach(c => setCase(c.getPosX, c.getPosY, c))
|
||||||
|
}
|
||||||
|
|
||||||
|
def getAllCases: util.List[Case] = {
|
||||||
|
val list = new util.ArrayList[Case]
|
||||||
|
casesMap.values.forEach(l => list.addAll(l.values()))
|
||||||
|
list
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package fr.ynerant.leveleditor.editor
|
||||||
|
|
||||||
|
import javax.swing._
|
||||||
|
import java.awt._
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
|
||||||
|
|
||||||
|
@SerialVersionUID(2629019576253690557L)
|
||||||
|
class MapPanel(val frame: EditorFrame) extends JPanel {
|
||||||
|
def getMap: Map = frame.getMap
|
||||||
|
|
||||||
|
override def paintComponent(g: Graphics): Unit = {
|
||||||
|
g.fillRect(0, 0, getWidth, getHeight)
|
||||||
|
val img = getMap.getFont
|
||||||
|
val x = getWidth / 2 - img.getWidth
|
||||||
|
val y = getHeight / 2 - img.getHeight
|
||||||
|
val width = img.getWidth * 2
|
||||||
|
val height = img.getHeight * 2
|
||||||
|
g.drawImage(getMap.getFont, x, y, width, height, null)
|
||||||
|
getMap.getAllCases.forEach(c => { // BufferedImage image;
|
||||||
|
if (!isEmpty(c.getCoucheOne.getImage)) g.drawImage(c.getCoucheOne.getImage, x + c.getPosX * 34 + 2, y + c.getPosY * 34 + 2, 32, 32, null)
|
||||||
|
/* if (frame.getSelectedLayerIndex() != 0)
|
||||||
|
{
|
||||||
|
image = recalculateAplha(c.getCoucheOne().getImage(), 0);
|
||||||
|
g.drawImage(image, x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
||||||
|
}*/ if (!isEmpty(c.getCoucheTwo.getImage) && frame.getSelectedLayerIndex >= 1) g.drawImage(c.getCoucheTwo.getImage, x + c.getPosX * 34 + 2, y + c.getPosY * 34 + 2, 32, 32, null)
|
||||||
|
/* if (frame.getSelectedLayerIndex() != 1)
|
||||||
|
{
|
||||||
|
image = recalculateAplha(c.getCoucheTwo().getImage(), 1);
|
||||||
|
g.drawImage(image, x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
||||||
|
}*/ if (!isEmpty(c.getCoucheThree.getImage) && frame.getSelectedLayerIndex == 2) g.drawImage(c.getCoucheThree.getImage, x + c.getPosX * 34 + 2, y + c.getPosY * 34 + 2, 32, 32, null)
|
||||||
|
/* if (frame.getSelectedLayerIndex() != 2)
|
||||||
|
{
|
||||||
|
image = recalculateAplha(c.getCoucheThree().getImage(), 2);
|
||||||
|
g.drawImage(image, x + c.getPosX() * 34 + 2, y + c.getPosY() * 34 + 2, 32, 32, null);
|
||||||
|
}*/
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings(Array("BooleanMethodIsAlwaysInverted")) private def isEmpty(image: BufferedImage) = {
|
||||||
|
var allrgba = 0
|
||||||
|
for (x <- 0 until image.getWidth) {
|
||||||
|
for (y <- 0 until image.getHeight) {
|
||||||
|
allrgba += image.getRGB(x, y) + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allrgba == 0
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package fr.ynerant.leveleditor.editor
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.Sprite
|
||||||
|
import javax.swing._
|
||||||
|
import java.awt._
|
||||||
|
|
||||||
|
|
||||||
|
@SerialVersionUID(-6512257366877053285L)
|
||||||
|
class SpriteComp(val sprite: Sprite, val couche: Int) extends JComponent {
|
||||||
|
this.setMinimumSize(new Dimension(32, 32))
|
||||||
|
this.setMaximumSize(new Dimension(32, 32))
|
||||||
|
this.setPreferredSize(new Dimension(32, 32))
|
||||||
|
this.setSize(new Dimension(32, 32))
|
||||||
|
repaint()
|
||||||
|
private var selected = false
|
||||||
|
|
||||||
|
def getSprite: Sprite = sprite
|
||||||
|
|
||||||
|
def getCouche: Int = couche
|
||||||
|
|
||||||
|
def isSelected: Boolean = selected
|
||||||
|
|
||||||
|
def setSelected(selected: Boolean): Unit = {
|
||||||
|
this.selected = selected
|
||||||
|
}
|
||||||
|
|
||||||
|
override def paintComponent(g: Graphics): Unit = {
|
||||||
|
super.paintComponent(g)
|
||||||
|
g.setColor(Color.white)
|
||||||
|
g.fillRect(0, 0, getWidth, getHeight)
|
||||||
|
g.drawImage(sprite.getImage, 0, 0, 32, 32, Color.white, null)
|
||||||
|
if (isSelected) {
|
||||||
|
g.setColor(Color.black)
|
||||||
|
g.drawLine(0, 0, getWidth - 1, 0)
|
||||||
|
g.drawLine(0, 0, 0, getHeight - 1)
|
||||||
|
g.drawLine(0, getHeight - 1, getWidth - 1, getHeight - 1)
|
||||||
|
g.drawLine(getWidth - 1, 0, getWidth - 1, getHeight - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package fr.ynerant.leveleditor.editor
|
||||||
|
|
||||||
|
import javax.swing._
|
||||||
|
import java.awt._
|
||||||
|
|
||||||
|
|
||||||
|
@SerialVersionUID(8777237960365591646L)
|
||||||
|
class WrapLayout(val alignment: Int) extends FlowLayout(alignment) {
|
||||||
|
override def preferredLayoutSize(target: Container): Dimension = layoutSize(target, preferred = true)
|
||||||
|
|
||||||
|
override def minimumLayoutSize(target: Container): Dimension = {
|
||||||
|
val minimum = layoutSize(target, preferred = false)
|
||||||
|
minimum.width -= (getHgap + 1)
|
||||||
|
minimum
|
||||||
|
}
|
||||||
|
|
||||||
|
private def layoutSize(target: Container, preferred: Boolean) = {
|
||||||
|
var targetWidth = target.getSize.width
|
||||||
|
if (targetWidth == 0) targetWidth = Integer.MAX_VALUE
|
||||||
|
val hgap = getHgap
|
||||||
|
val vgap = getVgap
|
||||||
|
val insets = target.getInsets
|
||||||
|
val horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2)
|
||||||
|
val maxWidth = targetWidth - horizontalInsetsAndGap
|
||||||
|
val dim = new Dimension(0, 0)
|
||||||
|
var rowWidth = 0
|
||||||
|
var rowHeight = 0
|
||||||
|
val nmembers = target.getComponentCount
|
||||||
|
for (i <- 0 until nmembers) {
|
||||||
|
val m = target.getComponent(i)
|
||||||
|
if (m.isVisible) {
|
||||||
|
val d = if (preferred) m.getPreferredSize
|
||||||
|
else m.getMinimumSize
|
||||||
|
if (rowWidth + d.width > maxWidth) {
|
||||||
|
addRow(dim, rowWidth, rowHeight)
|
||||||
|
rowWidth = 0
|
||||||
|
rowHeight = 0
|
||||||
|
}
|
||||||
|
if (rowWidth != 0) rowWidth += hgap
|
||||||
|
rowWidth += d.width
|
||||||
|
rowHeight = Math.max(rowHeight, d.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addRow(dim, rowWidth, rowHeight)
|
||||||
|
dim.width += horizontalInsetsAndGap
|
||||||
|
dim.height += insets.top + insets.bottom + vgap * 2
|
||||||
|
val scrollPane = SwingUtilities.getAncestorOfClass(classOf[JScrollPane], target)
|
||||||
|
if (scrollPane != null) dim.width -= (hgap + 1)
|
||||||
|
dim
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private def addRow(dim: Dimension, rowWidth: Int, rowHeight: Int): Unit = {
|
||||||
|
dim.width = Math.max(dim.width, rowWidth)
|
||||||
|
if (dim.height > 0) dim.height += getVgap
|
||||||
|
dim.height += rowHeight
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package fr.ynerant.leveleditor.frame
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.frame.listeners.ChangeLAFListener
|
||||||
|
import fr.ynerant.leveleditor.frame.listeners.CreateMapListener
|
||||||
|
import fr.ynerant.leveleditor.frame.listeners.OpenMapListener
|
||||||
|
import javax.swing._
|
||||||
|
import java.awt._
|
||||||
|
import java.awt.event.{ActionEvent, KeyEvent}
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.client.main.Main
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fenêtre principale du jeu
|
||||||
|
*
|
||||||
|
* @author ÿnérant
|
||||||
|
*/
|
||||||
|
@SerialVersionUID(-3168760121879418534L)
|
||||||
|
object MainFrame {
|
||||||
|
/**
|
||||||
|
* Instance unique principale
|
||||||
|
*
|
||||||
|
* @see #MainFrame()
|
||||||
|
* @see #getInstance()
|
||||||
|
*/
|
||||||
|
private var INSTANCE = null: MainFrame
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cet accesseur renvoie l'accesseur unique de la classe
|
||||||
|
*
|
||||||
|
* @return l'instance unique de la classe
|
||||||
|
* @see #INSTANCE
|
||||||
|
* @see #MainFrame()
|
||||||
|
*/
|
||||||
|
def getInstance: MainFrame = {
|
||||||
|
if (INSTANCE == null) INSTANCE = new MainFrame
|
||||||
|
INSTANCE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerialVersionUID(-3168760121879418534L)
|
||||||
|
class MainFrame @SuppressWarnings(Array("JavadocReference")) private()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructeur
|
||||||
|
*
|
||||||
|
* @see Main#launchFrame()
|
||||||
|
*/
|
||||||
|
extends JFrame {
|
||||||
|
println("Initialisation de la fen\u00eatre")
|
||||||
|
this.setTitle("Level Editor")
|
||||||
|
this.setPreferredSize(new Dimension(1000, 800))
|
||||||
|
this.setSize(800, 700)
|
||||||
|
this.setLocationRelativeTo(null)
|
||||||
|
this.setExtendedState(Frame.MAXIMIZED_BOTH)
|
||||||
|
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
|
||||||
|
val fichier = new JMenu("Fichier")
|
||||||
|
fichier.setMnemonic(KeyEvent.VK_F + KeyEvent.VK_ALT)
|
||||||
|
val display = new JMenu("Affichage")
|
||||||
|
display.setMnemonic(KeyEvent.VK_A + KeyEvent.VK_ALT)
|
||||||
|
val createMap = new JMenuItem("Cr\u00e9er")
|
||||||
|
createMap.addActionListener(new CreateMapListener)
|
||||||
|
val editMaps = new JMenu("Cartes")
|
||||||
|
editMaps.add(createMap)
|
||||||
|
val openMap = new JMenuItem("Ouvrir")
|
||||||
|
openMap.addActionListener(new OpenMapListener)
|
||||||
|
editMaps.add(openMap)
|
||||||
|
fichier.add(editMaps)
|
||||||
|
val systemLAF = new JMenuItem("Apparence syst\u00e8me")
|
||||||
|
systemLAF.addActionListener(new ChangeLAFListener(systemLAF, this))
|
||||||
|
val changeLAF = new JMenu("Modfier l'apparence")
|
||||||
|
changeLAF.add(systemLAF)
|
||||||
|
val javaLAF = new JMenuItem("Apparence Java")
|
||||||
|
javaLAF.addActionListener(new ChangeLAFListener(javaLAF, this))
|
||||||
|
changeLAF.add(javaLAF)
|
||||||
|
val darkLAF = new JMenuItem("Apparence sombre")
|
||||||
|
darkLAF.addActionListener(new ChangeLAFListener(darkLAF, this))
|
||||||
|
changeLAF.add(darkLAF)
|
||||||
|
display.add(changeLAF)
|
||||||
|
val bar = new JMenuBar
|
||||||
|
bar.add(fichier)
|
||||||
|
bar.add(display)
|
||||||
|
this.setJMenuBar(bar)
|
||||||
|
val start = new JButton("Commencer la partie !")
|
||||||
|
start.addActionListener((actionEvent: ActionEvent) => {
|
||||||
|
if (Main.launchGameMode) MainFrame.getInstance.dispose()
|
||||||
|
})
|
||||||
|
this.setContentPane(start)
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package fr.ynerant.leveleditor.frame.listeners
|
||||||
|
|
||||||
|
import javax.swing._
|
||||||
|
import java.awt.event.ActionEvent
|
||||||
|
import java.awt.event.ActionListener
|
||||||
|
|
||||||
|
|
||||||
|
class ChangeLAFListener(val item: JMenuItem, val frame: JFrame) extends ActionListener {
|
||||||
|
override def actionPerformed(event: ActionEvent): Unit = {
|
||||||
|
if (item.getText.toLowerCase.contains("sys")) {
|
||||||
|
try UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName)
|
||||||
|
catch {
|
||||||
|
case e: Exception =>
|
||||||
|
new ExceptionInInitializerError("Erreur lors du changement de 'look and feel'").printStackTrace()
|
||||||
|
System.err.print("Caused by ")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
SwingUtilities.updateComponentTreeUI(frame)
|
||||||
|
}
|
||||||
|
else if (item.getText.toLowerCase.contains("java")) {
|
||||||
|
try UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName)
|
||||||
|
catch {
|
||||||
|
case e: Exception =>
|
||||||
|
new ExceptionInInitializerError("Erreur lors du changement de 'look and feel'").printStackTrace()
|
||||||
|
System.err.print("Caused by ")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
SwingUtilities.updateComponentTreeUI(frame)
|
||||||
|
}
|
||||||
|
else if (item.getText.toLowerCase.contains("sombre")) {
|
||||||
|
try UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel")
|
||||||
|
catch {
|
||||||
|
case e: Exception =>
|
||||||
|
new ExceptionInInitializerError("Erreur lors du changement de 'look and feel'").printStackTrace()
|
||||||
|
System.err.print("Caused by ")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
SwingUtilities.updateComponentTreeUI(frame)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package fr.ynerant.leveleditor.frame.listeners
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.{Case, Collision}
|
||||||
|
import java.awt.event.MouseAdapter
|
||||||
|
import java.awt.event.MouseEvent
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.editor.{CollidPanel, EditorFrame}
|
||||||
|
|
||||||
|
|
||||||
|
class CollidMapMouseListener(val panel: CollidPanel, val frame: EditorFrame) extends MouseAdapter {
|
||||||
|
def getFrame: EditorFrame = frame
|
||||||
|
|
||||||
|
override def mouseReleased(event: MouseEvent): Unit = {
|
||||||
|
val map = getFrame.getMap
|
||||||
|
val x = panel.getWidth / 2 - map.getFont.getWidth
|
||||||
|
val y = panel.getHeight / 2 - map.getFont.getHeight
|
||||||
|
val c = map.getCase((event.getX - x + 2) / 34, (event.getY - y + 2) / 34)
|
||||||
|
if (c != null && event.getX - x >= 2 && event.getY - y >= 2) {
|
||||||
|
val colIndex = c.getCollision.id
|
||||||
|
var newColIndex = colIndex + 1
|
||||||
|
if (newColIndex >= Collision.values.size) newColIndex = 0
|
||||||
|
val col = Collision.apply(newColIndex)
|
||||||
|
val n = Case.create(c.getPosX, c.getPosY, c.getCoucheOne, c.getCoucheTwo, c.getCoucheThree, col)
|
||||||
|
map.setCase((event.getX - x + 2) / 34, (event.getY - y + 2) / 34, n)
|
||||||
|
panel.repaint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package fr.ynerant.leveleditor.frame.listeners
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent
|
||||||
|
import java.awt.event.ActionListener
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.client.main.Main
|
||||||
|
import fr.ynerant.leveleditor.frame.MainFrame
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ÿnérant
|
||||||
|
*/
|
||||||
|
class CreateMapListener extends ActionListener {
|
||||||
|
/* !CodeTemplates.overridecomment.nonjd!
|
||||||
|
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
|
||||||
|
*/ override def actionPerformed(event: ActionEvent): Unit = {
|
||||||
|
if (Main.launchEditMode) MainFrame.getInstance.dispose()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package fr.ynerant.leveleditor.frame.listeners
|
||||||
|
|
||||||
|
import java.awt.event.MouseAdapter
|
||||||
|
import java.awt.event.MouseEvent
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.Case
|
||||||
|
import fr.ynerant.leveleditor.editor.{EditorFrame, MapPanel}
|
||||||
|
|
||||||
|
|
||||||
|
class MapMouseListener(val panel: MapPanel, val frame: EditorFrame) extends MouseAdapter {
|
||||||
|
def getFrame: EditorFrame = frame
|
||||||
|
|
||||||
|
override def mouseClicked(event: MouseEvent): Unit = {
|
||||||
|
if (frame.getSelectedPaintingMode == 0) {
|
||||||
|
val map = getFrame.getMap
|
||||||
|
val x = panel.getWidth / 2 - map.getFont.getWidth
|
||||||
|
val y = panel.getHeight / 2 - map.getFont.getHeight
|
||||||
|
val c = map.getCase((event.getX - x + 2) / 34, (event.getY - y + 2) / 34): Case
|
||||||
|
if (c != null && event.getX - x >= 2 && event.getY - y >= 2) if (getFrame.getSelectedSprite != null) {
|
||||||
|
var n = null: Case
|
||||||
|
getFrame.getSelectedSprite.getCouche match {
|
||||||
|
case 0 =>
|
||||||
|
n = Case.create(c.getPosX, c.getPosY, getFrame.getSelectedSprite.getSprite, c.getCoucheTwo, c.getCoucheThree, c.getCollision)
|
||||||
|
|
||||||
|
case 1 =>
|
||||||
|
n = Case.create(c.getPosX, c.getPosY, c.getCoucheOne, getFrame.getSelectedSprite.getSprite, c.getCoucheThree, c.getCollision)
|
||||||
|
|
||||||
|
case 2 =>
|
||||||
|
n = Case.create(c.getPosX, c.getPosY, c.getCoucheOne, c.getCoucheTwo, getFrame.getSelectedSprite.getSprite, c.getCollision)
|
||||||
|
|
||||||
|
case _ =>
|
||||||
|
n = c
|
||||||
|
|
||||||
|
}
|
||||||
|
map.setCase(n.getPosX, n.getPosY, n)
|
||||||
|
panel.repaint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (frame.getSelectedPaintingMode == 1) {
|
||||||
|
getFrame.getMap.getAllCases.forEach(c => {
|
||||||
|
val map = getFrame.getMap
|
||||||
|
if (getFrame.getSelectedSprite != null) {
|
||||||
|
if (getFrame.getSelectedSprite.getCouche - 1 > getFrame.getSelectedLayerIndex) return
|
||||||
|
var n = null: Case
|
||||||
|
getFrame.getSelectedSprite.getCouche match {
|
||||||
|
case 0 =>
|
||||||
|
n = Case.create(c.getPosX, c.getPosY, getFrame.getSelectedSprite.getSprite, c.getCoucheTwo, c.getCoucheThree, c.getCollision)
|
||||||
|
|
||||||
|
case 1 =>
|
||||||
|
n = Case.create(c.getPosX, c.getPosY, c.getCoucheOne, getFrame.getSelectedSprite.getSprite, c.getCoucheThree, c.getCollision)
|
||||||
|
|
||||||
|
case 2 =>
|
||||||
|
n = Case.create(c.getPosX, c.getPosY, c.getCoucheOne, c.getCoucheTwo, getFrame.getSelectedSprite.getSprite, c.getCollision)
|
||||||
|
|
||||||
|
case _ =>
|
||||||
|
n = c
|
||||||
|
|
||||||
|
}
|
||||||
|
map.setCase(n.getPosX, n.getPosY, n)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
panel.repaint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def mouseDragged(event: MouseEvent): Unit = {
|
||||||
|
if (frame.getSelectedPaintingMode == 0) mouseClicked(event)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package fr.ynerant.leveleditor.frame.listeners
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent
|
||||||
|
import java.awt.event.ActionListener
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.EditorAPI
|
||||||
|
import fr.ynerant.leveleditor.frame.MainFrame
|
||||||
|
|
||||||
|
|
||||||
|
class OpenMapListener extends ActionListener {
|
||||||
|
/* !CodeTemplates.overridecomment.nonjd!
|
||||||
|
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
|
||||||
|
*/ override def actionPerformed(event: ActionEvent): Unit = {
|
||||||
|
if (EditorAPI.open != null) MainFrame.getInstance.dispose()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package fr.ynerant.leveleditor.frame.listeners
|
||||||
|
|
||||||
|
import java.awt.event.MouseAdapter
|
||||||
|
import java.awt.event.MouseEvent
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.editor.{EditorFrame, SpriteComp}
|
||||||
|
|
||||||
|
|
||||||
|
class SpriteMouseListener(val sprite: SpriteComp, val frame: EditorFrame) extends MouseAdapter {
|
||||||
|
override def mouseReleased(event: MouseEvent): Unit = {
|
||||||
|
if (frame.getSelectedSprite != null) {
|
||||||
|
frame.getSelectedSprite.setSelected(false)
|
||||||
|
frame.getSelectedSprite.repaint()
|
||||||
|
}
|
||||||
|
frame.setSelectedSprite(sprite)
|
||||||
|
sprite.setSelected(true)
|
||||||
|
sprite.repaint()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,193 @@
|
||||||
|
package fr.ynerant.leveleditor.game
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.{Collision, RawMap}
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister
|
||||||
|
import fr.ynerant.leveleditor.game.mobs.Mob
|
||||||
|
import fr.ynerant.leveleditor.game.towers.AutoTower
|
||||||
|
import fr.ynerant.leveleditor.game.towers.BasicTower
|
||||||
|
import fr.ynerant.leveleditor.game.towers.NullTower
|
||||||
|
import fr.ynerant.leveleditor.game.towers.Tower
|
||||||
|
import javax.swing._
|
||||||
|
import java.awt._
|
||||||
|
import java.awt.event.MouseEvent
|
||||||
|
import java.awt.event.MouseListener
|
||||||
|
import java.util
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.editor.CollidPanel
|
||||||
|
|
||||||
|
|
||||||
|
class GameFrame(val map: RawMap) extends JFrame("Jeu") {
|
||||||
|
final private val RANDOM = new Random
|
||||||
|
private var round = 0
|
||||||
|
private var hp = 5
|
||||||
|
private var reward = 20
|
||||||
|
final private val mobs = new util.ArrayList[Mob]
|
||||||
|
final private val towers = new util.ArrayList[Tower]
|
||||||
|
final private var basicTower = null: JRadioButton
|
||||||
|
final private var nullTower = null: JRadioButton
|
||||||
|
final private var autoTower = null: JRadioButton
|
||||||
|
final private var waveLabel = null: JLabel
|
||||||
|
final private var nbMobsLabel = null: JLabel
|
||||||
|
final private var hpLabel = null: JLabel
|
||||||
|
final private var rewardLabel = null: JLabel
|
||||||
|
final private var winLabel = null: JLabel
|
||||||
|
|
||||||
|
this.setSize(600, 600)
|
||||||
|
this.setPreferredSize(getSize)
|
||||||
|
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
|
||||||
|
this.setExtendedState(Frame.MAXIMIZED_BOTH)
|
||||||
|
this.setLocationRelativeTo(null)
|
||||||
|
val root = new JPanel
|
||||||
|
root.setLayout(new BorderLayout)
|
||||||
|
this.setContentPane(root)
|
||||||
|
val pane = new JPanel
|
||||||
|
pane.setLayout(new GridLayout(8, 1))
|
||||||
|
root.add(pane, BorderLayout.SOUTH)
|
||||||
|
val grid = new Grid()
|
||||||
|
grid.setSize(map.getWidth, map.getHeight)
|
||||||
|
grid.setPreferredSize(grid.getSize)
|
||||||
|
grid.setMinimumSize(grid.getSize)
|
||||||
|
grid.setMaximumSize(grid.getSize)
|
||||||
|
root.add(grid, BorderLayout.CENTER)
|
||||||
|
val towerSelect = new ButtonGroup
|
||||||
|
basicTower = new JRadioButton("Tour basique (" + new BasicTower(0, 0).getPrice + " pièces)")
|
||||||
|
basicTower.setSelected(true)
|
||||||
|
towerSelect.add(basicTower)
|
||||||
|
pane.add(basicTower)
|
||||||
|
nullTower = new JRadioButton("Tour nulle (" + new NullTower(0, 0).getPrice + " pièces)")
|
||||||
|
towerSelect.add(nullTower)
|
||||||
|
pane.add(nullTower)
|
||||||
|
autoTower = new JRadioButton("Tour automatique (" + new AutoTower(0, 0).getPrice + " pièces)")
|
||||||
|
towerSelect.add(autoTower)
|
||||||
|
pane.add(autoTower)
|
||||||
|
waveLabel = new JLabel
|
||||||
|
pane.add(waveLabel)
|
||||||
|
nbMobsLabel = new JLabel
|
||||||
|
pane.add(nbMobsLabel)
|
||||||
|
hpLabel = new JLabel
|
||||||
|
pane.add(hpLabel)
|
||||||
|
rewardLabel = new JLabel
|
||||||
|
pane.add(rewardLabel)
|
||||||
|
winLabel = new JLabel
|
||||||
|
pane.add(winLabel)
|
||||||
|
setVisible(true)
|
||||||
|
new Thread(() => {
|
||||||
|
while ( {
|
||||||
|
hp > 0 && (round < 4 || !mobs.isEmpty)
|
||||||
|
}) {
|
||||||
|
tick()
|
||||||
|
try Thread.sleep(50L)
|
||||||
|
catch {
|
||||||
|
case e: InterruptedException =>
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start()
|
||||||
|
repaint()
|
||||||
|
|
||||||
|
def getMap: RawMap = map
|
||||||
|
|
||||||
|
def tick(): Unit = {
|
||||||
|
if (mobs.isEmpty && round < 4) {
|
||||||
|
round += 1
|
||||||
|
val nb_mobs = round * (RANDOM.nextInt(16) + 1)
|
||||||
|
for (i <- 1 to nb_mobs) {
|
||||||
|
val mob = Mob.getRandomMob
|
||||||
|
do mob.move(RANDOM.nextInt(getMap.getWidth / 16), RANDOM.nextInt(getMap.getHeight / 16)) while ( {
|
||||||
|
getMap.getCase(mob.getX, mob.getY).getCollision != Collision.ANY
|
||||||
|
})
|
||||||
|
getMap.getCase(mob.getX, mob.getY).setCollision(Collision.PARTIAL)
|
||||||
|
mobs.add(mob)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
towers.forEach(tower => {
|
||||||
|
tower.filterDetectedMobs(mobs).forEach(mob => {
|
||||||
|
mob.hit(tower.getDamagePerShot)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
new util.ArrayList[Mob](mobs).forEach(mob => {
|
||||||
|
getMap.getCase(mob.getX, mob.getY).setCollision(Collision.ANY)
|
||||||
|
mob.tick(this)
|
||||||
|
if (mob.getX < 0 || mob.isDead) {
|
||||||
|
mobs.remove(mob)
|
||||||
|
if (mob.getX < 0) {
|
||||||
|
hp -= 1
|
||||||
|
if (hp == 0) {
|
||||||
|
winLabel.setForeground(Color.red)
|
||||||
|
winLabel.setText("Vous avez perdu !")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else reward += mob.getReward
|
||||||
|
}
|
||||||
|
else getMap.getCase(mob.getX, mob.getY).setCollision(Collision.PARTIAL)
|
||||||
|
})
|
||||||
|
waveLabel.setText("Vague " + round)
|
||||||
|
nbMobsLabel.setText(mobs.size + " mob" + (if (mobs.size > 1) "s"
|
||||||
|
else "") + " restant" + (if (mobs.size > 1) "s"
|
||||||
|
else ""))
|
||||||
|
hpLabel.setText("Points de vie : " + hp)
|
||||||
|
rewardLabel.setText("Butin : " + reward)
|
||||||
|
if (round == 4 && mobs.isEmpty) {
|
||||||
|
winLabel.setForeground(Color.green.darker)
|
||||||
|
winLabel.setText("Vous avez gagné !")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Grid() extends JComponent with MouseListener {
|
||||||
|
addMouseListener(this)
|
||||||
|
|
||||||
|
override protected def paintComponent(_g: Graphics): Unit = {
|
||||||
|
val g = _g.asInstanceOf[Graphics2D]
|
||||||
|
if (getMap.getFont != null) g.drawImage(getMap.getFont, null, null)
|
||||||
|
SpriteRegister.refreshAllSprites()
|
||||||
|
val SPRITE_SIZE = 32
|
||||||
|
getMap.getCases.forEach(c => {
|
||||||
|
val s1 = SpriteRegister.getCategory(c.getCoucheOne.getCategory).getSprites.get(c.getCoucheOne.getIndex)
|
||||||
|
val s2 = SpriteRegister.getCategory(c.getCoucheTwo.getCategory).getSprites.get(c.getCoucheTwo.getIndex)
|
||||||
|
val s3 = SpriteRegister.getCategory(c.getCoucheThree.getCategory).getSprites.get(c.getCoucheThree.getIndex)
|
||||||
|
g.drawImage(s1.getImage, SPRITE_SIZE * c.getPosX, SPRITE_SIZE * c.getPosY, SPRITE_SIZE, SPRITE_SIZE, Color.white, null)
|
||||||
|
if (!CollidPanel.isEmpty(s2.getImage)) g.drawImage(s2.getImage, SPRITE_SIZE * c.getPosX, SPRITE_SIZE * c.getPosY, SPRITE_SIZE, SPRITE_SIZE, null, null)
|
||||||
|
if (!CollidPanel.isEmpty(s3.getImage)) g.drawImage(s3.getImage, SPRITE_SIZE * c.getPosX, SPRITE_SIZE * c.getPosY, SPRITE_SIZE, SPRITE_SIZE, null, null)
|
||||||
|
})
|
||||||
|
new util.ArrayList[Mob](mobs).forEach(mob => {
|
||||||
|
val s = mob.getSprite
|
||||||
|
g.drawImage(s.getImage, SPRITE_SIZE * mob.getX, SPRITE_SIZE * mob.getY, SPRITE_SIZE, SPRITE_SIZE, null, null)
|
||||||
|
})
|
||||||
|
towers.forEach(tower => {
|
||||||
|
val s = tower.getSprite
|
||||||
|
g.drawImage(s.getImage, SPRITE_SIZE * tower.getX, SPRITE_SIZE * tower.getY, SPRITE_SIZE, SPRITE_SIZE, null, null)
|
||||||
|
})
|
||||||
|
repaint()
|
||||||
|
}
|
||||||
|
|
||||||
|
override def mouseClicked(event: MouseEvent): Unit = {
|
||||||
|
}
|
||||||
|
|
||||||
|
override def mousePressed(event: MouseEvent): Unit = {
|
||||||
|
}
|
||||||
|
|
||||||
|
override def mouseReleased(event: MouseEvent): Unit = {
|
||||||
|
val x = event.getX / 32
|
||||||
|
val y = event.getY / 32
|
||||||
|
val tower = if (basicTower.isSelected) new BasicTower(x, y)
|
||||||
|
else if (nullTower.isSelected) new NullTower(x, y)
|
||||||
|
else if (autoTower.isSelected) new AutoTower(x, y)
|
||||||
|
else null
|
||||||
|
if (tower == null || tower.getPrice > reward) return
|
||||||
|
val c = getMap.getCase(x, y)
|
||||||
|
if (c == null || (c.getCollision ne Collision.ANY)) return
|
||||||
|
c.setCollision(Collision.FULL)
|
||||||
|
reward -= tower.getPrice
|
||||||
|
towers.add(tower)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def mouseEntered(event: MouseEvent): Unit = {
|
||||||
|
}
|
||||||
|
|
||||||
|
override def mouseExited(event: MouseEvent): Unit = {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package fr.ynerant.leveleditor.game.mobs
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.Sprite
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister
|
||||||
|
import fr.ynerant.leveleditor.game.GameFrame
|
||||||
|
import java.util
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.RawCase
|
||||||
|
|
||||||
|
|
||||||
|
object Mob {
|
||||||
|
private val RANDOM = new Random
|
||||||
|
|
||||||
|
def getRandomMob: Mob = RANDOM.nextInt(3) match {
|
||||||
|
case 1 =>
|
||||||
|
new Mob1
|
||||||
|
case 2 =>
|
||||||
|
new Mob2
|
||||||
|
case _ =>
|
||||||
|
new MobCancer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Mob() {
|
||||||
|
private var hp = getMaxHP
|
||||||
|
private var tickRemains = getSlowness
|
||||||
|
private var sprite = null: Sprite
|
||||||
|
private var x = 0
|
||||||
|
private var y = 0
|
||||||
|
|
||||||
|
def getMaxHP: Int
|
||||||
|
|
||||||
|
def getSlowness: Long
|
||||||
|
|
||||||
|
def getReward: Int
|
||||||
|
|
||||||
|
def getName: String
|
||||||
|
|
||||||
|
def getSprite: Sprite = {
|
||||||
|
if (sprite == null) sprite = SpriteRegister.getCategory(getName).getSprites.get(0)
|
||||||
|
sprite
|
||||||
|
}
|
||||||
|
|
||||||
|
def getX: Int = x
|
||||||
|
|
||||||
|
def getY: Int = y
|
||||||
|
|
||||||
|
def move(x: Int, y: Int): Unit = {
|
||||||
|
this.x = x
|
||||||
|
this.y = y
|
||||||
|
}
|
||||||
|
|
||||||
|
def getHP: Int = hp
|
||||||
|
|
||||||
|
def isDead: Boolean = hp <= 0
|
||||||
|
|
||||||
|
def setHP(hp: Int): Unit = {
|
||||||
|
this.hp = hp
|
||||||
|
}
|
||||||
|
|
||||||
|
def hit(damage: Int): Boolean = {
|
||||||
|
if (!isDead) {
|
||||||
|
this.hp -= damage
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
def tick(game: GameFrame): Unit = {
|
||||||
|
if (tickRemains > 0) tickRemains -= 1
|
||||||
|
else {
|
||||||
|
tickRemains = getSlowness
|
||||||
|
val current = game.getMap.getCase(getX, getY)
|
||||||
|
if (current.getPosX == 0) {
|
||||||
|
move(-1, getY)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val visited = new util.ArrayList[RawCase]
|
||||||
|
val queue = new util.ArrayDeque[RawCase]
|
||||||
|
val pred = new util.HashMap[RawCase, RawCase]
|
||||||
|
var last = null: RawCase
|
||||||
|
queue.add(current)
|
||||||
|
while (!queue.isEmpty) {
|
||||||
|
val visiting = queue.poll
|
||||||
|
visited.add(visiting)
|
||||||
|
game.getMap.getNeighbours(visiting).forEach(neighbour => {
|
||||||
|
if (neighbour != null && !visited.contains(neighbour)) {
|
||||||
|
pred.put(neighbour, visiting)
|
||||||
|
queue.add(neighbour)
|
||||||
|
if (neighbour.getPosX == 0) {
|
||||||
|
last = neighbour
|
||||||
|
queue.clear()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (last != null) {
|
||||||
|
while (pred.get(last) != current) last = pred.get(last)
|
||||||
|
move(last.getPosX, last.getPosY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def toString: String = "Mob{" + "sprite=" + sprite + ", x=" + x + ", y=" + y + '}'
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package fr.ynerant.leveleditor.game.mobs
|
||||||
|
|
||||||
|
class Mob1 extends Mob {
|
||||||
|
override def getMaxHP = 2
|
||||||
|
|
||||||
|
override def getSlowness = 60
|
||||||
|
|
||||||
|
override def getReward = 10
|
||||||
|
|
||||||
|
override def getName = "mob1"
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package fr.ynerant.leveleditor.game.mobs
|
||||||
|
|
||||||
|
class Mob2 extends Mob {
|
||||||
|
override def getMaxHP = 6
|
||||||
|
|
||||||
|
override def getSlowness = 20
|
||||||
|
|
||||||
|
override def getReward = 20
|
||||||
|
|
||||||
|
override def getName = "mob2"
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package fr.ynerant.leveleditor.game.mobs
|
||||||
|
|
||||||
|
class MobCancer extends Mob {
|
||||||
|
override def getMaxHP = 50
|
||||||
|
|
||||||
|
override def getSlowness = 100
|
||||||
|
|
||||||
|
override def getReward = 100
|
||||||
|
|
||||||
|
override def getName = "mobcancer"
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package fr.ynerant.leveleditor.game.towers
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.game.mobs.Mob
|
||||||
|
import java.util
|
||||||
|
|
||||||
|
|
||||||
|
class AutoTower(override val x: Int, override val y: Int) extends Tower(x, y) {
|
||||||
|
override def getName = "autotower"
|
||||||
|
|
||||||
|
override def getDamagePerShot = 20
|
||||||
|
|
||||||
|
override def getPeriod = 10
|
||||||
|
|
||||||
|
override def getPrice = 142
|
||||||
|
|
||||||
|
override private[towers] def _filterDetectedMobs(mobs: util.Collection[Mob]) = mobs
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package fr.ynerant.leveleditor.game.towers
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.game.mobs.Mob
|
||||||
|
import java.util
|
||||||
|
|
||||||
|
|
||||||
|
class BasicTower(override val x: Int, override val y: Int) extends Tower(x, y) {
|
||||||
|
override def getName = "basictower"
|
||||||
|
|
||||||
|
override def getDamagePerShot = 1
|
||||||
|
|
||||||
|
override def getPeriod = 5
|
||||||
|
|
||||||
|
override def getPrice = 10
|
||||||
|
|
||||||
|
override private[towers] def _filterDetectedMobs(mobs: util.Collection[Mob]) = {
|
||||||
|
val filtered = new util.ArrayList[Mob]
|
||||||
|
mobs.forEach(mob => {
|
||||||
|
if ((mob.getX == getX || mob.getY == getY) && Math.abs(mob.getX - getX) <= 3 && Math.abs(mob.getY - getY) <= 3) filtered.add(mob)
|
||||||
|
})
|
||||||
|
filtered
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package fr.ynerant.leveleditor.game.towers
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.game.mobs.Mob
|
||||||
|
import java.util
|
||||||
|
|
||||||
|
|
||||||
|
class NullTower(override val x: Int, override val y: Int) extends Tower(x, y) {
|
||||||
|
override def getName = "nulltower"
|
||||||
|
|
||||||
|
override def getDamagePerShot: Int = Integer.MAX_VALUE
|
||||||
|
|
||||||
|
override def getPeriod = 1
|
||||||
|
|
||||||
|
override def getPrice = 5
|
||||||
|
|
||||||
|
override private[towers] def _filterDetectedMobs(mobs: util.Collection[Mob]) = new util.ArrayList[Mob]
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package fr.ynerant.leveleditor.game.towers
|
||||||
|
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.Sprite
|
||||||
|
import fr.ynerant.leveleditor.api.editor.sprites.SpriteRegister
|
||||||
|
import fr.ynerant.leveleditor.game.mobs.Mob
|
||||||
|
import java.util
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
|
||||||
|
object Tower {
|
||||||
|
private val RANDOM = new Random
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Tower(val x: Int, val y: Int) {
|
||||||
|
final private val sprite = SpriteRegister.getCategory(getName).getSprites.get(0)
|
||||||
|
private var remainingTicks = 0L
|
||||||
|
|
||||||
|
def getSprite: Sprite = sprite
|
||||||
|
|
||||||
|
def getName: String
|
||||||
|
|
||||||
|
def getDamagePerShot: Int
|
||||||
|
|
||||||
|
def getPeriod: Long
|
||||||
|
|
||||||
|
def getPrice: Int
|
||||||
|
|
||||||
|
private[towers] def _filterDetectedMobs(mobs: util.Collection[Mob]): util.Collection[Mob]
|
||||||
|
|
||||||
|
def filterDetectedMobs(mobs: util.Collection[Mob]): util.Collection[Mob] = if (remainingTicks > 0) {
|
||||||
|
remainingTicks -= 1
|
||||||
|
new util.ArrayList[Mob]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
remainingTicks = getPeriod
|
||||||
|
_filterDetectedMobs(mobs)
|
||||||
|
}
|
||||||
|
|
||||||
|
def getX: Int = x
|
||||||
|
|
||||||
|
def getY: Int = y
|
||||||
|
}
|
Loading…
Reference in New Issue