optimization

This commit is contained in:
Ethan Adams 2025-01-28 16:07:58 -05:00
parent 0620990611
commit 868ec3eb56
49 changed files with 1385 additions and 148 deletions

View file

@ -0,0 +1,14 @@
<animations>
<animation name="shot_gun_idle_anim" type="idle">
<FPS>4</FPS>
<sprite path="sprites/shotGunIdle128.png" frameSize="128.0"/>
</animation>
<animation name="shot_gun_fire_anim" type="fire">
<FPS>8</FPS>
<sprite path="sprites/shotGunFire128.png" frameSize="128.0"/>
</animation>
<animation name="shot_gun_reload_anim" type="reload">
<FPS>8</FPS>
<sprite path="sprites/shotGunReload128.png" frameSize="128.0"/>
</animation>
</animations>

View file

@ -1,20 +1,21 @@
<?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">
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="62" tileheight="62" infinite="0" nextlayerid="5" nextobjectid="20">
<tileset firstgid="1" source="tilesets/shooterWorldOne.tsx"/>
<tileset firstgid="65" source="tilesets/wOne.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,25,15,6,1,2,14,28,32,30,24,11,0,0,0,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,0,0,0,0,0,0,14,25,32,91,32,24,16,16,16,23,29,27,0,
0,31,29,31,27,26,27,30,29,27,0,0,0,0,0,0,0,0,27,32,32,29,15,8,4,2,14,26,27,0,
0,30,30,30,25,32,29,30,27,28,32,32,30,0,0,0,0,0,27,25,29,31,20,13,13,13,19,31,26,0,
0,28,30,30,28,31,26,29,31,29,26,20,31,0,0,0,0,31,31,28,27,26,29,26,32,25,31,25,32,0,
0,26,26,31,29,20,29,31,25,32,28,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,28,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,32,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,
@ -43,20 +44,44 @@
<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="4" name="Tile Layer 3" 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,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,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,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,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,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,176,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,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,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,0,0,0,0,0,0,56,156,155,156,157,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,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,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,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,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,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,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>
<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,
36,46,0,0,0,0,0,0,0,0,0,31,32,27,31,30,29,0,0,0,0,0,0,0,0,0,0,0,47,39,
37,46,0,0,0,0,0,0,0,0,25,25,28,27,25,27,32,27,0,126,127,128,0,0,0,0,0,0,47,36,
35,46,0,176,149,150,150,144,0,0,30,28,31,30,32,29,31,32,0,117,141,131,0,0,0,0,0,0,47,34,
37,46,0,177,182,181,180,169,0,0,27,29,28,30,27,26,26,30,0,124,125,132,0,0,0,0,0,0,47,39,
34,46,0,153,180,146,156,175,149,164,176,149,144,25,27,25,31,32,0,0,0,0,0,0,0,0,0,0,47,34,
40,46,0,151,180,167,164,177,161,145,177,166,145,27,25,31,32,0,0,0,0,0,0,0,0,0,0,0,47,35,
33,46,0,153,180,181,145,151,180,167,165,159,169,0,0,0,0,0,0,56,48,48,48,48,55,0,56,48,43,33,
35,46,0,151,152,146,147,177,166,161,180,161,169,0,0,0,0,0,0,47,34,36,34,39,44,48,43,34,36,40,
40,46,0,154,155,157,0,178,155,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,

100
Resources/maps/newmap.tmx Normal file
View file

@ -0,0 +1,100 @@
<?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="62" tileheight="62" infinite="0" nextlayerid="5" nextobjectid="1">
<tileset firstgid="1" source="tilesets/wOne.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,34,31,31,30,70,72,30,34,29,34,73,33,29,71,72,30,33,31,71,29,70,34,0,0,0,0,0,0,0,
0,31,29,54,33,27,29,32,31,28,29,71,54,72,27,71,71,31,33,70,70,73,31,0,0,0,0,0,0,0,
0,72,70,34,73,31,0,0,30,31,33,32,29,34,70,71,33,27,32,30,31,30,29,0,0,0,0,0,0,0,
0,27,28,31,29,0,0,0,0,34,32,30,28,32,31,27,34,31,54,33,27,27,29,0,0,0,0,0,0,0,
0,54,27,54,28,0,0,0,0,54,31,72,71,34,27,72,70,29,71,73,30,30,71,70,0,0,0,0,0,0,
0,32,27,29,54,70,0,0,71,32,54,70,71,72,34,70,54,70,32,34,72,33,72,32,34,0,0,0,0,0,
0,70,27,54,34,31,27,33,31,28,31,33,54,71,29,33,73,28,34,34,34,71,32,33,30,73,0,0,0,0,
0,29,71,27,31,34,30,71,70,32,72,54,29,31,29,29,54,28,73,33,72,30,30,31,72,31,32,0,0,0,
0,34,72,29,72,29,71,34,31,33,27,70,70,29,71,27,33,28,34,73,54,72,70,73,71,31,54,0,0,0,
0,31,73,27,27,33,34,29,54,73,54,54,70,73,30,73,73,54,34,30,54,34,30,29,34,70,54,0,0,0,
0,28,72,28,28,33,33,29,31,32,30,27,73,27,31,34,73,54,31,32,28,34,70,73,72,33,28,0,0,0,
0,0,73,34,54,32,33,34,33,54,30,29,70,72,73,70,70,54,29,29,34,27,70,71,72,28,70,0,0,0,
0,0,0,29,30,32,27,32,31,28,73,27,72,28,73,71,31,28,71,30,28,34,72,73,54,27,32,0,0,0,
0,0,0,32,27,31,33,33,27,27,30,31,71,28,29,32,31,27,34,34,31,32,27,30,72,54,31,0,0,0,
0,0,0,0,0,34,32,31,29,70,33,32,0,34,34,33,72,70,70,28,30,70,29,30,30,30,34,0,0,0,
0,0,0,0,0,0,0,28,30,27,73,0,0,0,0,70,28,30,34,54,33,32,34,54,27,71,28,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,54,32,32,27,31,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,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>
<layer id="3" name="Tile Layer 3" 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,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,14,16,16,49,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,50,51,22,20,43,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,21,20,38,38,19,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,21,1,3,19,22,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,40,37,6,2,39,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,36,41,41,42,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,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,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,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,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,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,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,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,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,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,0
</data>
</layer>
<layer id="4" name="Tile Layer 4" 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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,77,0,0,0,77,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,75,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,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,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,0,0,0,0,0,0,0,0,0,0,78,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,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,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,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,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,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,
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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
<layer id="1" name="Tile Layer 1" width="30" height="20">
<data encoding="csv">
88,94,102,97,116,102,96,102,117,88,116,116,118,118,117,95,117,96,115,116,115,116,115,115,97,116,115,116,96,102,
88,106,91,92,92,91,91,92,92,92,91,92,92,91,91,92,92,92,92,91,91,92,108,116,115,97,117,94,94,115,
95,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,113,88,118,95,117,116,116,95,
118,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,88,116,94,96,95,102,102,
88,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,113,115,95,115,94,115,88,118,
94,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,114,108,96,96,88,116,97,102,
117,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,114,108,117,115,117,94,95,
116,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,114,108,118,95,118,118,
88,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,114,108,102,115,94,
118,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,97,118,117,
115,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,115,88,95,
97,103,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,116,96,88,
97,116,103,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,95,96,96,
88,96,97,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,97,102,88,
118,94,115,103,86,100,0,0,0,0,0,112,86,100,0,0,0,0,0,0,0,0,0,0,0,0,89,88,117,118,
95,97,96,97,118,103,85,100,0,0,112,101,88,103,86,100,0,0,0,0,0,0,0,0,0,0,87,102,94,88,
115,94,97,115,115,96,96,103,86,86,101,94,96,116,96,103,85,86,100,0,0,0,0,84,85,86,101,97,116,97,
95,88,116,96,115,116,97,97,96,115,97,117,115,102,102,97,115,118,103,85,86,85,86,101,94,115,97,118,117,115,
102,116,118,88,102,97,102,102,88,97,117,116,88,102,95,94,117,97,117,116,88,96,116,94,115,96,94,97,115,117,
88,95,96,115,94,97,117,116,96,94,94,94,116,96,88,102,97,115,94,94,117,97,116,88,88,88,96,118,118,116
</data>
</layer>
</map>

View file

@ -1,5 +1,6 @@
<?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">
<tileset version="1.10" tiledversion="1.11.0" name="worldOne" class="shooter" tilewidth="62" tileheight="62" spacing="2" tilecount="64" columns="8">
<grid orientation="orthogonal" width="64" height="64"/>
<image source="shooterWorldOneAtlas64.png" width="512" height="512"/>
<tile id="0" type="grass">
<properties>

View file

@ -0,0 +1,570 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.10" tiledversion="1.11.0" name="wOne" class="shooter" tilewidth="62" tileheight="62" spacing="2" tilecount="484" columns="11">
<grid orientation="orthogonal" width="30" height="30"/>
<image source="worldOne.png" width="704" height="704"/>
<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="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="9" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="10" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="11" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="12" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="13" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="14" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="15" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="16" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="17" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="18" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="19" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="20" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="21" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="22" type="grass"/>
<tile id="23" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="24" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="25" type="grass">
<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="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="33" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="34" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="35" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="36" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="37" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="38" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="39" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="40" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="41" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="42" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="43" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="44" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="45" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="46" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="47" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="48" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="49" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="50" type="grass">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="51" type="grass">
<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"/>
<tile id="55" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="56" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="57" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="58" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="59" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="60" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="61" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="62" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="63" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="64" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="65" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="66" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="67" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="68" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="69" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="70" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="71" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="72" type="dirt">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="73" type="bush"/>
<tile id="74" type="bush"/>
<tile id="75" type="bush"/>
<tile id="76" type="bush"/>
<tile id="77" type="bush"/>
<tile id="78" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="79" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="80" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="81" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="82" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="83" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="84" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="85" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="86" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="87" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="88" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="89" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="90" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="91" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="92" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="93" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="94" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="95" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="96" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="97" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="98" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="99" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="100" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="101" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="102" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="103" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="104" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="105" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="106" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="107" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="108" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="109" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="110" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="111" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="112" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="113" type="water">
<properties>
<property name="walkable" type="bool" value="true"/>
</properties>
</tile>
<tile id="114" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="115" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="116" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="117" type="water">
<properties>
<property name="walkable" type="bool" value="false"/>
</properties>
</tile>
<tile id="118" type="water"/>
<tile id="119" type="water"/>
<tile id="120" type="water"/>
</tileset>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -1,6 +1,13 @@
{
"activeFile": "",
"Map/SizeTest": {
"height": 4300,
"width": 2
},
"activeFile": "debugmap.tmx",
"expandedProjectPaths": [
"tilesets",
"C:/Users/Ethan/source/repos/YuppleMayham/Resources",
"."
],
"fileStates": {
"": {
@ -22,33 +29,76 @@
"scaleInEditor": 1
},
"debugmap.tmx": {
"scale": 0.45125,
"selectedLayer": 0,
"scale": 0.75,
"selectedLayer": 2,
"viewCenter": {
"x": 959.5567867036011,
"y": 955.1246537396123
"x": 989.3333333333334,
"y": 665.3333333333334
}
},
"newmap.tmx": {
"scale": 0.5,
"selectedLayer": 1,
"viewCenter": {
"x": 930,
"y": 621
}
},
"shooterWorldOneAtlas.tsx": {
"scaleInDock": 0.5,
"scaleInEditor": 1
},
"tilesets/shooterWorldOne.tsx": {
"scaleInDock": 0.5,
"scaleInEditor": 1
},
"tilesets/shooterWorldOneAtlas.tsx": {
"scaleInDock": 0.5,
"scaleInEditor": 1
},
"tilesets/wOne.tsx": {
"scaleInDock": 0.33,
"scaleInEditor": 1
},
"tilesets/was.tsx": {
"scaleInDock": 1,
"scaleInEditor": 1
},
"tilesets/wsa.tsx": {
"dynamicWrapping": false,
"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",
"map.lastUsedFormat": "tmx",
"openFiles": [
"debugmap.tmx",
"tilesets/shooterWorldOne.tsx",
"newmap.tmx",
"tilesets/wOne.tsx"
],
"project": "yupple.tiled-project",
"property.type": "bool",
"recentFiles": [
"tilesets/wOne.tsx",
"newmap.tmx",
"tilesets/shooterWorldOne.tsx",
"debugmap.tmx",
"tilesets/wsa.tsx",
"tilesets/was.tsx",
"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)"
"tileset.lastUsedFilter": "Tiled tileset files (*.tsx *.xml)",
"tileset.lastUsedFormat": "tsx",
"tileset.margin": 0,
"tileset.spacing": 2,
"tileset.tileSize": {
"height": 62,
"width": 62
}
}

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<scene type="shooter" id="000">
<map name="debugmap"/>
<map name="newmap"/>
<entities>
<player x="7" y="5" weapon="shotGun">
<animation name="player_anim"/>

View file

@ -3,22 +3,26 @@ patrolDestination = { x=500.0, y=500.0, z=0.0 }
moveLeft = true
-- helper functions
function watchPosition(actor, pos)
y = pos.y - actor.position.y
x = pos.x - actor.position.x
rotation = math.atan(y, x)
local y = pos.y - actor.position.y
local x = pos.x - actor.position.x
local rotation = math.atan(y, x)
actor.rotation = math.deg(rotation)
end
function distance(a, b)
return math.sqrt((math.abs(a.x - b.x)^2) + (math.abs(a.y - b.y)^2))
local dx = a.x - b.x
local dy = a.y - b.y
return math.sqrt(dx * dx + dy * dy)
end
function moveTo(actor, pos)
watchPosition(actor, pos)
if distance(actor.position, pos) < 50 then
local a = actor
local p = pos
watchPosition(a, p)
if distance(a.position, p) < 50 then
return true
end
actor:moveForward()
a:moveForward()
return false
end
@ -28,19 +32,23 @@ end
-- The AI will be spawned in idle mode, so if you want to put the bot into patrol mode
-- It's on you to do that in this function.
function idle(actor, target)
if target ~= nil then
local a = actor
local t = target
if t ~= nil then
-- print("target is at " .. target.position.x)
-- watchPosition(actor, target.position)
ai.state = AIState.Patrol
actor.rotation = 180
a.rotation = 180
end
actor:shoot()
a:shoot()
--print("actor is idling at " .. actor.position.x)
end
-- It is most appropriate to put any patrolling behaviour into this function of course
function patrol(actor, target)
if target ~= nil then
local a = actor
local t = target
if t ~= nil then
-- print("target is at " .. target.position.x)
end
--if moveTo(actor, patrolDestination) == true then
@ -52,7 +60,7 @@ function patrol(actor, target)
--if raycaster:performRaycast(actor.position, actor.rotation, target.position) == true then
--ai.state = AIState.Alert
--end
if raycaster:bresenhamRaycast(actor.position, actor.rotation, target.position) == true then
if raycaster:bresenhamRaycast(a.position, a.rotation, t.position) == true then
--target hit!
ai.state = AIState.Alert
end
@ -60,32 +68,34 @@ function patrol(actor, target)
upOrDown = math.random(2)
if moveLeft == true then
if upOrDown == 1 then
actor.rotation = 180
a.rotation = 180
else
actor.rotation = 270
a.rotation = 270
end
moveLeft = false
else
if upOrDown == 1 then
actor.rotation = 0
a.rotation = 0
else
actor.rotation = 90
a.rotation = 90
end
moveLeft = true
end
end
actor:moveForward()
a:moveForward()
end
-- the ai has found the player, this is what function is called
function alert(actor, target)
local a = actor
local t = target
if target ~= nil then
-- print("target is at " .. target.position.x)
watchPosition(actor, target.position)
watchPosition(a, t.position)
end
--print("actor is alert at " .. actor.position.x)
if distance(actor.position, target.position) > 300 then
actor:moveForward()
if distance(a.position, t.position) > 300 then
a:moveForward()
end
actor:shoot()
a:shoot()
end

View file

@ -6,8 +6,12 @@ out vec2 texCoord;
uniform mat4 MVP;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
void main()
{
texCoord = aTexCoord;
gl_Position = MVP * vec4(aPos, 1.0);
gl_Position = projection * view * model * vec4(aPos, 1.0);
}

View file

@ -5,12 +5,16 @@ layout (location = 1) in vec2 aTexCoord;
out vec2 texCoord;
uniform mat4 MVP;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform bool flip;
void main()
{
texCoord = aTexCoord;
gl_Position = MVP * vec4(aPos, 1.0);
gl_Position = projection * view * model * vec4(aPos, 1.0);
if (flip)
{
texCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y);

View file

@ -7,9 +7,13 @@ out vec2 texPos;
uniform mat4 MVP;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
void main()
{
pos = aPos;
texPos = aTexPos;
gl_Position = MVP * vec4(aPos, 1.0);
gl_Position = projection * view * model * vec4(aPos, 1.0);
}

View file

@ -1,8 +1,9 @@
#version 330 core
out vec4 FragColor;
in vec2 texCoord;
flat in int textureIndex;
uniform sampler2D tileTexture;
uniform sampler2DArray tileTexture;
void main()
{
@ -12,7 +13,7 @@ void main()
}
else
{
FragColor = texture(tileTexture, texCoord);
FragColor = texture(tileTexture, vec3(texCoord.xy, textureIndex));
}
//FragColor = vec4(mod(tileindex / float(tilesperrow), 1.0), mod(tileindex / float(tilesperrow), 1.0), 0.0, 1.0);
}

View file

@ -2,32 +2,37 @@
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
layout (location = 2) in int aTileIndex;
layout (location = 3) in mat4 aModel;
layout (location = 3) in int aTextureIndex;
layout (location = 4) in int aTilesPerRow;
layout (location = 5) in int aStartIndex;
layout (location = 6) in vec2 aOriginalSize;
layout (location = 7) in mat4 aModel;
uniform int tilesPerRow;
uniform vec2 uCanvasSize;
uniform mat4 proj;
uniform mat4 view;
out vec2 texCoord;
out int tileIndex;
flat out int textureIndex;
void main()
{
tileIndex = aTileIndex;
int tilesPerRow = aTilesPerRow;
gl_Position = proj * view * aModel * vec4(aPos, 1.0);
if (tileIndex != 0)
textureIndex = aTextureIndex;
if (aTileIndex != 0)
{
int index = tileIndex - 1;
vec2 scale = vec2(aOriginalSize.x / uCanvasSize.x, aOriginalSize.y / uCanvasSize.y);
int index = aTileIndex - aStartIndex;
float tileSize = 1.0 / float(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;
texCoord = texCoord * scale;
}
else
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View file

@ -11,9 +11,9 @@
</bullet>
</weapon>
<weapon name="shotGun" fireSpeed="750.0" maxAmmo="64" clipSize="4">
<weapon name="shotGun" fireSpeed="1750.0" maxAmmo="64" clipSize="4">
<script file="scripts/weapons/shotgun_script.lua"/>
<animation name="machine_gun_anim">
<animation name="shot_gun_anim">
<size x="55.0" y="55.0"/>
<offset x="-30.0" y="0.0"/>
</animation>

View file

@ -67,7 +67,7 @@ add_executable (YuppleMayham
"include/utility/raycaster.h"
"include/utility/ftfont.h"
"include/utility/direction.h"
"include/graphics/animation.h" "src/graphics/animation.cpp")
"include/graphics/animation.h" "src/graphics/animation.cpp" "include/utility/logger.h" "src/utility/logger.cpp")
add_custom_command(TARGET YuppleMayham PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/Resources/ $<TARGET_FILE_DIR:YuppleMayham>)

View file

@ -2,7 +2,10 @@
#define _H_AI_H
#include <memory>
#include <thread>
#include <mutex>
#include <string>
#include <sol/sol.hpp>
class GameActor;
class Raycaster;
@ -33,6 +36,11 @@ private:
std::shared_ptr<AIScript> behaviour;
std::shared_ptr<GameActor> actor;
std::shared_ptr<GameActor> target;
// cache our lua function calls
sol::function idleFunc;
sol::function patrolFunc;
sol::function alertFunc;
};
#endif

View file

@ -44,6 +44,7 @@ public:
const bool getIsMoving() const { return isMoving; }
const int getEntityID() const { return entityid; }
const std::shared_ptr<PhysicsComponent> getPhysicsComponent() const { return physics; }
const std::shared_ptr<Shader> getShader() const { return shader; }
// TODO: right now there is no default behavior, but eventually the Entity class will be expanded to handle physics
virtual void update(float deltaTime) = 0;

View file

@ -25,8 +25,10 @@ private:
void loadMap();
void createCollisionMap();
int getTileSetIndex(int id) const;
std::shared_ptr<MapData> mapData;
std::shared_ptr<TileSetData> tileSetData;
std::vector<std::shared_ptr<TileSetData>> tileSetData;
std::vector<std::shared_ptr<TileTextureInstance>> instanceHandles;
std::shared_ptr<Shader> shader;

View file

@ -33,11 +33,14 @@ public:
void play() { isPlaying = true; }
void stop() { isPlaying = false; }
void reset() { currentFrame = 0; }
const bool getPlaying() const { return isPlaying; }
const bool getDirectional() const { return isDirectional; }
const int getCycles() const { return cycles; }
void setFPS(const float fps) { FPS = fps; }
private:
std::string animName;
std::string animType;

View file

@ -5,12 +5,18 @@
#include <glm/glm.hpp>
#define MAX_INSTANCES 1000
#define MAX_TEXTURES 31
class Texture;
class TextureArray;
struct InstanceData {
glm::mat4 modelMatrix;
glm::vec2 originalSize;
int tileIndex = 0;
int textureIndex = 0;
int tilesPerRow = 0;
int startID = 0;
};
class BaseInstanceDraw
@ -26,7 +32,6 @@ 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
@ -37,12 +42,17 @@ class TileTextureInstance : public BaseInstanceDraw
{
public:
TileTextureInstance(const char* texturePath);
TileTextureInstance(const std::vector<const char*> texturePaths);
void updateInstanceData(const std::vector<InstanceData>&) override;
void draw() override;
const TextureArray* getTextureArray() { return textures; }
const Texture* getTexture() { return texture; }
private:
void setup() override;
TextureArray* textures = nullptr;
float vertices[20] = {
// vertex
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left

View file

@ -18,6 +18,7 @@ public:
void setFloat(const std::string& name, float value);
void setInt(const std::string& name, int value);
void setBool(const std::string& name, bool value);
void setVec2(const std::string& name, const float* value);
void setMatrix4f(const std::string& name, const float* value);
~Shader();

View file

@ -1,6 +1,10 @@
#ifndef _H_TEXTURE_H
#define _H_TEXTURE_H
#include <vector>
struct SDL_Surface;
class Texture
{
public:
@ -19,4 +23,43 @@ private:
int textureHeight = 0;
};
class TextureArray
{
private:
struct TextureData {
int width, height;
};
public:
TextureArray() : numOfLayers(0) {}
/* We are going to assume each texture atlas is a square (512x512, 756x756 ... etc) */
bool loadTextures(std::vector<const char*> imagePaths);
void bind();
TextureData* operator[](const size_t index) {
try
{
return textures.at(index);
}
catch (std::exception&)
{
return nullptr;
}
}
const int getWidth() const { return canvasWidth; }
const int getHeight() const { return canvasHeight; }
~TextureArray();
private:
bool adjustCanvasSizes(std::vector<SDL_Surface*>& surfaces);
int numOfLayers;
unsigned ID = 0;
std::vector<TextureData*> textures;
int canvasWidth = 0;
int canvasHeight = 0;
};
#endif

View file

@ -78,6 +78,14 @@ public:
int entityid;
};
class EntityFireEvent : public Event {
public:
EntityFireEvent(const int entityid, const float fireDelay) : entityid(entityid), fireDelay(fireDelay) {}
std::string getType() const override { return "OnEntityFire"; }
int entityid;
float fireDelay;
};
class AnimationFinishedEvent : public Event {
public:
AnimationFinishedEvent(const int entityid, const std::string animType) : entityid(entityid), animType(animType) {}

View file

@ -0,0 +1,60 @@
#ifndef _H_LOGGER_H
#define _H_LOGGER_H
#include <mutex>
#include <chrono>
#include <iostream>
#include <sstream>
#define LOG(lvl, msg, ...) Logger::getInstance()->log(lvl, msg, __VA_ARGS__)
#define ERROR_LOG(msg, ...) {Logger::getInstance()->log(ERROR, msg, __VA_ARGS__); return false;}
#define LOG_LEVEL(lvl) Logger::getInstance()->setLevel(lvl)
enum LogLevel {DEBUG, INFO, WARN, ERROR};
class Logger
{
public:
static Logger* getInstance();
template <typename... Args>
void log(LogLevel level, const std::string& message, Args... args) const
{
if (level >= currentLogLevel)
{
std::lock_guard<std::mutex> lock(mutex);
auto msg = formatString(message, args...);
std::cout
<< "["
<< std::format("{:%m-%d-%Y %X}", std::chrono::current_zone()->to_local(std::chrono::system_clock::now()))
<< "] "
<< msg
<< std::endl;
}
}
void setLevel(LogLevel level) { currentLogLevel = level; }
Logger(const Logger& l) = delete;
void operator=(const Logger& l) = delete;
protected:
Logger()
{
};
~Logger() { };
LogLevel currentLogLevel = INFO;
template <typename... Args>
std::string formatString(const std::string& str, Args... args) const
{
return std::vformat(str, std::make_format_args(args...));
}
private:
static Logger* instance;
static std::mutex mutex;
};
#endif

View file

@ -45,6 +45,8 @@ public:
void clearResources();
~ResourceManager();
private:
std::unordered_map<std::string, std::shared_ptr<Sprite>> sprites;
std::unordered_map<std::string, std::shared_ptr<Shader>> shaders;

View file

@ -4,6 +4,7 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <chrono>
#include <memory>
class Script {
@ -22,6 +23,11 @@ private:
return result.valid();
}
void registerGlobalUserTypes();
void performIncrementalGC();
std::chrono::high_resolution_clock::time_point lastGCTime = std::chrono::high_resolution_clock::now();
std::chrono::milliseconds gcInterval = std::chrono::milliseconds(16);
const int gcStepSize = 500;
};
class AIScript : public Script {

View file

@ -25,11 +25,15 @@ struct EntityData {
struct MapData {
std::string name;
std::string tileSet;
struct TileSet {
int startID = 1;
std::string path;
};
std::vector<TileSet> tileSets;
int width = 0, height = 0;
float tileSize = 32.f;
// 3D array, 0: layer, 1: y, 2: x
// Holding tile ids + 1, 0 is an empty tile
// Holding tile startID + ids, 0 is an empty tile
std::vector<std::vector<std::vector<int>>> tiles;
};

View file

@ -16,6 +16,15 @@ void AI::attachBehaviourScript(const std::shared_ptr<AIScript>& behaviour)
this->behaviour = behaviour;
this->behaviour->lua["raycaster"] = raycaster;
this->behaviour->lua["ai"] = shared_from_this();
if (this->behaviour->lua["idle"].valid())
idleFunc = this->behaviour->lua["idle"];
if (this->behaviour->lua["patrol"].valid())
patrolFunc = this->behaviour->lua["patrol"];
if (this->behaviour->lua["alert"].valid())
alertFunc = this->behaviour->lua["alert"];
this->behaviour->lua.set("actor", actor);
this->behaviour->lua.set("target", target);
}
void AI::update()
@ -24,9 +33,9 @@ void AI::update()
switch (state)
{
case AIState::Idle:
if (behaviour && behaviour->lua["idle"].valid())
if (idleFunc.valid())
{
auto result = behaviour->lua["idle"](actor, target);
auto result = idleFunc(actor, target);
if (!result.valid())
{
sol::error err = result;
@ -35,9 +44,9 @@ void AI::update()
}
break;
case AIState::Patrol:
if (behaviour && behaviour->lua["patrol"].valid())
if (patrolFunc.valid())
{
auto result = behaviour->lua["patrol"](actor, target);
auto result = patrolFunc(actor, target);
if (!result.valid())
{
sol::error err = result;
@ -46,9 +55,9 @@ void AI::update()
}
break;
case AIState::Alert:
if (behaviour && behaviour->lua["alert"].valid())
if (alertFunc.valid())
{
auto result = behaviour->lua["alert"](actor, target);
auto result = alertFunc(actor, target);
if (!result.valid())
{
sol::error err = result;
@ -57,7 +66,7 @@ void AI::update()
}
break;
}
behaviour->lua.collect_gc();
//behaviour->lua.collect_gc();
}
catch (const std::exception& e) {
std::cerr << "Error during AI update: " << e.what() << std::endl;

View file

@ -4,9 +4,9 @@ void Camera::update(float deltaTime)
{
if (target == nullptr)
return;
float smoothingFactor = 0.01f;
if (glm::distance(target->getCenter(), getCenterPos()) > 20.f)
position += (target->getCenter() - getCenterPos()) * speed * smoothingFactor * deltaTime;
float smoothingFactor = 5.0f;
//if (glm::distance(target->getCenter(), getCenterPos()) > 20.f)
position += (target->getCenter() - getCenterPos()) * smoothingFactor * deltaTime;
}
glm::mat4 Camera::getViewMatrix()

View file

@ -56,10 +56,11 @@ void Entity::update(float deltaTime)
void Entity::render(const std::shared_ptr<Camera>& camera)
{
glm::mat4 mvp = camera->getProjectionMatrix() * camera->getViewMatrix() * modelMatrix;
//glm::mat4 mvp = camera->getProjectionMatrix() * camera->getViewMatrix() * modelMatrix;
shader->use();
shader->setMatrix4f("MVP", glm::value_ptr(mvp));
shader->setMatrix4f("model", glm::value_ptr(modelMatrix));
shader->setMatrix4f("projection", glm::value_ptr(camera->getProjectionMatrix()));
shader->setMatrix4f("view", glm::value_ptr(camera->getViewMatrix()));
shader->setBool("flip", flipped);
}
@ -73,5 +74,4 @@ void Entity::updateModelMatrix()
rotationMat *
origin *
glm::scale(glm::mat4(1.0f), scale);
}

View file

@ -9,6 +9,7 @@
#include "utility/command.h"
#include "utility/resourcemanager.h"
#include "utility/ftfont.h"
#include "utility/logger.h"
#include "graphics/glwindow.h"
@ -31,6 +32,12 @@ bool Game::init()
return false;
}
#if _DEBUG 1
LOG_LEVEL(DEBUG);
#elif
LOG_LEVEL(INFO);
#endif
SDL_GL_SetSwapInterval(1);
glViewport(0, 0, window->width(), window->height());
glEnable(GL_BLEND);

View file

@ -1,6 +1,7 @@
#include "gameplay/map.h"
#include "gameplay/camera.h"
#include "graphics/shader.h"
#include "graphics/texture.h"
#include "utility/xmlloader.h"
#include "utility/resourcemanager.h"
@ -11,11 +12,21 @@ Map::Map(std::shared_ptr<MapData> mapData, const std::shared_ptr<Shader>& shader
mapData(mapData),
tileIds(mapData->tiles)
{
tileSetData = resourceManager->loadTileSet(mapData->tileSet);
if (tileSetData)
for (auto& tileSet : mapData->tileSets)
tileSetData.push_back(resourceManager->loadTileSet(tileSet.path));
if (!tileSetData.empty())
{
std::vector<const char*> buffer;
for (int layer = 0; layer < tileIds.size(); layer++)
instanceHandles.push_back(std::make_shared<TileTextureInstance>(tileSetData->file.c_str()));
{
buffer.clear();
for (auto& set : tileSetData)
buffer.push_back(set->file.c_str());
if (!buffer.empty())
instanceHandles.push_back(std::make_shared<TileTextureInstance>(buffer));
}
loadMap();
createCollisionMap();
}
@ -34,14 +45,24 @@ void Map::loadMap()
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[layer][y][x]);
tileData[layer].push_back({modelMatrix, tileIndex});
int textureIndex = getTileSetIndex(tileIds[layer][y][x]);
glm::vec2 originalSize = (textureIndex != -1) ?
glm::vec2(tileSetData[textureIndex]->width, tileSetData[textureIndex]->height) :
glm::vec2(0.0f);
int tilesPerRow = (textureIndex != -1) ? tileSetData[textureIndex]->columns : 0;
int startID = (textureIndex != -1) ? mapData->tileSets[textureIndex].startID : 0;
int tileIndex = tileIds[layer][y][x];
tileData[layer].push_back({modelMatrix, originalSize, tileIndex, textureIndex, tilesPerRow, startID});
}
}
instanceHandles[layer]->updateInstanceData(tileData[layer]);
}
glm::vec2 canvasSize = glm::vec2(instanceHandles[0]->getTextureArray()->getWidth(), instanceHandles[0]->getTextureArray()->getHeight());
shader->use();
// TODO: Figure someway to put these in with my xml data
shader->setInt("tilesPerRow", tileSetData->columns);
shader->setVec2("uCanvasSize", glm::value_ptr(canvasSize));
}
void Map::createCollisionMap()
@ -60,11 +81,13 @@ void Map::createCollisionMap()
for (int x = 0; x < tileIds[layer][y].size(); x++)
{
int id = tileIds[layer][y][x];
if (id == 0)
int tileSetIndex = getTileSetIndex(id);
if (tileSetIndex == -1)
collisionMap[y][x] = 0;
else
{
auto& tile = tileSetData->tiles[id - 1];
int startID = mapData->tileSets[tileSetIndex].startID;
auto& tile = tileSetData[tileSetIndex]->tiles[id - startID];
if (!tile->walkable)
collisionMap[y][x] = 1;
}
@ -80,7 +103,26 @@ void Map::render(const std::shared_ptr<Camera>& camera)
shader->setMatrix4f("view", glm::value_ptr(camera->getViewMatrix()));
for (int layer = 0; layer < instanceHandles.size(); layer++)
{
instanceHandles[layer]->updateInstanceData(tileData[layer]);
instanceHandles[layer]->draw();
}
}
/*
Use this function to get the tileSetIndex from a tile ID.
the index of the tileSet is the same index as the texture index used in the instanceHandle
returns tileSetIndex of the tile id passed. Unless the id is either 0 or
the returned tileSetIndex is out of bounds, returns -1
*/
int Map::getTileSetIndex(int id) const
{
// work from the bottom, break if ID > startID
// If we get a textureIndex of -1 then we are on an empty tile
int tileSetIndex = mapData->tileSets.size() - 1;
for (; tileSetIndex != -1; --tileSetIndex)
{
if (id >= mapData->tileSets[tileSetIndex].startID)
break;
}
return (tileSetIndex >= mapData->tileSets.size()) ? -1 : tileSetIndex;
}

View file

@ -2,6 +2,8 @@
#include "gameplay/weapons/bullet.h"
#include "utility/events.h"
#include "utility/logger.h"
#include <iostream>
void PhysicsEngine::hookEventManager(const std::shared_ptr<EventManager>& eventManager)
@ -21,7 +23,7 @@ std::shared_ptr<PhysicsComponent> PhysicsEngine::createObject(const unsigned int
const glm::vec3& pos,
float mass,
PhysicsComponent::Collider::Shape shape,
glm::vec3 dimensions,
glm::vec3 dimensions, const
glm::vec3 offset)
{
auto component = std::make_shared <PhysicsComponent>();

View file

@ -2,6 +2,8 @@
#include "gameplay/physics.h"
#include "utility/component.h"
#include "gameplay/camera.h"
void Bullet::addComponent(std::shared_ptr<Component> component)
{
components.push_back(component);
@ -23,7 +25,6 @@ void Bullet::render(const std::shared_ptr<Camera>& camera)
{
Entity::render(camera);
shader->use();
for (auto& component : components)
{
component->play();

View file

@ -1,6 +1,7 @@
#include "gameplay/weapons/bulletmanager.h"
#include "gameplay/weapons/bullet.h"
#include "gameplay/physics.h"
#include "gameplay/camera.h"
#include "utility/events.h"
#include "utility/component.h"

View file

@ -71,25 +71,30 @@ void Weapon::shoot()
if (wielder)
{
Uint32 currentTime = SDL_GetTicks();
if (weaponMag <= 0 && !reloading) reload();
if (currentTime - lastFireTime >= fireSpeed && !reloading && weaponMag > 0)
if (currentTime - lastFireTime >= fireSpeed && !reloading)
{
if (!weaponScript || !weaponScript->lua["onShoot"].valid())
if (weaponMag > 0)
{
// create bullet using this generated data
BulletData b = genBulletData();
createBullet(b);
weaponMag -= 1;
}
else {
auto result = weaponScript->lua["onShoot"]();
if (!result.valid())
if (eventManager)
eventManager->notify(std::make_shared<EntityFireEvent>(entityid, fireSpeed));
if (!weaponScript || !weaponScript->lua["onShoot"].valid())
{
sol::error err = result;
std::cerr << "lua error: " << err.what() << std::endl;
// create bullet using this generated data
BulletData b = genBulletData();
createBullet(b);
weaponMag -= 1;
}
else {
auto result = weaponScript->lua["onShoot"]();
if (!result.valid())
{
sol::error err = result;
std::cerr << "lua error: " << err.what() << std::endl;
}
weaponMag -= 1;
}
weaponMag -= 1;
}
else if (weaponMag <= 0) reload();
lastFireTime = currentTime;
}
}

View file

@ -143,7 +143,10 @@ void AnimationSet::attachEventManager(const std::shared_ptr<EventManager>& e)
if (reloadEvent->entityid == entityid)
{
if (anims["reload"] != NULL)
{
curAnim = anims["reload"];
curAnim->reset();
}
}
});
@ -155,6 +158,29 @@ void AnimationSet::attachEventManager(const std::shared_ptr<EventManager>& e)
curAnim = anims["idle"];
}
});
eventManager->subscribe("OnEntityFire", [this](std::shared_ptr<Event> e) {
auto fireEvent = std::static_pointer_cast<EntityFireEvent>(e);
if (fireEvent->entityid == entityid)
{
if (anims["fire"] != NULL)
{
curAnim = anims["fire"];
curAnim->reset();
float newFPS = (1000.f / fireEvent->fireDelay) * 15.f;
curAnim->setFPS(newFPS);
}
}
});
eventManager->subscribe("OnAnimationFinished", [this](std::shared_ptr<Event> e) {
auto animEvent = std::static_pointer_cast<AnimationFinishedEvent>(e);
if (animEvent->entityid == entityid && animEvent->animType == "fire")
{
if (anims["idle"] != NULL)
curAnim = anims["idle"];
}
});
}
void AnimationSet::bind()

View file

@ -12,6 +12,13 @@ TileTextureInstance::TileTextureInstance(const char* texturePath)
setup();
}
TileTextureInstance::TileTextureInstance(const std::vector<const char*> texturePaths)
{
textures = new TextureArray();
if (textures->loadTextures(texturePaths))
setup();
}
void TileTextureInstance::setup()
{
glGenVertexArrays(1, &VAO);
@ -37,15 +44,38 @@ void TileTextureInstance::setup()
glBufferData(GL_ARRAY_BUFFER, sizeof(InstanceData) * MAX_INSTANCES, nullptr, GL_DYNAMIC_DRAW);
// tileIndex instanceData layout position 2
glVertexAttribIPointer(2, 1, GL_INT, sizeof(InstanceData), (void*)(offsetof(InstanceData, tileIndex)));
glEnableVertexAttribArray(2);
glVertexAttribDivisor(2, 1);
// textureIndex instanceData layout position 3 -> We are using multiple textures to hold each tileset
glVertexAttribIPointer(3, 1, GL_INT, sizeof(InstanceData), (void*)(offsetof(InstanceData, textureIndex)));
glEnableVertexAttribArray(3);
glVertexAttribDivisor(3, 1);
// tilesPerRow instanceData layout position 4, This is needed since we are supporting multiple tilesets
// of different sizes
glVertexAttribIPointer(4, 1, GL_INT, sizeof(InstanceData), (void*)(offsetof(InstanceData, tilesPerRow)));
glEnableVertexAttribArray(4);
glVertexAttribDivisor(4, 1);
// startID instanceData layout position 5
glVertexAttribIPointer(5, 1, GL_INT, sizeof(InstanceData), (void*)(offsetof(InstanceData, startID)));
glEnableVertexAttribArray(5);
glVertexAttribDivisor(5, 1);
// originalSize instanceData layout position 6
glVertexAttribPointer(6, 2, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (void*)(offsetof(InstanceData, originalSize)));
glEnableVertexAttribArray(6);
glVertexAttribDivisor(6, 1);
// modelMatrix instanceData as 4 vec 4s (a 4x4 matrix) layout head position 7
for (int i = 0; i < 4; i++)
{
glVertexAttribPointer(3 + i, 4, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (void*)(offsetof(InstanceData, modelMatrix) + (sizeof(glm::vec4) * i)));
glEnableVertexAttribArray(3 + i);
glVertexAttribDivisor(3 + i, 1);
glVertexAttribPointer(7 + i, 4, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (void*)(offsetof(InstanceData, modelMatrix) + (sizeof(glm::vec4) * i)));
glEnableVertexAttribArray(7 + i);
glVertexAttribDivisor(7 + i, 1);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
@ -60,23 +90,39 @@ void TileTextureInstance::updateInstanceData(const std::vector<InstanceData>& in
InstanceData* instances = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0,
sizeof(InstanceData) * instanceData.size(),
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
if (!instances)
return;
if (instances)
{
std::memcpy(instances, instanceData.data(), sizeof(InstanceData) * instanceData.size());
glUnmapBuffer(GL_ARRAY_BUFFER);
}
/*
for (int i = 0; i < instanceData.size(); i++)
{
instances[i].modelMatrix = instanceData[i].modelMatrix;
instances[i].originalSize = instanceData[i].originalSize;
instances[i].tileIndex = instanceData[i].tileIndex;
instances[i].textureIndex = instanceData[i].textureIndex;
instances[i].tilesPerRow = instanceData[i].tilesPerRow;
instances[i].startID = instanceData[i].startID;
}
*/
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void TileTextureInstance::draw()
{
texture->bind();
// bind textures
if (texture)
texture->bind();
else if (textures)
textures->bind();
glBindVertexArray(VAO);
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr, numOfInstances);
glBindVertexArray(0);

View file

@ -93,6 +93,11 @@ void Shader::setBool(const std::string& name, bool value)
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setVec2(const std::string& name, const float* value)
{
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, value);
}
void Shader::setMatrix4f(const std::string& name, const float* value)
{
GLuint loc = glGetUniformLocation(ID, name.c_str());

View file

@ -45,7 +45,127 @@ void Texture::bind()
glBindTexture(GL_TEXTURE_2D, ID);
}
Texture::~Texture()
{
glDeleteTextures(1, &ID);
}
bool TextureArray::loadTextures(std::vector<const char*> imagePaths)
{
std::vector<SDL_Surface*> surfaces;
surfaces.resize(imagePaths.size());
// Fill surfaces vector
for (int i = 0; i < imagePaths.size(); ++i)
{
surfaces[i] = IMG_Load(imagePaths[i]);
if (!surfaces[i])
{
std::cout << "Failed to load image file: " << imagePaths[i] << std::endl;
return false;
}
}
if (!adjustCanvasSizes(surfaces))
{
std::cout << "ERROR: Failed to adjust canvas size of images!" << std::endl
<< "Make sure to check that every tileset has square dimensions! (512x512, 756x756 ... etc)" << std::endl;
return false;
}
if (surfaces.empty())
{
std::cout << "ERROR: No surfaces created" << std::endl;
return false;
}
numOfLayers = imagePaths.size();
glGenTextures(1, &ID);
glBindTexture(GL_TEXTURE_2D_ARRAY, ID);
// Creating the texture array all of our textures will live in.
// adjustCanvasSizes makes every image the same size, so we can just use the first
// surface in the list of surfaces
glTexImage3D(GL_TEXTURE_2D_ARRAY,
0,
GL_RGBA,
surfaces[0]->w,
surfaces[0]->h,
numOfLayers,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
nullptr);
for (int layer = 0; layer < numOfLayers; ++layer)
{
glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
0,
0, 0, layer,
surfaces[layer]->w,
surfaces[layer]->h,
1,
GL_RGBA,
GL_UNSIGNED_BYTE,
surfaces[layer]->pixels);
}
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
for (auto& surface : surfaces)
SDL_FreeSurface(surface);
surfaces.clear();
return true;
}
void TextureArray::bind()
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, ID);
}
bool TextureArray::adjustCanvasSizes(std::vector<SDL_Surface*>& surfaces)
{
int maxWidth = 0;
int maxHeight = 0;
for (auto& surface : surfaces)
{
if (surface->w != surface->h)
{
std::cout << "Image must be a square!" << std::endl;
return false;
}
if (surface->w > maxWidth) maxWidth = surface->w;
if (surface->h > maxHeight) maxHeight = surface->h;
textures.push_back(new TextureData({ surface->w, surface->h }));
}
for (int i = 0; i < surfaces.size(); ++i)
{
SDL_Surface* canvas = SDL_CreateRGBSurface(0, maxWidth, maxHeight,
surfaces[i]->format->BitsPerPixel,
surfaces[i]->format->Rmask,
surfaces[i]->format->Gmask,
surfaces[i]->format->Bmask,
surfaces[i]->format->Amask);
SDL_FillRect(canvas, NULL, SDL_MapRGBA(canvas->format, 0, 0, 0, 0));
SDL_BlitSurface(surfaces[i], NULL, canvas, NULL);
SDL_FreeSurface(surfaces[i]);
surfaces[i] = canvas;
}
canvasWidth = maxWidth;
canvasHeight = maxHeight;
return true;
}
TextureArray::~TextureArray()
{
glDeleteTextures(1, &ID);
}

View file

@ -44,7 +44,7 @@ int main(int argc, char* args[])
{
Uint64 curCounter = SDL_GetPerformanceCounter();
float deltaTime = ((curCounter - lastCounter) / freq);
deltaTime = (deltaTime < 10.f) ? deltaTime : 1.f;
deltaTime = (deltaTime < 1.f) ? deltaTime : 1.f;
SDL_PollEvent(&e);
if (e.type == SDL_QUIT)
game->quit();

View file

@ -0,0 +1,14 @@
#include "utility/logger.h"
Logger* Logger::instance{ nullptr };
std::mutex Logger::mutex;
Logger* Logger::getInstance()
{
std::lock_guard<std::mutex> lock(mutex);
if (instance == nullptr)
{
instance = new Logger();
}
return instance;
}

View file

@ -70,6 +70,7 @@ std::shared_ptr<SceneData> ResourceManager::loadScene(const std::string& id)
std::shared_ptr<AnimationSet> ResourceManager::loadAnimationSet(const std::string& name, int entityid)
{
auto animSetData = xmlLoader->getAnimationSet(name);
return std::make_shared<AnimationSet>(entityid, this, animSetData);
}
@ -94,3 +95,9 @@ void ResourceManager::clearResources()
weapons.clear();
tileSets.clear();
}
ResourceManager::~ResourceManager()
{
clearResources();
xmlLoader.reset();
}

View file

@ -106,4 +106,5 @@ Script::Script(const std::string& path)
lua.open_libraries(sol::lib::base, sol::lib::math);
registerGlobalUserTypes();
loadScript(path);
}

View file

@ -1,5 +1,7 @@
#include "utility/xmlloader.h"
#include "utility/logger.h"
/*
Loading every scene in the scene folder and storing in hashmap scenes
hashkey is the id of the scene
@ -26,26 +28,28 @@ bool XMLLoader::loadXmlScene(const char* xmlFile, SceneData* out)
{
tinyxml2::XMLDocument doc;
if (doc.LoadFile(xmlFile) != tinyxml2::XML_SUCCESS)
return false;
ERROR_LOG("Failed to load file: {}", xmlFile);
tinyxml2::XMLElement* scene = doc.FirstChildElement("scene");
const char* type, * id, * mapName;
if (scene->QueryStringAttribute("type", &type) != tinyxml2::XML_SUCCESS ||
scene->QueryStringAttribute("id", &id) != tinyxml2::XML_SUCCESS)
return false;
ERROR_LOG("Could not read type or id tag in file: {}", xmlFile);
out->type = type;
out->id = id;
tinyxml2::XMLElement* map = scene->FirstChildElement("map");
if (map == NULL)
return false;
ERROR_LOG("Could not find 'map' tag in file: {}", xmlFile);
if (map->QueryStringAttribute("name", &mapName) != tinyxml2::XML_SUCCESS)
return false;
ERROR_LOG("Could not find attribute 'name' in map tag. file: {}", xmlFile)
if (!(out->map = getMapData(mapName)))
return false;
if (!loadEntityData(xmlFile, out))
return false;
LOG(DEBUG, "Loading scene: {}", xmlFile);
return true;
}
@ -56,21 +60,21 @@ bool XMLLoader::loadEntityData(const char* xmlFile, SceneData* out)
{
tinyxml2::XMLDocument doc;
if (doc.LoadFile(xmlFile) != tinyxml2::XML_SUCCESS)
return false;
ERROR_LOG("Failed to load file: {}", xmlFile);
tinyxml2::XMLElement* entities = doc.FirstChildElement()->FirstChildElement("entities");
// Adding the player. Player must be in the scene or the scene will not load!
tinyxml2::XMLElement* playerElement = entities->FirstChildElement("player");
if (playerElement == NULL)
return false;
ERROR_LOG("Player element not found in scene! File: {}", xmlFile);
EntityData playData;
const char *graphic, *weaponName = "pistolGun";
if (playerElement->QueryIntAttribute("x", &playData.x) != tinyxml2::XML_SUCCESS ||
playerElement->QueryIntAttribute("y", &playData.y) != tinyxml2::XML_SUCCESS)
return false;
ERROR_LOG("Failed to find x or y attribute in 'player' tag. File: {}", xmlFile);
playerElement->QueryStringAttribute("weapon", &weaponName);
tinyxml2::XMLElement* anim = playerElement->FirstChildElement("animation");
if (anim == NULL)
@ -78,33 +82,33 @@ bool XMLLoader::loadEntityData(const char* xmlFile, SceneData* out)
playData.animated = false;
tinyxml2::XMLElement* sprite = playerElement->FirstChildElement("sprite");
if (sprite == NULL)
return false;
ERROR_LOG("Could not find tag 'sprite' in 'player' tag. File: {}", xmlFile);
if (sprite->QueryStringAttribute("file", &graphic) != tinyxml2::XML_SUCCESS)
return false;
ERROR_LOG("Could not find attribute 'file' in 'player' -> 'sprite' tag. File: {}", xmlFile);
}
else
{
playData.animated = true;
if (anim->QueryStringAttribute("name", &graphic) != tinyxml2::XML_SUCCESS)
return false;
ERROR_LOG("Could not find 'name' attribute in 'animation' tag. File: {}", xmlFile);
}
playData.isPlayer = true;
playData.graphic = graphic;
playData.weapon = weaponName;
out->entities.push_back(playData);
LOG(DEBUG, "Loaded player with sprite: {} in file: {}", graphic, xmlFile);
// Adding every other entity...
// TODO: Add npcs to game and enable their use with XMLLoader
for (tinyxml2::XMLElement* e = entities->FirstChildElement("entity"); e != NULL; e = e->NextSiblingElement("entity"))
{
EntityData data;
const char *graphic, *weaponName = "pistolGun", *scriptPath;
if (e->QueryIntAttribute("x", &data.x) != tinyxml2::XML_SUCCESS ||
e->QueryIntAttribute("y", &data.y) != tinyxml2::XML_SUCCESS)
return false;
ERROR_LOG("Could not load position coordinates for entity. File: {}", xmlFile);
e->QueryStringAttribute("weapon", &weaponName);
tinyxml2::XMLElement* anim = e->FirstChildElement("animation");
if (anim == NULL)
@ -154,7 +158,7 @@ bool XMLLoader::loadWeapons(const char* weaponFolder)
// We are gonna check every xml file within the weaponFolder, then check every weapon node within each file.
std::filesystem::path folder(weaponFolder);
if (!std::filesystem::exists(folder) || !std::filesystem::is_directory(folder))
return false;
ERROR_LOG("'{}' folder does not exist!", weaponFolder);
for (auto& file : std::filesystem::directory_iterator(folder))
{
if (!file.path().has_extension() || !file.path().has_filename() || !file.exists() || file.is_directory())
@ -261,6 +265,7 @@ bool XMLLoader::loadWeapons(const char* weaponFolder)
modifier->QueryFloatAttribute("max", &data.modMax);
}
LOG(DEBUG, "Loaded {} from {}", data.name, file.path().filename().generic_string());
weapons.try_emplace(data.name, std::make_shared<WeaponData>(data));
}
}
@ -274,19 +279,22 @@ bool XMLLoader::loadAnimations(const char* animationFolder)
{
std::filesystem::path folder(animationFolder);
if (!std::filesystem::exists(folder) || !std::filesystem::is_directory(folder))
return false;
ERROR_LOG("'{}' folder does not exist!", animationFolder);
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* anims = doc.FirstChildElement("animations");
bool directional = false;
anims->QueryBoolAttribute("directional", &directional);
if (anims == NULL)
continue;
for (tinyxml2::XMLElement* e = anims->FirstChildElement("animation"); e != NULL; e = e->NextSiblingElement("animation"))
{
AnimationData animData;
@ -295,6 +303,7 @@ bool XMLLoader::loadAnimations(const char* animationFolder)
if (e->QueryStringAttribute("name", &name) != tinyxml2::XML_SUCCESS ||
e->QueryStringAttribute("type", &type) != tinyxml2::XML_SUCCESS)
continue;
tinyxml2::XMLElement* fps = e->FirstChildElement("FPS");
fps->QueryFloatText(&animData.FPS);
@ -333,7 +342,7 @@ bool XMLLoader::loadTileSets(const char* tileSetFolder)
{
std::filesystem::path folder(tileSetFolder);
if (!std::filesystem::exists(folder) || !std::filesystem::is_directory(folder))
return false;
ERROR_LOG("'{}' folder failed to load!", tileSetFolder);
for (auto& file : std::filesystem::directory_iterator(folder))
{
@ -347,11 +356,12 @@ bool XMLLoader::loadTileSets(const char* tileSetFolder)
if (tileSet == NULL)
continue;
TileSetData tileSetData;
const char* setName, * setType, * setFile;
const char* setName, * setType = "shooter", * setFile;
tileSet->QueryStringAttribute("class", &setType);
// 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)
@ -390,10 +400,10 @@ bool XMLLoader::loadTile(tinyxml2::XMLElement* tileElement, TileSetData::TileDat
const char* tileType;
if (tileElement == NULL)
return false;
ERROR_LOG("Failed to find 'tile' tag.");
if (tileElement->QueryIntAttribute("id", &tileData.id) != tinyxml2::XML_SUCCESS ||
tileElement->QueryStringAttribute("type", &tileType) != tinyxml2::XML_SUCCESS)
return false;
ERROR_LOG("Failed to load tile id or type. {}", tileElement->Value());
if (std::string(tileType).compare("object") == 0)
{
@ -405,7 +415,7 @@ bool XMLLoader::loadTile(tinyxml2::XMLElement* tileElement, TileSetData::TileDat
*/
tinyxml2::XMLElement* objectGroup = tileElement->FirstChildElement("objectgroup");
if (objectGroup == NULL)
return false;
ERROR_LOG("Failed to find tag 'objectgroup' in tile id: {}", tileData.id);
for (tinyxml2::XMLElement* obj = objectGroup->FirstChildElement("object"); obj != NULL; obj = obj->NextSiblingElement("object"))
{
TileSetData::TileData::ObjectData objData;
@ -414,7 +424,7 @@ bool XMLLoader::loadTile(tinyxml2::XMLElement* tileElement, TileSetData::TileDat
tileData.objects.push_back(std::make_shared<TileSetData::TileData::ObjectData>(objData));
}
if (tileData.objects.empty())
return false;
ERROR_LOG("No objects found");
}
else
{
@ -445,19 +455,19 @@ bool XMLLoader::loadObject(tinyxml2::XMLElement* objElement, TileSetData::TileDa
// avoid null pointer exception
if (objElement == NULL)
return false;
ERROR_LOG("Failed to find 'object' tag");
// load id and name
if (objElement->QueryIntAttribute("id", &objData.id) != tinyxml2::XML_SUCCESS ||
objElement->QueryStringAttribute("name", &objName) != tinyxml2::XML_SUCCESS)
return false;
ERROR_LOG("No id or name found for object. {}", objElement->Value());
// 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;
ERROR_LOG("Failed to load position coordinates for object: {}", objData.name);
// 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;
ERROR_LOG("Failed to load size of object: {}", objData.name);
// refer to comment in XMLLoader::loadTile regarding the properties portion as to why we return true here
tinyxml2::XMLElement* properties = objElement->FirstChildElement("properties");
@ -479,7 +489,7 @@ bool XMLLoader::loadMaps(const char* mapFolder)
{
std::filesystem::path folder(mapFolder);
if (!std::filesystem::exists(folder) || !std::filesystem::is_directory(folder))
return false;
ERROR_LOG("'{}' folder not found!", mapFolder);
for (auto& file : std::filesystem::directory_iterator(folder))
{
@ -493,17 +503,23 @@ bool XMLLoader::loadMaps(const char* mapFolder)
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)
for (tinyxml2::XMLElement* tileSet = map->FirstChildElement("tileset"); tileSet != NULL; tileSet = tileSet->NextSiblingElement("tileset"))
{
int firstGID = 0;
const char* tileSetPath;
if (tileSet->QueryStringAttribute("source", &tileSetPath) != tinyxml2::XML_SUCCESS ||
tileSet->QueryIntAttribute("firstgid", &firstGID) != tinyxml2::XML_SUCCESS)
continue;
mapData.tileSets.push_back({ firstGID, tileSetPath });
}
if (mapData.tileSets.empty())
continue;
mapData.tiles.reserve(10);
@ -557,7 +573,6 @@ bool XMLLoader::loadMaps(const char* mapFolder)
/* TODO: Add object layer */
mapData.name = file.path().stem().string();
mapData.tileSet = tileSetPath;
maps.try_emplace(mapData.name, std::make_shared<MapData>(mapData));
}