Added Tiled mapping support

This commit is contained in:
Ethan Adams 2024-08-22 20:13:38 -04:00
parent 6ee1e08e2a
commit 0620990611
25 changed files with 1023 additions and 397 deletions

View file

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="64" tileheight="64" infinite="0" nextlayerid="4" nextobjectid="20">
<tileset firstgid="1" source="tilesets/shooterWorldOne.tsx"/>
<layer id="2" name="Tile Layer 2" width="30" height="20">
<data encoding="csv">
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,28,28,29,25,28,28,29,27,31,28,28,31,28,32,26,29,30,27,25,27,32,28,31,26,29,25,29,32,0,
0,32,27,22,16,16,23,31,26,30,31,31,29,28,30,25,28,26,26,25,29,26,25,32,28,28,31,32,25,0,
0,30,24,11,4,8,14,26,28,31,26,24,16,16,16,16,23,27,25,25,30,26,29,29,30,29,25,29,27,0,
0,25,15,6,1,2,14,28,32,30,24,11,8,7,3,8,12,23,28,27,25,32,30,32,30,28,27,27,26,0,
0,28,20,13,13,13,19,32,28,29,15,5,2,5,3,5,2,14,25,32,31,32,24,16,16,16,23,29,27,0,
0,31,29,31,27,26,27,30,29,27,15,8,7,5,2,3,6,14,27,32,32,29,15,8,4,2,14,26,27,0,
0,30,30,30,25,32,29,31,30,29,20,10,1,3,5,3,9,19,27,25,29,31,20,13,13,13,19,31,26,0,
0,28,30,30,28,24,23,27,31,28,29,20,13,13,13,13,19,27,31,28,27,26,29,26,32,25,31,25,32,0,
0,26,26,31,29,20,19,30,25,29,25,25,25,28,30,27,28,25,31,30,27,26,26,28,25,29,25,32,31,0,
0,30,32,29,29,32,31,27,25,31,31,31,26,30,31,27,29,25,29,32,0,0,0,0,30,26,31,0,0,0,
0,30,27,31,31,28,25,25,28,26,30,27,26,28,30,29,30,25,30,32,0,0,0,0,0,0,0,0,0,0,
0,27,29,22,21,30,29,29,32,0,0,0,0,32,30,30,31,32,26,28,0,0,0,0,0,0,0,0,0,0,
0,27,25,18,17,30,28,30,0,0,0,0,0,26,31,26,25,30,27,29,26,0,0,0,0,0,0,0,0,0,
0,32,30,31,30,30,28,0,0,0,0,0,0,32,27,31,30,28,26,31,26,0,0,0,0,0,0,0,0,0,
0,32,31,27,31,31,25,28,25,27,27,32,27,30,32,26,31,28,25,30,31,31,0,0,0,0,0,0,0,0,
0,32,26,26,26,31,29,27,26,27,30,26,29,29,28,25,32,28,29,28,32,25,0,0,0,0,0,0,0,0,
0,25,26,28,30,32,28,25,27,29,30,30,28,28,28,26,25,30,26,27,29,27,0,0,0,0,0,0,0,0,
0,29,26,31,29,30,26,25,32,29,31,28,26,32,32,27,28,26,27,28,29,30,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
<objectgroup id="3" name="Object Layer 1">
<object id="2" gid="57" x="452" y="516" width="64" height="64"/>
<object id="3" gid="61" x="896" y="444" width="64" height="64"/>
<object id="4" gid="61" x="956" y="314" width="64" height="64"/>
<object id="6" gid="63" x="1152" y="768" width="64" height="64"/>
<object id="8" gid="64" x="1214" y="256" width="64" height="64"/>
<object id="9" gid="62" x="1022" y="640" width="64" height="64"/>
<object id="10" gid="58" x="894" y="772" width="64" height="64"/>
<object id="11" gid="58" x="314" y="832" width="64" height="64"/>
<object id="12" gid="59" x="768" y="1152" width="64" height="64"/>
<object id="13" gid="64" x="320" y="254" width="64" height="64"/>
<object id="14" gid="62" x="190" y="1090" width="64" height="64"/>
<object id="15" gid="62" x="576" y="194" width="64" height="64"/>
<object id="16" gid="60" x="580" y="638" width="64" height="64"/>
<object id="17" gid="60" x="516" y="1152" width="64" height="64"/>
<object id="18" gid="57" x="126" y="894" width="64" height="64"/>
<object id="19" gid="58" x="1536" y="260" width="64" height="64"/>
</objectgroup>
<layer id="1" name="Tile Layer 1" width="30" height="20">
<data encoding="csv">
35,36,34,35,33,38,38,34,35,34,34,39,38,39,35,39,38,37,39,39,33,33,38,34,34,34,33,37,34,40,
37,41,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,42,34,
38,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,33,
36,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,39,
37,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,36,
35,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,34,
37,46,0,28,28,30,25,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,39,
34,46,0,30,30,29,25,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,34,
40,46,0,29,26,31,29,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,35,
33,46,0,30,31,32,27,27,0,0,0,0,0,0,0,0,0,0,0,56,48,48,48,48,55,0,56,48,43,33,
35,46,0,25,30,32,31,28,0,0,0,0,0,0,0,0,0,0,0,47,34,36,34,39,44,48,43,34,36,40,
40,46,0,0,0,0,0,0,56,48,48,48,48,55,0,0,0,0,0,47,36,36,34,39,38,36,36,38,36,37,
35,46,0,0,0,0,0,56,43,36,38,38,39,46,0,0,0,0,0,47,40,39,38,36,38,40,40,34,38,37,
38,46,0,0,0,0,56,43,37,39,36,36,33,46,0,0,0,0,0,0,42,39,35,36,33,34,33,38,40,39,
34,46,0,0,0,0,47,35,34,40,39,38,36,46,0,0,0,0,0,0,47,38,36,34,34,33,36,40,35,40,
38,46,0,0,0,0,52,45,45,45,45,45,45,51,0,0,0,0,0,0,52,42,37,34,40,37,33,38,37,37,
37,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,35,33,33,39,35,40,34,37,
39,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,34,37,36,34,34,39,40,33,
38,44,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,43,39,35,34,35,38,38,37,39,
38,38,40,37,38,35,36,37,36,39,36,39,36,36,34,39,40,36,40,37,37,33,40,37,38,38,33,38,39,38
</data>
</layer>
</map>

View file

@ -0,0 +1,366 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.10" tiledversion="1.11.0" name="worldOne" class="shooter" tilewidth="64" tileheight="64" tilecount="64" columns="8">
<image source="shooterWorldOneAtlas64.png" width="512" height="512"/>
<tile id="0" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="1" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="2" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="3" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="4" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="5" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="6" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="7" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="8" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="9" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="10" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="11" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="12" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="13" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="14" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="15" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="16" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="17" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="18" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="19" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="20" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="21" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="22" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="23" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="24" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="25" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="26" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="27" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="28" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="29" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="30" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="31" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="32" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="33" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="34" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="35" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="36" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="37" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="38" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="39" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="40" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="41" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="42" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="43" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="44" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="45" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="46" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="47" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="48" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="49" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="50" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="51" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="52" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="53" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="54" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="55" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="56" type="object">
<objectgroup draworder="index" id="2">
<object id="1" name="flower" type="object" x="15.5" y="14" width="14" height="26.5">
<properties>
<property name="collidable" type="bool" value="false"/>
</properties>
</object>
<object id="2" name="flower" type="object" x="34.25" y="26.5" width="13.25" height="24">
<properties>
<property name="collidable" type="bool" value="false"/>
</properties>
</object>
</objectgroup>
</tile>
<tile id="57" type="object">
<objectgroup draworder="index" id="2">
<object id="1" name="flower" type="object" x="11.5" y="17.75" width="15" height="29.25">
<properties>
<property name="collidable" type="bool" value="false"/>
</properties>
</object>
<object id="2" name="flower" type="object" x="41.5" y="5.75" width="13" height="22.75">
<properties>
<property name="collidable" type="bool" value="false"/>
</properties>
</object>
</objectgroup>
</tile>
<tile id="58" type="object">
<objectgroup draworder="index" id="2">
<object id="1" name="duck" type="object" x="6.25" y="12" width="47" height="41.75">
<properties>
<property name="collidable" type="bool" value="true"/>
</properties>
</object>
</objectgroup>
</tile>
<tile id="59" type="object">
<objectgroup draworder="index" id="2">
<object id="1" name="pebbles" type="object" x="11.25" y="21.25" width="23.75" height="22.25">
<properties>
<property name="collidable" type="bool" value="false"/>
</properties>
</object>
</objectgroup>
</tile>
<tile id="60" type="object">
<objectgroup draworder="index" id="2">
<object id="1" name="rock" type="object" x="7" y="28.75" width="50.5" height="26.5">
<properties>
<property name="collidable" type="bool" value="true"/>
</properties>
</object>
</objectgroup>
</tile>
<tile id="61" type="object">
<objectgroup draworder="index" id="2">
<object id="1" name="shrub" type="object" x="6.75" y="3.75" width="50.75" height="54.75">
<properties>
<property name="collidable" type="bool" value="true"/>
</properties>
</object>
</objectgroup>
</tile>
<tile id="62" type="object">
<objectgroup draworder="index" id="2">
<object id="1" name="pebbles" type="object" x="23" y="34" width="30.5" height="22.75">
<properties>
<property name="collidable" type="bool" value="false"/>
</properties>
</object>
</objectgroup>
</tile>
<tile id="63" type="object">
<objectgroup draworder="index" id="2">
<object id="1" name="pebbles" type="object" x="33.5" y="4.25" width="24" height="28">
<properties>
<property name="collidable" type="bool" value="false"/>
</properties>
</object>
</objectgroup>
</tile>
</tileset>

View file

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View file

@ -0,0 +1,14 @@
{
"automappingRulesFile": "",
"commands": [
],
"compatibilityVersion": 1100,
"extensionsPath": "extensions",
"folders": [
"../"
],
"properties": [
],
"propertyTypes": [
]
}

View file

@ -0,0 +1,54 @@
{
"activeFile": "",
"expandedProjectPaths": [
],
"fileStates": {
"": {
"scaleInDock": 1
},
":/automap-tiles.tsx": {
"scaleInDock": 1
},
"C:/Users/Ethan/Documents/yupplemayham/debugmap.tmx": {
"scale": 0.5472395833333333,
"selectedLayer": 0,
"viewCenter": {
"x": 959.3604263824117,
"y": 639.5736175882744
}
},
"C:/Users/Ethan/Documents/yupplemayham/shooterWorldOneAtlas.tsx": {
"scaleInDock": 0.5,
"scaleInEditor": 1
},
"debugmap.tmx": {
"scale": 0.45125,
"selectedLayer": 0,
"viewCenter": {
"x": 959.5567867036011,
"y": 955.1246537396123
}
},
"shooterWorldOneAtlas.tsx": {
"scaleInDock": 0.5,
"scaleInEditor": 1
},
"tilesets/shooterWorldOneAtlas.tsx": {
"scaleInDock": 0.5,
"scaleInEditor": 1
}
},
"last.externalTilesetPath": "C:/Users/Ethan/source/repos/YuppleMayham/Resources/maps/tilesets",
"last.imagePath": "C:/Users/Ethan/source/repos/YuppleMayham/Resources/maps/tilesets",
"openFiles": [
],
"project": "yupple.tiled-project",
"property.type": "bool",
"recentFiles": [
"tilesets/shooterWorldOneAtlas.tsx",
"shooterWorldOneAtlas.tsx",
"C:/Users/Ethan/Documents/yupplemayham/shooterWorldOneAtlas.tsx",
"C:/Users/Ethan/Documents/yupplemayham/debugmap.tmx"
],
"tileset.lastUsedFilter": "Tiled tileset files (*.tsx *.xml)"
}

View file

@ -1,38 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<scene type="shooter" id="000">
<map name="debugShooterMap" file="sprites/shooterWorldOneAtlas64.png" width="100" height="100" tilesize="64.0">
<tiledata>
<row data="66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,66,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66"/>
</tiledata>
<spriteids>
<row data="32,33,34,35,36,32,33,34,35,36,32,33,34,35,36,37,33,34,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,35,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,32,33,34,35,36,32,33,34,35,36,37,33,34,32,33,34,35,36"/>
</spriteids>
</map>
<map name="debugmap"/>
<entities>
<player x="7" y="5" weapon="shotGun">
<animation name="player_anim"/>

View file

@ -6,6 +6,13 @@ uniform sampler2D tileTexture;
void main()
{
if (texCoord.x == 0.0 && texCoord.y == 0.0)
{
FragColor = vec4(0.0, 0.0, 0.0, 0.0);
}
else
{
FragColor = texture(tileTexture, texCoord);
}
//FragColor = vec4(mod(tileindex / float(tilesperrow), 1.0), mod(tileindex / float(tilesperrow), 1.0), 0.0, 1.0);
}

View file

@ -1,7 +1,7 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
layout (location = 2) in int tileIndex;
layout (location = 2) in int aTileIndex;
layout (location = 3) in mat4 aModel;
uniform int tilesPerRow;
@ -9,19 +9,29 @@ uniform mat4 proj;
uniform mat4 view;
out vec2 texCoord;
out int tileIndex;
void main()
{
tileIndex = aTileIndex;
gl_Position = proj * view * aModel * vec4(aPos, 1.0);
if (tileIndex != 0)
{
int index = tileIndex - 1;
float tileSize = 1.0 / float(tilesPerRow);
gl_Position = proj * view * aModel * vec4(aPos, 1.0);
int row = tileIndex / tilesPerRow;
int col = tileIndex % tilesPerRow;
int row = index / tilesPerRow;
int col = index % tilesPerRow;
float offsetX = float(col) * tileSize;
float offsetY = float(row) * tileSize;
texCoord.x = (aTexCoord.x + col) * tileSize;
texCoord.y = (aTexCoord.y + row) * tileSize;
}
else
{
texCoord.x = 0.0;
texCoord.y = 0.0;
}
}

View file

@ -35,7 +35,7 @@ add_executable (YuppleMayham
"src/gameplay/weapons/bulletmanager.cpp"
"src/gameplay/scene.cpp"
"src/graphics/texture.cpp"
"src/graphics/tile.cpp"
"src/utility/resourcemanager.cpp"
"src/utility/xmlloader.cpp"
"src/gameplay/game.cpp"
@ -52,9 +52,9 @@ add_executable (YuppleMayham
"include/utility/mousestate.h"
"include/gameplay/weapons/bulletmanager.h"
"include/gameplay/scene.h"
"include/graphics/tile.h"
"include/graphics/texture.h"
"include/graphics/tiletype.h"
"include/utility/resourcemanager.h"
"include/utility/xmlloader.h"
"include/gameplay/game.h"

View file

@ -6,17 +6,16 @@
#include "graphics/instancedraw.h"
//class TileTextureInstance;
class Shader;
class Camera;
class ResourceManager;
struct MapData;
//struct InstanceData;
struct Tile;
struct TileSetData;
class Map
{
public:
Map(const std::shared_ptr<MapData>& mapData, const std::shared_ptr<Shader>& shader);
Map(std::shared_ptr<MapData> mapData, const std::shared_ptr<Shader>& shader, std::shared_ptr<ResourceManager> resourceManager);
const std::vector<std::vector<int>> getCollisionMap() const { return collisionMap; }
@ -26,13 +25,14 @@ private:
void loadMap();
void createCollisionMap();
const std::shared_ptr<MapData> mapData;
std::shared_ptr<MapData> mapData;
std::shared_ptr<TileSetData> tileSetData;
std::shared_ptr<TileTextureInstance> instanceHandle;
std::vector<std::shared_ptr<TileTextureInstance>> instanceHandles;
std::shared_ptr<Shader> shader;
std::vector<std::vector<std::shared_ptr<Tile>>> tileIds;
std::vector<std::vector<std::vector<int>>> tileIds;
std::vector<std::vector<int>> collisionMap;
std::vector<InstanceData> tileData;
std::vector<std::vector<InstanceData>> tileData;
};
#endif

View file

@ -27,7 +27,7 @@ struct WeaponData;
class Weapon : public Entity, public std::enable_shared_from_this<Weapon>
{
public:
Weapon(const WeaponData* data, const std::shared_ptr<Shader>& weaponShader, const std::shared_ptr<Shader>& bulletShader, ResourceManager* resourceManager);
Weapon(std::shared_ptr<WeaponData> data, const std::shared_ptr<Shader>& weaponShader, const std::shared_ptr<Shader>& bulletShader, ResourceManager* resourceManager);
void setWielder(const std::shared_ptr<GameActor>& wielder) { this->wielder = wielder; }
void toggleInfiniteAmmo() { infiniteAmmo = !infiniteAmmo; }

View file

@ -10,7 +10,7 @@ class Texture;
struct InstanceData {
glm::mat4 modelMatrix;
int tileIndex;
int tileIndex = 0;
};
class BaseInstanceDraw
@ -26,6 +26,7 @@ protected:
Texture* texture = nullptr;
InstanceData instanceData[MAX_INSTANCES];
size_t numOfInstances = 0;
size_t numOfLayers = 0;
unsigned indices[6] = {
0, 1, 2,
3, 2, 0

View file

@ -1,37 +0,0 @@
#ifndef _H_TILE_H
#define _H_TILE_H
#include <vector>
#include <unordered_map>
#include <memory>
#include <glad/glad.h>
enum class TileType;
class Texture;
// TODO: Decide how this struct will be used.
// This holds only the texture data of the tile, this texture data will be held in
// a further struct called Tile
struct TileTexture {
Texture* texture = nullptr;
unsigned VAO, VBO, EBO;
};
// TODO: Finished replacing the Sprite version of tile set with this one
// This class is NOT for game logic, only for the storage of the tile pointers that point to the TileTexture
class TileSet
{
public:
TileSet(const char* tileSetImage, float frameSize);
void setupTiles(float frameSize);
~TileSet();
const std::shared_ptr<TileTexture>& getTileTexture(TileType tileType) const;
private:
Texture* texture;
std::unordered_map<TileType, std::shared_ptr<TileTexture>> tiles;
};
#endif

View file

@ -1,78 +0,0 @@
#ifndef _H_TILETYPE_H
#define _H_TILETYPE_H
struct Tile {
enum class SpriteID {
TILE_SOLID_GRASS_1,
TILE_SOLID_GRASS_2,
TILE_SOLID_GRASS_3,
TILE_SOLID_GRASS_4,
TILE_SOLID_GRASS_5,
TILE_SOLID_GRASS_6,
TILE_SOLID_GRASS_7,
TILE_SOLID_GRASS_8,
TILE_LSHAPE_GRASS_TL,
TILE_LSHAPE_GRASS_TR,
TILE_LSHAPE_GRASS_BR,
TILE_LSHAPE_GRASS_BL,
TILE_LINE_GRASS_T,
TILE_LINE_GRASS_L,
TILE_LINE_GRASS_R,
TILE_LINE_GRASS_B,
TILE_VSEG_GRASS_TL,
TILE_VSEG_GRASS_TR,
TILE_HSEG_GRASS_TL,
TILE_HSEG_GRASS_TR,
TILE_VSEG_GRASS_BL,
TILE_VSEG_GRASS_BR,
TILE_HSEG_GRASS_BL,
TILE_HSEG_GRASS_BR,
TILE_SOLID_DIRT_1,
TILE_SOLID_DIRT_2,
TILE_SOLID_DIRT_3,
TILE_SOLID_DIRT_4,
TILE_SOLID_DIRT_5,
TILE_SOLID_DIRT_6,
TILE_SOLID_DIRT_7,
TILE_SOLID_DIRT_8,
TILE_SOLID_WATER_1,
TILE_SOLID_WATER_2,
TILE_SOLID_WATER_3,
TILE_SOLID_WATER_4,
TILE_SOLID_WATER_5,
TILE_SOLID_WATER_6,
TILE_SOLID_WATER_7,
TILE_SOLID_WATER_8,
TILE_LSHAPE_WATER_TL,
TILE_LSHAPE_WATER_TR,
TILE_LSHAPE_WATER_BR,
TILE_LSHAPE_WATER_BL,
TILE_LINE_WATER_T,
TILE_LINE_WATER_L,
TILE_LINE_WATER_R,
TILE_LINE_WATER_B,
TILE_VSEG_WATER_TL,
TILE_VSEG_WATER_TR,
TILE_HSEG_WATER_TL,
TILE_HSEG_WATER_TR,
TILE_VSEG_WATER_BL,
TILE_VSEG_WATER_BR,
TILE_HSEG_WATER_BL,
TILE_HSEG_WATER_BR,
TILE_MISC_FLOWERS_1,
TILE_MISC_FLOWERS_2,
TILE_MISC_DUCK,
TILE_MISC_PEBBLE_1,
TILE_MISC_ROCK,
TILE_MISC_SHRUB,
TILE_MISC_PEBBLE_2,
TILE_MISC_PEBBLE_3
}spriteID;
enum class TileData {
TILE_WALKABLE = 1,
TILE_WATER = 2,
TILE_UNWALKABLE = 64
}tileData;
};
#endif // _H_TILETYPE_H

View file

@ -16,7 +16,7 @@ class Script;
class AnimationSet;
class AIScript;
class WeaponScript;
class TileSet;
class TileSetData;
class SpriteComponent;
class ResourceManager
@ -26,20 +26,22 @@ public:
xmlLoader(std::make_shared<XMLLoader>())
{
xmlLoader->loadWeapons("weapons");
xmlLoader->loadScenes("scenes");
xmlLoader->loadAnimations("animations");
xmlLoader->loadTileSets("maps/tilesets");
xmlLoader->loadMaps("maps");
xmlLoader->loadScenes("scenes");
};
std::shared_ptr<SpriteAtlas> loadSpriteAtlas (const std::string& path, float frameSize, bool isDirectional = false);
std::shared_ptr<Sprite> loadSpriteStatic (const std::string& path);
std::shared_ptr<AIScript> loadAIScript (const std::string& path);
std::shared_ptr<WeaponScript> loadWeaponScript (const std::string& path);
std::shared_ptr<TileSet> loadTileSet (const std::string& path, float frameSize);
std::shared_ptr<Shader> loadShader (const std::string& name, const std::string& vertexPath, const std::string& fragPath);
std::shared_ptr<Weapon> loadWeapon (const std::string& name, std::shared_ptr<Shader> weaponShader, std::shared_ptr<Shader> bulletShader);
std::shared_ptr<SceneData> loadScene (const std::string& id);
std::shared_ptr<AnimationSet> loadAnimationSet(const std::string& name, int entityid = 0);
std::shared_ptr<TileSetData> loadTileSet (const std::string& name);
void clearResources();
@ -48,7 +50,7 @@ private:
std::unordered_map<std::string, std::shared_ptr<Shader>> shaders;
std::unordered_map<std::string, std::shared_ptr<Weapon>> weapons;
std::unordered_map<std::string, std::shared_ptr<Script>> scripts;
std::unordered_map<std::string, std::shared_ptr<TileSet>> tileSets;
std::unordered_map<std::string, std::shared_ptr<TileSetData>>tileSets;
//std::unordered_map<std::string, std::shared_ptr<EntityData>> entityData;
//std::unordered_map<std::string, std::shared_ptr<SceneData>> scenes;
//std::unordered_map<std::string, std::shared_ptr<MapData>> maps;

View file

@ -5,6 +5,12 @@
#include <string>
#include <memory>
#include <unordered_map>
#include <glm/glm.hpp>
#include <sstream>
#include <fstream>
#include <filesystem>
#include <tinyxml2.h>
struct Tile;
@ -19,17 +25,44 @@ struct EntityData {
struct MapData {
std::string name;
std::string file;
std::string tileSet;
int width = 0, height = 0;
float tileSize = 32.f;
std::vector<std::vector<std::shared_ptr<Tile>>> groundTiles;
// 3D array, 0: layer, 1: y, 2: x
// Holding tile ids + 1, 0 is an empty tile
std::vector<std::vector<std::vector<int>>> tiles;
};
struct TileSetData {
std::string name;
std::string type;
std::string file;
int width = 0, height = 0;
int columns = 0;
int tileCount = 0;
float tileSize = 64.f;
struct TileData {
int id = 0;
std::string type;
bool walkable = true;
struct ObjectData {
int id = 0;
std::string name;
glm::vec2 pos;
glm::vec2 size;
bool collidable = false;
bool pickup = false;
};
std::vector<std::shared_ptr<ObjectData>> objects;
};
std::vector<std::shared_ptr<TileData>> tiles;
};
struct SceneData {
std::string id;
std::string type;
MapData map;
std::shared_ptr<MapData> map;
std::vector<EntityData> entities;
};
@ -74,6 +107,8 @@ public:
bool loadScenes(const char* sceneFolder);
bool loadWeapons(const char* weaponFolder);
bool loadAnimations(const char* animationFolder);
bool loadTileSets(const char* tileSetFolder);
bool loadMaps(const char* mapFolder);
const std::shared_ptr<SceneData> getSceneData(const std::string& id) const {
try {
@ -84,6 +119,24 @@ public:
}
}
const std::shared_ptr<MapData> getMapData(const std::string& name) const {
try {
return maps.at(name);
}
catch (std::exception&) {
return nullptr;
}
}
const std::shared_ptr<WeaponData> getWeaponData(const std::string& name) const {
try {
return weapons.at(name);
}
catch (std::exception&) {
return nullptr;
}
}
const std::shared_ptr<AnimationData> getAnimationData(const std::string& name) const {
try {
return animations.at(name);
@ -93,6 +146,15 @@ public:
}
}
const std::shared_ptr<TileSetData> getTileSetData(const std::string& name) const {
try {
return tileSets.at(name);
}
catch (std::exception&) {
return nullptr;
}
}
// return a full set of animations, may need further optimization.
// one idea is when loading animations we create a seperate map that holds each set by their reference, so we can just do a simple,
// hash table lookup.
@ -106,18 +168,18 @@ public:
return animSet;
}
const WeaponData* getWeaponDataByName(const char* name) const;
void clearData() { scenes.clear(); weaponData.clear(); animations.clear(); }
void clearData() { scenes.clear(); weapons.clear(); animations.clear(); maps.clear(); tileSets.clear(); }
protected:
bool loadXmlScene(const char* xmlFile, SceneData* out);
bool loadMap(const char* xmlFile, SceneData* out);
bool loadEntityData(const char* xmlFile, SceneData* out);
bool loadTile(tinyxml2::XMLElement* tileElement, TileSetData::TileData* out);
bool loadObject(tinyxml2::XMLElement* objectElement, TileSetData::TileData::ObjectData* out);
private:
std::unordered_map<std::string, std::shared_ptr<SceneData>> scenes;
std::unordered_map<std::string, std::shared_ptr<WeaponData>> weapons;
std::unordered_map<std::string, std::shared_ptr<AnimationData>> animations;
std::vector<WeaponData> weaponData;
std::unordered_map<std::string, std::shared_ptr<MapData>> maps;
std::unordered_map<std::string, std::shared_ptr<TileSetData>> tileSets;
};
#endif // _H_XMLLOADER_H

View file

@ -1,52 +1,75 @@
#include "gameplay/map.h"
#include "utility/xmlloader.h"
#include "graphics/tiletype.h"
#include "graphics/shader.h"
#include "gameplay/camera.h"
#include "graphics/shader.h"
#include "utility/xmlloader.h"
#include "utility/resourcemanager.h"
#include <glm/gtc/matrix_transform.hpp>
Map::Map(const std::shared_ptr<MapData>& mapData, const std::shared_ptr<Shader>& shader) :
Map::Map(std::shared_ptr<MapData> mapData, const std::shared_ptr<Shader>& shader, std::shared_ptr<ResourceManager> resourceManager) :
shader(shader),
mapData(mapData)
mapData(mapData),
tileIds(mapData->tiles)
{
instanceHandle = std::make_shared<TileTextureInstance>(this->mapData->file.c_str());
tileIds = mapData->groundTiles;
tileSetData = resourceManager->loadTileSet(mapData->tileSet);
if (tileSetData)
{
for (int layer = 0; layer < tileIds.size(); layer++)
instanceHandles.push_back(std::make_shared<TileTextureInstance>(tileSetData->file.c_str()));
loadMap();
createCollisionMap();
}
}
void Map::loadMap()
{
for (int y = 0; y < tileIds.size(); y++)
tileData.resize(tileIds.size());
for (int layer = 0; layer < tileIds.size(); layer++)
{
for (int x = 0; x < tileIds[y].size(); x++)
for (int y = 0; y < tileIds[layer].size(); y++)
{
for (int x = 0; x < tileIds[layer][y].size(); x++)
{
glm::mat4 modelMatrix =
glm::translate(glm::mat4(1.f), glm::vec3(x * mapData->tileSize, y * mapData->tileSize, 0.0f)) *
glm::scale(glm::mat4(1.f), glm::vec3(mapData->tileSize, mapData->tileSize, 1.0f));
int tileIndex = static_cast<int>(tileIds[y][x]->spriteID);
tileData.push_back({ modelMatrix, tileIndex });
int tileIndex = static_cast<int>(tileIds[layer][y][x]);
tileData[layer].push_back({modelMatrix, tileIndex});
}
}
}
shader->use();
// TODO: Figure someway to put these in with my xml data
shader->setInt("tilesPerRow", 8);
shader->setInt("tilesPerRow", tileSetData->columns);
}
void Map::createCollisionMap()
{
for (int y = 0; y < mapData->groundTiles.size(); y++)
// Match collisionMap to map size
collisionMap.resize(tileIds[0].size());
for (int y = 0; y < tileIds[0].size(); ++y)
{
std::vector<int> row;
for (int x = 0; x < mapData->groundTiles[y].size(); x++)
{
if ((int)mapData->groundTiles[y][x]->tileData & (int)Tile::TileData::TILE_UNWALKABLE)
row.push_back(1);
else
row.push_back(0);
collisionMap[y].resize(tileIds[0][y].size(), 0);
}
for (int layer = 0; layer < tileIds.size(); layer++)
{
for (int y = 0; y < tileIds[layer].size(); y++)
{
for (int x = 0; x < tileIds[layer][y].size(); x++)
{
int id = tileIds[layer][y][x];
if (id == 0)
collisionMap[y][x] = 0;
else
{
auto& tile = tileSetData->tiles[id - 1];
if (!tile->walkable)
collisionMap[y][x] = 1;
}
}
}
collisionMap.push_back(row);
}
}
@ -55,6 +78,9 @@ void Map::render(const std::shared_ptr<Camera>& camera)
shader->use();
shader->setMatrix4f("proj", glm::value_ptr(camera->getProjectionMatrix()));
shader->setMatrix4f("view", glm::value_ptr(camera->getViewMatrix()));
instanceHandle->updateInstanceData(tileData);
instanceHandle->draw();
for (int layer = 0; layer < instanceHandles.size(); layer++)
{
instanceHandles[layer]->updateInstanceData(tileData[layer]);
instanceHandles[layer]->draw();
}
}

View file

@ -6,7 +6,6 @@
#include "gameplay/physics.h"
#include "gameplay/ai.h"
#include "graphics/tile.h"
#include "graphics/sprite.h"
#include "graphics/animation.h"
@ -46,14 +45,14 @@ void Scene::loadDebugShooterScene()
if (!sceneData)
return;
EntityData playerData = sceneData->entities[0];
MapData mapData = sceneData->map;
auto mapData = sceneData->map;
auto playerShader = resourceManager->loadShader("GL_player", "shaders/GL_player.vert", "shaders/GL_player.frag");
auto bubbleShader = resourceManager->loadShader("GL_bubble", "shaders/GL_bubble.vert", "shaders/GL_bubble.frag");
auto weaponShader = resourceManager->loadShader("GL_pistol", "shaders/GL_pistol.vert", "shaders/GL_pistol.frag");
// creating map from scene
auto tileShader = resourceManager->loadShader("GL_tile", "shaders/GL_tile.vert", "shaders/GL_tile.frag");
map = std::make_shared<Map>(std::make_shared<MapData>(mapData), tileShader);
map = std::make_shared<Map>(mapData, tileShader, resourceManager);
for (EntityData entityData : sceneData->entities)
{
@ -80,15 +79,15 @@ void Scene::loadDebugShooterScene()
entity->pickupWeapon(defaultWeapon);
entity->pickupWeapon(entityWeapon);
entity->hookEventManager(eventManager);
entity->setPosition(glm::vec3(entityData.x * mapData.tileSize, entityData.y * mapData.tileSize, 0.f));
entity->setScale(glm::vec3(mapData.tileSize, mapData.tileSize, 1.f));
entity->setPosition(glm::vec3(entityData.x * mapData->tileSize, entityData.y * mapData->tileSize, 0.f));
entity->setScale(glm::vec3(mapData->tileSize, mapData->tileSize, 1.f));
entity->addPhysicsComponent(
physicsEngine->createObject(entity->getEntityID(),
entity->getPosition(),
49.0,
PhysicsComponent::Collider::Shape::Circle,
glm::vec3(mapData.tileSize / 2),
glm::vec3(mapData->tileSize / 2),
glm::abs(entity->getCenter() - entity->getPosition()))
);
@ -104,7 +103,7 @@ void Scene::loadDebugShooterScene()
if (!entityData.script.empty())
{
auto behaviourScript = resourceManager->loadAIScript(entityData.script);
auto rayCaster = std::make_shared<Raycaster>(40.f, 300.f, map->getCollisionMap(), mapData.tileSize);
auto rayCaster = std::make_shared<Raycaster>(40.f, 300.f, map->getCollisionMap(), mapData->tileSize);
auto ai = std::make_shared<AI>(entity, rayCaster);
ai->setTarget(player);
ai->attachBehaviourScript(behaviourScript);
@ -114,7 +113,7 @@ void Scene::loadDebugShooterScene()
entities.emplace(entity->getEntityID(), entity);
}
physicsEngine->loadCollisionMap(map->getCollisionMap(), sceneData->map.tileSize);
physicsEngine->loadCollisionMap(map->getCollisionMap(), mapData->tileSize);
// Setup map and other entities...
}

View file

@ -13,7 +13,7 @@
// TODO: Regular clean up, make this mess readable!
Weapon::Weapon(const WeaponData* data, const std::shared_ptr<Shader>& weaponShader, const std::shared_ptr<Shader>& bulletShader, ResourceManager* resourceManager)
Weapon::Weapon(std::shared_ptr<WeaponData> data, const std::shared_ptr<Shader>& weaponShader, const std::shared_ptr<Shader>& bulletShader, ResourceManager* resourceManager)
:
Entity (weaponShader),
bulletShader (bulletShader),

View file

@ -24,12 +24,12 @@ bool Texture::loadTexture(const char* imagePath)
glBindTexture(GL_TEXTURE_2D, ID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, buffer->w, buffer->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer->pixels);
glGenerateMipmap(ID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glGenerateMipmap(ID);
textureWidth = buffer->w;
textureHeight = buffer->h;

View file

@ -1,80 +0,0 @@
#include "graphics/tile.h"
#include "graphics/texture.h"
#include "graphics/tiletype.h"
TileSet::TileSet(const char* tileSetImage, float frameSize)
{
texture->loadTexture(tileSetImage);
setupTiles(frameSize);
}
void TileSet::setupTiles(float frameSize)
{
int width = texture->getWidth();
int height = texture->getHeight();
float frameRows = height / frameSize;
float frameCols = width / frameSize;
int frame = 0;
float indices[] = {
0, 1, 2,
3, 2, 0
};
for (int row = 0; row < frameRows; row++)
{
for (int column = 0; column < frameCols; column++)
{
float left = (column) * (frameSize / width);
float right = (column + 1) * (frameSize / width);
float bottom = (row) * (frameSize / height);
float top = (row + 1) * (frameSize / height);
float vertices[] = {
0.0f, 0.0f, 0.0f, left, bottom, // bottom left
1.0f, 0.0f, 0.0f, right, bottom, // bottom right
1.0f, 1.0f, 0.0f, right, top, // top right
0.0f, 1.0f, 0.0f, left, top // top left
};
unsigned VAO, EBO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &EBO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_VERTEX_ARRAY, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_VERTEX_ARRAY, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_VERTEX_ARRAY, 0);
glBindVertexArray(0);
tiles[(TileType)frame++] = std::make_shared<TileTexture>(TileTexture({ this->texture, VAO, EBO, VBO }));
}
}
}
const std::shared_ptr<TileTexture>& TileSet::getTileTexture(TileType tileType) const
{
auto tile = tiles.find(tileType);
if (tile != tiles.end())
return tile->second;
return nullptr;
}
TileSet::~TileSet()
{
delete texture;
for (auto& [type, tile] : tiles)
{
glDeleteBuffers(1, &tile->EBO);
glDeleteBuffers(1, &tile->VBO);
glDeleteVertexArrays(1, &tile->VAO);
}
}

View file

@ -1,9 +1,7 @@
#include "utility/resourcemanager.h"
#include "utility/component.h"
#include "graphics/sprite.h"
#include "graphics/tile.h"
#include "utility/script.h"
#include "graphics/tiletype.h"
#include "graphics/shader.h"
#include "graphics/animation.h"
#include "gameplay/weapons/weapons.h"
@ -38,14 +36,9 @@ std::shared_ptr<WeaponScript> ResourceManager::loadWeaponScript(const std::strin
return std::make_shared<WeaponScript>(path.c_str());
}
std::shared_ptr<TileSet> ResourceManager::loadTileSet(const std::string& path, float frameSize)
std::shared_ptr<TileSetData> ResourceManager::loadTileSet(const std::string& name)
{
auto iterator = tileSets.find(path);
if (iterator != tileSets.end())
return iterator->second;
auto tileset = std::make_shared<TileSet>(path.c_str(), frameSize);
tileSets[path] = tileset;
return tileset;
return xmlLoader->getTileSetData(name);
}
std::shared_ptr<Shader> ResourceManager::loadShader(const std::string& name, const std::string& vertexPath, const std::string& fragPath)
@ -62,7 +55,7 @@ std::shared_ptr<Shader> ResourceManager::loadShader(const std::string& name, con
// incomplete reference to our script.
std::shared_ptr<Weapon> ResourceManager::loadWeapon(const std::string& name, std::shared_ptr<Shader> weaponShader, std::shared_ptr<Shader> shader)
{
const WeaponData* data = xmlLoader->getWeaponDataByName(name.c_str());
std::shared_ptr<WeaponData> data = xmlLoader->getWeaponData(name);
auto weapon = std::make_shared<Weapon>(data, weaponShader, shader, this);
if (!data->script.empty())
weapon->attachScript(loadWeaponScript(data->script));
@ -99,4 +92,5 @@ void ResourceManager::clearResources()
sprites.clear();
shaders.clear();
weapons.clear();
tileSets.clear();
}

View file

@ -1,21 +1,9 @@
#include "utility/xmlloader.h"
#include "graphics/tiletype.h"
#include <sstream>
#include <fstream>
#include <filesystem>
#include <tinyxml2.h>
const WeaponData* XMLLoader::getWeaponDataByName(const char* name) const
{
for (int i = 0; i < weaponData.size(); i++)
{
if (weaponData[i].name == name)
return &weaponData[i];
}
return nullptr;
}
/*
Loading every scene in the scene folder and storing in hashmap scenes
hashkey is the id of the scene
*/
bool XMLLoader::loadScenes(const char* sceneFolder)
{
std::filesystem::path folder(sceneFolder);
@ -31,6 +19,9 @@ bool XMLLoader::loadScenes(const char* sceneFolder)
return true;
}
/*
Loading scene data
*/
bool XMLLoader::loadXmlScene(const char* xmlFile, SceneData* out)
{
tinyxml2::XMLDocument doc;
@ -38,83 +29,29 @@ bool XMLLoader::loadXmlScene(const char* xmlFile, SceneData* out)
return false;
tinyxml2::XMLElement* scene = doc.FirstChildElement("scene");
const char* type, * id;
const char* type, * id, * mapName;
if (scene->QueryStringAttribute("type", &type) != tinyxml2::XML_SUCCESS ||
scene->QueryStringAttribute("id", &id) != tinyxml2::XML_SUCCESS)
return false;
out->type = type;
out->id = id;
if (!loadMap(xmlFile, out))
tinyxml2::XMLElement* map = scene->FirstChildElement("map");
if (map == NULL)
return false;
if (map->QueryStringAttribute("name", &mapName) != tinyxml2::XML_SUCCESS)
return false;
if (!(out->map = getMapData(mapName)))
return false;
if (!loadEntityData(xmlFile, out))
return false;
return true;
}
bool XMLLoader::loadMap(const char* xmlFile, SceneData* out)
{
tinyxml2::XMLDocument doc;
if (doc.LoadFile(xmlFile) != tinyxml2::XML_SUCCESS)
return false;
tinyxml2::XMLElement* map = doc.FirstChildElement("scene")->FirstChildElement("map");
const char* name, * file;
if (map->QueryStringAttribute("name", &name) != tinyxml2::XML_SUCCESS ||
map->QueryIntAttribute("width", &out->map.width) != tinyxml2::XML_SUCCESS ||
map->QueryIntAttribute("height", &out->map.height) != tinyxml2::XML_SUCCESS ||
map->QueryStringAttribute("file", &file) != tinyxml2::XML_SUCCESS)
return false;
map->QueryFloatAttribute("tilesize", &out->map.tileSize);
out->map.name = name;
out->map.file = file;
auto spriteIDs = map->FirstChildElement("spriteids");
auto tileData = map->FirstChildElement("tiledata");
if (spriteIDs == NULL || tileData == NULL)
return false;
auto data = tileData->FirstChildElement("row");
for (tinyxml2::XMLElement* e = spriteIDs->FirstChildElement("row"); e != NULL; e = e->NextSiblingElement("row"))
{
std::vector<std::shared_ptr<Tile>> buffer;
std::string row = e->Attribute("data", NULL);
std::string dataRow = (data == NULL) ? "0" : data->Attribute("data", NULL);
std::string tileString;
std::stringstream ss(row);
std::stringstream ssData(dataRow);
Tile t;
// TODO: Read TileData and move this loop to make sure we're reading SpriteID refer to xml
while (!ss.eof())
{
std::getline(ss, tileString, ',');
std::stringstream idss(tileString);
int id;
idss >> id;
if (!ssData.eof())
{
std::getline(ssData, tileString, ',');
std::stringstream datass(tileString);
int dataID;
datass >> dataID;
t.tileData = (Tile::TileData)dataID;
}
else
t.tileData = (Tile::TileData)1;
t.spriteID = (Tile::SpriteID)id;
buffer.push_back(std::make_shared<Tile>(t));
}
if (data != NULL)
data = data->NextSiblingElement("row");
out->map.groundTiles.push_back(buffer);
}
return true;
}
/*
Load entity data held in the scene file, store inside of the SceneData out parameter
*/
bool XMLLoader::loadEntityData(const char* xmlFile, SceneData* out)
{
tinyxml2::XMLDocument doc;
@ -208,6 +145,10 @@ float getFloatIfExists(tinyxml2::XMLElement* e)
return buf;
}
/*
Load every weapon file, weapon nodes can be fit together in one file or placed in seperate files.
hash key is the weapon name
*/
bool XMLLoader::loadWeapons(const char* weaponFolder)
{
// We are gonna check every xml file within the weaponFolder, then check every weapon node within each file.
@ -320,12 +261,15 @@ bool XMLLoader::loadWeapons(const char* weaponFolder)
modifier->QueryFloatAttribute("max", &data.modMax);
}
weaponData.push_back(data);
weapons.try_emplace(data.name, std::make_shared<WeaponData>(data));
}
}
return (!weaponData.empty());
return (!weapons.empty());
}
/*
Load every animation file and store inside of hashmap -> animations, filename is the hash key
*/
bool XMLLoader::loadAnimations(const char* animationFolder)
{
std::filesystem::path folder(animationFolder);
@ -369,3 +313,253 @@ bool XMLLoader::loadAnimations(const char* animationFolder)
}
return true;
}
/*
Start of (LoadTileSets)
Load every tileset and store them in hashmap tileSets
hashkey is the <parent directory>/<filename>, this is due to the expected
file structure, being
Resources
|
- maps
|
- tilesets
Thats is, the tilesets folder is within the maps folder.
This makes it easier to import maps from the Tiled program.
Refer to the Tiled project file for the file structure
*/
bool XMLLoader::loadTileSets(const char* tileSetFolder)
{
std::filesystem::path folder(tileSetFolder);
if (!std::filesystem::exists(folder) || !std::filesystem::is_directory(folder))
return false;
for (auto& file : std::filesystem::directory_iterator(folder))
{
if (!file.path().has_extension() || !file.path().has_filename() || !file.exists() || file.is_directory())
continue;
tinyxml2::XMLDocument doc;
if (doc.LoadFile(file.path().generic_string().c_str()) != tinyxml2::XML_SUCCESS)
continue;
tinyxml2::XMLElement* tileSet = doc.FirstChildElement("tileset");
if (tileSet == NULL)
continue;
TileSetData tileSetData;
const char* setName, * setType, * setFile;
// Read attributes of tileset element
if (tileSet->QueryStringAttribute("name", &setName) != tinyxml2::XML_SUCCESS ||
tileSet->QueryStringAttribute("class", &setType) != tinyxml2::XML_SUCCESS ||
tileSet->QueryFloatAttribute("tilewidth", &tileSetData.tileSize) != tinyxml2::XML_SUCCESS ||
tileSet->QueryIntAttribute("tilecount", &tileSetData.tileCount) != tinyxml2::XML_SUCCESS ||
tileSet->QueryIntAttribute("columns", &tileSetData.columns) != tinyxml2::XML_SUCCESS)
continue;
tinyxml2::XMLElement* image = tileSet->FirstChildElement("image");
if (image == NULL)
continue;
// Reading image element attribs
if (image->QueryStringAttribute("source", &setFile) != tinyxml2::XML_SUCCESS ||
image->QueryIntAttribute("width", &tileSetData.width) != tinyxml2::XML_SUCCESS ||
image->QueryIntAttribute("height", &tileSetData.height) != tinyxml2::XML_SUCCESS)
continue;
for (tinyxml2::XMLElement* tileElement = tileSet->FirstChildElement("tile"); tileElement != NULL; tileElement = tileElement->NextSiblingElement("tile"))
{
TileSetData::TileData tileData;
if (!loadTile(tileElement, &tileData))
continue;
tileSetData.tiles.push_back(std::make_shared<TileSetData::TileData>(tileData));
}
tileSetData.name = setName;
tileSetData.type = setType;
tileSetData.file = file.path().parent_path().string() + "/" + std::string(setFile);
std::string key = folder.filename().string() + "/" + file.path().filename().string();
tileSets.try_emplace(key, std::make_shared<TileSetData>(tileSetData));
}
return true;
}
bool XMLLoader::loadTile(tinyxml2::XMLElement* tileElement, TileSetData::TileData* out)
{
TileSetData::TileData tileData;
const char* tileType;
if (tileElement == NULL)
return false;
if (tileElement->QueryIntAttribute("id", &tileData.id) != tinyxml2::XML_SUCCESS ||
tileElement->QueryStringAttribute("type", &tileType) != tinyxml2::XML_SUCCESS)
return false;
if (std::string(tileType).compare("object") == 0)
{
/*
Refer to .tsx file of tile set for specific details regarding the layout of the tile element.
You will notice each tile has the potential to be a container for objects, so that is how we are
handling it here. If the tileType was specified as an object, but it contains no objects, then we don't
load the tile. Objects are defined in the Tiled program using the collision editor.
*/
tinyxml2::XMLElement* objectGroup = tileElement->FirstChildElement("objectgroup");
if (objectGroup == NULL)
return false;
for (tinyxml2::XMLElement* obj = objectGroup->FirstChildElement("object"); obj != NULL; obj = obj->NextSiblingElement("object"))
{
TileSetData::TileData::ObjectData objData;
if (!loadObject(obj, &objData))
continue;
tileData.objects.push_back(std::make_shared<TileSetData::TileData::ObjectData>(objData));
}
if (tileData.objects.empty())
return false;
}
else
{
/*
May support multiple properties in the future with a future property struct to hold any value type
But this may not be needed, so we'll just capture the walkable property for now.
Notice we just return true if there is no property, we can just safely default to walkable = true
*/
tinyxml2::XMLElement* properties = tileElement->FirstChildElement("properties");
if (properties == NULL)
return true;
tinyxml2::XMLElement* propWalk = properties->FirstChildElement("property");
if (propWalk == NULL || !propWalk->Attribute("name", "walkable"))
return true;
propWalk->QueryBoolAttribute("value", &tileData.walkable);
}
tileData.type = tileType;
*out = tileData;
return true;
}
bool XMLLoader::loadObject(tinyxml2::XMLElement* objElement, TileSetData::TileData::ObjectData* out)
{
TileSetData::TileData::ObjectData objData;
const char* objName;
// avoid null pointer exception
if (objElement == NULL)
return false;
// load id and name
if (objElement->QueryIntAttribute("id", &objData.id) != tinyxml2::XML_SUCCESS ||
objElement->QueryStringAttribute("name", &objName) != tinyxml2::XML_SUCCESS)
return false;
// load position into vec2
if (objElement->QueryFloatAttribute("x", &objData.pos.x) != tinyxml2::XML_SUCCESS ||
objElement->QueryFloatAttribute("y", &objData.pos.y) != tinyxml2::XML_SUCCESS)
return false;
// load size into seperate vec2
if (objElement->QueryFloatAttribute("width", &objData.size.x) != tinyxml2::XML_SUCCESS ||
objElement->QueryFloatAttribute("height", &objData.size.y) != tinyxml2::XML_SUCCESS)
return false;
// refer to comment in XMLLoader::loadTile regarding the properties portion as to why we return true here
tinyxml2::XMLElement* properties = objElement->FirstChildElement("properties");
if (properties != NULL)
{
tinyxml2::XMLElement* propCollide = properties->FirstChildElement("property");
if (propCollide != NULL && propCollide->Attribute("name", "collidable"))
propCollide->QueryBoolAttribute("value", &objData.collidable);
}
objData.name = objName;
*out = objData;
return true;
}
/* End of (LoadTileSets) */
bool XMLLoader::loadMaps(const char* mapFolder)
{
std::filesystem::path folder(mapFolder);
if (!std::filesystem::exists(folder) || !std::filesystem::is_directory(folder))
return false;
for (auto& file : std::filesystem::directory_iterator(folder))
{
if (!file.path().has_extension() || !file.path().has_filename() || !file.exists() || file.is_directory())
continue;
tinyxml2::XMLDocument doc;
if (doc.LoadFile(file.path().generic_string().c_str()) != tinyxml2::XML_SUCCESS)
continue;
tinyxml2::XMLElement* map = doc.FirstChildElement("map");
if (map == NULL)
continue;
MapData mapData;
const char* tileSetPath;
if (map->QueryIntAttribute("width", &mapData.width) != tinyxml2::XML_SUCCESS ||
map->QueryIntAttribute("height", &mapData.height) != tinyxml2::XML_SUCCESS ||
map->QueryFloatAttribute("tilewidth", &mapData.tileSize) != tinyxml2::XML_SUCCESS)
continue;
tinyxml2::XMLElement* tileSet = map->FirstChildElement("tileset");
if (tileSet == NULL)
continue;
if (tileSet->QueryStringAttribute("source", &tileSetPath) != tinyxml2::XML_SUCCESS)
continue;
mapData.tiles.reserve(10);
mapData.tiles.resize(10);
for (int layer = 0; layer < 10; ++layer)
{
mapData.tiles[layer].reserve(mapData.height);
mapData.tiles[layer].resize(mapData.height);
for (int y = 0; y < mapData.height; ++y)
{
mapData.tiles[layer][y].reserve(mapData.width);
mapData.tiles[layer][y].resize(mapData.width);
}
}
int layerNumber = 0;
for (tinyxml2::XMLElement* layer = map->FirstChildElement("layer"); layer != NULL; layer = layer->NextSiblingElement("layer"))
{
tinyxml2::XMLElement* data = layer->FirstChildElement("data");
if (data == NULL)
continue;
if (layerNumber >= 10)
continue;
std::string idSet = data->GetText();
std::string tileRow;
std::string tileString;
std::stringstream ssidSet(idSet);
int x = 0, y = -1;
while (std::getline(ssidSet, tileRow) && y < mapData.height)
{
std::stringstream ssid(tileRow);
x = 0;
while (std::getline(ssid, tileString, ',') && x < mapData.width)
{
int id = std::stoi(tileString);
mapData.tiles[layerNumber][y][x] = id;
x++;
}
y++;
}
layerNumber += 1;
}
mapData.tiles.resize(layerNumber);
mapData.tiles.shrink_to_fit();
/* TODO: Add object layer */
mapData.name = file.path().stem().string();
mapData.tileSet = tileSetPath;
maps.try_emplace(mapData.name, std::make_shared<MapData>(mapData));
}
return true;
}

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<scene type="shooter" id="000">
<map name="debugShooterMap" file="sprites/shooterWorldOneAtlas64.png" width="100" height="100" tilesize="64.0">
<tiledata>
<row data="66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,66,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,1,1,1,1,1,1,1,1,1,1,1,1,1,66,66,66,66,66"/>
<row data="66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66"/>
</tiledata>
<spriteids>
<row data="32,33,34,35,36,32,33,34,35,36,32,33,34,35,36,37,33,34,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,35,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,24,25,26,27,28,29,30,25,24,26,27,28,14,32,33,34,35,36"/>
<row data="32,33,34,35,36,32,33,34,35,36,32,33,34,35,36,37,33,34,32,33,34,35,36"/>
</spriteids>
</map>
<entities>
<player x="7" y="5" weapon="shotGun">
<animation name="player_anim"/>
</player>
<entity x="10" y="3" weapon="pistolGun">
<animation name="player_anim"/>
<script file="scripts/ai/grunt_behaviour.lua"/>
</entity>
<entity x="6" y="3" weapon="pistolGun">
<animation name="tmp_enemy_anim"/>
<script file="scripts/ai/grunt_behaviour.lua"/>
</entity>
<entity x="5" y="3" weapon="pistolGun">
<animation name="tmp_enemy_anim"/>
<script file="scripts/ai/grunt_behaviour.lua"/>
</entity>
</entities>
</scene>