add animated water ripple tile and a trap trigger
@@ -2,3 +2,4 @@ https://kenmi-art.itch.io/cute-fantasy-rpg
|
|||||||
https://yubatake.bandcamp.com/album/jrpg-collection
|
https://yubatake.bandcamp.com/album/jrpg-collection
|
||||||
https://crusenho.itch.io/complete-ui-essential-pack
|
https://crusenho.itch.io/complete-ui-essential-pack
|
||||||
https://xdeviruchi.itch.io/8-bit-fantasy-adventure-music-pack
|
https://xdeviruchi.itch.io/8-bit-fantasy-adventure-music-pack
|
||||||
|
https://sfxr.me/
|
||||||
|
|||||||
BIN
assets/audio/trap.wav
Normal file
@@ -361,3 +361,17 @@ player/walk_up
|
|||||||
orig: 32, 32
|
orig: 32, 32
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: 5
|
index: 5
|
||||||
|
trap/idle_down
|
||||||
|
rotate: false
|
||||||
|
xy: 38, 13
|
||||||
|
size: 16, 16
|
||||||
|
orig: 16, 16
|
||||||
|
offset: 0, 0
|
||||||
|
index: 0
|
||||||
|
trap/idle_down
|
||||||
|
rotate: false
|
||||||
|
xy: 410, 129
|
||||||
|
size: 16, 16
|
||||||
|
orig: 16, 16
|
||||||
|
offset: 0, 0
|
||||||
|
index: 1
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
@@ -1,21 +1,27 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="18" height="16" tilewidth="16" tileheight="16" infinite="0" nextlayerid="7" nextobjectid="15">
|
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="18" height="16" tilewidth="16" tileheight="16" infinite="0" nextlayerid="7" nextobjectid="17">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="music" value="TOWN"/>
|
<property name="music" value="TOWN"/>
|
||||||
</properties>
|
</properties>
|
||||||
<tileset firstgid="1" source="objects.tsx"/>
|
<tileset firstgid="1" source="objects.tsx"/>
|
||||||
<tileset firstgid="7" source="tileset.tsx"/>
|
<tileset firstgid="8" source="tileset.tsx"/>
|
||||||
<layer id="1" name="ground" width="18" height="16">
|
<layer id="1" name="ground" width="18" height="16">
|
||||||
<data encoding="base64" compression="zlib">
|
<data encoding="base64" compression="zlib">
|
||||||
eJylkjsPwjAMhLPykCoeEjDBxkgzARPqBEywla2w9lfkp3OVYumwTAgwfFIb+c7xOcE5twRzgxUIXzAyzkpQxO8t2Cn2hmYNesZ5ET1uoCXuoIo1G0PD/92sC3CI2gs4EWejb+c5i3l48gjkUxm6XHgm9vGZWslSPBpQOztbQe9BZ8rURr0g/bheMr0mPHl3rXvdAe/CU8ZWD00qK/F5kM8vezvG2fgO1rvJ9WJt+aFev+9/6YOBYvimNnW3MZgophn9n9wdbaQ=
|
eJylkjsOwjAQRF3z6SI+HVBDzwGIa6BGqYEa+tAHLpCz+G5MJK80Wm2MgeJJibUz6511cM6twdJgA8IXTIyzEhTxew8OiqOh2YKBcV5EjwdoiSeoYs3O0PB/N+sKnKL2Bi7E1ejbeS5iHp48AvlUhi4Xnol9fKZWshSPBtQ92Qp6DzpTpjbqBenH9ZLpPeHJu2vVDngXnjK2emhSWYnPi3x+2ds5zsZ3sN5Nrhdryw/1+n3/yxCMFOOe2tTdpmCmmGf0fwPl7aDo
|
||||||
</data>
|
</data>
|
||||||
</layer>
|
</layer>
|
||||||
<layer id="3" name="water" width="18" height="16">
|
<layer id="3" name="water" width="18" height="16">
|
||||||
<data encoding="base64" compression="zlib">
|
<data encoding="base64" compression="zlib">
|
||||||
eJxjYBgFo2AUjALKgTES24hIPQAWrABm
|
eJxjYBgFo2AUjALKgQcQC0DZ7kTqAQAhOACg
|
||||||
</data>
|
</data>
|
||||||
</layer>
|
</layer>
|
||||||
<objectgroup id="6" name="trigger"/>
|
<objectgroup id="6" name="trigger">
|
||||||
|
<object id="16" name="trap_trigger" x="97" y="114" width="14" height="12">
|
||||||
|
<properties>
|
||||||
|
<property name="sensor" type="bool" value="true"/>
|
||||||
|
</properties>
|
||||||
|
</object>
|
||||||
|
</objectgroup>
|
||||||
<objectgroup id="5" name="objects">
|
<objectgroup id="5" name="objects">
|
||||||
<object id="5" gid="3" x="197" y="118" width="80" height="112"/>
|
<object id="5" gid="3" x="197" y="118" width="80" height="112"/>
|
||||||
<object id="9" gid="5" x="32" y="32" width="16" height="16"/>
|
<object id="9" gid="5" x="32" y="32" width="16" height="16"/>
|
||||||
@@ -29,5 +35,6 @@
|
|||||||
<object id="12" gid="6" x="137" y="206" width="41" height="63"/>
|
<object id="12" gid="6" x="137" y="206" width="41" height="63"/>
|
||||||
<object id="13" gid="6" x="72" y="93" width="41" height="63"/>
|
<object id="13" gid="6" x="72" y="93" width="41" height="63"/>
|
||||||
<object id="14" gid="6" x="176" y="123" width="41" height="63"/>
|
<object id="14" gid="6" x="176" y="123" width="41" height="63"/>
|
||||||
|
<object id="15" gid="7" x="96" y="128" width="16" height="16"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
|||||||
@@ -30,6 +30,11 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"value": ""
|
"value": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "animationSpeed",
|
||||||
|
"type": "float",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "atlasAsset",
|
"name": "atlasAsset",
|
||||||
"propertyType": "AtlasAsset",
|
"propertyType": "AtlasAsset",
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<tileset version="1.10" tiledversion="1.11.0" name="objects" tilewidth="80" tileheight="112" tilecount="4" columns="0">
|
<tileset version="1.10" tiledversion="1.11.0" name="objects" tilewidth="80" tileheight="112" tilecount="5" columns="0">
|
||||||
<grid orientation="orthogonal" width="1" height="1"/>
|
<grid orientation="orthogonal" width="1" height="1"/>
|
||||||
<tile id="1" type="Object">
|
<tile id="1" type="Object">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="animation" value="IDLE"/>
|
<property name="animation" value="IDLE"/>
|
||||||
|
<property name="animationSpeed" type="float" value="1"/>
|
||||||
<property name="life" type="int" value="12"/>
|
<property name="life" type="int" value="12"/>
|
||||||
<property name="lifeReg" type="float" value="0.25"/>
|
<property name="lifeReg" type="float" value="0.25"/>
|
||||||
<property name="speed" type="float" value="3.5"/>
|
<property name="speed" type="float" value="3.5"/>
|
||||||
@@ -35,4 +36,11 @@
|
|||||||
</object>
|
</object>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
|
<tile id="6" type="Object">
|
||||||
|
<properties>
|
||||||
|
<property name="animation" value="IDLE"/>
|
||||||
|
<property name="z" type="int" value="0"/>
|
||||||
|
</properties>
|
||||||
|
<image source="objects/trap.png" width="16" height="16"/>
|
||||||
|
</tile>
|
||||||
</tileset>
|
</tileset>
|
||||||
|
|||||||
BIN
assets/maps/objects/trap.png
Normal file
|
After Width: | Height: | Size: 281 B |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<tileset version="1.10" tiledversion="1.11.0" name="tileset" tilewidth="16" tileheight="16" spacing="16" margin="8" tilecount="128" columns="8">
|
<tileset version="1.10" tiledversion="1.11.0" name="tileset" tilewidth="16" tileheight="16" spacing="16" margin="8" tilecount="192" columns="12">
|
||||||
<image source="tileset.png" width="256" height="512"/>
|
<image source="tileset.png" width="384" height="512"/>
|
||||||
<tile id="0">
|
<tile id="0">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="8" y="9" width="8" height="7"/>
|
<object id="1" x="8" y="9" width="8" height="7"/>
|
||||||
@@ -32,71 +32,79 @@
|
|||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="8">
|
<tile id="8">
|
||||||
|
<animation>
|
||||||
|
<frame tileid="8" duration="200"/>
|
||||||
|
<frame tileid="9" duration="200"/>
|
||||||
|
<frame tileid="10" duration="200"/>
|
||||||
|
<frame tileid="11" duration="200"/>
|
||||||
|
</animation>
|
||||||
|
</tile>
|
||||||
|
<tile id="12">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="8" y="0" width="4" height="16"/>
|
<object id="1" x="8" y="0" width="4" height="16"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="10">
|
<tile id="14">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="4" y="0" width="5" height="16"/>
|
<object id="1" x="4" y="0" width="5" height="16"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="11">
|
<tile id="15">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="7" y="0" width="5" height="16"/>
|
<object id="1" x="7" y="0" width="5" height="16"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="13">
|
<tile id="17">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="4" y="0" width="5" height="16"/>
|
<object id="1" x="4" y="0" width="5" height="16"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="16">
|
<tile id="24">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="9" y="0" width="7" height="8"/>
|
<object id="1" x="9" y="0" width="7" height="8"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="17">
|
<tile id="25">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="0" y="4" width="16" height="4"/>
|
<object id="1" x="0" y="4" width="16" height="4"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="18">
|
<tile id="26">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="0" y="0" width="7" height="7"/>
|
<object id="1" x="0" y="0" width="7" height="7"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="19">
|
<tile id="27">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="8" y="0" width="8" height="6"/>
|
<object id="1" x="8" y="0" width="8" height="6"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="20">
|
<tile id="28">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="0" y="6" width="16" height="4"/>
|
<object id="1" x="0" y="6" width="16" height="4"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="21">
|
<tile id="29">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="0" y="0" width="8" height="7"/>
|
<object id="1" x="0" y="0" width="8" height="7"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="24">
|
<tile id="36">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="4" y="5" width="12" height="11"/>
|
<object id="1" x="4" y="5" width="12" height="11"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="25">
|
<tile id="37">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="0" y="5" width="12" height="11"/>
|
<object id="1" x="0" y="5" width="12" height="11"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="32">
|
<tile id="48">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="4" y="0" width="12" height="14"/>
|
<object id="1" x="4" y="0" width="12" height="14"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="33">
|
<tile id="49">
|
||||||
<objectgroup draworder="index" id="2">
|
<objectgroup draworder="index" id="2">
|
||||||
<object id="1" x="0" y="0" width="12" height="14"/>
|
<object id="1" x="0" y="0" width="12" height="14"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
@@ -105,21 +113,21 @@
|
|||||||
<wangset name="Unnamed Set" type="corner" tile="-1">
|
<wangset name="Unnamed Set" type="corner" tile="-1">
|
||||||
<wangcolor name="gras" color="#ff0000" tile="-1" probability="1"/>
|
<wangcolor name="gras" color="#ff0000" tile="-1" probability="1"/>
|
||||||
<wangcolor name="dirt" color="#00ff00" tile="-1" probability="1"/>
|
<wangcolor name="dirt" color="#00ff00" tile="-1" probability="1"/>
|
||||||
<wangtile tileid="9" wangid="0,1,0,1,0,1,0,1"/>
|
<wangtile tileid="13" wangid="0,1,0,1,0,1,0,1"/>
|
||||||
<wangtile tileid="48" wangid="0,1,0,2,0,1,0,1"/>
|
<wangtile tileid="72" wangid="0,1,0,2,0,1,0,1"/>
|
||||||
<wangtile tileid="49" wangid="0,1,0,2,0,2,0,1"/>
|
<wangtile tileid="73" wangid="0,1,0,2,0,2,0,1"/>
|
||||||
<wangtile tileid="50" wangid="0,1,0,1,0,2,0,1"/>
|
<wangtile tileid="74" wangid="0,1,0,1,0,2,0,1"/>
|
||||||
<wangtile tileid="56" wangid="0,2,0,2,0,1,0,1"/>
|
<wangtile tileid="84" wangid="0,2,0,2,0,1,0,1"/>
|
||||||
<wangtile tileid="58" wangid="0,1,0,1,0,2,0,2"/>
|
<wangtile tileid="86" wangid="0,1,0,1,0,2,0,2"/>
|
||||||
<wangtile tileid="64" wangid="0,2,0,1,0,1,0,1"/>
|
<wangtile tileid="96" wangid="0,2,0,1,0,1,0,1"/>
|
||||||
<wangtile tileid="65" wangid="0,2,0,1,0,1,0,2"/>
|
<wangtile tileid="97" wangid="0,2,0,1,0,1,0,2"/>
|
||||||
<wangtile tileid="66" wangid="0,1,0,1,0,1,0,2"/>
|
<wangtile tileid="98" wangid="0,1,0,1,0,1,0,2"/>
|
||||||
<wangtile tileid="72" wangid="0,2,0,1,0,2,0,2"/>
|
<wangtile tileid="108" wangid="0,2,0,1,0,2,0,2"/>
|
||||||
<wangtile tileid="73" wangid="0,2,0,2,0,1,0,2"/>
|
<wangtile tileid="109" wangid="0,2,0,2,0,1,0,2"/>
|
||||||
<wangtile tileid="80" wangid="0,1,0,2,0,2,0,2"/>
|
<wangtile tileid="120" wangid="0,1,0,2,0,2,0,2"/>
|
||||||
<wangtile tileid="81" wangid="0,2,0,2,0,2,0,1"/>
|
<wangtile tileid="121" wangid="0,2,0,2,0,2,0,1"/>
|
||||||
<wangtile tileid="99" wangid="0,2,0,2,0,2,0,2"/>
|
<wangtile tileid="147" wangid="0,2,0,2,0,2,0,2"/>
|
||||||
<wangtile tileid="121" wangid="0,1,0,1,0,1,0,1"/>
|
<wangtile tileid="181" wangid="0,1,0,1,0,1,0,1"/>
|
||||||
</wangset>
|
</wangset>
|
||||||
</wangsets>
|
</wangsets>
|
||||||
</tileset>
|
</tileset>
|
||||||
|
|||||||
BIN
assets_raw/map/Water_Ripple_00.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
assets_raw/map/Water_Ripple_01.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
assets_raw/map/Water_Ripple_02.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
assets_raw/map/Water_Ripple_03.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.7 KiB |
BIN
assets_raw/objects/trap/idle_down_00.png
Normal file
|
After Width: | Height: | Size: 281 B |
BIN
assets_raw/objects/trap/idle_down_01.png
Normal file
|
After Width: | Height: | Size: 472 B |
@@ -3,6 +3,7 @@ package io.github.com.quillraven.asset;
|
|||||||
public enum SoundAsset {
|
public enum SoundAsset {
|
||||||
SWORD_HIT("sword_hit.wav"),
|
SWORD_HIT("sword_hit.wav"),
|
||||||
LIFE_REG("life_reg.wav"),
|
LIFE_REG("life_reg.wav"),
|
||||||
|
TRAP("trap.wav"),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final String path;
|
private final String path;
|
||||||
|
|||||||
@@ -68,10 +68,6 @@ public class Animation2D implements Component {
|
|||||||
return playMode;
|
return playMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getSpeed() {
|
|
||||||
return speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSpeed(float speed) {
|
public void setSpeed(float speed) {
|
||||||
this.speed = speed;
|
this.speed = speed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package io.github.com.quillraven.component;
|
||||||
|
|
||||||
|
import com.badlogic.ashley.core.Component;
|
||||||
|
import com.badlogic.ashley.core.ComponentMapper;
|
||||||
|
import com.badlogic.gdx.maps.MapObject;
|
||||||
|
|
||||||
|
public class Tiled implements Component {
|
||||||
|
public static final ComponentMapper<Tiled> MAPPER = ComponentMapper.getFor(Tiled.class);
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final MapObject mapObjectRef;
|
||||||
|
|
||||||
|
public Tiled(MapObject mapObjectRef) {
|
||||||
|
this.id = mapObjectRef.getProperties().get("id", -1, Integer.class);
|
||||||
|
this.mapObjectRef = mapObjectRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapObject getMapObjectRef() {
|
||||||
|
return mapObjectRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package io.github.com.quillraven.component;
|
||||||
|
|
||||||
|
import com.badlogic.ashley.core.Component;
|
||||||
|
import com.badlogic.ashley.core.ComponentMapper;
|
||||||
|
import com.badlogic.ashley.core.Entity;
|
||||||
|
|
||||||
|
public class Trigger implements Component {
|
||||||
|
public static final ComponentMapper<Trigger> MAPPER = ComponentMapper.getFor(Trigger.class);
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private Entity triggeringEntity;
|
||||||
|
|
||||||
|
public Trigger(String name) {
|
||||||
|
this.name = name;
|
||||||
|
this.triggeringEntity = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTriggeringEntity(Entity triggeringEntity) {
|
||||||
|
this.triggeringEntity = triggeringEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity getTriggeringEntity() {
|
||||||
|
return triggeringEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,4 @@ public class IdleControllerState implements ControllerState {
|
|||||||
@Override
|
@Override
|
||||||
public void keyDown(Command command) {
|
public void keyDown(Command command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyUp(Command command) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ import io.github.com.quillraven.system.PhysicDebugRenderSystem;
|
|||||||
import io.github.com.quillraven.system.PhysicMoveSystem;
|
import io.github.com.quillraven.system.PhysicMoveSystem;
|
||||||
import io.github.com.quillraven.system.PhysicSystem;
|
import io.github.com.quillraven.system.PhysicSystem;
|
||||||
import io.github.com.quillraven.system.RenderSystem;
|
import io.github.com.quillraven.system.RenderSystem;
|
||||||
import io.github.com.quillraven.tiled.TiledAshleySpawner;
|
import io.github.com.quillraven.system.TriggerSystem;
|
||||||
|
import io.github.com.quillraven.tiled.TiledAshleyConfigurator;
|
||||||
import io.github.com.quillraven.tiled.TiledService;
|
import io.github.com.quillraven.tiled.TiledService;
|
||||||
import io.github.com.quillraven.ui.model.GameViewModel;
|
import io.github.com.quillraven.ui.model.GameViewModel;
|
||||||
import io.github.com.quillraven.ui.view.GameView;
|
import io.github.com.quillraven.ui.view.GameView;
|
||||||
@@ -43,7 +44,7 @@ public class GameScreen extends ScreenAdapter {
|
|||||||
private final Viewport uiViewport;
|
private final Viewport uiViewport;
|
||||||
private final TiledService tiledService;
|
private final TiledService tiledService;
|
||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
private final TiledAshleySpawner tiledAshleySpawner;
|
private final TiledAshleyConfigurator tiledAshleyConfigurator;
|
||||||
private final World physicWorld;
|
private final World physicWorld;
|
||||||
private final KeyboardController keyboardController;
|
private final KeyboardController keyboardController;
|
||||||
private final AudioService audioService;
|
private final AudioService audioService;
|
||||||
@@ -55,11 +56,11 @@ public class GameScreen extends ScreenAdapter {
|
|||||||
this.skin = game.getAssetService().get(SkinAsset.DEFAULT);
|
this.skin = game.getAssetService().get(SkinAsset.DEFAULT);
|
||||||
this.viewModel = new GameViewModel(game);
|
this.viewModel = new GameViewModel(game);
|
||||||
this.audioService = game.getAudioService();
|
this.audioService = game.getAudioService();
|
||||||
this.tiledService = new TiledService(game.getAssetService());
|
|
||||||
this.physicWorld = new World(Vector2.Zero, true);
|
this.physicWorld = new World(Vector2.Zero, true);
|
||||||
this.physicWorld.setAutoClearForces(false);
|
this.physicWorld.setAutoClearForces(false);
|
||||||
|
this.tiledService = new TiledService(game.getAssetService(), this.physicWorld);
|
||||||
this.engine = new Engine();
|
this.engine = new Engine();
|
||||||
this.tiledAshleySpawner = new TiledAshleySpawner(this.engine, this.physicWorld, this.game.getAssetService());
|
this.tiledAshleyConfigurator = new TiledAshleyConfigurator(this.engine, this.physicWorld, this.game.getAssetService());
|
||||||
this.keyboardController = new KeyboardController(GameControllerState.class, engine, null);
|
this.keyboardController = new KeyboardController(GameControllerState.class, engine, null);
|
||||||
|
|
||||||
// add ECS systems
|
// add ECS systems
|
||||||
@@ -67,6 +68,7 @@ public class GameScreen extends ScreenAdapter {
|
|||||||
this.engine.addSystem(new PhysicSystem(physicWorld, 1 / 60f));
|
this.engine.addSystem(new PhysicSystem(physicWorld, 1 / 60f));
|
||||||
this.engine.addSystem(new FacingSystem());
|
this.engine.addSystem(new FacingSystem());
|
||||||
this.engine.addSystem(new FsmSystem());
|
this.engine.addSystem(new FsmSystem());
|
||||||
|
this.engine.addSystem(new TriggerSystem(audioService));
|
||||||
this.engine.addSystem(new LifeSystem(this.viewModel));
|
this.engine.addSystem(new LifeSystem(this.viewModel));
|
||||||
this.engine.addSystem(new AnimationSystem(game.getAssetService()));
|
this.engine.addSystem(new AnimationSystem(game.getAssetService()));
|
||||||
this.engine.addSystem(new CameraSystem(game.getCamera()));
|
this.engine.addSystem(new CameraSystem(game.getCamera()));
|
||||||
@@ -83,12 +85,12 @@ public class GameScreen extends ScreenAdapter {
|
|||||||
this.stage.addActor(new GameView(stage, skin, this.viewModel));
|
this.stage.addActor(new GameView(stage, skin, this.viewModel));
|
||||||
|
|
||||||
Consumer<TiledMap> renderConsumer = this.engine.getSystem(RenderSystem.class)::setMap;
|
Consumer<TiledMap> renderConsumer = this.engine.getSystem(RenderSystem.class)::setMap;
|
||||||
Consumer<TiledMap> ashleySpawnerConsumer = this.tiledAshleySpawner::loadMapObjects;
|
|
||||||
Consumer<TiledMap> cameraConsumer = this.engine.getSystem(CameraSystem.class)::setMap;
|
Consumer<TiledMap> cameraConsumer = this.engine.getSystem(CameraSystem.class)::setMap;
|
||||||
Consumer<TiledMap> audioConsumer = this.audioService::setMap;
|
Consumer<TiledMap> audioConsumer = this.audioService::setMap;
|
||||||
this.tiledService.setMapChangeConsumer(
|
this.tiledService.setMapChangeConsumer(renderConsumer.andThen(cameraConsumer).andThen(audioConsumer));
|
||||||
renderConsumer.andThen(ashleySpawnerConsumer).andThen(cameraConsumer).andThen(audioConsumer)
|
this.tiledService.setLoadTriggerConsumer(tiledAshleyConfigurator::onLoadTrigger);
|
||||||
);
|
this.tiledService.setLoadObjectConsumer(tiledAshleyConfigurator::onLoadObject);
|
||||||
|
this.tiledService.setLoadTileConsumer(tiledAshleyConfigurator::onLoadTile);
|
||||||
|
|
||||||
TiledMap startMap = this.tiledService.loadMap(MapAsset.MAIN);
|
TiledMap startMap = this.tiledService.loadMap(MapAsset.MAIN);
|
||||||
this.tiledService.setMap(startMap);
|
this.tiledService.setMap(startMap);
|
||||||
|
|||||||
@@ -7,11 +7,17 @@ import com.badlogic.ashley.core.Family;
|
|||||||
import com.badlogic.ashley.systems.IteratingSystem;
|
import com.badlogic.ashley.systems.IteratingSystem;
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.physics.box2d.Body;
|
import com.badlogic.gdx.physics.box2d.Body;
|
||||||
|
import com.badlogic.gdx.physics.box2d.Contact;
|
||||||
|
import com.badlogic.gdx.physics.box2d.ContactImpulse;
|
||||||
|
import com.badlogic.gdx.physics.box2d.ContactListener;
|
||||||
|
import com.badlogic.gdx.physics.box2d.Manifold;
|
||||||
import com.badlogic.gdx.physics.box2d.World;
|
import com.badlogic.gdx.physics.box2d.World;
|
||||||
import io.github.com.quillraven.component.Physic;
|
import io.github.com.quillraven.component.Physic;
|
||||||
|
import io.github.com.quillraven.component.Player;
|
||||||
import io.github.com.quillraven.component.Transform;
|
import io.github.com.quillraven.component.Transform;
|
||||||
|
import io.github.com.quillraven.component.Trigger;
|
||||||
|
|
||||||
public class PhysicSystem extends IteratingSystem implements EntityListener {
|
public class PhysicSystem extends IteratingSystem implements EntityListener, ContactListener {
|
||||||
|
|
||||||
private final World world;
|
private final World world;
|
||||||
private final float interval;
|
private final float interval;
|
||||||
@@ -22,6 +28,7 @@ public class PhysicSystem extends IteratingSystem implements EntityListener {
|
|||||||
this.world = world;
|
this.world = world;
|
||||||
this.interval = interval;
|
this.interval = interval;
|
||||||
this.accumulator = 0f;
|
this.accumulator = 0f;
|
||||||
|
world.setContactListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -86,4 +93,42 @@ public class PhysicSystem extends IteratingSystem implements EntityListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginContact(Contact contact) {
|
||||||
|
Object userDataA = contact.getFixtureA().getBody().getUserData();
|
||||||
|
Object userDataB = contact.getFixtureB().getBody().getUserData();
|
||||||
|
|
||||||
|
if (!(userDataA instanceof Entity entityA) || !(userDataB instanceof Entity entityB)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerTriggerContact(entityA, entityB);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void playerTriggerContact(Entity entityA, Entity entityB) {
|
||||||
|
Trigger trigger = Trigger.MAPPER.get(entityA);
|
||||||
|
boolean isPlayer = Player.MAPPER.get(entityB) != null;
|
||||||
|
if (trigger != null && isPlayer) {
|
||||||
|
trigger.setTriggeringEntity(entityB);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
trigger = Trigger.MAPPER.get(entityB);
|
||||||
|
isPlayer = Player.MAPPER.get(entityA) != null;
|
||||||
|
if (trigger != null && isPlayer) {
|
||||||
|
trigger.setTriggeringEntity(entityA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endContact(Contact contact) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preSolve(Contact contact, Manifold oldManifold) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postSolve(Contact contact, ContactImpulse impulse) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package io.github.com.quillraven.system;
|
||||||
|
|
||||||
|
import com.badlogic.ashley.core.Entity;
|
||||||
|
import com.badlogic.ashley.core.Family;
|
||||||
|
import com.badlogic.ashley.systems.IteratingSystem;
|
||||||
|
import com.badlogic.ashley.utils.ImmutableArray;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.Animation;
|
||||||
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||||
|
import com.badlogic.gdx.utils.Timer;
|
||||||
|
import io.github.com.quillraven.asset.SoundAsset;
|
||||||
|
import io.github.com.quillraven.audio.AudioService;
|
||||||
|
import io.github.com.quillraven.component.Animation2D;
|
||||||
|
import io.github.com.quillraven.component.Life;
|
||||||
|
import io.github.com.quillraven.component.Tiled;
|
||||||
|
import io.github.com.quillraven.component.Trigger;
|
||||||
|
|
||||||
|
public class TriggerSystem extends IteratingSystem {
|
||||||
|
private final AudioService audioService;
|
||||||
|
|
||||||
|
public TriggerSystem(AudioService audioService) {
|
||||||
|
super(Family.all(Trigger.class).get());
|
||||||
|
this.audioService = audioService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void processEntity(Entity entity, float deltaTime) {
|
||||||
|
Trigger trigger = Trigger.MAPPER.get(entity);
|
||||||
|
if (trigger.getTriggeringEntity() == null) return;
|
||||||
|
|
||||||
|
fireTrigger(trigger.getName(), trigger.getTriggeringEntity());
|
||||||
|
trigger.setTriggeringEntity(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Entity getByTiledId(int tiledId) {
|
||||||
|
ImmutableArray<Entity> entities = getEngine().getEntitiesFor(Family.all(Tiled.class).get());
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
if (Tiled.MAPPER.get(entity).getId() == tiledId) {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireTrigger(String triggerName, Entity triggeringEntity) {
|
||||||
|
switch (triggerName) {
|
||||||
|
case "trap_trigger" -> trapTrigger(triggeringEntity);
|
||||||
|
default -> throw new GdxRuntimeException("Unsupported trigger: " + triggerName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void trapTrigger(Entity triggeringEntity) {
|
||||||
|
Entity trapEntity = getByTiledId(15);
|
||||||
|
if (trapEntity != null) {
|
||||||
|
// play trap animation
|
||||||
|
Animation2D animation2D = Animation2D.MAPPER.get(trapEntity);
|
||||||
|
animation2D.setSpeed(1f);
|
||||||
|
animation2D.setPlayMode(Animation.PlayMode.NORMAL);
|
||||||
|
audioService.playSound(SoundAsset.TRAP);
|
||||||
|
// reset animation
|
||||||
|
Timer.schedule(new Timer.Task() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
animation2D.setSpeed(0f);
|
||||||
|
animation2D.setType(Animation2D.AnimationType.IDLE);
|
||||||
|
}
|
||||||
|
}, 2.5f);
|
||||||
|
|
||||||
|
// damage player
|
||||||
|
Life life = Life.MAPPER.get(triggeringEntity);
|
||||||
|
if (life.getLife() > 2) {
|
||||||
|
life.addLife(-2f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,13 +7,10 @@ import com.badlogic.gdx.graphics.g2d.Animation;
|
|||||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
import com.badlogic.gdx.graphics.glutils.FileTextureData;
|
import com.badlogic.gdx.graphics.glutils.FileTextureData;
|
||||||
import com.badlogic.gdx.maps.MapLayer;
|
|
||||||
import com.badlogic.gdx.maps.MapObject;
|
import com.badlogic.gdx.maps.MapObject;
|
||||||
import com.badlogic.gdx.maps.MapObjects;
|
import com.badlogic.gdx.maps.MapObjects;
|
||||||
import com.badlogic.gdx.maps.objects.RectangleMapObject;
|
import com.badlogic.gdx.maps.objects.RectangleMapObject;
|
||||||
import com.badlogic.gdx.maps.tiled.TiledMap;
|
|
||||||
import com.badlogic.gdx.maps.tiled.TiledMapTile;
|
import com.badlogic.gdx.maps.tiled.TiledMapTile;
|
||||||
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
|
|
||||||
import com.badlogic.gdx.maps.tiled.objects.TiledMapTileMapObject;
|
import com.badlogic.gdx.maps.tiled.objects.TiledMapTileMapObject;
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
@@ -21,7 +18,6 @@ import com.badlogic.gdx.physics.box2d.Body;
|
|||||||
import com.badlogic.gdx.physics.box2d.BodyDef;
|
import com.badlogic.gdx.physics.box2d.BodyDef;
|
||||||
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
|
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
|
||||||
import com.badlogic.gdx.physics.box2d.FixtureDef;
|
import com.badlogic.gdx.physics.box2d.FixtureDef;
|
||||||
import com.badlogic.gdx.physics.box2d.PolygonShape;
|
|
||||||
import com.badlogic.gdx.physics.box2d.World;
|
import com.badlogic.gdx.physics.box2d.World;
|
||||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||||
import io.github.com.quillraven.GdxGame;
|
import io.github.com.quillraven.GdxGame;
|
||||||
@@ -39,10 +35,12 @@ import io.github.com.quillraven.component.Life;
|
|||||||
import io.github.com.quillraven.component.Move;
|
import io.github.com.quillraven.component.Move;
|
||||||
import io.github.com.quillraven.component.Physic;
|
import io.github.com.quillraven.component.Physic;
|
||||||
import io.github.com.quillraven.component.Player;
|
import io.github.com.quillraven.component.Player;
|
||||||
|
import io.github.com.quillraven.component.Tiled;
|
||||||
import io.github.com.quillraven.component.Transform;
|
import io.github.com.quillraven.component.Transform;
|
||||||
|
import io.github.com.quillraven.component.Trigger;
|
||||||
|
|
||||||
public class TiledAshleySpawner {
|
public class TiledAshleyConfigurator {
|
||||||
private static final Vector2 DEFAULT_SCALING = new Vector2(1f, 1f);
|
private static final Vector2 DEFAULT_PHYSIC_SCALING = new Vector2(1f, 1f);
|
||||||
|
|
||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
private final World physicWorld;
|
private final World physicWorld;
|
||||||
@@ -50,7 +48,7 @@ public class TiledAshleySpawner {
|
|||||||
private final Vector2 tmpVec2;
|
private final Vector2 tmpVec2;
|
||||||
private final AssetService assetService;
|
private final AssetService assetService;
|
||||||
|
|
||||||
public TiledAshleySpawner(Engine engine, World physicWorld, AssetService assetService) {
|
public TiledAshleyConfigurator(Engine engine, World physicWorld, AssetService assetService) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.physicWorld = physicWorld;
|
this.physicWorld = physicWorld;
|
||||||
this.tmpMapObjects = new MapObjects();
|
this.tmpMapObjects = new MapObjects();
|
||||||
@@ -58,120 +56,49 @@ public class TiledAshleySpawner {
|
|||||||
this.assetService = assetService;
|
this.assetService = assetService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadMapObjects(TiledMap tiledMap) {
|
public void onLoadTile(TiledMapTile tile, float x, float y) {
|
||||||
for (MapLayer layer : tiledMap.getLayers()) {
|
createBody(tile.getObjects(),
|
||||||
if (layer instanceof TiledMapTileLayer tileLayer) {
|
new Vector2(x, y),
|
||||||
loadTileLayer(tileLayer);
|
DEFAULT_PHYSIC_SCALING,
|
||||||
} else if ("objects".equals(layer.getName())) {
|
BodyDef.BodyType.StaticBody,
|
||||||
loadObjectLayer(layer);
|
Vector2.Zero,
|
||||||
} else if ("trigger".equals(layer.getName())) {
|
"environment");
|
||||||
loadTriggerLayer(layer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spawnMapBoundary(tiledMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spawnMapBoundary(TiledMap tiledMap) {
|
public void onLoadTrigger(String triggerName, MapObject mapObject) {
|
||||||
// create four boxes for the map boundary (left, right, bottom and top edge)
|
if (mapObject instanceof RectangleMapObject rectMapObj) {
|
||||||
int width = tiledMap.getProperties().get("width", 0, Integer.class);
|
Entity entity = this.engine.createEntity();
|
||||||
int tileW = tiledMap.getProperties().get("tilewidth", 0, Integer.class);
|
Rectangle rect = rectMapObj.getRectangle();
|
||||||
int height = tiledMap.getProperties().get("height", 0, Integer.class);
|
addEntityTransform(
|
||||||
int tileH = tiledMap.getProperties().get("tileheight", 0, Integer.class);
|
rect.getX(), rect.getY(), 0,
|
||||||
float mapW = width * tileW * GdxGame.UNIT_SCALE;
|
rect.getWidth(), rect.getHeight(),
|
||||||
float mapH = height * tileH * GdxGame.UNIT_SCALE;
|
1f, 1f,
|
||||||
float halfW = mapW * 0.5f;
|
0,
|
||||||
float halfH = mapH * 0.5f;
|
entity);
|
||||||
float boxThickness = 0.5f;
|
addEntityPhysic(
|
||||||
|
rectMapObj,
|
||||||
BodyDef bodyDef = new BodyDef();
|
BodyDef.BodyType.StaticBody,
|
||||||
bodyDef.type = BodyType.StaticBody;
|
tmpVec2.set(rect.getX(), rect.getY()).scl(GdxGame.UNIT_SCALE),
|
||||||
bodyDef.position.setZero();
|
entity);
|
||||||
bodyDef.fixedRotation = true;
|
entity.add(new Trigger(triggerName));
|
||||||
Body body = physicWorld.createBody(bodyDef);
|
entity.add(new Tiled(rectMapObj));
|
||||||
|
this.engine.addEntity(entity);
|
||||||
// left edge
|
} else {
|
||||||
PolygonShape shape = new PolygonShape();
|
throw new GdxRuntimeException("Unsupported map object type for trigger: " + mapObject.getClass().getSimpleName());
|
||||||
shape.setAsBox(boxThickness, halfH, new Vector2(-boxThickness, halfH), 0f);
|
|
||||||
body.createFixture(shape, 0f).setFriction(0f);
|
|
||||||
shape.dispose();
|
|
||||||
// right edge
|
|
||||||
shape = new PolygonShape();
|
|
||||||
shape.setAsBox(boxThickness, halfH, new Vector2(mapW + boxThickness, halfH), 0f);
|
|
||||||
body.createFixture(shape, 0f).setFriction(0f);
|
|
||||||
shape.dispose();
|
|
||||||
// bottom edge
|
|
||||||
shape = new PolygonShape();
|
|
||||||
shape.setAsBox(halfW, boxThickness, new Vector2(halfW, -boxThickness), 0f);
|
|
||||||
body.createFixture(shape, 0f).setFriction(0f);
|
|
||||||
shape.dispose();
|
|
||||||
// top edge
|
|
||||||
shape = new PolygonShape();
|
|
||||||
shape.setAsBox(halfW, boxThickness, new Vector2(halfW, mapH + boxThickness), 0f);
|
|
||||||
body.createFixture(shape, 0f).setFriction(0f);
|
|
||||||
shape.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadTileLayer(TiledMapTileLayer tileLayer) {
|
|
||||||
for (int y = 0; y < tileLayer.getHeight(); y++) {
|
|
||||||
for (int x = 0; x < tileLayer.getWidth(); x++) {
|
|
||||||
TiledMapTileLayer.Cell cell = tileLayer.getCell(x, y);
|
|
||||||
if (cell == null) continue;
|
|
||||||
|
|
||||||
TiledMapTile tile = cell.getTile();
|
|
||||||
createBody(tile.getObjects(),
|
|
||||||
new Vector2(x, y),
|
|
||||||
DEFAULT_SCALING,
|
|
||||||
BodyType.StaticBody,
|
|
||||||
Vector2.Zero,
|
|
||||||
"environment");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadTriggerLayer(MapLayer triggerLayer) {
|
public void onLoadObject(TiledMapTileMapObject tileMapObject) {
|
||||||
for (MapObject mapObject : triggerLayer.getObjects()) {
|
|
||||||
if (mapObject instanceof RectangleMapObject rectMapObj) {
|
|
||||||
Entity entity = this.engine.createEntity();
|
|
||||||
Rectangle rect = rectMapObj.getRectangle();
|
|
||||||
addEntityTransform(
|
|
||||||
rect.getX(), rect.getY(),
|
|
||||||
rect.getWidth(), rect.getHeight(),
|
|
||||||
1f, 1f,
|
|
||||||
0,
|
|
||||||
entity);
|
|
||||||
addEntityPhysic(
|
|
||||||
rectMapObj,
|
|
||||||
BodyType.StaticBody,
|
|
||||||
tmpVec2.set(rect.getX(), rect.getY()).scl(GdxGame.UNIT_SCALE),
|
|
||||||
entity);
|
|
||||||
this.engine.addEntity(entity);
|
|
||||||
} else {
|
|
||||||
throw new GdxRuntimeException("Unsupported trigger: " + mapObject.getClass().getSimpleName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadObjectLayer(MapLayer objectLayer) {
|
|
||||||
for (MapObject mapObject : objectLayer.getObjects()) {
|
|
||||||
if (mapObject instanceof TiledMapTileMapObject tileMapObject) {
|
|
||||||
spawnEntityOf(tileMapObject);
|
|
||||||
} else {
|
|
||||||
throw new GdxRuntimeException("Unsupported object: " + mapObject.getClass().getSimpleName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void spawnEntityOf(TiledMapTileMapObject tileMapObject) {
|
|
||||||
Entity entity = this.engine.createEntity();
|
Entity entity = this.engine.createEntity();
|
||||||
TiledMapTile tile = tileMapObject.getTile();
|
TiledMapTile tile = tileMapObject.getTile();
|
||||||
TextureRegion textureRegion = getTextureRegion(tile);
|
TextureRegion textureRegion = getTextureRegion(tile);
|
||||||
String classType = tile.getProperties().get("type", "", String.class);
|
String classType = tile.getProperties().get("type", "", String.class);
|
||||||
float sortOffsetY = tile.getProperties().get("sortOffsetY", 0, Integer.class);
|
float sortOffsetY = tile.getProperties().get("sortOffsetY", 0, Integer.class);
|
||||||
sortOffsetY *= GdxGame.UNIT_SCALE;
|
sortOffsetY *= GdxGame.UNIT_SCALE;
|
||||||
|
int z = tile.getProperties().get("z", 1, Integer.class);
|
||||||
|
|
||||||
addEntityTransform(
|
addEntityTransform(
|
||||||
tileMapObject.getX(), tileMapObject.getY(),
|
tileMapObject.getX(), tileMapObject.getY(), z,
|
||||||
textureRegion.getRegionWidth(), textureRegion.getRegionHeight(),
|
textureRegion.getRegionWidth(), textureRegion.getRegionHeight(),
|
||||||
tileMapObject.getScaleX(), tileMapObject.getScaleY(),
|
tileMapObject.getScaleX(), tileMapObject.getScaleY(),
|
||||||
sortOffsetY,
|
sortOffsetY,
|
||||||
@@ -190,6 +117,7 @@ public class TiledAshleySpawner {
|
|||||||
entity.add(new Facing(FacingDirection.DOWN));
|
entity.add(new Facing(FacingDirection.DOWN));
|
||||||
entity.add(new Fsm(entity));
|
entity.add(new Fsm(entity));
|
||||||
entity.add(new Graphic(textureRegion, Color.WHITE.cpy()));
|
entity.add(new Graphic(textureRegion, Color.WHITE.cpy()));
|
||||||
|
entity.add(new Tiled(tileMapObject));
|
||||||
|
|
||||||
this.engine.addEntity(entity);
|
this.engine.addEntity(entity);
|
||||||
}
|
}
|
||||||
@@ -258,8 +186,9 @@ public class TiledAshleySpawner {
|
|||||||
AtlasAsset atlasAsset = AtlasAsset.valueOf(atlasAssetStr);
|
AtlasAsset atlasAsset = AtlasAsset.valueOf(atlasAssetStr);
|
||||||
FileTextureData textureData = (FileTextureData) tile.getTextureRegion().getTexture().getTextureData();
|
FileTextureData textureData = (FileTextureData) tile.getTextureRegion().getTexture().getTextureData();
|
||||||
String atlasKey = textureData.getFileHandle().nameWithoutExtension();
|
String atlasKey = textureData.getFileHandle().nameWithoutExtension();
|
||||||
|
float speed = tile.getProperties().get("animationSpeed", 0f, Float.class);
|
||||||
|
|
||||||
entity.add(new Animation2D(atlasAsset, atlasKey, animationType, Animation.PlayMode.LOOP, 1f));
|
entity.add(new Animation2D(atlasAsset, atlasKey, animationType, Animation.PlayMode.LOOP, speed));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addEntityPhysic(MapObject mapObject, @SuppressWarnings("SameParameterValue") BodyType bodyType, Vector2 relativeTo, Entity entity) {
|
private void addEntityPhysic(MapObject mapObject, @SuppressWarnings("SameParameterValue") BodyType bodyType, Vector2 relativeTo, Entity entity) {
|
||||||
@@ -305,7 +234,7 @@ public class TiledAshleySpawner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void addEntityTransform(
|
private static void addEntityTransform(
|
||||||
float x, float y,
|
float x, float y, int z,
|
||||||
float w, float h,
|
float w, float h,
|
||||||
float scaleX, float scaleY,
|
float scaleX, float scaleY,
|
||||||
float sortOffsetY,
|
float sortOffsetY,
|
||||||
@@ -318,7 +247,7 @@ public class TiledAshleySpawner {
|
|||||||
position.scl(GdxGame.UNIT_SCALE);
|
position.scl(GdxGame.UNIT_SCALE);
|
||||||
size.scl(GdxGame.UNIT_SCALE);
|
size.scl(GdxGame.UNIT_SCALE);
|
||||||
|
|
||||||
entity.add(new Transform(position, 0, size, scaling, 0f, sortOffsetY));
|
entity.add(new Transform(position, z, size, scaling, 0f, sortOffsetY));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,43 @@
|
|||||||
package io.github.com.quillraven.tiled;
|
package io.github.com.quillraven.tiled;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.maps.MapLayer;
|
||||||
|
import com.badlogic.gdx.maps.MapObject;
|
||||||
|
import com.badlogic.gdx.maps.objects.RectangleMapObject;
|
||||||
import com.badlogic.gdx.maps.tiled.TiledMap;
|
import com.badlogic.gdx.maps.tiled.TiledMap;
|
||||||
|
import com.badlogic.gdx.maps.tiled.TiledMapTile;
|
||||||
|
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
|
||||||
|
import com.badlogic.gdx.maps.tiled.objects.TiledMapTileMapObject;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.badlogic.gdx.physics.box2d.Body;
|
||||||
|
import com.badlogic.gdx.physics.box2d.BodyDef;
|
||||||
|
import com.badlogic.gdx.physics.box2d.PolygonShape;
|
||||||
|
import com.badlogic.gdx.physics.box2d.World;
|
||||||
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||||
|
import io.github.com.quillraven.GdxGame;
|
||||||
import io.github.com.quillraven.asset.AssetService;
|
import io.github.com.quillraven.asset.AssetService;
|
||||||
import io.github.com.quillraven.asset.MapAsset;
|
import io.github.com.quillraven.asset.MapAsset;
|
||||||
|
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class TiledService {
|
public class TiledService {
|
||||||
private final AssetService assetService;
|
private final AssetService assetService;
|
||||||
private Consumer<TiledMap> mapChangeConsumer;
|
private final World physicWorld;
|
||||||
|
|
||||||
private TiledMap currentMap;
|
private TiledMap currentMap;
|
||||||
|
|
||||||
public TiledService(AssetService assetService) {
|
private Consumer<TiledMap> mapChangeConsumer;
|
||||||
|
private BiConsumer<String, MapObject> loadTriggerConsumer;
|
||||||
|
private Consumer<TiledMapTileMapObject> loadObjectConsumer;
|
||||||
|
private LoadTileConsumer loadTileConsumer;
|
||||||
|
|
||||||
|
public TiledService(AssetService assetService, World physicWorld) {
|
||||||
this.assetService = assetService;
|
this.assetService = assetService;
|
||||||
|
this.physicWorld = physicWorld;
|
||||||
this.mapChangeConsumer = null;
|
this.mapChangeConsumer = null;
|
||||||
|
this.loadTriggerConsumer = null;
|
||||||
|
this.loadObjectConsumer = null;
|
||||||
|
this.loadTileConsumer = null;
|
||||||
this.currentMap = null;
|
this.currentMap = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +53,7 @@ public class TiledService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.currentMap = tiledMap;
|
this.currentMap = tiledMap;
|
||||||
|
loadMapObjects(tiledMap);
|
||||||
if (this.mapChangeConsumer != null) {
|
if (this.mapChangeConsumer != null) {
|
||||||
this.mapChangeConsumer.accept(tiledMap);
|
this.mapChangeConsumer.accept(tiledMap);
|
||||||
}
|
}
|
||||||
@@ -37,4 +62,116 @@ public class TiledService {
|
|||||||
public void setMapChangeConsumer(Consumer<TiledMap> mapChangeConsumer) {
|
public void setMapChangeConsumer(Consumer<TiledMap> mapChangeConsumer) {
|
||||||
this.mapChangeConsumer = mapChangeConsumer;
|
this.mapChangeConsumer = mapChangeConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLoadObjectConsumer(Consumer<TiledMapTileMapObject> loadObjectConsumer) {
|
||||||
|
this.loadObjectConsumer = loadObjectConsumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoadTriggerConsumer(BiConsumer<String, MapObject> loadTriggerConsumer) {
|
||||||
|
this.loadTriggerConsumer = loadTriggerConsumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoadTileConsumer(LoadTileConsumer loadTileConsumer) {
|
||||||
|
this.loadTileConsumer = loadTileConsumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadMapObjects(TiledMap tiledMap) {
|
||||||
|
for (MapLayer layer : tiledMap.getLayers()) {
|
||||||
|
if (layer instanceof TiledMapTileLayer tileLayer) {
|
||||||
|
loadTileLayer(tileLayer);
|
||||||
|
} else if ("objects".equals(layer.getName())) {
|
||||||
|
loadObjectLayer(layer);
|
||||||
|
} else if ("trigger".equals(layer.getName())) {
|
||||||
|
loadTriggerLayer(layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spawnMapBoundary(tiledMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spawnMapBoundary(TiledMap tiledMap) {
|
||||||
|
// create four boxes for the map boundary (left, right, bottom and top edge)
|
||||||
|
int width = tiledMap.getProperties().get("width", 0, Integer.class);
|
||||||
|
int tileW = tiledMap.getProperties().get("tilewidth", 0, Integer.class);
|
||||||
|
int height = tiledMap.getProperties().get("height", 0, Integer.class);
|
||||||
|
int tileH = tiledMap.getProperties().get("tileheight", 0, Integer.class);
|
||||||
|
float mapW = width * tileW * GdxGame.UNIT_SCALE;
|
||||||
|
float mapH = height * tileH * GdxGame.UNIT_SCALE;
|
||||||
|
float halfW = mapW * 0.5f;
|
||||||
|
float halfH = mapH * 0.5f;
|
||||||
|
float boxThickness = 0.5f;
|
||||||
|
|
||||||
|
BodyDef bodyDef = new BodyDef();
|
||||||
|
bodyDef.type = BodyDef.BodyType.StaticBody;
|
||||||
|
bodyDef.position.setZero();
|
||||||
|
bodyDef.fixedRotation = true;
|
||||||
|
Body body = physicWorld.createBody(bodyDef);
|
||||||
|
|
||||||
|
// left edge
|
||||||
|
PolygonShape shape = new PolygonShape();
|
||||||
|
shape.setAsBox(boxThickness, halfH, new Vector2(-boxThickness, halfH), 0f);
|
||||||
|
body.createFixture(shape, 0f).setFriction(0f);
|
||||||
|
shape.dispose();
|
||||||
|
// right edge
|
||||||
|
shape = new PolygonShape();
|
||||||
|
shape.setAsBox(boxThickness, halfH, new Vector2(mapW + boxThickness, halfH), 0f);
|
||||||
|
body.createFixture(shape, 0f).setFriction(0f);
|
||||||
|
shape.dispose();
|
||||||
|
// bottom edge
|
||||||
|
shape = new PolygonShape();
|
||||||
|
shape.setAsBox(halfW, boxThickness, new Vector2(halfW, -boxThickness), 0f);
|
||||||
|
body.createFixture(shape, 0f).setFriction(0f);
|
||||||
|
shape.dispose();
|
||||||
|
// top edge
|
||||||
|
shape = new PolygonShape();
|
||||||
|
shape.setAsBox(halfW, boxThickness, new Vector2(halfW, mapH + boxThickness), 0f);
|
||||||
|
body.createFixture(shape, 0f).setFriction(0f);
|
||||||
|
shape.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadTileLayer(TiledMapTileLayer tileLayer) {
|
||||||
|
if (loadTileConsumer == null) return;
|
||||||
|
|
||||||
|
for (int y = 0; y < tileLayer.getHeight(); y++) {
|
||||||
|
for (int x = 0; x < tileLayer.getWidth(); x++) {
|
||||||
|
TiledMapTileLayer.Cell cell = tileLayer.getCell(x, y);
|
||||||
|
if (cell == null) continue;
|
||||||
|
|
||||||
|
loadTileConsumer.accept(cell.getTile(), x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadTriggerLayer(MapLayer triggerLayer) {
|
||||||
|
if (loadTriggerConsumer == null) return;
|
||||||
|
|
||||||
|
for (MapObject mapObject : triggerLayer.getObjects()) {
|
||||||
|
if (mapObject.getName() == null || mapObject.getName().isBlank()) {
|
||||||
|
throw new GdxRuntimeException("Trigger must have a name: " + mapObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapObject instanceof RectangleMapObject rectMapObj) {
|
||||||
|
loadTriggerConsumer.accept(mapObject.getName(), rectMapObj);
|
||||||
|
} else {
|
||||||
|
throw new GdxRuntimeException("Unsupported trigger: " + mapObject.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadObjectLayer(MapLayer objectLayer) {
|
||||||
|
if (loadObjectConsumer == null) return;
|
||||||
|
|
||||||
|
for (MapObject mapObject : objectLayer.getObjects()) {
|
||||||
|
if (mapObject instanceof TiledMapTileMapObject tileMapObject) {
|
||||||
|
loadObjectConsumer.accept(tileMapObject);
|
||||||
|
} else {
|
||||||
|
throw new GdxRuntimeException("Unsupported object: " + mapObject.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface LoadTileConsumer {
|
||||||
|
void accept(TiledMapTile tile, float x, float y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class GameViewModel extends ViewModel {
|
|||||||
public void setLifePoints(int lifePoints) {
|
public void setLifePoints(int lifePoints) {
|
||||||
if (this.lifePoints != lifePoints) {
|
if (this.lifePoints != lifePoints) {
|
||||||
this.propertyChangeSupport.firePropertyChange(LIFE_POINTS, this.lifePoints, lifePoints);
|
this.propertyChangeSupport.firePropertyChange(LIFE_POINTS, this.lifePoints, lifePoints);
|
||||||
if (this.lifePoints < lifePoints) {
|
if (this.lifePoints != 0 && this.lifePoints < lifePoints) {
|
||||||
audioService.playSound(SoundAsset.LIFE_REG);
|
audioService.playSound(SoundAsset.LIFE_REG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||