Add project files.
15
CMakeLists.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# CMakeList.txt : Top-level CMake project file, do global configuration
|
||||
# and include sub-projects here.
|
||||
#
|
||||
cmake_minimum_required (VERSION 3.8)
|
||||
|
||||
# Enable Hot Reload for MSVC compilers if supported.
|
||||
if (POLICY CMP0141)
|
||||
cmake_policy(SET CMP0141 NEW)
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
|
||||
endif()
|
||||
|
||||
project ("YuppleMayham")
|
||||
|
||||
# Include sub-projects.
|
||||
add_subdirectory ("YuppleMayham")
|
||||
101
CMakePresets.json
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "windows-base",
|
||||
"hidden": true,
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"installDir": "${sourceDir}/out/install/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "cl.exe",
|
||||
"CMAKE_CXX_COMPILER": "cl.exe"
|
||||
},
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x64-debug",
|
||||
"displayName": "x64 Debug",
|
||||
"inherits": "windows-base",
|
||||
"architecture": {
|
||||
"value": "x64",
|
||||
"strategy": "external"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x64-release",
|
||||
"displayName": "x64 Release",
|
||||
"inherits": "x64-debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x86-debug",
|
||||
"displayName": "x86 Debug",
|
||||
"inherits": "windows-base",
|
||||
"architecture": {
|
||||
"value": "x86",
|
||||
"strategy": "external"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x86-release",
|
||||
"displayName": "x86 Release",
|
||||
"inherits": "x86-debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-debug",
|
||||
"displayName": "Linux Debug",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"installDir": "${sourceDir}/out/install/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
},
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Linux"
|
||||
},
|
||||
"vendor": {
|
||||
"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
|
||||
"sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-debug",
|
||||
"displayName": "macOS Debug",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"installDir": "${sourceDir}/out/install/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
},
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Darwin"
|
||||
},
|
||||
"vendor": {
|
||||
"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
|
||||
"sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Resources/fonts/comic.ttf
Normal file
BIN
Resources/fonts/comicbd.ttf
Normal file
BIN
Resources/fonts/comici.ttf
Normal file
BIN
Resources/fonts/comicz.ttf
Normal file
BIN
Resources/scenes/.debugScene.xml.swp
Normal file
53
Resources/scenes/debugScene.xml
Normal 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="machineGun">
|
||||
<sprite file="sprites/player3Atlas.png" framesize="64.0" directional="true"/>
|
||||
</player>
|
||||
<entity x="10" y="3" weapon="pistolGun">
|
||||
<sprite file="sprites/player3Atlas.png" frameSize="64.0" directional="true"/>
|
||||
<script file="scripts/grunt_behaviour.lua"/>
|
||||
</entity>
|
||||
<entity x="6" y="3" weapon="pistolGun">
|
||||
<sprite file="sprites/player2Atlas.png" frameSize="128.0"/>
|
||||
<script file="scripts/grunt_behaviour.lua"/>
|
||||
</entity>
|
||||
<entity x="5" y="3" weapon="pistolGun">
|
||||
<sprite file="sprites/player2Atlas.png" frameSize="128.0"/>
|
||||
<script file="scripts/grunt_behaviour.lua"/>
|
||||
</entity>
|
||||
</entities>
|
||||
</scene>
|
||||
BIN
Resources/scripts/.grunt_behaviour.lua.swp
Normal file
91
Resources/scripts/grunt_behaviour.lua
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
-- global vars
|
||||
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)
|
||||
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))
|
||||
end
|
||||
|
||||
function moveTo(actor, pos)
|
||||
watchPosition(actor, pos)
|
||||
if distance(actor.position, pos) < 50 then
|
||||
return true
|
||||
end
|
||||
actor:moveForward()
|
||||
return false
|
||||
end
|
||||
|
||||
-- Behaviour Functions called on AI
|
||||
|
||||
-- These functions are ai behaviour functions called in the game
|
||||
-- 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
|
||||
-- print("target is at " .. target.position.x)
|
||||
-- watchPosition(actor, target.position)
|
||||
ai.state = AIState.Patrol
|
||||
actor.rotation = 180
|
||||
end
|
||||
actor: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
|
||||
-- print("target is at " .. target.position.x)
|
||||
end
|
||||
--if moveTo(actor, patrolDestination) == true then
|
||||
-- patrolDestination = { x=math.random(400.0, 750.0), y=math.random(400.0, 750.0), z=0.0 }
|
||||
--end
|
||||
-- performRaycast returns if true if the raycast hits the target position it also sets the getter function
|
||||
-- distFromWall, at bot creation distFromWall is and infinite float value.
|
||||
-- This performRaycast function is highly discourage due to slow down
|
||||
--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
|
||||
--target hit!
|
||||
ai.state = AIState.Alert
|
||||
end
|
||||
if raycaster:distFromWall() < 3 then
|
||||
upOrDown = math.random(2)
|
||||
if moveLeft == true then
|
||||
if upOrDown == 1 then
|
||||
actor.rotation = 180
|
||||
else
|
||||
actor.rotation = 270
|
||||
end
|
||||
moveLeft = false
|
||||
else
|
||||
if upOrDown == 1 then
|
||||
actor.rotation = 0
|
||||
else
|
||||
actor.rotation = 90
|
||||
end
|
||||
moveLeft = true
|
||||
end
|
||||
end
|
||||
actor:moveForward()
|
||||
end
|
||||
|
||||
-- the ai has found the player, this is what function is called
|
||||
function alert(actor, target)
|
||||
if target ~= nil then
|
||||
-- print("target is at " .. target.position.x)
|
||||
watchPosition(actor, target.position)
|
||||
end
|
||||
--print("actor is alert at " .. actor.position.x)
|
||||
if distance(actor.position, target.position) > 300 then
|
||||
actor:moveForward()
|
||||
end
|
||||
actor:shoot()
|
||||
end
|
||||
29
Resources/scripts/scared_behaviour.lua
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
-- helper functions
|
||||
|
||||
function lookAway(actor, pos)
|
||||
y = actor.position.y - pos.y
|
||||
x = actor.position.x - pos.x
|
||||
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))
|
||||
end
|
||||
|
||||
function idle(actor, target)
|
||||
-- do nothing here for now
|
||||
end
|
||||
|
||||
function patrol(actor, target)
|
||||
-- do nothing for now
|
||||
end
|
||||
|
||||
function alert(actor, target)
|
||||
if target ~= nil then
|
||||
lookAway(actor, target.position)
|
||||
if distance(actor.position, target.position) < 250 then
|
||||
actor:moveForward()
|
||||
end
|
||||
end
|
||||
end
|
||||
11
Resources/shaders/GL_bubble.frag
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#version 330 core
|
||||
in vec2 texCoord;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D sprite;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(sprite, texCoord) * vec4(1.0, 0.8, 1.0, 1.0);
|
||||
}
|
||||
13
Resources/shaders/GL_bubble.vert
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
|
||||
out vec2 texCoord;
|
||||
|
||||
uniform mat4 MVP;
|
||||
|
||||
void main()
|
||||
{
|
||||
texCoord = aTexCoord;
|
||||
gl_Position = MVP * vec4(aPos, 1.0);
|
||||
}
|
||||
11
Resources/shaders/GL_pistol.frag
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#version 330 core
|
||||
in vec2 texCoord;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D sprite;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(sprite, texCoord);
|
||||
}
|
||||
18
Resources/shaders/GL_pistol.vert
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
|
||||
out vec2 texCoord;
|
||||
|
||||
uniform mat4 MVP;
|
||||
uniform bool flip;
|
||||
|
||||
void main()
|
||||
{
|
||||
texCoord = aTexCoord;
|
||||
gl_Position = MVP * vec4(aPos, 1.0);
|
||||
if (flip)
|
||||
{
|
||||
texCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y);
|
||||
}
|
||||
}
|
||||
12
Resources/shaders/GL_player.frag
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 pos;
|
||||
in vec2 texPos;
|
||||
|
||||
uniform sampler2D sprite;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(sprite, texPos);
|
||||
}
|
||||
15
Resources/shaders/GL_player.vert
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexPos;
|
||||
|
||||
out vec3 pos;
|
||||
out vec2 texPos;
|
||||
|
||||
uniform mat4 MVP;
|
||||
|
||||
void main()
|
||||
{
|
||||
pos = aPos;
|
||||
texPos = aTexPos;
|
||||
gl_Position = MVP * vec4(aPos, 1.0);
|
||||
}
|
||||
11
Resources/shaders/GL_tile.frag
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D tileTexture;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(tileTexture, texCoord);
|
||||
//FragColor = vec4(mod(tileindex / float(tilesperrow), 1.0), mod(tileindex / float(tilesperrow), 1.0), 0.0, 1.0);
|
||||
}
|
||||
27
Resources/shaders/GL_tile.vert
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
layout (location = 2) in int tileIndex;
|
||||
layout (location = 3) in mat4 aModel;
|
||||
|
||||
uniform int tilesPerRow;
|
||||
uniform mat4 proj;
|
||||
uniform mat4 view;
|
||||
|
||||
out vec2 texCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
float tileSize = 1.0 / float(tilesPerRow);
|
||||
|
||||
gl_Position = proj * view * aModel * vec4(aPos, 1.0);
|
||||
|
||||
int row = tileIndex / tilesPerRow;
|
||||
int col = tileIndex % tilesPerRow;
|
||||
|
||||
float offsetX = float(col) * tileSize;
|
||||
float offsetY = float(row) * tileSize;
|
||||
|
||||
texCoord.x = (aTexCoord.x + col) * tileSize;
|
||||
texCoord.y = (aTexCoord.y + row) * tileSize;
|
||||
}
|
||||
7
Resources/shaders/triangle.frag
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#version 330 core
|
||||
in vec3 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(pos.xyz, 1.0);
|
||||
}
|
||||
10
Resources/shaders/triangle.vert
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
out vec3 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
pos = aPos;
|
||||
gl_Position = vec4(aPos.xyz, 1.0);
|
||||
}
|
||||
BIN
Resources/sprites/bubbleoAtlas64.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
Resources/sprites/machineGunAtlas256.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
Resources/sprites/pistolAtlas256.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
Resources/sprites/player2Atlas.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Resources/sprites/player3Atlas.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
Resources/sprites/playerAtlas.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
Resources/sprites/shooterWorldOneAtlas64.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
Resources/weapons/.bubblegun.xml.swp
Normal file
41
Resources/weapons/bubblegun.xml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<weapons>
|
||||
<weapon name="bubbleGun" fireSpeed="100.0">
|
||||
<bullet sprite="sprites/bubbleoAtlas64.png" animated="true" frameSize="64.0">
|
||||
<spread>60</spread>
|
||||
<speed>20.0</speed>
|
||||
<drop>250.0</drop>
|
||||
<size x="50.0" y="50.0"/>
|
||||
<modifier min="0.5" max="1.0"/>
|
||||
</bullet>
|
||||
</weapon>
|
||||
|
||||
<weapon name="machineGun" fireSpeed="50.0">
|
||||
<sprite file="sprites/machineGunAtlas256.png" animated="true" frameSize="256.0">
|
||||
<size x="55.0" y="55.0"/>
|
||||
<offset x="-30.0" y="0.0"/>
|
||||
</sprite>
|
||||
<bullet sprite="sprites/bullet.png" animated="false" frameSize="64.0">
|
||||
<spread>20</spread>
|
||||
<speed>60.0</speed>
|
||||
<drop>950.0</drop>
|
||||
<size x="10.0" y="10.0"/>
|
||||
<modifier min="1.0" max="1.0"/>
|
||||
</bullet>
|
||||
</weapon>
|
||||
|
||||
<weapon name="pistolGun" fireSpeed="750.0">
|
||||
<sprite file="sprites/pistolAtlas256.png" animated="true" frameSize="256.0">
|
||||
<size x="30.0" y="30.0"/>
|
||||
<offset x="0.0" y="0.0"/>
|
||||
</sprite>
|
||||
<bullet sprite="sprites/bullet.png" animated="false" frameSize="64.0">
|
||||
<spread>5.0</spread>
|
||||
<speed>50.0</speed>
|
||||
<drop>500.0</drop>
|
||||
<size x="25.0" y="25.0"/>
|
||||
<modifier min="1.0" max="1.0"/>
|
||||
</bullet>
|
||||
</weapon>
|
||||
</weapons>
|
||||
34
YuppleMayham/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# CMakeList.txt : CMake project for YuppleMayham, include source and define
|
||||
# project specific logic here.
|
||||
#
|
||||
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_package(SDL2_IMAGE REQUIRED)
|
||||
|
||||
include_directories(SYSTEM "c:/sdks/glad/include")
|
||||
include_directories(SYSTEM "c:/sdks/tinyxml2-10.0.0/include")
|
||||
include_directories(SYSTEM "c:/sdks/glm")
|
||||
include_directories(SYSTEM "C:/sdks/sol2-3.3.0/single/single/include")
|
||||
include_directories(SYSTEM "c:/sdks/lua-5.4.6/include")
|
||||
include_directories(SYSTEM "C:/sdks/freetype-2.13.2/include")
|
||||
link_directories(SYSTEM "C:/sdks/freetype-2.13.2/objs")
|
||||
link_directories(SYSTEM "c:/sdks/tinyxml2-10.0.0/lib")
|
||||
link_directories(SYSTEM "c:/sdks/lua-5.4.6/lib")
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/YupplyMayham/gameplay)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/YupplyMayham/graphics)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/YupplyMayham/gameplay/weapons)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/YupplyMayham)
|
||||
|
||||
# Add source to this project's executable.
|
||||
add_executable (YuppleMayham "src/main.cpp" "c:/sdks/glad/src/glad.c" "graphics/glwindow.h" "src/graphics/sprite.cpp" "src/graphics/mesh.cpp" "src/gameplay/entity.cpp" "src/gameplay/gameactor.cpp" "src/graphics/shader.cpp" "src/util.cpp" "gameplay/camera.h" "src/gameplay/camera.cpp" "src/utility/command.cpp" "src/gameplay/input.cpp" "gameplay/mousestate.h" "graphics/line.h" "src/gameplay/weapons/bullet.cpp" "gameplay/weapons/bulletmanager.h" "src/gameplay/weapons/bulletmanager.cpp" "src/gameplay/scene.cpp" "gameplay/scene.h" "graphics/tile.h" "graphics/texture.h" "src/graphics/texture.cpp" "src/graphics/tile.cpp" "graphics/tiletype.h" "utility/resourcemanager.h" "src/utility/resourcemanager.cpp" "utility/xmlloader.h" "src/utility/xmlloader.cpp" "gameplay/game.h" "src/gameplay/game.cpp" "src/graphics/instancedraw.cpp" "gameplay/map.h" "src/gameplay/map.cpp" "src/gameplay/weapons/weapon.cpp" "gameplay/physics.h" "src/gameplay/physics.cpp" "utility/events.h" "utility/debugdraw.h" "src/utility/debugdraw.cpp" "utility/script.h" "src/utility/script.cpp" "gameplay/ai.h" "utility/raycaster.h" "src/gameplay/ai.cpp" "utility/ftfont.h" "src/utility/ftfont.cpp" "utility/direction.h")
|
||||
|
||||
add_custom_command(TARGET YuppleMayham PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/Resources/ $<TARGET_FILE_DIR:YuppleMayham>)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET YuppleMayham PROPERTY CXX_STANDARD 20)
|
||||
endif()
|
||||
|
||||
target_link_libraries(YuppleMayham SDL2::SDL2main SDL2::SDL2 SDL2_image::SDL2_image tinyxml2 lua_static freetype)
|
||||
|
||||
# TODO: Add tests and install targets if needed.
|
||||
38
YuppleMayham/gameplay/ai.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef _H_AI_H
|
||||
#define _H_AI_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class GameActor;
|
||||
class Raycaster;
|
||||
class Script;
|
||||
|
||||
enum class AIState {
|
||||
Idle,
|
||||
Alert,
|
||||
Patrol
|
||||
};
|
||||
|
||||
class AI {
|
||||
public:
|
||||
AI(const std::shared_ptr<GameActor>& actor, const std::shared_ptr<Raycaster>& raycaster);
|
||||
void update();
|
||||
|
||||
void setTarget(const std::shared_ptr<GameActor>& target) { this->target = target; }
|
||||
void attachBehaviourScript(const std::shared_ptr<Script>& behaviour);
|
||||
|
||||
AIState getState() const { return state; }
|
||||
void setState(AIState state) { this->state = state; }
|
||||
|
||||
~AI() {}
|
||||
|
||||
private:
|
||||
AIState state;
|
||||
std::shared_ptr<Raycaster> raycaster;
|
||||
std::shared_ptr<Script> behaviour;
|
||||
std::shared_ptr<GameActor> actor;
|
||||
std::shared_ptr<GameActor> target;
|
||||
};
|
||||
|
||||
#endif
|
||||
44
YuppleMayham/gameplay/camera.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef _H_CAMERA_H
|
||||
#define _H_CAMERA_H
|
||||
|
||||
#include "entity.h"
|
||||
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
Camera(float viewPortW, float viewPortH) :
|
||||
position(glm::vec3(0.0f, 0.0f, 1.0f)),
|
||||
front(glm::vec3(0.0f, 0.0f, -1.0f)),
|
||||
up(glm::vec3(0.0f, 1.0f, 0.0f)),
|
||||
viewPortW(viewPortW),
|
||||
viewPortH(viewPortH)
|
||||
{};
|
||||
|
||||
void setPosition(const glm::vec3& position) { this->position = position; }
|
||||
|
||||
const Entity* getTarget() const { return target; }
|
||||
const glm::vec3 getCenterPos() const { return glm::vec3(position.x + (viewPortW / 2.f), position.y + (viewPortH / 2.f), 0.0f); }
|
||||
void setTarget(Entity* target) { this->target = target; }
|
||||
void unsetTarget() { target = nullptr; }
|
||||
bool isTargeting() { return (target != nullptr); }
|
||||
|
||||
void update(float deltaTime);
|
||||
|
||||
const glm::vec3 worldToLocal(const glm::vec3& worldCoordinates) const;
|
||||
|
||||
glm::mat4 getViewMatrix();
|
||||
glm::mat4 getProjectionMatrix();
|
||||
const glm::vec3 getPosition() const { return position; }
|
||||
private:
|
||||
Entity* target = nullptr;
|
||||
|
||||
glm::vec3 position;
|
||||
glm::vec3 front;
|
||||
glm::vec3 up;
|
||||
|
||||
float viewPortW, viewPortH;
|
||||
|
||||
float speed = 300.0f;
|
||||
};
|
||||
|
||||
#endif // _H_CAMERA_H
|
||||
69
YuppleMayham/gameplay/entity.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#ifndef _H_ENTITY_H
|
||||
#define _H_ENTITY_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include "../graphics/shader.h"
|
||||
|
||||
class Camera;
|
||||
struct PhysicsComponent;
|
||||
|
||||
class Entity
|
||||
{
|
||||
public:
|
||||
Entity(const std::shared_ptr<Shader>& shader) :
|
||||
shader(shader),
|
||||
position(glm::vec3(0.0f)),
|
||||
scale(glm::vec3(1.0f)),
|
||||
rotation(0.0f),
|
||||
speed(5.0f) {};
|
||||
virtual ~Entity() {};
|
||||
|
||||
void setPosition(const glm::vec3& position);
|
||||
void setScale(const glm::vec3& scale);
|
||||
virtual void setRotation(const float& rotation);
|
||||
void setLocalPosition(const glm::vec3& localPosition);
|
||||
void setRotatable(bool rotatable);
|
||||
|
||||
void flip();
|
||||
|
||||
void addPhysicsComponent(const std::shared_ptr<PhysicsComponent>& physics);
|
||||
|
||||
const glm::vec3& getPosition() const { return this->position; }
|
||||
const glm::vec3& getScale() const { return this->scale; }
|
||||
const float getRotation() const { return this->rotation; }
|
||||
const bool isFlipped() const { return flipped; }
|
||||
const glm::vec2 getFacingDir() const { return glm::vec2(cos(glm::radians(rotation)), sin(glm::radians(rotation))); }
|
||||
const glm::vec3 getCenter() const { return glm::vec3(position.x + (0.5f * scale.x), position.y + (0.5f * scale.y), 0.0f); }
|
||||
const bool getIsMoving() const { return isMoving; }
|
||||
const std::shared_ptr<PhysicsComponent> getPhysicsComponent() const { return physics; }
|
||||
|
||||
// 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;
|
||||
virtual void render(const std::shared_ptr<Camera>& camera) = 0;
|
||||
|
||||
protected:
|
||||
glm::vec3 localPosition;
|
||||
glm::vec3 position;
|
||||
glm::vec3 deltaPosition; // future position frame, updated in update
|
||||
glm::vec3 scale;
|
||||
float rotation;
|
||||
float speed;
|
||||
|
||||
std::shared_ptr<PhysicsComponent> physics;
|
||||
|
||||
bool isMoving = false;
|
||||
bool isRotatable = true;
|
||||
bool flipped = false;
|
||||
|
||||
glm::mat4 modelMatrix;
|
||||
|
||||
void updateModelMatrix();
|
||||
|
||||
std::shared_ptr<Shader> shader;
|
||||
};
|
||||
|
||||
|
||||
#endif //_H_ENTITY_H
|
||||
51
YuppleMayham/gameplay/game.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef _H_GAME_H
|
||||
#define _H_GAME_H
|
||||
|
||||
#include <memory>
|
||||
#include <SDL_events.h>
|
||||
|
||||
class InputHandler;
|
||||
class Scene;
|
||||
class Text;
|
||||
class ResourceManager;
|
||||
class GLWindow;
|
||||
|
||||
enum {
|
||||
GAME_QUITTING = 0,
|
||||
GAME_RUNNING = 1,
|
||||
GAME_MENU = 2,
|
||||
GAME_PLAYING = 4
|
||||
};
|
||||
|
||||
class Game
|
||||
{
|
||||
public:
|
||||
Game() {}
|
||||
bool init();
|
||||
|
||||
bool loadDebugScene();
|
||||
|
||||
void handleInput(SDL_Event& e);
|
||||
|
||||
void update(float deltaTime);
|
||||
void render();
|
||||
|
||||
const unsigned getGameState() const { return game_state; }
|
||||
|
||||
const unsigned getWindowWidth() const;
|
||||
const unsigned getWindowHeight() const;
|
||||
|
||||
void quit() { game_state = GAME_QUITTING; }
|
||||
|
||||
private:
|
||||
unsigned game_state = GAME_QUITTING;
|
||||
|
||||
std::shared_ptr<GLWindow> window;
|
||||
|
||||
std::shared_ptr<Scene> currentScene;
|
||||
std::shared_ptr<InputHandler> inputHandler;
|
||||
std::shared_ptr<ResourceManager> resourceManager;
|
||||
std::shared_ptr<Text> textHandler;
|
||||
};
|
||||
|
||||
#endif
|
||||
52
YuppleMayham/gameplay/gameactor.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef _H_GAMEACTOR_H
|
||||
#define _H_GAMEACTOR_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <SDL_timer.h>
|
||||
|
||||
#include "entity.h"
|
||||
#include "mousestate.h"
|
||||
|
||||
class Component;
|
||||
class AI;
|
||||
class Weapon;
|
||||
class EventManager;
|
||||
|
||||
class GameActor : public Entity
|
||||
{
|
||||
public:
|
||||
GameActor(const std::shared_ptr<Shader>& shader) : Entity(shader) { actorid = SDL_GetTicks(); }
|
||||
~GameActor();
|
||||
|
||||
void addComponent(std::shared_ptr<Component> component);
|
||||
void equipWeapon(std::shared_ptr<Weapon> weapon);
|
||||
void attachEventManager(std::shared_ptr<EventManager> eventManager);
|
||||
void update(float deltaTime) override;
|
||||
void render(const std::shared_ptr<Camera>& camera) override;
|
||||
|
||||
const std::shared_ptr<Weapon>& getHeldWeapon() const;
|
||||
const int getActorID() const { return actorid; }
|
||||
|
||||
void setRotation(const float& rotation) override;
|
||||
|
||||
void moveUp();
|
||||
void moveDown();
|
||||
void moveLeft();
|
||||
void moveRight();
|
||||
|
||||
// Top down shooter controls, mostly for the player to use in top down shooting sections
|
||||
void moveForward();
|
||||
void moveBackward();
|
||||
void strafeLeft();
|
||||
void strafeRight();
|
||||
void fireWeapon();
|
||||
void followMouse(const MouseState&);
|
||||
private:
|
||||
int actorid;
|
||||
std::vector<std::shared_ptr<Component>> components;
|
||||
std::shared_ptr<AI> ai;
|
||||
std::shared_ptr<Weapon> currentWeapon = nullptr;
|
||||
std::shared_ptr<EventManager> eventManager;
|
||||
};
|
||||
|
||||
#endif //_H_GAMEACTOR_H
|
||||
98
YuppleMayham/gameplay/input.h
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#ifndef _H_INPUT_H
|
||||
#define _H_INPUT_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <SDL_keycode.h>
|
||||
#include <SDL_events.h>
|
||||
|
||||
#include "mousestate.h"
|
||||
|
||||
class Command;
|
||||
class MouseCommand;
|
||||
class GameActor;
|
||||
|
||||
enum {
|
||||
MOUSE_BUTTON_LEFT = 1,
|
||||
MOUSE_BUTTON_RIGHT = 2,
|
||||
MOUSE_BUTTON_MIDDLE = 4,
|
||||
MOUSE_MOTION = 8
|
||||
};
|
||||
|
||||
class Keyboard
|
||||
{
|
||||
protected:
|
||||
Keyboard() {}
|
||||
|
||||
void captureKeyboard(const SDL_Event& e)
|
||||
{
|
||||
if (e.type == SDL_KEYDOWN)
|
||||
keys[e.key.keysym.sym] = true;
|
||||
if (e.type == SDL_KEYUP)
|
||||
keys[e.key.keysym.sym] = false;
|
||||
}
|
||||
std::unordered_map<SDL_Keycode, bool> keys;
|
||||
};
|
||||
|
||||
class Mouse
|
||||
{
|
||||
protected:
|
||||
Mouse() {}
|
||||
|
||||
void captureMouse(const SDL_Event& e)
|
||||
{
|
||||
if (e.type == SDL_MOUSEBUTTONDOWN)
|
||||
mouseButtons[MOUSE_BUTTON_LEFT] = true;
|
||||
if (e.type == SDL_MOUSEBUTTONUP)
|
||||
mouseButtons[MOUSE_BUTTON_LEFT] = false;
|
||||
if (e.type == SDL_MOUSEMOTION)
|
||||
{
|
||||
mouse_state.x = static_cast<float>(e.motion.x);
|
||||
mouse_state.y = static_cast<float>(e.motion.y);
|
||||
}
|
||||
}
|
||||
MouseState mouse_state;
|
||||
std::unordered_map<Uint8, bool> mouseButtons;
|
||||
};
|
||||
|
||||
class InputHandler : public Keyboard, public Mouse
|
||||
{
|
||||
private:
|
||||
struct CommandWithDelay{
|
||||
Command* cmd;
|
||||
Uint32 lastExecution;
|
||||
Uint32 delay;
|
||||
};
|
||||
struct MouseCommandWithDelay{
|
||||
MouseCommand* cmd;
|
||||
Uint32 lastExecution;
|
||||
Uint32 delay;
|
||||
};
|
||||
public:
|
||||
InputHandler() {}
|
||||
void captureInput(const SDL_Event& e) {
|
||||
Keyboard::captureKeyboard(e); Mouse::captureMouse(e);
|
||||
}
|
||||
void setActor(GameActor* actor) {
|
||||
this->actor = actor;
|
||||
}
|
||||
|
||||
void bindKeyCommand(SDL_Keycode key, Uint32 delay, Command* command) {
|
||||
keyCommands[key] = { command, 0, delay };
|
||||
}
|
||||
void bindMouseCommand(Uint8 mouse, Uint32 delay, MouseCommand* command) {
|
||||
mouseCommands[mouse] = { command, 0, delay };
|
||||
}
|
||||
void bindMouseMotion(MouseCommand* command) {
|
||||
mouseMotionCommand = command;
|
||||
}
|
||||
void handleInput();
|
||||
|
||||
private:
|
||||
GameActor* actor = nullptr;
|
||||
// final int is delay
|
||||
std::unordered_map<SDL_Keycode, CommandWithDelay> keyCommands;
|
||||
std::unordered_map<Uint8, MouseCommandWithDelay> mouseCommands;
|
||||
MouseCommand* mouseMotionCommand = nullptr;
|
||||
};
|
||||
|
||||
#endif // _H_INPUT_H
|
||||
38
YuppleMayham/gameplay/map.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef _H_MAP_H
|
||||
#define _H_MAP_H
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "../graphics/instancedraw.h"
|
||||
|
||||
//class TileTextureInstance;
|
||||
class Shader;
|
||||
class Camera;
|
||||
struct MapData;
|
||||
//struct InstanceData;
|
||||
struct Tile;
|
||||
|
||||
class Map
|
||||
{
|
||||
public:
|
||||
Map(const std::shared_ptr<MapData>& mapData, const std::shared_ptr<Shader>& shader);
|
||||
|
||||
const std::vector<std::vector<int>> getCollisionMap() const { return collisionMap; }
|
||||
|
||||
void render(const std::shared_ptr<Camera>& camera);
|
||||
|
||||
private:
|
||||
void loadMap();
|
||||
void createCollisionMap();
|
||||
|
||||
const std::shared_ptr<MapData> mapData;
|
||||
|
||||
std::shared_ptr<TileTextureInstance> instanceHandle;
|
||||
std::shared_ptr<Shader> shader;
|
||||
std::vector<std::vector<std::shared_ptr<Tile>>> tileIds;
|
||||
std::vector<std::vector<int>> collisionMap;
|
||||
std::vector<InstanceData> tileData;
|
||||
};
|
||||
|
||||
#endif
|
||||
9
YuppleMayham/gameplay/mousestate.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef _H_MOUSESTATE_H
|
||||
#define _H_MOUSESTATE_H
|
||||
|
||||
struct MouseState {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
};
|
||||
|
||||
#endif
|
||||
65
YuppleMayham/gameplay/physics.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#ifndef _H_PHYSICS_H
|
||||
#define _H_PHYSICS_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
class EventManager;
|
||||
|
||||
struct PhysicsComponent {
|
||||
bool isBullet = false;
|
||||
struct RigidBody {
|
||||
glm::vec3 position;
|
||||
glm::vec3 velocity;
|
||||
glm::vec3 acceleration;
|
||||
float elasticity = 0.7f;
|
||||
float mass = 1.0f;
|
||||
void applyForce(glm::vec3 dir, float mag) {
|
||||
acceleration += ((dir * mag) / mass);
|
||||
}
|
||||
}rigidBody;
|
||||
|
||||
struct Collider {
|
||||
enum class Shape { Square, Circle } shape = Shape::Circle;
|
||||
glm::vec3 offset = glm::vec3(0.f);
|
||||
glm::vec3 dimensions;
|
||||
}collider;
|
||||
};
|
||||
|
||||
class PhysicsComponentFactory {
|
||||
public:
|
||||
static PhysicsComponent makeBullet(const glm::vec3& pos, float mass, float radius) {
|
||||
PhysicsComponent p;
|
||||
p.rigidBody.position = pos;
|
||||
p.rigidBody.mass = mass;
|
||||
p.collider = { PhysicsComponent::Collider::Shape::Circle, glm::vec3(radius, radius, 0.f), glm::vec3(radius) };
|
||||
p.isBullet = true;
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
class PhysicsEngine {
|
||||
public:
|
||||
PhysicsEngine() {}
|
||||
|
||||
void hookEventManager(const std::shared_ptr<EventManager>& eventManager);
|
||||
|
||||
std::shared_ptr<PhysicsComponent> createObject(const glm::vec3& pos, float mass, PhysicsComponent::Collider::Shape shape, glm::vec3 dimensions, glm::vec3 offset = glm::vec3(0.f));
|
||||
void loadCollisionMap(const std::vector<std::vector<int>>&, float tileSize);
|
||||
void addObject(const std::shared_ptr<PhysicsComponent>&);
|
||||
void removeObject(const std::shared_ptr<PhysicsComponent>&);
|
||||
void update(float deltaTime);
|
||||
private:
|
||||
void resolveWorldCollision(const std::shared_ptr<PhysicsComponent>&);
|
||||
void resolvePossibleCollisions();
|
||||
void getPossibleCollisions();
|
||||
int getTileCollider(const glm::vec3& position);
|
||||
std::vector<std::shared_ptr<PhysicsComponent>> objects;
|
||||
std::vector<std::pair<PhysicsComponent*, PhysicsComponent*>> objCollisions;
|
||||
std::vector<std::vector<int>> collisionMap;
|
||||
float tileSize = 32.f;
|
||||
std::shared_ptr<EventManager> eventManager;
|
||||
};
|
||||
|
||||
#endif //_H_PHYSICS_H
|
||||
55
YuppleMayham/gameplay/scene.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef _H_SCENE_H
|
||||
#define _H_SCENE_H
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
class Entity;
|
||||
class Camera;
|
||||
class Map;
|
||||
class ResourceManager;
|
||||
class EventManager;
|
||||
class GameActor;
|
||||
class Line;
|
||||
class PhysicsEngine;
|
||||
|
||||
struct SceneData;
|
||||
|
||||
enum SceneType {
|
||||
SCENE_STORY,
|
||||
SCENE_SHOOTER
|
||||
};
|
||||
|
||||
class Scene
|
||||
{
|
||||
public:
|
||||
Scene(SceneType type, std::shared_ptr<ResourceManager> resources);
|
||||
|
||||
void update(float deltaTime);
|
||||
void render();
|
||||
|
||||
std::shared_ptr<GameActor> getPlayer() const;
|
||||
|
||||
void unloadScene();
|
||||
|
||||
protected:
|
||||
void loadDebugShooterScene();
|
||||
void loadDebugStoryScene() { /*not implemented yet*/ }
|
||||
|
||||
private:
|
||||
SceneType type;
|
||||
std::shared_ptr<Map> map;
|
||||
//std::shared_ptr<TileSet> tileSet;
|
||||
std::shared_ptr<GameActor> player;
|
||||
std::vector<std::shared_ptr<Entity>> entities;
|
||||
std::shared_ptr<Camera> camera;
|
||||
std::shared_ptr<PhysicsEngine> physicsEngine;
|
||||
|
||||
std::shared_ptr<Line> debugLine;
|
||||
std::shared_ptr<ResourceManager> resourceManager;
|
||||
std::shared_ptr<EventManager> eventManager;
|
||||
std::shared_ptr<SceneData> sceneData;
|
||||
};
|
||||
|
||||
#endif //_H_SCENE_H
|
||||
43
YuppleMayham/gameplay/weapons/bullet.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef _H_BULLET_H
|
||||
#define _H_BULLET_H
|
||||
|
||||
#include "../entity.h"
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
class Component;
|
||||
class Camera;
|
||||
|
||||
class Bullet : public Entity
|
||||
{
|
||||
public:
|
||||
Bullet(std::shared_ptr<Shader> shader, glm::vec3 fireFrom, glm::vec2 direction, float bulletSpeed, float bulletDrop, glm::vec2 bulletSize) :
|
||||
Entity(shader),
|
||||
origin(fireFrom),
|
||||
direction(direction),
|
||||
bulletSpeed(bulletSpeed),
|
||||
bulletDrop(bulletDrop),
|
||||
bulletSize(bulletSize) {
|
||||
this->setPosition(origin);
|
||||
this->setScale(glm::vec3(bulletSize, 1.0f));
|
||||
};
|
||||
|
||||
void addComponent(std::shared_ptr<Component> component);
|
||||
|
||||
void update(float deltaTime) override;
|
||||
void render(const std::shared_ptr<Camera>& camera) override;
|
||||
|
||||
float getBulletDrop() const { return bulletDrop; }
|
||||
glm::vec3 getBulletOrigin() const { return origin; }
|
||||
|
||||
~Bullet();
|
||||
|
||||
private:
|
||||
glm::vec3 origin;
|
||||
glm::vec2 direction;
|
||||
float bulletSpeed;
|
||||
float bulletDrop;
|
||||
glm::vec2 bulletSize;
|
||||
std::vector<std::shared_ptr<Component>> components;
|
||||
};
|
||||
|
||||
#endif // _H_BULLET_H
|
||||
37
YuppleMayham/gameplay/weapons/bulletmanager.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef _H_BULLETMANAGER_H
|
||||
#define _H_BULLETMANAGER_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
class Bullet;
|
||||
class Sprite;
|
||||
class Shader;
|
||||
class Component;
|
||||
class Camera;
|
||||
class EventManager;
|
||||
|
||||
class BulletManager
|
||||
{
|
||||
public:
|
||||
void addBullet(const std::shared_ptr<Bullet>& bullet);
|
||||
void addBullet(const glm::vec3& fireFrom,
|
||||
const glm::vec2& direction,
|
||||
float bulletSpeed,
|
||||
float bulletDrop,
|
||||
glm::vec2 bulletSize,
|
||||
const std::shared_ptr<Shader>& shader,
|
||||
const std::shared_ptr<Component>& sprite);
|
||||
|
||||
void update(float deltaTime);
|
||||
void render(const std::shared_ptr<Camera>& camera);
|
||||
|
||||
void hookEventManager(const std::shared_ptr<EventManager>& eventManager);
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<Bullet>> bullets;
|
||||
std::shared_ptr<EventManager> eventManager;
|
||||
};
|
||||
|
||||
#endif
|
||||
61
YuppleMayham/gameplay/weapons/weapon.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef _H_WEAPON_H
|
||||
#define _H_WEAPON_H
|
||||
|
||||
#include <memory>
|
||||
#include <glm/glm.hpp>
|
||||
#include <functional>
|
||||
|
||||
#include "../../util.h"
|
||||
|
||||
#include "../../gameplay/entity.h"
|
||||
#include "../../utility/direction.h"
|
||||
|
||||
// TODO: Put all weapons inside of this base, we don't need a class for every weapon, we only need one class!
|
||||
|
||||
class Shader;
|
||||
class Component;
|
||||
class Camera;
|
||||
class BulletManager;
|
||||
class EventManager;
|
||||
class ResourceManager;
|
||||
struct WeaponData;
|
||||
|
||||
class Weapon : public Entity
|
||||
{
|
||||
public:
|
||||
Weapon(const WeaponData* data, const std::shared_ptr<Shader>& weaponShader, const std::shared_ptr<Shader>& bulletShader, ResourceManager* resourceManager);
|
||||
|
||||
void setWielder(Entity* wielder) { this->wielder = wielder; }
|
||||
|
||||
void addComponent(const std::shared_ptr<Component>& component);
|
||||
void hookEventManager(const std::shared_ptr<EventManager>& eventManager);
|
||||
void shoot();
|
||||
void update(float deltaTime);
|
||||
void render(const std::shared_ptr<Camera>& camera);
|
||||
|
||||
private:
|
||||
glm::vec2 weaponSize;
|
||||
glm::vec2 weaponOffset;
|
||||
|
||||
float bulletSpeed;
|
||||
float bulletDrop;
|
||||
// in ms
|
||||
float fireSpeed;
|
||||
glm::vec2 bulletSize;
|
||||
std::shared_ptr<Shader> bulletShader;
|
||||
std::shared_ptr<Component> bulletSprite;
|
||||
std::shared_ptr<BulletManager> bulletManager;
|
||||
std::shared_ptr<EventManager> eventManager;
|
||||
|
||||
std::shared_ptr<UTIL::RandomGenerator> bulletSpread;
|
||||
std::shared_ptr<UTIL::RandomGenerator> bulletModifer;
|
||||
Entity* wielder = nullptr;
|
||||
int lastFireTime = 0;
|
||||
|
||||
Direction lastDir;
|
||||
|
||||
std::vector <std::shared_ptr<Component>> components;
|
||||
|
||||
};
|
||||
|
||||
#endif // _H_WEAPON_H
|
||||
9
YuppleMayham/gameplay/weapons/weapons.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef _H_WEAPONS_H
|
||||
#define _H_WEAPONS_H
|
||||
|
||||
// Include directives for weapons folder
|
||||
|
||||
#include "weapon.h"
|
||||
#include "bullet.h"
|
||||
|
||||
#endif // _H_WEAPONS_H
|
||||
53
YuppleMayham/graphics/glwindow.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef _H_GLWINDOW_H
|
||||
#define _H_GLWINDOW_H
|
||||
|
||||
#include <SDL_video.h>
|
||||
//#include <SDL_opengl.h>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
class GLWindow
|
||||
{
|
||||
public:
|
||||
GLWindow(const char* windowName, int width, int height) :
|
||||
name(windowName),
|
||||
w(width),
|
||||
h(height) {};
|
||||
~GLWindow();
|
||||
|
||||
bool Init();
|
||||
|
||||
void swap() { SDL_GL_SwapWindow(window); }
|
||||
void makeCurrent() { SDL_GL_MakeCurrent(window, glContext); }
|
||||
|
||||
unsigned width() const { return w; }
|
||||
unsigned height() const { return h; }
|
||||
|
||||
SDL_Window* getWindow() const { return window; }
|
||||
const SDL_GLContext& getContext() const { return glContext; }
|
||||
private:
|
||||
SDL_Window* window = nullptr;
|
||||
SDL_GLContext glContext = NULL;
|
||||
|
||||
unsigned w, h;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
bool GLWindow::Init()
|
||||
{
|
||||
window = SDL_CreateWindow(name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_OPENGL);
|
||||
if (!window)
|
||||
return false;
|
||||
glContext = SDL_GL_CreateContext(window);
|
||||
if (!glContext)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLWindow::~GLWindow()
|
||||
{
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
|
||||
#endif // _H_GLWINDOW_H
|
||||
54
YuppleMayham/graphics/instancedraw.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef _H_INSTANCEDRAW_H
|
||||
#define _H_INSTANCEDRAW_H
|
||||
|
||||
#include <vector>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#define MAX_INSTANCES 1000
|
||||
|
||||
class Texture;
|
||||
|
||||
struct InstanceData {
|
||||
glm::mat4 modelMatrix;
|
||||
int tileIndex;
|
||||
};
|
||||
|
||||
class BaseInstanceDraw
|
||||
{
|
||||
public:
|
||||
virtual ~BaseInstanceDraw() {}
|
||||
|
||||
virtual void setup() = 0;
|
||||
virtual void updateInstanceData(const std::vector<InstanceData>&) = 0;
|
||||
virtual void draw() = 0;
|
||||
protected:
|
||||
unsigned VAO, VBO, EBO, instanceVBO;
|
||||
Texture* texture = nullptr;
|
||||
InstanceData instanceData[MAX_INSTANCES];
|
||||
size_t numOfInstances = 0;
|
||||
unsigned indices[6] = {
|
||||
0, 1, 2,
|
||||
3, 2, 0
|
||||
};
|
||||
};
|
||||
|
||||
class TileTextureInstance : public BaseInstanceDraw
|
||||
{
|
||||
public:
|
||||
TileTextureInstance(const char* texturePath);
|
||||
|
||||
void updateInstanceData(const std::vector<InstanceData>&) override;
|
||||
void draw() override;
|
||||
|
||||
private:
|
||||
void setup() override;
|
||||
float vertices[20] = {
|
||||
// vertex
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
|
||||
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
|
||||
0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
|
||||
};
|
||||
};
|
||||
|
||||
#endif // _H_INSTANCEDRAW_H
|
||||
31
YuppleMayham/graphics/mesh.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef _H_MESH_H
|
||||
#define _H_MESH_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
typedef struct {
|
||||
glm::vec3 vertex;
|
||||
glm::vec2 texCoord;
|
||||
}Vertex;
|
||||
|
||||
typedef std::vector<Vertex> VertexList;
|
||||
typedef std::vector<unsigned> IndexList;
|
||||
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
Mesh(const VertexList&, const IndexList& indexList);
|
||||
~Mesh();
|
||||
|
||||
void draw();
|
||||
|
||||
private:
|
||||
// Vertex Array, Vertex Buffer, Element Buffer
|
||||
unsigned VAO, VBO, EBO;
|
||||
size_t indexSize;
|
||||
};
|
||||
|
||||
#endif // _H_MESH_H
|
||||
26
YuppleMayham/graphics/shader.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef _H_SHADER_H
|
||||
#define _H_SHADER_H
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
class Shader
|
||||
{
|
||||
private:
|
||||
public:
|
||||
unsigned int ID;
|
||||
Shader(const char* vertexPath, const char* fragmentPath);
|
||||
|
||||
void use() { glUseProgram(ID); }
|
||||
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 setMatrix4f(const std::string& name, const float* value);
|
||||
|
||||
~Shader();
|
||||
};
|
||||
|
||||
#endif // _H_SHADER_H
|
||||
138
YuppleMayham/graphics/sprite.h
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
#ifndef _H_SPRITE_H
|
||||
#define _H_SPRITE_H
|
||||
|
||||
#include <SDL_image.h>
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
#include "../utility/direction.h"
|
||||
|
||||
enum class TileType;
|
||||
class Texture;
|
||||
class EventManager;
|
||||
|
||||
class Sprite
|
||||
{
|
||||
public:
|
||||
virtual ~Sprite() {}
|
||||
|
||||
void bind();
|
||||
virtual void draw() = 0;
|
||||
virtual void play() = 0;
|
||||
virtual void idle() = 0;
|
||||
|
||||
virtual std::shared_ptr<Sprite> clone() const = 0;
|
||||
protected:
|
||||
Texture* texture = nullptr;
|
||||
unsigned indices[6] = {
|
||||
0, 1, 2,
|
||||
3, 2, 0
|
||||
};
|
||||
};
|
||||
|
||||
class SpriteStatic : public Sprite
|
||||
{
|
||||
public:
|
||||
SpriteStatic(const char* texturePath);
|
||||
~SpriteStatic();
|
||||
|
||||
void draw() override;
|
||||
void play() override { /*unused*/ }
|
||||
void idle() override { /*unused*/ }
|
||||
|
||||
std::shared_ptr<Sprite> clone() const override {
|
||||
return std::make_shared<SpriteStatic>(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
void setupSprite();
|
||||
|
||||
// Vertex Array, Vertex Buffer, Element Buffer
|
||||
unsigned VAO, VBO, EBO;
|
||||
|
||||
// simple rectangle. Most scales will be done based on this generic vertex data.
|
||||
float vertices[20] = {
|
||||
// vertex texturecoords
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
|
||||
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
|
||||
0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class SpriteAnimated : public Sprite
|
||||
{
|
||||
public:
|
||||
// let's keep texture grids squares, saves everyone time...
|
||||
SpriteAnimated(const char* textureAtlasPath, float frameSize);
|
||||
~SpriteAnimated();
|
||||
|
||||
void draw() override;
|
||||
|
||||
void play() override;
|
||||
void idle() override;
|
||||
|
||||
std::shared_ptr<Sprite> clone() const override {
|
||||
return std::make_shared<SpriteAnimated>(*this);
|
||||
}
|
||||
|
||||
bool isPlaying = false;
|
||||
|
||||
private:
|
||||
void SetupAnimated(float frameSize);
|
||||
|
||||
struct VertexIDs {
|
||||
unsigned VAO, VBO;
|
||||
};
|
||||
unsigned EBO;
|
||||
|
||||
// Vertex array buffer IDs
|
||||
std::vector<VertexIDs> ids;
|
||||
|
||||
int currentFrame = 0;
|
||||
float FPS = 7.5f;
|
||||
Uint32 lastFrameTick = 0;
|
||||
};
|
||||
|
||||
class SpriteDirectionalAnimated : public Sprite
|
||||
{
|
||||
public:
|
||||
SpriteDirectionalAnimated(const char* textureAtlasPath, float frameSize);
|
||||
~SpriteDirectionalAnimated();
|
||||
|
||||
void draw() override;
|
||||
|
||||
void play() override;
|
||||
void idle() override;
|
||||
|
||||
std::shared_ptr<Sprite> clone() const override {
|
||||
return std::make_shared<SpriteDirectionalAnimated>(*this);
|
||||
}
|
||||
|
||||
Direction direction = Direction::Down;
|
||||
void setDirection(Direction& dir) { direction = dir; }
|
||||
bool isPlaying = false;
|
||||
|
||||
private:
|
||||
void Setup(float frameSize);
|
||||
|
||||
struct VertexIDs {
|
||||
unsigned VAO, VBO;
|
||||
};
|
||||
unsigned EBO;
|
||||
|
||||
std::unordered_map<Direction, VertexIDs> idleIDs;
|
||||
std::unordered_map<Direction, std::vector<VertexIDs>> walkingIDs;
|
||||
|
||||
int currentFrame = 0;
|
||||
float FPS = 7.5f;
|
||||
Uint32 lastFrameTick = 0;
|
||||
};
|
||||
|
||||
#endif // _H_SPRITE_H
|
||||
22
YuppleMayham/graphics/texture.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef _H_TEXTURE_H
|
||||
#define _H_TEXTURE_H
|
||||
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
Texture() {}
|
||||
bool loadTexture(const char* imagePath);
|
||||
|
||||
void bind();
|
||||
|
||||
const int getWidth() const { return textureWidth; }
|
||||
const int getHeight() const { return textureHeight; }
|
||||
|
||||
~Texture();
|
||||
private:
|
||||
unsigned ID = 0;
|
||||
int textureWidth = 0;
|
||||
int textureHeight = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
37
YuppleMayham/graphics/tile.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#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
|
||||
78
YuppleMayham/graphics/tiletype.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#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
|
||||
66
YuppleMayham/src/gameplay/ai.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#include "../../gameplay/ai.h"
|
||||
#include "../../gameplay/gameactor.h"
|
||||
|
||||
#include "../../utility/raycaster.h"
|
||||
#include "../../utility/script.h"
|
||||
|
||||
|
||||
AI::AI(const std::shared_ptr<GameActor>& actor, const std::shared_ptr<Raycaster>& raycaster)
|
||||
: actor(actor), raycaster(raycaster), state(AIState::Idle)
|
||||
{}
|
||||
|
||||
void AI::attachBehaviourScript(const std::shared_ptr<Script>& behaviour)
|
||||
{
|
||||
// passing out instance of raycaster this Ai into our scripting api
|
||||
// pay special attention each ai script has control of only their own instance of ai!
|
||||
this->behaviour = behaviour;
|
||||
this->behaviour->lua["raycaster"] = raycaster;
|
||||
this->behaviour->lua["ai"] = std::shared_ptr<AI>(this);
|
||||
}
|
||||
|
||||
void AI::update()
|
||||
{
|
||||
try {
|
||||
switch (state)
|
||||
{
|
||||
case AIState::Idle:
|
||||
if (behaviour && behaviour->lua["idle"].valid())
|
||||
{
|
||||
auto result = behaviour->lua["idle"](actor, target);
|
||||
if (!result.valid())
|
||||
{
|
||||
sol::error err = result;
|
||||
std::cerr << "lua error: " << err.what() << std::endl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AIState::Patrol:
|
||||
if (behaviour && behaviour->lua["patrol"].valid())
|
||||
{
|
||||
auto result = behaviour->lua["patrol"](actor, target);
|
||||
if (!result.valid())
|
||||
{
|
||||
sol::error err = result;
|
||||
std::cerr << "lua error: " << err.what() << std::endl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AIState::Alert:
|
||||
if (behaviour && behaviour->lua["alert"].valid())
|
||||
{
|
||||
auto result = behaviour->lua["alert"](actor, target);
|
||||
if (!result.valid())
|
||||
{
|
||||
sol::error err = result;
|
||||
std::cerr << "lua error: " << err.what() << std::endl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
behaviour->lua.collect_gc();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Error during AI update: " << e.what() << std::endl;
|
||||
state = AIState::Idle;
|
||||
}
|
||||
}
|
||||
25
YuppleMayham/src/gameplay/camera.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include "../../gameplay/camera.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::getViewMatrix()
|
||||
{
|
||||
return glm::lookAt(position, position + front, up);
|
||||
}
|
||||
|
||||
glm::mat4 Camera::getProjectionMatrix()
|
||||
{
|
||||
return glm::ortho(0.f, viewPortW, viewPortH, 0.f);
|
||||
}
|
||||
|
||||
const glm::vec3 Camera::worldToLocal(const glm::vec3& worldCoordinates) const
|
||||
{
|
||||
return worldCoordinates - position;
|
||||
}
|
||||
77
YuppleMayham/src/gameplay/entity.cpp
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#include "../../gameplay/entity.h"
|
||||
#include "../../gameplay/camera.h"
|
||||
#include "../../gameplay/physics.h"
|
||||
|
||||
void Entity::setPosition(const glm::vec3& position)
|
||||
{
|
||||
this->position = position;
|
||||
updateModelMatrix();
|
||||
}
|
||||
void Entity::setScale(const glm::vec3& scale)
|
||||
{
|
||||
this->scale = scale;
|
||||
updateModelMatrix();
|
||||
}
|
||||
void Entity::setRotation(const float& rotation)
|
||||
{
|
||||
this->rotation = rotation;
|
||||
updateModelMatrix();
|
||||
}
|
||||
|
||||
void Entity::setLocalPosition(const glm::vec3& localPosition)
|
||||
{
|
||||
this->localPosition = localPosition;
|
||||
}
|
||||
|
||||
void Entity::setRotatable(bool rotatable)
|
||||
{
|
||||
this->isRotatable = rotatable;
|
||||
}
|
||||
|
||||
void Entity::flip()
|
||||
{
|
||||
flipped = !flipped;
|
||||
}
|
||||
|
||||
void Entity::addPhysicsComponent(const std::shared_ptr<PhysicsComponent>& physics)
|
||||
{
|
||||
this->physics = physics;
|
||||
}
|
||||
|
||||
void Entity::update(float deltaTime)
|
||||
{
|
||||
if (physics && physics->rigidBody.velocity != glm::vec3(0.0f))
|
||||
{
|
||||
position = physics->rigidBody.position;
|
||||
updateModelMatrix();
|
||||
deltaPosition = glm::vec3(0.0f);
|
||||
}
|
||||
else if (!physics)
|
||||
{
|
||||
position += deltaPosition * 1.f;
|
||||
updateModelMatrix();
|
||||
deltaPosition = glm::vec3(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::render(const std::shared_ptr<Camera>& camera)
|
||||
{
|
||||
glm::mat4 mvp = camera->getProjectionMatrix() * camera->getViewMatrix() * modelMatrix;
|
||||
|
||||
shader->use();
|
||||
shader->setMatrix4f("MVP", glm::value_ptr(mvp));
|
||||
shader->setBool("flip", flipped);
|
||||
}
|
||||
|
||||
void Entity::updateModelMatrix()
|
||||
{
|
||||
glm::mat4 origin = glm::translate(glm::mat4(1.f), -0.5f * scale);
|
||||
glm::mat4 rotationMat = (isRotatable) ? glm::rotate(glm::mat4(1.f), glm::radians(rotation), glm::vec3(0.0f, 0.0f, 1.0f)) : glm::mat4(1.0f);
|
||||
glm::mat4 translation = glm::translate(glm::mat4(1.f), position + 0.5f * scale);
|
||||
modelMatrix =
|
||||
translation *
|
||||
rotationMat *
|
||||
origin *
|
||||
glm::scale(glm::mat4(1.0f), scale);
|
||||
|
||||
}
|
||||
85
YuppleMayham/src/gameplay/game.cpp
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
#include "../../gameplay/game.h"
|
||||
#include "../../graphics/glwindow.h"
|
||||
#include "../../gameplay/input.h"
|
||||
#include "../../utility/command.h"
|
||||
#include "../../gameplay/scene.h"
|
||||
#include "../../utility/resourcemanager.h"
|
||||
#include "../../utility/ftfont.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
bool Game::init()
|
||||
{
|
||||
window = std::make_shared<GLWindow>("Yupple Mayham", 800, 600);
|
||||
|
||||
if (!window->Init())
|
||||
{
|
||||
std::cout << "Failed to init GLWindow: \n" << SDL_GetError() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
|
||||
{
|
||||
std::cout << "Failed to load GLLoader" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
glViewport(0, 0, window->width(), window->height());
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// For now we'll init default bindings, but as we move forward controls will be set by the player and saved in controls.xml
|
||||
inputHandler = std::make_shared<InputHandler>();
|
||||
inputHandler->bindKeyCommand(SDLK_w, 0, new MoveUpCommand());
|
||||
inputHandler->bindKeyCommand(SDLK_a, 0, new MoveLeftCommand());
|
||||
inputHandler->bindKeyCommand(SDLK_s, 0, new MoveDownCommand());
|
||||
inputHandler->bindKeyCommand(SDLK_d, 0, new MoveRightCommand());
|
||||
|
||||
inputHandler->bindMouseCommand(MOUSE_BUTTON_LEFT, 100, new ShootCommand());
|
||||
inputHandler->bindMouseMotion(new FollowMouseCommand());
|
||||
|
||||
game_state |= GAME_RUNNING;
|
||||
resourceManager = std::make_shared<ResourceManager>();
|
||||
textHandler = std::make_shared<Text>();
|
||||
if (!textHandler->loadFonts("fonts"))
|
||||
return false;
|
||||
textHandler->setProjectionMatrix(glm::ortho(0.f, static_cast<float>(window->width()), 0.f, static_cast<float>(window->height())));
|
||||
return true;
|
||||
}
|
||||
|
||||
const unsigned Game::getWindowWidth() const { return window->width(); }
|
||||
const unsigned Game::getWindowHeight() const { return window->height(); }
|
||||
|
||||
bool Game::loadDebugScene()
|
||||
{
|
||||
currentScene = std::make_shared<Scene>(SCENE_SHOOTER, resourceManager);
|
||||
if (currentScene->getPlayer() == nullptr)
|
||||
return false;
|
||||
inputHandler->setActor(currentScene->getPlayer().get());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Game::handleInput(SDL_Event& e)
|
||||
{
|
||||
inputHandler->captureInput(e);
|
||||
inputHandler->handleInput();
|
||||
}
|
||||
|
||||
void Game::update(float deltaTime)
|
||||
{
|
||||
if (currentScene)
|
||||
currentScene->update(deltaTime);
|
||||
}
|
||||
|
||||
void Game::render()
|
||||
{
|
||||
glClearColor(0.05f, 0.25f, 0.05f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (currentScene)
|
||||
currentScene->render();
|
||||
|
||||
window->swap();
|
||||
}
|
||||
93
YuppleMayham/src/gameplay/gameactor.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#include "../../gameplay/gameactor.h"
|
||||
#include "../../utility/component.h"
|
||||
#include "../../gameplay/entity.h"
|
||||
#include "../../gameplay/physics.h"
|
||||
#include "../../gameplay/weapons/weapon.h"
|
||||
#include "../../utility/events.h"
|
||||
#include "../../utility/direction.h"
|
||||
|
||||
GameActor::~GameActor() { }
|
||||
|
||||
void GameActor::addComponent(std::shared_ptr<Component> component)
|
||||
{
|
||||
component->ownerid = actorid;
|
||||
components.push_back(component);
|
||||
}
|
||||
|
||||
const std::shared_ptr<Weapon>& GameActor::getHeldWeapon() const
|
||||
{
|
||||
return currentWeapon;
|
||||
}
|
||||
|
||||
void GameActor::equipWeapon(std::shared_ptr<Weapon> weapon)
|
||||
{
|
||||
currentWeapon = std::move(weapon);
|
||||
if (currentWeapon)
|
||||
currentWeapon->setWielder(this);
|
||||
}
|
||||
|
||||
void GameActor::attachEventManager(std::shared_ptr<EventManager> eventManager)
|
||||
{
|
||||
this->eventManager = eventManager;
|
||||
}
|
||||
|
||||
void GameActor::setRotation(const float& rotation)
|
||||
{
|
||||
if (!isRotatable && eventManager) {
|
||||
Direction newDir = getDirectionFromRotation(rotation);
|
||||
if (getDirectionFromRotation(this->rotation) != newDir)
|
||||
eventManager->notify(std::make_shared<DirectionChangeEvent>(actorid, newDir));
|
||||
}
|
||||
this->rotation = rotation;
|
||||
updateModelMatrix();
|
||||
}
|
||||
|
||||
void GameActor::update(float deltaTime)
|
||||
{
|
||||
Entity::update(deltaTime);
|
||||
|
||||
for (auto& component : components)
|
||||
component->update();
|
||||
if (currentWeapon)
|
||||
currentWeapon->update(deltaTime);
|
||||
}
|
||||
|
||||
void GameActor::render(const std::shared_ptr<Camera>& camera)
|
||||
{
|
||||
Entity::render(camera);
|
||||
|
||||
for (auto& component : components)
|
||||
{
|
||||
if (isMoving)
|
||||
component->play();
|
||||
else
|
||||
component->idle();
|
||||
component->bind();
|
||||
component->render();
|
||||
}
|
||||
if (currentWeapon)
|
||||
currentWeapon->render(camera);
|
||||
isMoving = false;
|
||||
}
|
||||
|
||||
void GameActor::moveUp() { if (physics) physics->rigidBody.applyForce(glm::vec3( 0.f,-1.f, 0.f), 1500.25f); isMoving = true; }
|
||||
void GameActor::moveDown() { if (physics) physics->rigidBody.applyForce(glm::vec3( 0.f, 1.f, 0.f), 1500.25f); isMoving = true; }
|
||||
void GameActor::moveLeft() { if (physics) physics->rigidBody.applyForce(glm::vec3(-1.f, 0.f, 0.f), 1500.25f); isMoving = true; }
|
||||
void GameActor::moveRight(){ if (physics) physics->rigidBody.applyForce(glm::vec3( 1.f, 0.f, 0.f), 1500.25f); isMoving = true; }
|
||||
|
||||
// top-down shooter mode controls
|
||||
void GameActor::strafeLeft() { position.x += sin(glm::radians(rotation)) * speed; position.y -= cos(glm::radians(rotation)) * speed; }
|
||||
void GameActor::strafeRight() { position.x -= sin(glm::radians(rotation)) * speed; position.y += cos(glm::radians(rotation)) * speed; }
|
||||
void GameActor::moveBackward() { position.x -= cos(glm::radians(rotation)) * speed; position.y -= sin(glm::radians(rotation)) * speed; }
|
||||
void GameActor::moveForward() { if (physics) physics->rigidBody.applyForce(glm::vec3(cos(glm::radians(rotation)), sin(glm::radians(rotation)), 0.f), 1000.f); isMoving = true; }
|
||||
void GameActor::fireWeapon() { if (currentWeapon) currentWeapon->shoot(); }
|
||||
void GameActor::followMouse(const MouseState& mouse_state)
|
||||
{
|
||||
glm::vec2 direction = glm::vec2(mouse_state.x, mouse_state.y) - glm::vec2(localPosition.x + 0.5f * scale.x, localPosition.y + 0.5f * scale.y);
|
||||
float newRotation = glm::degrees(glm::atan(direction.y, direction.x));
|
||||
if (getDirectionFromRotation(rotation) != getDirectionFromRotation(newRotation))
|
||||
if (eventManager)
|
||||
eventManager->notify(std::make_shared<DirectionChangeEvent>(actorid, getDirectionFromRotation(newRotation)));
|
||||
//setRotation(glm::degrees(glm::atan(direction.y, direction.x)));
|
||||
this->rotation = newRotation;
|
||||
}
|
||||
39
YuppleMayham/src/gameplay/input.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#include "../../gameplay/input.h"
|
||||
#include "../../utility/command.h"
|
||||
#include "../../gameplay/gameactor.h"
|
||||
|
||||
#include <SDL_timer.h>
|
||||
|
||||
void InputHandler::handleInput()
|
||||
{
|
||||
if (!actor) return;
|
||||
Uint32 currentTime = SDL_GetTicks();
|
||||
// check for bound keys that were pressed,
|
||||
// next check if the hasn't been executed within the amount specified in delay
|
||||
// if not execute the command and set lastExecution to currentTime
|
||||
for (auto& [key, command] : keyCommands)
|
||||
{
|
||||
if (keys[key] == true)
|
||||
{
|
||||
if (currentTime - command.lastExecution >= command.delay)
|
||||
{
|
||||
command.cmd->execute(*actor);
|
||||
command.lastExecution = currentTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Same with the mouse, for this context we'll be checking for motion events and for click events
|
||||
for (auto& [button, command] : mouseCommands)
|
||||
{
|
||||
if (mouseButtons[button] == true)
|
||||
{
|
||||
if (currentTime - command.lastExecution >= command.delay)
|
||||
{
|
||||
command.cmd->execute(*actor, mouse_state);
|
||||
command.lastExecution = currentTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!mouseMotionCommand) return;
|
||||
mouseMotionCommand->execute(*actor, mouse_state);
|
||||
}
|
||||
61
YuppleMayham/src/gameplay/map.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#include "../../gameplay/map.h"
|
||||
//#include "../../graphics/instancedraw.h"
|
||||
#include "../../utility/xmlloader.h"
|
||||
#include "../../graphics/tiletype.h"
|
||||
#include "../../graphics/shader.h"
|
||||
#include "../../gameplay/camera.h"
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
Map::Map(const std::shared_ptr<MapData>& mapData, const std::shared_ptr<Shader>& shader) :
|
||||
shader(shader),
|
||||
mapData(mapData)
|
||||
{
|
||||
instanceHandle = std::make_shared<TileTextureInstance>(this->mapData->file.c_str());
|
||||
tileIds = mapData->groundTiles;
|
||||
loadMap();
|
||||
createCollisionMap();
|
||||
}
|
||||
|
||||
void Map::loadMap()
|
||||
{
|
||||
for (int y = 0; y < tileIds.size(); y++)
|
||||
{
|
||||
for (int x = 0; x < tileIds[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 });
|
||||
}
|
||||
}
|
||||
shader->use();
|
||||
// TODO: Figure someway to put these in with my xml data
|
||||
shader->setInt("tilesPerRow", 8);
|
||||
}
|
||||
|
||||
void Map::createCollisionMap()
|
||||
{
|
||||
for (int y = 0; y < mapData->groundTiles.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.push_back(row);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
195
YuppleMayham/src/gameplay/physics.cpp
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
#include "../../gameplay/physics.h"
|
||||
#include "../../gameplay/weapons/bullet.h"
|
||||
#include "../../utility/events.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void PhysicsEngine::hookEventManager(const std::shared_ptr<EventManager>& eventManager)
|
||||
{
|
||||
this->eventManager = eventManager;
|
||||
this->eventManager->subscribe("OnBulletFired", [this](std::shared_ptr<Event> e) {
|
||||
auto bulletEvent = std::static_pointer_cast<BulletFiredEvent>(e);
|
||||
this->addObject(bulletEvent->bullet->getPhysicsComponent());
|
||||
});
|
||||
this->eventManager->subscribe("OnBulletDied", [this](std::shared_ptr<Event> e) {
|
||||
auto bulletEvent = std::static_pointer_cast<BulletDiedEvent>(e);
|
||||
this->removeObject(bulletEvent->physObj);
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<PhysicsComponent> PhysicsEngine::createObject(const glm::vec3& pos, float mass, PhysicsComponent::Collider::Shape shape, glm::vec3 dimensions, glm::vec3 offset)
|
||||
{
|
||||
auto component = std::make_shared <PhysicsComponent>();
|
||||
component->rigidBody.position = pos;
|
||||
component->rigidBody.mass = mass;
|
||||
component->collider.shape = shape;
|
||||
component->collider.dimensions = dimensions;
|
||||
component->collider.offset = offset;
|
||||
|
||||
addObject(component);
|
||||
return component;
|
||||
}
|
||||
|
||||
void PhysicsEngine::loadCollisionMap(const std::vector<std::vector<int>>& collisionMap, float tileSize)
|
||||
{
|
||||
this->collisionMap = collisionMap;
|
||||
this->tileSize = tileSize;
|
||||
}
|
||||
|
||||
void PhysicsEngine::addObject(const std::shared_ptr<PhysicsComponent>& component)
|
||||
{
|
||||
if (component)
|
||||
objects.emplace_back(component);
|
||||
}
|
||||
|
||||
void PhysicsEngine::removeObject(const std::shared_ptr<PhysicsComponent>& component)
|
||||
{
|
||||
if (std::find(objects.begin(), objects.end(), component) != objects.end())
|
||||
objects.erase(std::remove(objects.begin(), objects.end(), component));
|
||||
}
|
||||
|
||||
int PhysicsEngine::getTileCollider(const glm::vec3& position)
|
||||
{
|
||||
int x = static_cast<int>(position.x / tileSize);
|
||||
int y = static_cast<int>(position.y / tileSize);
|
||||
if (y >= 0 && y < collisionMap.size())
|
||||
{
|
||||
if (x >= 0 && x < collisionMap[y].size())
|
||||
return collisionMap[y][x];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PhysicsEngine::getPossibleCollisions()
|
||||
{
|
||||
objCollisions.clear();
|
||||
for (size_t i = 0; i < objects.size(); ++i)
|
||||
{
|
||||
auto& obj = objects[i];
|
||||
for (size_t j = i + 1; j < objects.size(); ++j)
|
||||
{
|
||||
auto& colliderObj = objects[j];
|
||||
if (obj.get() == colliderObj.get()) continue;
|
||||
float colliderRight = colliderObj->rigidBody.position.x + colliderObj->collider.dimensions.x;
|
||||
float colliderBottom = colliderObj->rigidBody.position.y + colliderObj->collider.dimensions.y;
|
||||
float objectRight = obj->rigidBody.position.x + obj->collider.dimensions.x;
|
||||
float objectBottom = obj->rigidBody.position.y + obj->collider.dimensions.y;
|
||||
if ((obj->rigidBody.position.x <= colliderRight &&
|
||||
objectRight >= colliderObj->rigidBody.position.x) ||
|
||||
(obj->rigidBody.position.y <= colliderBottom &&
|
||||
objectBottom >= colliderObj->rigidBody.position.y))
|
||||
objCollisions.push_back(std::make_pair(obj.get(), colliderObj.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsEngine::resolvePossibleCollisions()
|
||||
{
|
||||
for (auto& objs : objCollisions)
|
||||
{
|
||||
// Solve for two circles, we'll need to expand upon this for different colliders...
|
||||
float sumOfRadius = objs.first->collider.dimensions.x + objs.second->collider.dimensions.x;
|
||||
glm::vec3 objFirstCenter = objs.first->rigidBody.position + objs.first->collider.offset;
|
||||
glm::vec3 objSecondCenter = objs.second->rigidBody.position + objs.second->collider.offset;
|
||||
glm::vec3 distance = objFirstCenter - objSecondCenter;
|
||||
if (glm::length(distance) < sumOfRadius)
|
||||
{
|
||||
// We got impact!
|
||||
glm::vec3 normal = distance / glm::length(distance);
|
||||
float penetrationDepth = sumOfRadius - glm::length(distance);
|
||||
glm::vec3 correctionVector = normal * (penetrationDepth / ((1 / objs.first->rigidBody.mass) + (1 / objs.second->rigidBody.mass)));
|
||||
glm::vec3 vrel = objs.first->rigidBody.velocity - objs.second->rigidBody.velocity;
|
||||
|
||||
float e = std::min(objs.first->rigidBody.elasticity, objs.second->rigidBody.elasticity);
|
||||
float impulseMag = (-(1 + e) * glm::dot(vrel, normal)) / ((1 / objs.first->rigidBody.mass) + (1 / objs.second->rigidBody.mass));
|
||||
|
||||
//objs.first->rigidBody.applyForce(normal, impulseMag);
|
||||
//objs.second->rigidBody.applyForce(normal, -impulseMag);
|
||||
objs.first->rigidBody.position += (correctionVector / objs.first->rigidBody.mass);
|
||||
objs.second->rigidBody.position -= (correctionVector / objs.second->rigidBody.mass);
|
||||
objs.first->rigidBody.velocity += impulseMag * normal / objs.first->rigidBody.mass;
|
||||
objs.second->rigidBody.velocity -= impulseMag * normal / objs.second->rigidBody.mass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsEngine::resolveWorldCollision(const std::shared_ptr<PhysicsComponent>& obj)
|
||||
{
|
||||
switch (obj->collider.shape)
|
||||
{
|
||||
case PhysicsComponent::Collider::Shape::Circle:
|
||||
float radius = obj->collider.dimensions.x;
|
||||
glm::vec3 position = obj->rigidBody.position + obj->collider.offset;
|
||||
int topTile = getTileCollider(position - glm::vec3(0, radius, 0));
|
||||
int bottomTile = getTileCollider(position + glm::vec3(0, radius, 0));
|
||||
int leftTile = getTileCollider(position - glm::vec3(radius, 0, 0));
|
||||
int rightTile = getTileCollider(position + glm::vec3(radius, 0, 0));
|
||||
if (obj->isBullet)
|
||||
{
|
||||
if (topTile || bottomTile || leftTile || rightTile)
|
||||
{
|
||||
eventManager->notify(std::make_shared<BulletDiedEvent>(obj));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (topTile)
|
||||
{
|
||||
//obj->rigidBody.velocity.y = -obj->rigidBody.velocity.y;
|
||||
int tileY = static_cast<int>((position.y - radius) / tileSize);
|
||||
obj->rigidBody.position.y = (tileY) * tileSize + radius + obj->collider.offset.y;
|
||||
}
|
||||
if (bottomTile)
|
||||
{
|
||||
//obj->rigidBody.velocity.y = -obj->rigidBody.velocity.y;
|
||||
int tileY = static_cast<int>((position.y + radius) / tileSize);
|
||||
obj->rigidBody.position.y = tileY * tileSize - radius - obj->collider.offset.y;
|
||||
}
|
||||
if (leftTile)
|
||||
{
|
||||
//obj->rigidBody.velocity.x = -obj->rigidBody.velocity.x;
|
||||
int tileX = static_cast<int>((position.x - radius) / tileSize);
|
||||
obj->rigidBody.position.x = (tileX) * tileSize + radius + obj->collider.offset.x;
|
||||
}
|
||||
if (rightTile)
|
||||
{
|
||||
//obj->rigidBody.velocity.x = -obj->rigidBody.velocity.x;
|
||||
int tileX = static_cast<int>((position.x + radius) / tileSize);
|
||||
obj->rigidBody.position.x = tileX * tileSize - radius - obj->collider.offset.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsEngine::update(float deltaTime)
|
||||
{
|
||||
for (auto& obj : objects)
|
||||
{
|
||||
if (!obj) continue;
|
||||
glm::vec3 frictionForce = obj->rigidBody.velocity * -0.1f;
|
||||
if (std::abs(obj->rigidBody.acceleration.x) == std::abs(obj->rigidBody.acceleration.y))
|
||||
{
|
||||
obj->rigidBody.acceleration.x *= 0.75f;
|
||||
obj->rigidBody.acceleration.y *= 0.75f;
|
||||
}
|
||||
if (!obj->isBullet)
|
||||
obj->rigidBody.velocity += (frictionForce);
|
||||
obj->rigidBody.velocity += obj->rigidBody.acceleration;
|
||||
|
||||
float maxSpeed = 500.f;
|
||||
float curSpeed = glm::length(obj->rigidBody.velocity);
|
||||
if (curSpeed > maxSpeed)
|
||||
{
|
||||
// Move at maxspeed
|
||||
obj->rigidBody.velocity = glm::normalize(obj->rigidBody.velocity) * maxSpeed;
|
||||
}
|
||||
obj->rigidBody.acceleration = glm::vec3(0.f);
|
||||
if (obj->collider.dimensions != glm::vec3(0.f))
|
||||
{
|
||||
// check map collisions
|
||||
resolveWorldCollision(obj);
|
||||
}
|
||||
obj->rigidBody.position += obj->rigidBody.velocity * deltaTime;
|
||||
}
|
||||
getPossibleCollisions();
|
||||
if (!objCollisions.empty())
|
||||
resolvePossibleCollisions();
|
||||
}
|
||||
143
YuppleMayham/src/gameplay/scene.cpp
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
#include "../../gameplay/scene.h"
|
||||
#include "../../gameplay/camera.h"
|
||||
#include "../../gameplay/gameactor.h"
|
||||
#include "../../gameplay/weapons/weapons.h"
|
||||
#include "../../gameplay/map.h"
|
||||
#include "../../gameplay/physics.h"
|
||||
#include "../../gameplay/ai.h"
|
||||
|
||||
#include "../../graphics/tile.h"
|
||||
#include "../../graphics/sprite.h"
|
||||
|
||||
#include "../../utility/component.h"
|
||||
#include "../../utility/xmlloader.h"
|
||||
#include "../../utility/resourcemanager.h"
|
||||
#include "../../utility/events.h"
|
||||
#include "../../utility/raycaster.h"
|
||||
#include "../../utility/debugdraw.h"
|
||||
|
||||
// Scene xml files, should contain a node called <player> that holds the sprite location
|
||||
/*
|
||||
like this:
|
||||
<player sprite="sprites/player2Atlas.png" frameSize=64.0>
|
||||
<x=5/>
|
||||
<y=6/>
|
||||
</player>
|
||||
*/
|
||||
|
||||
Scene::Scene(SceneType sceneType, std::shared_ptr<ResourceManager> resources) : type(sceneType), resourceManager(resources)
|
||||
{
|
||||
camera = std::make_shared<Camera>(800.f, 600.f);
|
||||
physicsEngine = std::make_shared<PhysicsEngine>();
|
||||
eventManager = std::make_shared<EventManager>();
|
||||
physicsEngine->hookEventManager(eventManager);
|
||||
if (sceneType == SCENE_SHOOTER)
|
||||
loadDebugShooterScene();
|
||||
}
|
||||
|
||||
// This function is full of hardcoded values and test sprites, NOT for use with final product
|
||||
void Scene::loadDebugShooterScene()
|
||||
{
|
||||
sceneData = resourceManager->loadScene("000");
|
||||
if (!sceneData)
|
||||
return;
|
||||
EntityData playerData = sceneData->entities[0];
|
||||
MapData 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);
|
||||
|
||||
for (EntityData entityData : sceneData->entities)
|
||||
{
|
||||
auto entity = std::make_shared<GameActor>(playerShader);
|
||||
std::shared_ptr<Sprite> entitySprite;
|
||||
// Directional is the kind of sprite sheet we are using, in this case for directional, I have the sprite sheet handle the rotations
|
||||
// instead of just rotating the object, this makes it look quite a bit better from the end user perspective.
|
||||
if (entityData.isDirectional)
|
||||
{
|
||||
entitySprite = resourceManager->loadSpriteDirAnimated(entityData.sprite, entityData.frameSize);
|
||||
// because we don't want to have the engine rotate the object based on the entities rotation,
|
||||
// we set the this value to false so we no longer rotate the object.
|
||||
entity->setRotatable(false);
|
||||
}
|
||||
else
|
||||
entitySprite = resourceManager->loadSpriteAnimated(entityData.sprite, entityData.frameSize);
|
||||
auto entityWeapon = resourceManager->loadWeapon(entityData.weapon, weaponShader, bubbleShader);
|
||||
|
||||
entityWeapon->hookEventManager(eventManager);
|
||||
entity->addComponent(std::make_shared<SpriteComponent>(entitySprite, eventManager));
|
||||
entity->equipWeapon(entityWeapon);
|
||||
entity->attachEventManager(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->addPhysicsComponent(
|
||||
physicsEngine->createObject(entity->getPosition(), 49.0,
|
||||
PhysicsComponent::Collider::Shape::Circle,
|
||||
glm::vec3(mapData.tileSize / 2),
|
||||
glm::abs(entity->getCenter() - entity->getPosition()))
|
||||
);
|
||||
|
||||
if (entityData.isPlayer)
|
||||
{
|
||||
player = entity;
|
||||
camera->setTarget(entity.get());
|
||||
entity->setLocalPosition(camera->worldToLocal(entity->getPosition()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// attach ai
|
||||
if (!entityData.script.empty())
|
||||
{
|
||||
auto behaviourScript = resourceManager->loadScript(entityData.script);
|
||||
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);
|
||||
entity->addComponent(std::make_shared<AIComponent>(ai));
|
||||
}
|
||||
}
|
||||
entities.push_back(entity);
|
||||
}
|
||||
|
||||
physicsEngine->loadCollisionMap(map->getCollisionMap(), sceneData->map.tileSize);
|
||||
|
||||
// Setup map and other entities...
|
||||
}
|
||||
|
||||
std::shared_ptr<GameActor> Scene::getPlayer() const
|
||||
{
|
||||
return (!player) ? nullptr : player;
|
||||
}
|
||||
|
||||
void Scene::update(float deltaTime)
|
||||
{
|
||||
for (auto& e : entities)
|
||||
{
|
||||
e->update(deltaTime);
|
||||
if (camera->getTarget() == e.get())
|
||||
e->setLocalPosition(camera->worldToLocal(e->getPosition()));
|
||||
}
|
||||
physicsEngine->update(deltaTime);
|
||||
camera->update(deltaTime);
|
||||
}
|
||||
|
||||
void Scene::render()
|
||||
{
|
||||
map->render(camera);
|
||||
for (auto& e : entities)
|
||||
{
|
||||
e->render(camera);
|
||||
}
|
||||
DebugDrawer::getInstance().draw(camera->getProjectionMatrix() * camera->getViewMatrix());
|
||||
}
|
||||
|
||||
void Scene::unloadScene()
|
||||
{
|
||||
//xmlLoader.reset();
|
||||
}
|
||||
|
||||
38
YuppleMayham/src/gameplay/weapons/bullet.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include "../../../gameplay/weapons/bullet.h"
|
||||
#include "../../../utility/component.h"
|
||||
#include "../../../gameplay/physics.h"
|
||||
|
||||
void Bullet::addComponent(std::shared_ptr<Component> component)
|
||||
{
|
||||
components.push_back(component);
|
||||
}
|
||||
|
||||
void Bullet::update(float deltaTime)
|
||||
{
|
||||
Entity::update(deltaTime);
|
||||
|
||||
deltaPosition.x += direction.x * bulletSpeed;
|
||||
deltaPosition.y += direction.y * bulletSpeed;
|
||||
//physics->rigidBody.position = position;
|
||||
|
||||
for (auto& component : components)
|
||||
component->update();
|
||||
}
|
||||
|
||||
void Bullet::render(const std::shared_ptr<Camera>& camera)
|
||||
{
|
||||
Entity::render(camera);
|
||||
|
||||
shader->use();
|
||||
for (auto& component : components)
|
||||
{
|
||||
component->play();
|
||||
component->bind();
|
||||
component->render();
|
||||
}
|
||||
}
|
||||
|
||||
Bullet::~Bullet()
|
||||
{
|
||||
components.clear();
|
||||
}
|
||||
64
YuppleMayham/src/gameplay/weapons/bulletmanager.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#include "../../../gameplay/weapons/bulletmanager.h"
|
||||
#include "../../../gameplay/weapons/bullet.h"
|
||||
#include "../../../utility/component.h"
|
||||
#include "../../../gameplay/physics.h"
|
||||
#include "../../../utility/events.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
void BulletManager::hookEventManager(const std::shared_ptr<EventManager>& eventManager)
|
||||
{
|
||||
this->eventManager = eventManager;
|
||||
this->eventManager->subscribe("OnBulletDied", [this](std::shared_ptr<Event> e) {
|
||||
auto bulletEvent = std::static_pointer_cast<BulletDiedEvent>(e);
|
||||
auto iterator = std::find_if(bullets.begin(), bullets.end(), [&](std::shared_ptr<Bullet> bullet) {
|
||||
return bullet->getPhysicsComponent() == bulletEvent->physObj;
|
||||
});
|
||||
if (iterator != bullets.end())
|
||||
bullets.erase(iterator);
|
||||
});
|
||||
}
|
||||
|
||||
void BulletManager::addBullet(const std::shared_ptr<Bullet>& bullet)
|
||||
{
|
||||
bullets.emplace_back(bullet);
|
||||
}
|
||||
|
||||
void BulletManager::addBullet(const glm::vec3& fireFrom,
|
||||
const glm::vec2& direction,
|
||||
float bulletSpeed,
|
||||
float bulletDrop,
|
||||
glm::vec2 bulletSize,
|
||||
const std::shared_ptr<Shader>& shader,
|
||||
const std::shared_ptr<Component>& sprite)
|
||||
{
|
||||
auto bullet = std::make_shared<Bullet>(shader, fireFrom, direction, bulletSpeed, bulletDrop, bulletSize);
|
||||
bullet->addComponent(sprite);
|
||||
//bullet->addPhysicsComponent(phy)
|
||||
bullets.emplace_back(bullet);
|
||||
}
|
||||
|
||||
void BulletManager::update(float deltaTime)
|
||||
{
|
||||
for (auto& bullet : bullets)
|
||||
{
|
||||
if (!bullet) continue;
|
||||
bullet->update(deltaTime);
|
||||
float distance = glm::distance(bullet->getPosition(), bullet->getBulletOrigin());
|
||||
if (distance > bullet->getBulletDrop())
|
||||
{
|
||||
if (eventManager)
|
||||
eventManager->notify(std::make_shared<BulletDiedEvent>(bullet->getPhysicsComponent()));
|
||||
//bullets.erase(std::remove(bullets.begin(), bullets.end(), bullet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BulletManager::render(const std::shared_ptr<Camera>& camera)
|
||||
{
|
||||
for (auto& bullet : bullets)
|
||||
{
|
||||
if (!bullet) continue;
|
||||
bullet->render(camera);
|
||||
}
|
||||
}
|
||||
141
YuppleMayham/src/gameplay/weapons/weapon.cpp
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include "../../../gameplay/weapons/weapon.h"
|
||||
#include "../../../utility/resourcemanager.h"
|
||||
#include "../../../gameplay/weapons/bulletmanager.h"
|
||||
#include "../../../gameplay/weapons/bullet.h"
|
||||
#include "../../../gameplay/entity.h"
|
||||
#include "../../../utility/component.h"
|
||||
#include "../../../utility/events.h"
|
||||
#include "../../../gameplay/physics.h"
|
||||
#include <SDL_timer.h>
|
||||
|
||||
#include "../../../utility/debugdraw.h"
|
||||
|
||||
// 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)
|
||||
:
|
||||
Entity (weaponShader),
|
||||
bulletShader (bulletShader),
|
||||
weaponSize (glm::vec2(data->sizeX, data->sizeY)),
|
||||
weaponOffset (glm::vec2(data->offsetX, data->offsetY)),
|
||||
bulletDrop (data->bulletDrop),
|
||||
bulletSpeed (data->bulletSpeed),
|
||||
bulletSize (glm::vec2(data->bulletSizeX, data->bulletSizeY)),
|
||||
bulletSpread (std::make_shared<UTIL::RandomGenerator>(-data->bulletSpread, data->bulletSpread)),
|
||||
bulletModifer (std::make_shared<UTIL::RandomGenerator>(data->modMin, data->modMax)),
|
||||
fireSpeed (data->fireSpeed),
|
||||
bulletManager (std::make_shared<BulletManager>()),
|
||||
bulletSprite (data->bulletAnimated ?
|
||||
std::make_shared<SpriteComponent>(resourceManager->loadSpriteAnimated(data->bulletSprite, data->bulletFrameSize))
|
||||
: std::make_shared<SpriteComponent>(resourceManager->loadSpriteStatic(data->bulletSprite)))
|
||||
{
|
||||
if (data->animated)
|
||||
{
|
||||
addComponent(std::make_shared<SpriteComponent>(resourceManager->loadSpriteAnimated(data->sprite, data->frameSize)));
|
||||
for (auto& c : components)
|
||||
c->play();
|
||||
}
|
||||
else
|
||||
addComponent(std::make_shared<SpriteComponent>(resourceManager->loadSpriteStatic(data->sprite)));
|
||||
this->setScale(glm::vec3(weaponSize.x, weaponSize.y, 1.0f));
|
||||
};
|
||||
|
||||
void Weapon::addComponent(const std::shared_ptr<Component>& comp) {
|
||||
components.push_back(comp);
|
||||
}
|
||||
|
||||
// TODO: Fix this tangled web of garbage
|
||||
void Weapon::shoot()
|
||||
{
|
||||
if (wielder)
|
||||
{
|
||||
Uint32 currentTime = SDL_GetTicks();
|
||||
if (currentTime - lastFireTime >= fireSpeed)
|
||||
{
|
||||
float rotation = glm::radians(wielder->getRotation());
|
||||
float mass = 0.1f;
|
||||
glm::vec2 facing = glm::vec2(
|
||||
cos(rotation + glm::radians(static_cast<float>(bulletSpread->genFloat()))),
|
||||
sin(rotation + glm::radians(static_cast<float>(bulletSpread->genFloat())))
|
||||
);
|
||||
facing = glm::normalize(facing);
|
||||
float sizeMod = bulletModifer->genFloat();
|
||||
float speedMod = bulletModifer->genFloat();
|
||||
float dropMod = bulletModifer->genFloat();
|
||||
|
||||
float radius = wielder->getScale().x + (weaponSize.x * 0.5) + weaponOffset.x;
|
||||
|
||||
glm::vec3 offset = glm::vec3(
|
||||
// x offset from the wielder
|
||||
wielder->getCenter().x + cos(rotation) * radius - sin(rotation) * weaponOffset.y,
|
||||
// y offset from the wielder
|
||||
wielder->getCenter().y + sin(rotation) * radius + cos(rotation) * weaponOffset.y,
|
||||
0.0f
|
||||
);
|
||||
glm::vec3 origin = offset;
|
||||
origin.x -= ((bulletSize.x) * sizeMod) * 0.5f;
|
||||
origin.y -= ((bulletSize.y) * sizeMod) * 0.5f;
|
||||
|
||||
auto bullet = std::make_shared<Bullet>(bulletShader, origin, facing, bulletSpeed, bulletDrop, bulletSize);
|
||||
bullet->addComponent(bulletSprite);
|
||||
bullet->addPhysicsComponent(std::make_shared<PhysicsComponent>(PhysicsComponentFactory::makeBullet(origin, mass, bulletSize.x / 2)));
|
||||
bullet->getPhysicsComponent()->rigidBody.velocity += bulletSpeed * glm::vec3(facing.x, facing.y, 0.f) / mass;
|
||||
if (eventManager)
|
||||
eventManager->notify(std::make_shared<BulletFiredEvent>(bullet));
|
||||
bulletManager->addBullet(bullet);
|
||||
lastFireTime = currentTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Weapon::hookEventManager(const std::shared_ptr<EventManager>& eventManager)
|
||||
{
|
||||
this->eventManager = eventManager;
|
||||
bulletManager->hookEventManager(eventManager);
|
||||
}
|
||||
|
||||
void Weapon::update(float deltaTime)
|
||||
{
|
||||
Entity::update(deltaTime);
|
||||
if (wielder)
|
||||
{
|
||||
float rotation = glm::radians(wielder->getRotation());
|
||||
|
||||
glm::vec3 offset = glm::vec3(
|
||||
cos(rotation) * ((wielder->getScale().x) - weaponSize.x * 0.5f),
|
||||
sin(rotation) * ((wielder->getScale().y) - weaponSize.y * 0.5f),
|
||||
0.0f
|
||||
);
|
||||
glm::vec3 origin = wielder->getCenter() + offset;
|
||||
origin.x -= (weaponSize.x) * 0.5f;
|
||||
origin.y -= (weaponSize.y) * 0.5f;
|
||||
|
||||
// Flip the texture if the weapon is facing upwards or downwards
|
||||
Direction d = getDirectionFromRotation(glm::degrees(rotation));
|
||||
if ((lastDir == Direction::Up || lastDir == Direction::Left) &&
|
||||
(d == Direction::Down || d == Direction::Right) && !isFlipped())
|
||||
flip();
|
||||
if ((lastDir == Direction::Down || lastDir == Direction::Right) &&
|
||||
(d == Direction::Up || d == Direction::Left) && isFlipped())
|
||||
flip();
|
||||
|
||||
setRotation(wielder->getRotation() - 180);
|
||||
setPosition(origin);
|
||||
lastDir = getDirectionFromRotation(glm::degrees(rotation));
|
||||
}
|
||||
for (auto& component : components)
|
||||
component->update();
|
||||
bulletManager->update(deltaTime);
|
||||
}
|
||||
|
||||
void Weapon::render(const std::shared_ptr<Camera>& camera)
|
||||
{
|
||||
Entity::render(camera);
|
||||
for (auto& component : components)
|
||||
{
|
||||
component->bind();
|
||||
component->render();
|
||||
}
|
||||
DebugDrawer::getInstance().addCircle(wielder->getCenter(), wielder->getScale().x + (weaponSize.x * 0.5) + (weaponOffset.x), glm::vec4(1.f, 0.5f, 0.25f, 0.4f));
|
||||
bulletManager->render(camera);
|
||||
}
|
||||
83
YuppleMayham/src/graphics/instancedraw.cpp
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#include "../../graphics/instancedraw.h"
|
||||
#include "../../graphics/texture.h"
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <iostream>
|
||||
|
||||
TileTextureInstance::TileTextureInstance(const char* texturePath)
|
||||
{
|
||||
texture = new Texture();
|
||||
texture->loadTexture(texturePath);
|
||||
if (texture)
|
||||
setup();
|
||||
}
|
||||
|
||||
void TileTextureInstance::setup()
|
||||
{
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, 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_ARRAY_BUFFER, 0);
|
||||
|
||||
glGenBuffers(1, &instanceVBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(InstanceData) * MAX_INSTANCES, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
glVertexAttribIPointer(2, 1, GL_INT, sizeof(InstanceData), (void*)(offsetof(InstanceData, tileIndex)));
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribDivisor(2, 1);
|
||||
|
||||
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);
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void TileTextureInstance::updateInstanceData(const std::vector<InstanceData>& instanceData)
|
||||
{
|
||||
if (instanceData.empty())
|
||||
return;
|
||||
numOfInstances = instanceData.size();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
|
||||
|
||||
InstanceData* instances = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0,
|
||||
sizeof(InstanceData) * instanceData.size(),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
if (!instances)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < instanceData.size(); i++)
|
||||
{
|
||||
instances[i].modelMatrix = instanceData[i].modelMatrix;
|
||||
instances[i].tileIndex = instanceData[i].tileIndex;
|
||||
}
|
||||
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void TileTextureInstance::draw()
|
||||
{
|
||||
texture->bind();
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr, numOfInstances);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
39
YuppleMayham/src/graphics/mesh.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#include "../../graphics/mesh.h"
|
||||
|
||||
Mesh::Mesh(const VertexList& vertexList, const IndexList& indexList) : indexSize(indexList.size())
|
||||
{
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexList.size() * sizeof(Vertex), &vertexList[0], GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexList.size() * sizeof(unsigned), &indexList[0], GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(unsigned), (void*)offsetof(Vertex, texCoord));
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindVertexArray(1);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Mesh::draw()
|
||||
{
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElements(GL_TRIANGLES, indexSize, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(VAO);
|
||||
}
|
||||
|
||||
Mesh::~Mesh()
|
||||
{
|
||||
glDeleteBuffers(1, &VBO);
|
||||
glDeleteBuffers(1, &EBO);
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
}
|
||||
105
YuppleMayham/src/graphics/shader.cpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#include "../../graphics/shader.h"
|
||||
|
||||
Shader::Shader(const char* vertexPath, const char* fragmentPath)
|
||||
{
|
||||
std::string vertexSource;
|
||||
std::string fragmentSource;
|
||||
std::ifstream vertexStream;
|
||||
std::ifstream fragmentStream;
|
||||
|
||||
vertexStream.exceptions(std::ifstream::badbit | std::ifstream::failbit);
|
||||
fragmentStream.exceptions(std::ifstream::badbit | std::ifstream::failbit);
|
||||
try
|
||||
{
|
||||
vertexStream.open(vertexPath);
|
||||
fragmentStream.open(fragmentPath);
|
||||
|
||||
std::stringstream vStringStream, fStringStream;
|
||||
|
||||
vStringStream << vertexStream.rdbuf();
|
||||
fStringStream << fragmentStream.rdbuf();
|
||||
|
||||
vertexSource = vStringStream.str();
|
||||
fragmentSource = fStringStream.str();
|
||||
|
||||
vertexStream.close();
|
||||
fragmentStream.close();
|
||||
}
|
||||
catch(std::exception e)
|
||||
{
|
||||
std::cout << "failed to open shader files " << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
const char* vSource = vertexSource.c_str();
|
||||
const char* fSource = fragmentSource.c_str();
|
||||
|
||||
unsigned int vertexid, fragmentid;
|
||||
char infoLog[512];
|
||||
int success;
|
||||
|
||||
//compile vertex shader
|
||||
vertexid = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexid, 1, &vSource, NULL);
|
||||
glCompileShader(vertexid);
|
||||
|
||||
glGetShaderiv(vertexid, GL_COMPILE_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetShaderInfoLog(vertexid, 512, NULL, infoLog);
|
||||
std::cout << "VERTEX SHADER COMPILE ERROR\n" << infoLog << std::endl;
|
||||
}
|
||||
|
||||
//compile fragment shader
|
||||
fragmentid = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragmentid, 1, &fSource, NULL);
|
||||
glCompileShader(fragmentid);
|
||||
|
||||
glGetShaderiv(fragmentid, GL_COMPILE_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetShaderInfoLog(fragmentid, 512, NULL, infoLog);
|
||||
std::cout << "FRAGMENT SHADER COMPILE ERROR\n" << infoLog << std::endl;
|
||||
}
|
||||
|
||||
//create and link program with compiled shaders
|
||||
ID = glCreateProgram();
|
||||
glAttachShader(ID, vertexid);
|
||||
glAttachShader(ID, fragmentid);
|
||||
glLinkProgram(ID);
|
||||
|
||||
glGetProgramiv(ID, GL_LINK_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetProgramInfoLog(ID, 512, NULL, infoLog);
|
||||
std::cout << "PROGRAM LINKER ERROR\n" << infoLog << std::endl;
|
||||
}
|
||||
|
||||
glDeleteShader(vertexid);
|
||||
glDeleteShader(fragmentid);
|
||||
}
|
||||
|
||||
void Shader::setFloat(const std::string& name, float value)
|
||||
{
|
||||
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
|
||||
}
|
||||
|
||||
void Shader::setInt(const std::string& name, int value)
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
|
||||
}
|
||||
|
||||
void Shader::setBool(const std::string& name, bool value)
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
|
||||
}
|
||||
|
||||
void Shader::setMatrix4f(const std::string& name, const float* value)
|
||||
{
|
||||
GLuint loc = glGetUniformLocation(ID, name.c_str());
|
||||
glUniformMatrix4fv(loc, 1, GL_FALSE, value);
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
{
|
||||
glDeleteProgram(ID);
|
||||
}
|
||||
264
YuppleMayham/src/graphics/sprite.cpp
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
#include "../../graphics/sprite.h"
|
||||
#include "../../graphics/texture.h"
|
||||
#include "../../util.h"
|
||||
#include "../../utility/events.h"
|
||||
|
||||
SpriteStatic::SpriteStatic(const char* texturePath)
|
||||
{
|
||||
EBO = 0, VBO = 0, VAO = 0;
|
||||
texture = new Texture();
|
||||
texture->loadTexture(texturePath);
|
||||
if (texture)
|
||||
setupSprite();
|
||||
}
|
||||
|
||||
void SpriteStatic::setupSprite()
|
||||
{
|
||||
// Assigning vertex data
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
||||
|
||||
// Position
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
// Texture Coordinates
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Sprite::bind()
|
||||
{
|
||||
if (texture)
|
||||
texture->bind();
|
||||
}
|
||||
|
||||
void SpriteStatic::draw()
|
||||
{
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
SpriteStatic::~SpriteStatic()
|
||||
{
|
||||
delete texture;
|
||||
glDeleteBuffers(1, &VBO);
|
||||
glDeleteBuffers(1, &EBO);
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
}
|
||||
|
||||
SpriteAnimated::SpriteAnimated(const char* textureAtlasPath, float frameSize)
|
||||
{
|
||||
EBO = 0;
|
||||
texture = new Texture();
|
||||
texture->loadTexture(textureAtlasPath);
|
||||
if (texture)
|
||||
SetupAnimated(frameSize);
|
||||
}
|
||||
|
||||
void SpriteAnimated::SetupAnimated(float frameSize)
|
||||
{
|
||||
int width = texture->getWidth();
|
||||
int height = texture->getHeight();
|
||||
float frameRows = height / frameSize;
|
||||
float frameCols = width / frameSize;
|
||||
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
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, VBO;
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, 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_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
ids.push_back({ VAO, VBO });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteAnimated::draw()
|
||||
{
|
||||
if (isPlaying)
|
||||
{
|
||||
Uint32 currentTime = SDL_GetTicks();
|
||||
if (currentTime - lastFrameTick >= 1000.f / FPS)
|
||||
{
|
||||
if (++currentFrame > ids.size() - 1)
|
||||
currentFrame = 0;
|
||||
lastFrameTick = currentTime;
|
||||
}
|
||||
glBindVertexArray(ids[currentFrame].VAO);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindVertexArray(ids[0].VAO);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteAnimated::play() { isPlaying = true; }
|
||||
void SpriteAnimated::idle() { isPlaying = false; }
|
||||
|
||||
SpriteAnimated::~SpriteAnimated()
|
||||
{
|
||||
delete texture;
|
||||
glDeleteBuffers(1, &EBO);
|
||||
for (VertexIDs idSet : ids)
|
||||
{
|
||||
glDeleteBuffers(1, &idSet.VBO);
|
||||
glDeleteVertexArrays(1, &idSet.VAO);
|
||||
}
|
||||
}
|
||||
|
||||
SpriteDirectionalAnimated::SpriteDirectionalAnimated(const char* textureAtlas, float frameSize)
|
||||
{
|
||||
texture = new Texture();
|
||||
texture->loadTexture(textureAtlas);
|
||||
if (texture)
|
||||
Setup(frameSize);
|
||||
}
|
||||
|
||||
void SpriteDirectionalAnimated::Setup(float frameSize)
|
||||
{
|
||||
int width = texture->getWidth();
|
||||
int height = texture->getHeight();
|
||||
int frameRows = height / frameSize;
|
||||
int frameCols = width / frameSize;
|
||||
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
for (int row = 0; row < frameRows; row++)
|
||||
{
|
||||
for (int col = 0; col < frameCols; col++)
|
||||
{
|
||||
Direction dir;
|
||||
// top of the spritesheet is the entities idle directions
|
||||
// then each row is a 4 frame walk cycle of each direction
|
||||
if (row == 0) dir = (Direction)(col + 1);
|
||||
else dir = (Direction)(row);
|
||||
|
||||
float left = (col) * (frameSize / width);
|
||||
float right = (col + 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, VBO;
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, 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_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
if (row == 0)
|
||||
idleIDs.emplace(std::pair<Direction, VertexIDs>(dir, { VAO, VBO }));
|
||||
else
|
||||
walkingIDs[dir].push_back({ VAO, VBO });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteDirectionalAnimated::draw()
|
||||
{
|
||||
if (isPlaying)
|
||||
{
|
||||
Uint32 currentTime = SDL_GetTicks();
|
||||
if (currentTime - lastFrameTick >= 1000.f / FPS)
|
||||
{
|
||||
if (++currentFrame > walkingIDs[direction].size() - 1)
|
||||
currentFrame = 0;
|
||||
lastFrameTick = currentTime;
|
||||
}
|
||||
glBindVertexArray(walkingIDs[direction][currentFrame].VAO);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindVertexArray(idleIDs[direction].VAO);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteDirectionalAnimated::play() { isPlaying = true; }
|
||||
void SpriteDirectionalAnimated::idle() { isPlaying = false; }
|
||||
|
||||
SpriteDirectionalAnimated::~SpriteDirectionalAnimated()
|
||||
{
|
||||
delete texture;
|
||||
glDeleteBuffers(1, &EBO);
|
||||
auto deleteBuffers = [](std::pair<Direction, VertexIDs> item) {
|
||||
glDeleteBuffers(1, &item.second.VBO);
|
||||
glDeleteVertexArrays(1, &item.second.VAO);
|
||||
};
|
||||
auto deleteBufferList = [](std::pair <Direction, std::vector<VertexIDs>> items) {
|
||||
for (VertexIDs v : items.second) {
|
||||
glDeleteBuffers(1, &v.VBO);
|
||||
glDeleteVertexArrays(1, &v.VAO);
|
||||
}
|
||||
};
|
||||
std::for_each(idleIDs.begin(), idleIDs.end(), deleteBuffers);
|
||||
std::for_each(walkingIDs.begin(), walkingIDs.end(), deleteBufferList);
|
||||
idleIDs.clear();
|
||||
walkingIDs.clear();
|
||||
}
|
||||
51
YuppleMayham/src/graphics/texture.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include "../../graphics/texture.h"
|
||||
#include "../../util.h"
|
||||
|
||||
#include <SDL_image.h>
|
||||
#include <iostream>
|
||||
#include <glad/glad.h>
|
||||
|
||||
bool Texture::loadTexture(const char* imagePath)
|
||||
{
|
||||
SDL_Surface* buffer = IMG_Load(imagePath);
|
||||
if (!buffer)
|
||||
{
|
||||
std::cout << "Failed to load image file: " << imagePath << std::endl;
|
||||
return false;
|
||||
}
|
||||
//UTIL::flip_surface(buffer);
|
||||
|
||||
glGenTextures(1, &ID);
|
||||
GLenum error = glGetError();
|
||||
if(error != GL_NO_ERROR) {
|
||||
std::cout << "OpenGL error: " << error << std::endl;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
textureWidth = buffer->w;
|
||||
textureHeight = buffer->h;
|
||||
|
||||
SDL_FreeSurface(buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Texture::bind()
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, ID);
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
glDeleteTextures(1, &ID);
|
||||
}
|
||||
80
YuppleMayham/src/graphics/tile.cpp
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#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);
|
||||
}
|
||||
}
|
||||
65
YuppleMayham/src/main.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// TODO: Fix circular dependency issues, mostly with input.h needing gameactor.h and command.h
|
||||
#include "../gameplay/game.h"
|
||||
|
||||
const float vertices[] = {
|
||||
0.0f, 0.5f, 0.0f,
|
||||
-0.5f, -0.5f, 0.0f,
|
||||
0.5f, -0.5f, 0.0f
|
||||
};
|
||||
|
||||
int main(int argc, char* args[])
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||
return -1;
|
||||
if (IMG_Init(IMG_INIT_PNG) < 0)
|
||||
return -1;
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
|
||||
Game* game = new Game();
|
||||
if (!game->init())
|
||||
{
|
||||
std::cout << "Failed to init game!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!game->loadDebugScene())
|
||||
{
|
||||
std::cout << "Failed to load debug scene!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_Event e;
|
||||
Uint64 lastCounter = SDL_GetPerformanceCounter();
|
||||
double freq = static_cast<double>(SDL_GetPerformanceFrequency());
|
||||
while (game->getGameState() & GAME_RUNNING)
|
||||
{
|
||||
Uint64 curCounter = SDL_GetPerformanceCounter();
|
||||
float deltaTime = ((curCounter - lastCounter) / freq);
|
||||
deltaTime = (deltaTime < 10.f) ? deltaTime : 1.f;
|
||||
SDL_PollEvent(&e);
|
||||
if (e.type == SDL_QUIT)
|
||||
game->quit();
|
||||
|
||||
game->handleInput(e);
|
||||
|
||||
game->update(deltaTime);
|
||||
|
||||
game->render();
|
||||
lastCounter = curCounter;
|
||||
|
||||
}
|
||||
|
||||
IMG_Quit();
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
25
YuppleMayham/src/util.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include "../util.h"
|
||||
|
||||
namespace UTIL
|
||||
{
|
||||
void flip_surface(SDL_Surface* surface)
|
||||
{
|
||||
SDL_LockSurface(surface);
|
||||
|
||||
int pitch = surface->pitch;
|
||||
char* temp = new char[pitch];
|
||||
char* pixels = (char*)surface->pixels;
|
||||
|
||||
for (int i = 0; i < surface->h / 2; i++)
|
||||
{
|
||||
char* row1 = pixels + i * pitch;
|
||||
char* row2 = pixels + (surface->h - i - 1) * pitch;
|
||||
|
||||
SDL_memcpy(temp, row1, pitch);
|
||||
SDL_memcpy(row1, row2, pitch);
|
||||
SDL_memcpy(row2, temp, pitch);
|
||||
}
|
||||
delete[] temp;
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
}
|
||||
16
YuppleMayham/src/utility/command.cpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#include "../../utility/command.h"
|
||||
#include "../../gameplay/gameactor.h"
|
||||
|
||||
//void LambdaCommand::execute(GameActor& actor) { func(actor); }
|
||||
|
||||
void MoveUpCommand::execute(GameActor& actor) { actor.moveUp(); }
|
||||
void MoveDownCommand::execute(GameActor& actor) { actor.moveDown(); }
|
||||
void MoveLeftCommand::execute(GameActor& actor) { actor.moveLeft(); }
|
||||
void MoveRightCommand::execute(GameActor& actor) { actor.moveRight(); }
|
||||
void MoveForwardCommand::execute(GameActor& actor) { actor.moveForward(); }
|
||||
void MoveBackwardCommand::execute(GameActor& actor) { actor.moveBackward(); }
|
||||
void StrafeLeftCommand::execute(GameActor& actor) { actor.strafeLeft(); }
|
||||
void StrafeRightCommand::execute(GameActor& actor) { actor.strafeRight(); }
|
||||
void ShootCommand::execute(GameActor& actor, const MouseState& mouse_state) { actor.fireWeapon(); }
|
||||
|
||||
void FollowMouseCommand::execute(GameActor& actor, const MouseState& mouse_state) { actor.followMouse(mouse_state); }
|
||||
113
YuppleMayham/src/utility/debugdraw.cpp
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#include "../../utility/debugdraw.h"
|
||||
|
||||
Circle::Circle(const glm::vec3& position, float radius)
|
||||
{
|
||||
this->radius = radius;
|
||||
float vertex[4] = {
|
||||
position.x, position.y, position.z, radius
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), &vertex, GL_DYNAMIC_DRAW);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
|
||||
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
setMVP(glm::mat4(1.f));
|
||||
setColor(glm::vec4(1.f, 0.0f, 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
void Circle::updatePosition(const glm::vec3& position)
|
||||
{
|
||||
float vertex[4] = {
|
||||
position.x, position.y, position.z, radius
|
||||
};
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
float* ptr = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||
if (ptr)
|
||||
{
|
||||
for (int i = 0; i < sizeof(vertex) / sizeof(float); i++)
|
||||
{
|
||||
ptr[i] = vertex[i];
|
||||
}
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void Circle::draw()
|
||||
{
|
||||
glBindVertexArray(VAO);
|
||||
glPointSize(2.0f);
|
||||
glDrawArraysInstanced(GL_POINTS, 0, 1, 360);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
Circle::~Circle()
|
||||
{
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
glDeleteBuffers(1, &VBO);
|
||||
}
|
||||
|
||||
Line::Line(glm::vec3 start, glm::vec3 end)
|
||||
{
|
||||
float vertices[] = {
|
||||
start.x, start.y, start.z,
|
||||
end.x, end.y, end.z
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_DYNAMIC_DRAW);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
color = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void Line::updateVertices(const glm::vec3& origin, const glm::vec3& target)
|
||||
{
|
||||
float vertices[] = {
|
||||
origin.x, origin.y, origin.z,
|
||||
target.x, target.y, target.z
|
||||
};
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
float* ptr = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||
if (ptr)
|
||||
{
|
||||
for (int i = 0; i < sizeof(vertices) / sizeof(vertices[0]); i++)
|
||||
{
|
||||
ptr[i] = vertices[i];
|
||||
}
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void Line::draw()
|
||||
{
|
||||
glBindVertexArray(VAO);
|
||||
glLineWidth(2.0f);
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
Line::~Line()
|
||||
{
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
glDeleteBuffers(1, &VBO);
|
||||
}
|
||||
221
YuppleMayham/src/utility/ftfont.cpp
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
#include "../../utility/ftfont.h"
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
Text::Text()
|
||||
{
|
||||
const char* vertexShader = R"(
|
||||
#version 330 core
|
||||
layout (location = 0) in vec4 vertex;
|
||||
out vec2 texCoords;
|
||||
uniform mat4 projection;
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
|
||||
texCoords = vertex.zw;
|
||||
}
|
||||
)";
|
||||
const char* fragShader = R"(
|
||||
#version 330 core
|
||||
in vec2 texCoords;
|
||||
out vec4 color;
|
||||
uniform sampler2D text;
|
||||
uniform vec4 textColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, texCoords).r);
|
||||
color = vec4(textColor) * sampled;
|
||||
}
|
||||
)";
|
||||
unsigned vertexID, fragID;
|
||||
int success;
|
||||
char log[512];
|
||||
|
||||
vertexID = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexID, 1, &vertexShader, NULL);
|
||||
glCompileShader(vertexID);
|
||||
|
||||
glGetShaderiv(vertexID, GL_COMPILE_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetShaderInfoLog(vertexID, 512, 0, log);
|
||||
std::cout << "ERROR::COMPILER VERTEX SHADER FAILED TO COMPILE: " << log << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
fragID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragID, 1, &fragShader, NULL);
|
||||
glCompileShader(fragID);
|
||||
|
||||
glGetShaderiv(fragID, GL_COMPILE_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetShaderInfoLog(fragID, 512, NULL, log);
|
||||
std::cout << "ERROR::COMPILER FRAGMENT SHADER FAILED TO COMPILE: " << log << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
programID = glCreateProgram();
|
||||
glAttachShader(programID, vertexID);
|
||||
glAttachShader(programID, fragID);
|
||||
glLinkProgram(programID);
|
||||
|
||||
glGetProgramiv(programID, GL_LINK_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetProgramInfoLog(programID, 512, NULL, log);
|
||||
std::cout << "ERROR::LINKER FAILED: " << log << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
colorPos = glGetUniformLocation(programID, "textColor");
|
||||
projPos = glGetUniformLocation(programID, "projection");
|
||||
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
bool Text::loadFonts(const std::string& font_folder)
|
||||
{
|
||||
FT_Library ft;
|
||||
if (FT_Init_FreeType(&ft))
|
||||
{
|
||||
std::cout << "ERROR::FREETYPE Failed to init freetype library" << std::endl;
|
||||
return false;
|
||||
}
|
||||
// load every font in the fonts folder then create corresponding textures for each character of each font.
|
||||
std::filesystem::path folder(font_folder);
|
||||
for (auto& file : std::filesystem::directory_iterator(folder))
|
||||
{
|
||||
if (!file.path().has_extension() || !file.path().has_filename() || !file.exists() || file.is_directory())
|
||||
continue;
|
||||
FT_Face face;
|
||||
if (FT_New_Face(ft, file.path().string().c_str(), 0, &face))
|
||||
{
|
||||
std::cout << "ERROR::FREETYPE Failed to load font: " << file.path().string() << std::endl;
|
||||
continue;
|
||||
}
|
||||
FT_Set_Pixel_Sizes(face, 0, 48);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
Font f;
|
||||
|
||||
for (int c = 0; c < 128; c++)
|
||||
{
|
||||
if (FT_Load_Char(face, c, FT_LOAD_RENDER))
|
||||
{
|
||||
std::cout << "ERROR::FREETYPE Failed to load glyph ( " << (char)c << " )" << std::endl;
|
||||
continue;
|
||||
}
|
||||
unsigned int texture;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RED,
|
||||
face->glyph->bitmap.width,
|
||||
face->glyph->bitmap.rows,
|
||||
0,
|
||||
GL_RED,
|
||||
GL_UNSIGNED_BYTE,
|
||||
face->glyph->bitmap.buffer
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
Font::Character character = {
|
||||
texture,
|
||||
glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
|
||||
glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
|
||||
face->glyph->advance.x
|
||||
};
|
||||
f.characters.emplace(std::pair<char, Font::Character>(c, character));
|
||||
}
|
||||
fonts.emplace(std::pair<std::string, Font>(file.path().filename().string(), f));
|
||||
FT_Done_Face(face);
|
||||
}
|
||||
FT_Done_FreeType(ft);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Text::DrawText(
|
||||
const std::string& fontName,
|
||||
const std::string& text,
|
||||
const glm::vec2& position,
|
||||
float scale,
|
||||
const glm::vec4& color)
|
||||
{
|
||||
auto iterator = fonts.find(fontName);
|
||||
if (iterator == fonts.end())
|
||||
{
|
||||
std::cout << "ERROR: Font: " << fontName << " not found!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
float x = position.x;
|
||||
float y = position.y;
|
||||
|
||||
glUseProgram(programID);
|
||||
glUniformMatrix4fv(projPos, 1, GL_FALSE, glm::value_ptr(projMatrix));
|
||||
glUniform4fv(colorPos, 1, glm::value_ptr(color));
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
std::string::const_iterator c;
|
||||
for (c = text.begin(); c != text.end(); c++)
|
||||
{
|
||||
Font::Character ch = iterator->second.characters[*c];
|
||||
|
||||
float xpos = x + ch.Bearing.x * scale;
|
||||
float ypos = y - (ch.Size.y - ch.Bearing.y) * scale;
|
||||
|
||||
float w = ch.Size.x * scale;
|
||||
float h = ch.Size.y * scale;
|
||||
|
||||
float vertices[6][4] = {
|
||||
{ xpos, ypos + h, 0.0f, 0.0f },
|
||||
{ xpos, ypos, 0.0f, 1.0f },
|
||||
{ xpos + w, ypos, 1.0f, 1.0f },
|
||||
|
||||
{ xpos, ypos + h, 0.0f, 0.0f },
|
||||
{ xpos + w, ypos, 1.0f, 1.0f },
|
||||
{ xpos + w, ypos + h, 1.0f, 0.0f }
|
||||
};
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
x += (ch.Advance >> 6) * scale;
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// Too lazy to fix rn
|
||||
void Text::DrawTextOutline(
|
||||
const std::string& fontName,
|
||||
const std::string& text,
|
||||
const glm::vec2& position,
|
||||
float scale,
|
||||
const glm::vec4& color)
|
||||
{
|
||||
DrawText("comicbd.ttf", text, position, scale, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
DrawText(fontName, text, position, scale, color);
|
||||
}
|
||||
89
YuppleMayham/src/utility/resourcemanager.cpp
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
#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 "../../gameplay/weapons/weapons.h"
|
||||
|
||||
std::shared_ptr<Sprite> ResourceManager::loadSpriteAnimated(const std::string& path, float frameSize)
|
||||
{
|
||||
auto iterator = sprites.find(path);
|
||||
if (iterator != sprites.end())
|
||||
return iterator->second;
|
||||
auto sprite = std::make_shared<SpriteAnimated>(path.c_str(), frameSize);
|
||||
sprites[path] = sprite;
|
||||
return sprite;
|
||||
}
|
||||
|
||||
std::shared_ptr<Sprite> ResourceManager::loadSpriteDirAnimated(const std::string& path, float frameSize)
|
||||
{
|
||||
return std::make_shared<SpriteDirectionalAnimated>(path.c_str(), frameSize);
|
||||
}
|
||||
|
||||
std::shared_ptr<Sprite> ResourceManager::loadSpriteStatic(const std::string& path)
|
||||
{
|
||||
auto iterator = sprites.find(path);
|
||||
if (iterator != sprites.end())
|
||||
return iterator->second;
|
||||
auto sprite = std::make_shared<SpriteStatic>(path.c_str());
|
||||
sprites[path] = sprite;
|
||||
return sprite;
|
||||
}
|
||||
|
||||
std::shared_ptr<Script> ResourceManager::loadScript(const std::string& path)
|
||||
{
|
||||
return std::make_shared<Script>(path.c_str());
|
||||
}
|
||||
|
||||
std::shared_ptr<TileSet> ResourceManager::loadTileSet(const std::string& path, float frameSize)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
std::shared_ptr<Shader> ResourceManager::loadShader(const std::string& name, const std::string& vertexPath, const std::string& fragPath)
|
||||
{
|
||||
auto iterator = shaders.find(name);
|
||||
if (iterator != shaders.end())
|
||||
return iterator->second;
|
||||
auto shader = std::make_shared<Shader>(vertexPath.c_str(), fragPath.c_str());
|
||||
shaders[name] = shader;
|
||||
return shader;
|
||||
}
|
||||
|
||||
std::shared_ptr<Weapon> ResourceManager::loadWeapon(const std::string& name, std::shared_ptr<Shader> weaponShader, std::shared_ptr<Shader> shader)
|
||||
{
|
||||
return std::make_shared<Weapon>(xmlLoader->getWeaponDataByName(name.c_str()), weaponShader, shader, this);
|
||||
}
|
||||
|
||||
std::shared_ptr<SceneData> ResourceManager::loadScene(const std::string& id)
|
||||
{
|
||||
return xmlLoader->getSceneData(id);
|
||||
}
|
||||
|
||||
// this will need some work, but for now where there is only one weapon type we can work with it
|
||||
// TODO: Allow different weapon types!
|
||||
/*
|
||||
template <typename T>
|
||||
std::shared_ptr<T> ResourceManager::loadWeapon(const std::string& name, std::shared_ptr<Shader> shader, std::shared_ptr<SpriteComponent> spriteComponent)
|
||||
{
|
||||
auto iterator = weapons.find(name);
|
||||
if (iterator != weapons.end())
|
||||
return iterator->second;
|
||||
auto weapon = std::make_shared<T>(T(shader, spriteComponent));
|
||||
weapons[name] = weapon;
|
||||
return weapon;
|
||||
}
|
||||
*/
|
||||
void ResourceManager::clearResources()
|
||||
{
|
||||
sprites.clear();
|
||||
shaders.clear();
|
||||
weapons.clear();
|
||||
}
|
||||
51
YuppleMayham/src/utility/script.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include "../../utility/script.h"
|
||||
#include "../../gameplay/gameactor.h"
|
||||
#include "../../gameplay/physics.h"
|
||||
#include "../../gameplay/ai.h"
|
||||
#include "../../utility/raycaster.h"
|
||||
|
||||
void Script::registerUserTypes()
|
||||
{
|
||||
lua.new_usertype<glm::vec3>("vec3",
|
||||
sol::constructors<glm::vec3(), glm::vec3(float, float, float)>(),
|
||||
"x", &glm::vec3::x,
|
||||
"y", &glm::vec3::y,
|
||||
"z", &glm::vec3::z);
|
||||
lua["AIState"] = lua.create_table_with(
|
||||
"Idle", AIState::Idle,
|
||||
"Patrol", AIState::Patrol,
|
||||
"Alert", AIState::Alert
|
||||
);
|
||||
lua.new_usertype<AI>("AI",
|
||||
"state", sol::property(&AI::getState, &AI::setState));
|
||||
lua.new_usertype<Raycaster>("Raycaster",
|
||||
"performRaycast", &Raycaster::performRaycast,
|
||||
"bresenhamRaycast", &Raycaster::bresenhamRaycast,
|
||||
"distFromWall", &Raycaster::getDistanceFromWall,
|
||||
"tileSize", &Raycaster::getTileSize);
|
||||
lua.new_usertype<GameActor>("GameActor",
|
||||
// properties
|
||||
"position", sol::property(&GameActor::getCenter, &GameActor::setPosition),
|
||||
"rotation", sol::property(&GameActor::getRotation, &GameActor::setRotation),
|
||||
// methods
|
||||
"moveUp", &GameActor::moveUp,
|
||||
"moveDown", &GameActor::moveDown,
|
||||
"moveLeft", &GameActor::moveLeft,
|
||||
"moveRight", &GameActor::moveRight,
|
||||
"moveForward", &GameActor::moveForward,
|
||||
"shoot", &GameActor::fireWeapon,
|
||||
"physics", &GameActor::getPhysicsComponent);
|
||||
lua.new_usertype<PhysicsComponent>("PhysicsComponent",
|
||||
"rigidBody", &PhysicsComponent::rigidBody);
|
||||
lua.new_usertype<PhysicsComponent::RigidBody>("RigidBody",
|
||||
"mass", &PhysicsComponent::RigidBody::mass,
|
||||
"veloctiy", &PhysicsComponent::RigidBody::velocity,
|
||||
"applyForce", &PhysicsComponent::RigidBody::applyForce);
|
||||
}
|
||||
|
||||
Script::Script(const std::string& path)
|
||||
{
|
||||
lua.open_libraries(sol::lib::base, sol::lib::math);
|
||||
registerUserTypes();
|
||||
loadScript(path);
|
||||
}
|
||||
277
YuppleMayham/src/utility/xmlloader.cpp
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
#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;
|
||||
}
|
||||
|
||||
bool XMLLoader::loadScenes(const char* sceneFolder)
|
||||
{
|
||||
std::filesystem::path folder(sceneFolder);
|
||||
for (auto& file : std::filesystem::directory_iterator(folder))
|
||||
{
|
||||
if (!file.path().has_extension() || !file.path().has_filename() || !file.exists() || file.is_directory())
|
||||
continue;
|
||||
SceneData scene;
|
||||
if (!loadXmlScene((const char*)file.path().string().c_str(), &scene))
|
||||
continue;
|
||||
scenes.try_emplace(scene.id, std::make_shared<SceneData>(scene));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XMLLoader::loadXmlScene(const char* xmlFile, SceneData* out)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
if (doc.LoadFile(xmlFile) != tinyxml2::XML_SUCCESS)
|
||||
return false;
|
||||
tinyxml2::XMLElement* scene = doc.FirstChildElement("scene");
|
||||
|
||||
const char* type, * id;
|
||||
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))
|
||||
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;
|
||||
}
|
||||
|
||||
bool XMLLoader::loadEntityData(const char* xmlFile, SceneData* out)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
if (doc.LoadFile(xmlFile) != tinyxml2::XML_SUCCESS)
|
||||
return false;
|
||||
|
||||
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;
|
||||
int x, y;
|
||||
float frameSize = 64.f;
|
||||
bool isDirectional = false;
|
||||
const char* spritePath, * weaponName = "pistolGun";
|
||||
if (playerElement->QueryIntAttribute("x", &x) != tinyxml2::XML_SUCCESS ||
|
||||
playerElement->QueryIntAttribute("y", &y) != tinyxml2::XML_SUCCESS)
|
||||
return false;
|
||||
playerElement->QueryStringAttribute("weapon", &weaponName);
|
||||
tinyxml2::XMLElement* sprite = playerElement->FirstChildElement("sprite");
|
||||
if (sprite == NULL)
|
||||
return false;
|
||||
if (sprite->QueryStringAttribute("file", &spritePath) != tinyxml2::XML_SUCCESS)
|
||||
return false;
|
||||
sprite->QueryFloatAttribute("framesize", &frameSize);
|
||||
sprite->QueryBoolAttribute("directional", &isDirectional);
|
||||
out->entities.push_back({ true, x, y, spritePath, frameSize, weaponName, "", isDirectional});
|
||||
|
||||
// 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"))
|
||||
{
|
||||
int x, y;
|
||||
float frameSize = 64.f;
|
||||
const char* spritePath, * weaponName = "pistolGun", * scriptPath;
|
||||
bool isDirectional = false;
|
||||
if (e->QueryIntAttribute("x", &x) != tinyxml2::XML_SUCCESS ||
|
||||
e->QueryIntAttribute("y", &y) != tinyxml2::XML_SUCCESS)
|
||||
return false;
|
||||
e->QueryStringAttribute("weapon", &weaponName);
|
||||
tinyxml2::XMLElement* sprite = e->FirstChildElement("sprite");
|
||||
if (sprite == NULL)
|
||||
return false;
|
||||
if (sprite->QueryStringAttribute("file", &spritePath) != tinyxml2::XML_SUCCESS)
|
||||
return false;
|
||||
sprite->QueryFloatAttribute("frameSize", &frameSize);
|
||||
sprite->QueryBoolAttribute("directional", &isDirectional);
|
||||
tinyxml2::XMLElement* script = e->FirstChildElement("script");
|
||||
if (script == NULL || script->QueryStringAttribute("file", &scriptPath))
|
||||
{
|
||||
out->entities.push_back({ false, x, y, spritePath, frameSize, weaponName, "", isDirectional });
|
||||
continue;
|
||||
}
|
||||
out->entities.push_back({ false, x, y, spritePath, frameSize, weaponName, scriptPath, isDirectional });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float getFloatIfExists(tinyxml2::XMLElement* e)
|
||||
{
|
||||
float buf = 0.f;
|
||||
if (e)
|
||||
{
|
||||
e->QueryFloatText(&buf);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
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;
|
||||
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* guns = doc.FirstChildElement("weapons");
|
||||
if (guns == NULL)
|
||||
continue;
|
||||
|
||||
for (tinyxml2::XMLElement* weapon = guns->FirstChildElement("weapon"); weapon != NULL; weapon = weapon->NextSiblingElement("weapon"))
|
||||
{
|
||||
// populate weapon data into this temp buffer, then push it into our list of weapons
|
||||
WeaponData data;
|
||||
const char* name, * sprite, * bulletSprite;
|
||||
// Getting top level weapon data, attribs in the weapon Node
|
||||
if (weapon->QueryStringAttribute("name", &name) != tinyxml2::XML_SUCCESS)
|
||||
continue;
|
||||
weapon->QueryFloatAttribute("fireSpeed", &data.fireSpeed);
|
||||
// Getting weapon sprite information, held in the sprite node
|
||||
tinyxml2::XMLElement* wepSprite = weapon->FirstChildElement("sprite");
|
||||
if (wepSprite)
|
||||
{
|
||||
wepSprite->QueryStringAttribute("file", &sprite);
|
||||
wepSprite->QueryBoolAttribute("animated", &data.animated);
|
||||
if (data.animated)
|
||||
wepSprite->QueryFloatAttribute("frameSize", &data.frameSize);
|
||||
if (wepSprite->ChildElementCount() != 0)
|
||||
{
|
||||
tinyxml2::XMLElement* size = wepSprite->FirstChildElement("size");
|
||||
size->QueryFloatAttribute("x", &data.sizeX);
|
||||
size->QueryFloatAttribute("y", &data.sizeY);
|
||||
tinyxml2::XMLElement* offset = wepSprite->FirstChildElement("offset");
|
||||
offset->QueryFloatAttribute("x", &data.offsetX);
|
||||
offset->QueryFloatAttribute("y", &data.offsetY);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If we don't have a sprite element, default to pistol
|
||||
sprite = "sprites/pistolAtlas256.png";
|
||||
data.animated = true;
|
||||
data.frameSize = 256.f;
|
||||
data.sizeX = 30.f;
|
||||
data.sizeY = 30.f;
|
||||
}
|
||||
// getting bullet information held in the bullet node and each child node held therein
|
||||
tinyxml2::XMLElement* bullet = weapon->FirstChildElement("bullet");
|
||||
|
||||
if (bullet->QueryStringAttribute("sprite", &bulletSprite) != tinyxml2::XML_SUCCESS ||
|
||||
bullet->QueryBoolAttribute( "animated", &data.bulletAnimated) != tinyxml2::XML_SUCCESS ||
|
||||
bullet->FirstChildElement("size")->QueryFloatAttribute("x", &data.bulletSizeX) != tinyxml2::XML_SUCCESS ||
|
||||
bullet->FirstChildElement("size")->QueryFloatAttribute("y", &data.bulletSizeY) != tinyxml2::XML_SUCCESS)
|
||||
continue;
|
||||
|
||||
data.name = name;
|
||||
data.sprite = sprite;
|
||||
data.bulletSprite = bulletSprite;
|
||||
|
||||
if (data.animated)
|
||||
if (bullet->QueryFloatAttribute("frameSize", &data.bulletFrameSize) != tinyxml2::XML_SUCCESS)
|
||||
continue;
|
||||
tinyxml2::XMLElement* spread = bullet->FirstChildElement("spread");
|
||||
tinyxml2::XMLElement* speed = bullet->FirstChildElement("speed");
|
||||
tinyxml2::XMLElement* drop = bullet->FirstChildElement("drop");
|
||||
tinyxml2::XMLElement* modifier = bullet->FirstChildElement("modifier");
|
||||
if (spread)
|
||||
spread->QueryFloatText(&data.bulletSpread);
|
||||
if (speed)
|
||||
speed->QueryFloatText(&data.bulletSpeed);
|
||||
if (drop)
|
||||
drop->QueryFloatText(&data.bulletDrop);
|
||||
if (modifier)
|
||||
{
|
||||
modifier->QueryFloatAttribute("min", &data.modMin);
|
||||
modifier->QueryFloatAttribute("max", &data.modMax);
|
||||
}
|
||||
|
||||
weaponData.push_back(data);
|
||||
}
|
||||
}
|
||||
return (!weaponData.empty());
|
||||
}
|
||||
26
YuppleMayham/util.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef _H_UTIL_H
|
||||
#define _H_UTIL_H
|
||||
|
||||
#include <SDL_video.h>
|
||||
#include <random>
|
||||
|
||||
namespace UTIL
|
||||
{
|
||||
void flip_surface(SDL_Surface* surface);
|
||||
|
||||
class RandomGenerator
|
||||
{
|
||||
public:
|
||||
RandomGenerator(float min, float max) :
|
||||
rd(),
|
||||
gen(rd()),
|
||||
dist(min, max) {};
|
||||
float genFloat() { return dist(gen); }
|
||||
private:
|
||||
std::random_device rd;
|
||||
std::mt19937 gen;
|
||||
std::uniform_real_distribution<float> dist;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _H_UTIL_H
|
||||
102
YuppleMayham/utility/command.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#ifndef _H_COMMAND_H
|
||||
#define _H_COMMAND_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "../gameplay/mousestate.h"
|
||||
|
||||
class GameActor;
|
||||
|
||||
class Command
|
||||
{
|
||||
public:
|
||||
virtual ~Command() { }
|
||||
virtual void execute(GameActor& actor) = 0;
|
||||
};
|
||||
|
||||
class MouseCommand
|
||||
{
|
||||
public:
|
||||
virtual ~MouseCommand() { }
|
||||
virtual void execute(GameActor& actor, const MouseState& mouse_state) = 0;
|
||||
};
|
||||
|
||||
class LambdaCommand : public Command
|
||||
{
|
||||
public:
|
||||
LambdaCommand(std::function<void(GameActor&)> func) : func(func) {};
|
||||
void execute(GameActor& actor) override { func(actor); }
|
||||
private:
|
||||
std::function<void(GameActor&)> func;
|
||||
};
|
||||
|
||||
class MoveUpCommand : public Command
|
||||
{
|
||||
public:
|
||||
MoveUpCommand() {}
|
||||
void execute(GameActor& actor) override;
|
||||
};
|
||||
|
||||
class MoveDownCommand : public Command
|
||||
{
|
||||
public:
|
||||
MoveDownCommand() {}
|
||||
void execute(GameActor& actor) override;
|
||||
};
|
||||
|
||||
class MoveLeftCommand : public Command
|
||||
{
|
||||
public:
|
||||
MoveLeftCommand() {}
|
||||
void execute(GameActor& actor) override;
|
||||
};
|
||||
|
||||
class MoveRightCommand : public Command
|
||||
{
|
||||
public:
|
||||
MoveRightCommand() {}
|
||||
void execute(GameActor& actor) override;
|
||||
};
|
||||
|
||||
class MoveForwardCommand : public Command
|
||||
{
|
||||
public:
|
||||
MoveForwardCommand() {}
|
||||
void execute(GameActor& actor) override;
|
||||
};
|
||||
|
||||
class MoveBackwardCommand : public Command
|
||||
{
|
||||
public:
|
||||
MoveBackwardCommand() {}
|
||||
void execute(GameActor& actor) override;
|
||||
};
|
||||
|
||||
class StrafeLeftCommand : public Command
|
||||
{
|
||||
public:
|
||||
StrafeLeftCommand() {}
|
||||
void execute(GameActor& actor) override;
|
||||
};
|
||||
|
||||
class StrafeRightCommand : public Command
|
||||
{
|
||||
public:
|
||||
StrafeRightCommand() {}
|
||||
void execute(GameActor& actor) override;
|
||||
};
|
||||
|
||||
class ShootCommand : public MouseCommand
|
||||
{
|
||||
public:
|
||||
ShootCommand() {}
|
||||
void execute(GameActor& actor, const MouseState& mouse_state) override;
|
||||
};
|
||||
|
||||
class FollowMouseCommand : public MouseCommand
|
||||
{
|
||||
public:
|
||||
void execute(GameActor& actor, const MouseState& mouse_state) override;
|
||||
};
|
||||
|
||||
#endif //_H_COMMAND_H
|
||||
123
YuppleMayham/utility/component.h
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
#ifndef _H_COMPONENT_H
|
||||
#define _H_COMPONENT_H
|
||||
|
||||
#include "../graphics/mesh.h"
|
||||
#include "../graphics/sprite.h"
|
||||
#include "../graphics/shader.h"
|
||||
#include "../gameplay/ai.h"
|
||||
#include "events.h"
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
class Component
|
||||
{
|
||||
public:
|
||||
Component(const std::shared_ptr<EventManager>& eventManager) : eventManager(eventManager) {}
|
||||
virtual ~Component() {};
|
||||
virtual void bind() = 0;
|
||||
virtual void update() = 0;
|
||||
virtual void render() = 0;
|
||||
virtual void play() = 0;
|
||||
virtual void idle() = 0;
|
||||
|
||||
int ownerid = 0;
|
||||
std::shared_ptr<EventManager> eventManager;
|
||||
};
|
||||
|
||||
class MeshComponent : public Component
|
||||
{
|
||||
public:
|
||||
MeshComponent(Mesh* mesh, const std::shared_ptr<EventManager>& eventManager) : Component(eventManager), mesh(mesh) {};
|
||||
|
||||
void bind() override {}
|
||||
void update() override {}
|
||||
void render() override {
|
||||
if (mesh) mesh->draw();
|
||||
}
|
||||
void play() override { /*unused*/ }
|
||||
void idle() override { /*unused*/ }
|
||||
|
||||
~MeshComponent() { mesh->~Mesh(); }
|
||||
|
||||
private:
|
||||
Mesh* mesh;
|
||||
|
||||
};
|
||||
|
||||
class SpriteComponent : public Component
|
||||
{
|
||||
public:
|
||||
SpriteComponent(std::shared_ptr<Sprite> sprite) : sprite(sprite), Component(nullptr) {}
|
||||
SpriteComponent(std::shared_ptr<Sprite> sprite, const std::shared_ptr<EventManager>& eventManager) :
|
||||
Component(eventManager), sprite(sprite) {
|
||||
auto directionalSprite = std::dynamic_pointer_cast<SpriteDirectionalAnimated>(sprite);
|
||||
if (directionalSprite)
|
||||
{
|
||||
eventManager->subscribe("OnDirectionChange", [sprite, this](std::shared_ptr<Event> e) {
|
||||
auto directionEvent = std::static_pointer_cast<DirectionChangeEvent>(e);
|
||||
auto directionSprite = std::static_pointer_cast<SpriteDirectionalAnimated>(sprite);
|
||||
if (directionEvent->actorid == ownerid)
|
||||
directionSprite->setDirection(directionEvent->direction);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
void bind() override {
|
||||
if (sprite) sprite->bind();
|
||||
}
|
||||
void update() override {}
|
||||
void render() override {
|
||||
if (sprite) sprite->draw();
|
||||
}
|
||||
void play() override {
|
||||
if (sprite) sprite->play();
|
||||
}
|
||||
void idle() override {
|
||||
if (sprite) sprite->idle();
|
||||
}
|
||||
|
||||
std::shared_ptr<Sprite>& getSprite() { return sprite; }
|
||||
|
||||
~SpriteComponent() { /*sprite->~Sprite();*/ }
|
||||
|
||||
private:
|
||||
std::shared_ptr<Sprite> sprite;
|
||||
};
|
||||
|
||||
class ShaderComponent : public Component
|
||||
{
|
||||
public:
|
||||
ShaderComponent(const char* vertexPath, const char* shaderPath) :
|
||||
shader(vertexPath, shaderPath), Component(nullptr) {};
|
||||
|
||||
void bind() override {
|
||||
shader.use();
|
||||
}
|
||||
void update() override {}
|
||||
void render() override {}
|
||||
void play() override { /*unused*/ }
|
||||
void idle() override { /*unused*/ }
|
||||
|
||||
Shader& getShader() { return shader; }
|
||||
|
||||
~ShaderComponent() { }
|
||||
|
||||
private:
|
||||
Shader shader;
|
||||
};
|
||||
|
||||
class AIComponent : public Component {
|
||||
public:
|
||||
AIComponent(std::shared_ptr<AI> ai) : ai(ai), Component(nullptr) {}
|
||||
|
||||
void bind() override { /*unused*/ }
|
||||
void update() override { if (ai) ai->update(); }
|
||||
void render() override { /*unused*/ }
|
||||
void play() override { /*unused*/ }
|
||||
void idle() override { /*unused*/ }
|
||||
|
||||
private:
|
||||
std::shared_ptr<AI> ai;
|
||||
};
|
||||
|
||||
#endif // _H_COMPONENT_H
|
||||
181
YuppleMayham/utility/debugdraw.h
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
#ifndef _H_DEBUGDRAW_H
|
||||
#define _H_DEBUGDRAW_H
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct ShaderSource {
|
||||
const char* vertexShader;
|
||||
const char* fragShader;
|
||||
};
|
||||
|
||||
struct ShaderProgram {
|
||||
unsigned programID;
|
||||
//uniform locations
|
||||
unsigned u_MVP, u_Color;
|
||||
void setup(const ShaderSource& source) {
|
||||
unsigned vertexID, fragID;
|
||||
// compile vertex shader
|
||||
vertexID = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexID, 1, &source.vertexShader, NULL);
|
||||
glCompileShader(vertexID);
|
||||
// compile fragment shader
|
||||
fragID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragID, 1, &source.fragShader, NULL);
|
||||
glCompileShader(fragID);
|
||||
// link shaders to program
|
||||
programID = glCreateProgram();
|
||||
glAttachShader(programID, vertexID);
|
||||
glAttachShader(programID, fragID);
|
||||
glLinkProgram(programID);
|
||||
// delete shaders
|
||||
glDeleteShader(vertexID);
|
||||
glDeleteShader(fragID);
|
||||
// get uniform locations
|
||||
u_MVP = glGetUniformLocation(programID, "u_MVP");
|
||||
u_Color = glGetUniformLocation(programID, "u_Color");
|
||||
}
|
||||
void use () { if (programID) glUseProgram(programID); }
|
||||
void setMVP (const float* mvpPointer) { use(); glUniformMatrix4fv(u_MVP, 1, GL_FALSE, mvpPointer); }
|
||||
void setColor (const float* colorPointer) { use(); glUniform4fv(u_Color, 1, colorPointer); }
|
||||
void delShader () { glDeleteProgram(programID); }
|
||||
};
|
||||
|
||||
class Circle
|
||||
{
|
||||
private:
|
||||
unsigned VAO, VBO;
|
||||
glm::mat4 MVP;
|
||||
glm::vec4 Color;
|
||||
float radius;
|
||||
public:
|
||||
Circle(const glm::vec3& position, float radius);
|
||||
void setMVP (const glm::mat4& mvp) { MVP = mvp; }
|
||||
void setColor(const glm::vec4& color) { Color = color; }
|
||||
const glm::mat4& getMVP () const { return MVP; }
|
||||
const glm::vec4& getColor() const { return Color; }
|
||||
void draw();
|
||||
void updatePosition(const glm::vec3& position);
|
||||
~Circle();
|
||||
};
|
||||
|
||||
class Line
|
||||
{
|
||||
private:
|
||||
unsigned VAO, VBO;
|
||||
glm::vec4 color;
|
||||
public:
|
||||
Line(glm::vec3 start, glm::vec3 end);
|
||||
void setColor(glm::vec4 color) { this->color = color; }
|
||||
const glm::vec4& getColor() const { return color; }
|
||||
void draw();
|
||||
void updateVertices(const glm::vec3& origin, const glm::vec3& target);
|
||||
~Line();
|
||||
};
|
||||
|
||||
class DebugDrawer {
|
||||
public:
|
||||
static DebugDrawer& getInstance() {
|
||||
static DebugDrawer instance;
|
||||
return instance;
|
||||
}
|
||||
DebugDrawer(DebugDrawer const&) = delete;
|
||||
void operator=(DebugDrawer const&) = delete;
|
||||
|
||||
void addLine(const glm::vec3& start, const glm::vec3& end, const glm::vec4& color) {
|
||||
auto line = std::make_shared<Line>(start, end);
|
||||
line->setColor(color);
|
||||
lines.push_back(line);
|
||||
}
|
||||
|
||||
void addCircle(const glm::vec3& position, float radius, const glm::vec4& color) {
|
||||
auto circle = std::make_shared<Circle>(position, radius);
|
||||
circle->setColor(color);
|
||||
circles.push_back(circle);
|
||||
}
|
||||
|
||||
void draw(const glm::mat4& mvp) {
|
||||
lineProgram.use();
|
||||
for (auto& line : lines)
|
||||
{
|
||||
lineProgram.setMVP(glm::value_ptr(mvp));
|
||||
lineProgram.setColor(glm::value_ptr(line->getColor()));
|
||||
line->draw();
|
||||
}
|
||||
lines.clear();
|
||||
circleProgram.use();
|
||||
for (auto& circle : circles)
|
||||
{
|
||||
circleProgram.setMVP(glm::value_ptr(mvp));
|
||||
circleProgram.setColor(glm::value_ptr(circle->getColor()));
|
||||
circle->draw();
|
||||
}
|
||||
circles.clear();
|
||||
}
|
||||
~DebugDrawer() {
|
||||
lineProgram.delShader();
|
||||
circleProgram.delShader();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<Line>> lines;
|
||||
std::vector<std::shared_ptr<Circle>> circles;
|
||||
|
||||
DebugDrawer() {
|
||||
circleProgram.setup(circleSource);
|
||||
lineProgram.setup(lineSource);
|
||||
}
|
||||
|
||||
ShaderSource circleSource {
|
||||
// vertex shader program
|
||||
"#version 330 core\n"
|
||||
"layout (location = 0) in vec3 aPos;\n"
|
||||
"layout (location = 1) in float aRadius;\n"
|
||||
"uniform mat4 u_MVP;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"float angle = 2.0 * 3.14159 * float(gl_InstanceID) / 360.0;\n"
|
||||
"float x = aPos.x + cos(angle) * aRadius;\n"
|
||||
"float y = aPos.y + sin(angle) * aRadius;\n"
|
||||
"gl_Position = u_MVP * vec4(x, y, aPos.z, 1.0);\n"
|
||||
"}\0"
|
||||
,
|
||||
// fragment shader program
|
||||
"#version 330 core\n"
|
||||
"out vec4 FragColor;\n"
|
||||
"uniform vec4 u_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"FragColor = u_Color;\n"
|
||||
"}\0"
|
||||
};
|
||||
ShaderSource lineSource {
|
||||
// vertex shader
|
||||
"#version 330 core\n"
|
||||
"layout (location = 0) in vec3 aPos;\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"gl_Position = mvp * vec4(aPos, 1.0);\n"
|
||||
"}\0"
|
||||
,
|
||||
// fragment shader
|
||||
"#version 330 core\n"
|
||||
"out vec4 FragColor;\n"
|
||||
"uniform vec4 Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"FragColor = Color;\n"
|
||||
"}\0"
|
||||
};
|
||||
|
||||
ShaderProgram circleProgram;
|
||||
ShaderProgram lineProgram;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
28
YuppleMayham/utility/direction.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _H_DIRECTION_H
|
||||
#define _H_DIRECTION_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
enum class Direction {
|
||||
|
||||
Down = 1,
|
||||
Right = 2,
|
||||
Left = 3,
|
||||
Up = 4
|
||||
};
|
||||
|
||||
static Direction getDirectionFromRotation(float rotation) {
|
||||
double normalizedRot = std::fmod(rotation + 360, 360);
|
||||
if ((normalizedRot >= 337.5) || (normalizedRot < 22.5))
|
||||
return Direction::Right;
|
||||
else if ((normalizedRot >= 22.5) && (normalizedRot < 157.5))
|
||||
return Direction::Down;
|
||||
else if ((normalizedRot >= 157.5) && (normalizedRot < 247.5))
|
||||
return Direction::Left;
|
||||
else if ((normalizedRot >= 247.5) && (normalizedRot < 337.5))
|
||||
return Direction::Up;
|
||||
|
||||
return Direction::Down;
|
||||
}
|
||||
|
||||
#endif // _H_DIRECTION_H
|
||||
63
YuppleMayham/utility/events.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef _H_EVENTS_H
|
||||
#define _H_EVENTS_H
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "direction.h"
|
||||
|
||||
class Bullet;
|
||||
struct PhysicsComponent;
|
||||
|
||||
class Event {
|
||||
public:
|
||||
virtual ~Event() { };
|
||||
virtual std::string getType() const = 0;
|
||||
};
|
||||
|
||||
class BulletFiredEvent : public Event {
|
||||
public:
|
||||
BulletFiredEvent(const std::shared_ptr<Bullet>& bullet) : bullet(bullet) {};
|
||||
std::string getType() const override { return "OnBulletFired"; }
|
||||
std::shared_ptr<Bullet> bullet;
|
||||
};
|
||||
|
||||
class BulletDiedEvent : public Event {
|
||||
public:
|
||||
BulletDiedEvent(const std::shared_ptr<PhysicsComponent>& physObj) : physObj(physObj) {};
|
||||
std::string getType() const override { return "OnBulletDied"; }
|
||||
std::shared_ptr<PhysicsComponent> physObj;
|
||||
};
|
||||
|
||||
class DirectionChangeEvent : public Event {
|
||||
public:
|
||||
DirectionChangeEvent(const int actorid, Direction direction) : actorid(actorid), direction(direction) {}
|
||||
std::string getType() const override { return "OnDirectionChange"; }
|
||||
Direction direction;
|
||||
int actorid;
|
||||
};
|
||||
|
||||
class EventManager {
|
||||
public:
|
||||
using EventCallback = std::function<void(std::shared_ptr<Event>)>;
|
||||
|
||||
void subscribe(std::string eventType, EventCallback callback) {
|
||||
listeners[eventType].push_back(callback);
|
||||
}
|
||||
void notify(const std::shared_ptr<Event>& event) {
|
||||
auto iterator = listeners.find(event->getType());
|
||||
if (iterator != listeners.end())
|
||||
{
|
||||
for (auto& callback : iterator->second)
|
||||
{
|
||||
callback(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::unordered_map <std::string, std::vector <EventCallback>> listeners;
|
||||
};
|
||||
|
||||
#endif //_H_EVENTS_H
|
||||
54
YuppleMayham/utility/ftfont.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef _H_FTFONT_H
|
||||
#define _H_FTFONT_H
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#include <glm/glm.hpp>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
class Text {
|
||||
private:
|
||||
struct Font {
|
||||
struct Character {
|
||||
unsigned int TextureID;
|
||||
glm::ivec2 Size;
|
||||
glm::ivec2 Bearing;
|
||||
unsigned int Advance;
|
||||
};
|
||||
std::map<char, Character> characters;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, Font> fonts;
|
||||
unsigned int programID = 0;
|
||||
unsigned int VAO = 0, VBO = 0;
|
||||
unsigned int colorPos = 0;
|
||||
unsigned int projPos = 0;
|
||||
glm::mat4 projMatrix = glm::mat4(1.f);
|
||||
|
||||
public:
|
||||
Text();
|
||||
bool loadFonts(const std::string& font_folder);
|
||||
|
||||
void setProjectionMatrix(const glm::mat4& proj) { projMatrix = proj; }
|
||||
|
||||
void DrawText(
|
||||
const std::string& fontName,
|
||||
const std::string& text,
|
||||
const glm::vec2& position,
|
||||
float scale,
|
||||
const glm::vec4& color = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)
|
||||
);
|
||||
void DrawTextOutline(
|
||||
const std::string& fontName,
|
||||
const std::string& text,
|
||||
const glm::vec2& position,
|
||||
float scale,
|
||||
const glm::vec4& color = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)
|
||||
);
|
||||
};
|
||||
|
||||
#endif // _H_FTFONT_H
|
||||
135
YuppleMayham/utility/raycaster.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
#ifndef _H_RAYCASTER_H
|
||||
#define _H_RAYCASTER_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "debugdraw.h"
|
||||
|
||||
class Raycaster {
|
||||
public:
|
||||
Raycaster(
|
||||
float FOV,
|
||||
float viewDist,
|
||||
const std::vector<std::vector<int>>& collisionMap,
|
||||
float tileSize)
|
||||
:
|
||||
FOV(FOV),
|
||||
viewDist(viewDist),
|
||||
collisionMap(collisionMap),
|
||||
tileSize(tileSize)
|
||||
{}
|
||||
bool bresenhamRaycast(const glm::vec3& origin, const float rotation, const glm::vec3& target)
|
||||
{
|
||||
float rayAngle = rotation - (FOV / 2);
|
||||
float angleIncrement = 2.0f;
|
||||
bool hitTarget = false;
|
||||
glm::ivec2 lastEnd = glm::ivec2(0);
|
||||
for (int rayCount = 0; rayCount <= FOV / 2; rayCount++)
|
||||
{
|
||||
float endX = (origin.x + (glm::cos(glm::radians(rayAngle)) * viewDist));
|
||||
float endY = (origin.y + (glm::sin(glm::radians(rayAngle)) * viewDist));
|
||||
|
||||
glm::ivec2 targetTile= glm::ivec2(static_cast<int>(target.x / tileSize), static_cast<int>(target.y / tileSize));
|
||||
glm::ivec2 startTile = glm::ivec2(static_cast<int>((origin.x + tileSize * 0.1f) / tileSize), static_cast<int>((origin.y + tileSize * 0.1f) / tileSize));
|
||||
glm::ivec2 endTile = glm::ivec2(static_cast<int>(endX / tileSize), static_cast<int>(endY / tileSize));
|
||||
|
||||
int dx = glm::abs(endTile.x - startTile.x);
|
||||
int dy = glm::abs(endTile.y - startTile.y);
|
||||
int sx = startTile.x < endTile.x ? 1 : -1;
|
||||
int sy = startTile.y < endTile.y ? 1 : -1;
|
||||
|
||||
int err = (dx > dy ? dx : -dy) / 2;
|
||||
|
||||
glm::ivec2 step = startTile;
|
||||
|
||||
while (step != endTile)
|
||||
{
|
||||
if (step.x < 0 || step.x >= collisionMap[0].size() ||
|
||||
step.y < 0 || step.y >= collisionMap.size())
|
||||
{
|
||||
if (glm::abs(rayAngle - rotation) <= 2)
|
||||
distFromWall = distFromWall < glm::distance(glm::vec2(startTile), glm::vec2(step)) ?
|
||||
distFromWall : glm::distance(glm::vec2(startTile), glm::vec2(step));
|
||||
break;
|
||||
}
|
||||
if (collisionMap[step.y][step.x] != 0)
|
||||
{
|
||||
if (glm::abs(rayAngle - rotation) <= 2)
|
||||
distFromWall = distFromWall < glm::distance(glm::vec2(startTile), glm::vec2(step)) ?
|
||||
distFromWall : glm::distance(glm::vec2(startTile), glm::vec2(step));
|
||||
break;
|
||||
}
|
||||
if (step == targetTile)
|
||||
hitTarget = true;
|
||||
int e2 = err;
|
||||
if (e2 > -dx)
|
||||
{
|
||||
err -= dy;
|
||||
step.x += sx;
|
||||
}
|
||||
if (e2 < dy)
|
||||
{
|
||||
err += dx;
|
||||
step.y += sy;
|
||||
}
|
||||
}
|
||||
//LineDrawer::getInstance().addLine(origin, glm::vec3(step.x * tileSize, step.y * tileSize, 0.f), glm::vec4(1.0 - (1.0f / rayCount), 1.0f / rayCount, 0.0f, 0.7f));
|
||||
if (step == endTile)
|
||||
distFromWall = std::numeric_limits<float>::infinity();
|
||||
rayAngle += angleIncrement;
|
||||
}
|
||||
return hitTarget;
|
||||
}
|
||||
// We need to collision map and tile size so we can hide behind tiles
|
||||
// returns true if the raycast lands on the targets tile
|
||||
bool performRaycast(const glm::vec3& origin, const float rotation, const glm::vec3& target) {
|
||||
float rayStepSize = 0.05f;
|
||||
float rayAngle = rotation - (FOV / 2);
|
||||
float angleInc = 2.0f;
|
||||
glm::ivec2 targetTile = glm::ivec2(static_cast<int>(target.x / tileSize), static_cast<int>(target.y / tileSize));
|
||||
bool hitTarget = false;
|
||||
for (int rayCount = 0; rayCount <= FOV / 2; rayCount++)
|
||||
{
|
||||
glm::vec2 ray = glm::vec2(origin);
|
||||
while (glm::distance(ray, glm::vec2(origin)) < viewDist)
|
||||
{
|
||||
ray.x += cos(glm::radians(rayAngle)) * rayStepSize;
|
||||
ray.y += sin(glm::radians(rayAngle)) * rayStepSize;
|
||||
glm::ivec2 rayTile = glm::ivec2(static_cast<int>(ray.x / tileSize), static_cast<int>(ray.y / tileSize));
|
||||
if (rayTile.x < 0 || rayTile.x >= collisionMap[0].size() ||
|
||||
rayTile.y < 0 || rayTile.y >= collisionMap.size())
|
||||
{
|
||||
if (rayCount == FOV / 2)
|
||||
distFromWall = glm::distance(glm::vec2(origin), ray);
|
||||
break;
|
||||
}
|
||||
if (collisionMap[rayTile.y][rayTile.x] != 0)
|
||||
{
|
||||
if (rayCount == FOV / 2)
|
||||
distFromWall = glm::distance(glm::vec2(origin), ray);
|
||||
break;
|
||||
}
|
||||
if (rayTile == targetTile)
|
||||
hitTarget = true;
|
||||
}
|
||||
DebugDrawer::getInstance().addLine(origin, glm::vec3(ray.x, ray.y, 0.f), glm::vec4(1.0f, 0.0f, 0.0f, 0.2f));
|
||||
if (glm::distance(ray, glm::vec2(origin)) >= viewDist)
|
||||
distFromWall = std::numeric_limits<float>::infinity();
|
||||
rayAngle += angleInc;
|
||||
}
|
||||
return hitTarget;
|
||||
}
|
||||
float getDistanceFromWall() const { return distFromWall; }
|
||||
float getTileSize() const { return tileSize; }
|
||||
private:
|
||||
float FOV;
|
||||
float viewDist;
|
||||
float distFromWall = std::numeric_limits<float>::infinity();
|
||||
std::vector<std::vector<int>> collisionMap;
|
||||
float tileSize;
|
||||
|
||||
};
|
||||
|
||||
#endif // _H_RAYCASTER_H
|
||||
54
YuppleMayham/utility/resourcemanager.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef _H_RESOURCEMANAGER_H
|
||||
#define _H_RESOURCEMANAGER_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "../utility/xmlloader.h"
|
||||
#include <cassert>
|
||||
|
||||
class Sprite;
|
||||
class Shader;
|
||||
class Weapon;
|
||||
class Script;
|
||||
class TileSet;
|
||||
class SpriteComponent;
|
||||
|
||||
class ResourceManager
|
||||
{
|
||||
public:
|
||||
ResourceManager() :
|
||||
xmlLoader(std::make_shared<XMLLoader>())
|
||||
{
|
||||
xmlLoader->loadWeapons("weapons");
|
||||
xmlLoader->loadScenes("scenes");
|
||||
};
|
||||
|
||||
std::shared_ptr<Sprite> loadSpriteAnimated(const std::string& path, float frameSize);
|
||||
std::shared_ptr<Sprite> loadSpriteDirAnimated(const std::string& path, float frameSize);
|
||||
std::shared_ptr<Sprite> loadSpriteStatic(const std::string& path);
|
||||
std::shared_ptr<Script> loadScript(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);
|
||||
|
||||
void clearResources();
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::shared_ptr<Sprite>> sprites;
|
||||
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<EntityData>> entityData;
|
||||
//std::unordered_map<std::string, std::shared_ptr<SceneData>> scenes;
|
||||
//std::unordered_map<std::string, std::shared_ptr<MapData>> maps;
|
||||
//std::unordered_map<std::string, std::shared_ptr<TileType>> tiles;
|
||||
|
||||
std::shared_ptr<XMLLoader> xmlLoader;
|
||||
};
|
||||
|
||||
#endif // _H_RESOURCEMANAGER_H
|
||||
28
YuppleMayham/utility/script.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _H_SCRIPT_H
|
||||
#define _H_SCRIPT_H
|
||||
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
|
||||
#include <sol/sol.hpp>
|
||||
#include <memory>
|
||||
|
||||
class Script {
|
||||
public:
|
||||
sol::state lua;
|
||||
Script(const std::string& path);
|
||||
Script(const Script& script);
|
||||
virtual ~Script() {};
|
||||
private:
|
||||
bool loadScript(const std::string& path) {
|
||||
auto result = lua.script_file(path);
|
||||
if (!result.valid())
|
||||
{
|
||||
sol::error err = result;
|
||||
std::cerr << "Failed to load script ( " << path << " ) Error: " << err.what() << std::endl;
|
||||
}
|
||||
return result.valid();
|
||||
}
|
||||
void registerUserTypes();
|
||||
};
|
||||
|
||||
#endif // _H_SCRIPT_H
|
||||
81
YuppleMayham/utility/xmlloader.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#ifndef _H_XMLLOADER_H
|
||||
#define _H_XMLLOADER_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
struct Tile;
|
||||
|
||||
struct EntityData {
|
||||
bool isPlayer;
|
||||
int x = 0, y = 0;
|
||||
std::string sprite;
|
||||
float frameSize = 0.f;
|
||||
std::string weapon = "pistolGun";
|
||||
std::string script;
|
||||
bool isDirectional = false;
|
||||
};
|
||||
|
||||
struct MapData {
|
||||
std::string name;
|
||||
std::string file;
|
||||
int width = 0, height = 0;
|
||||
float tileSize = 32.f;
|
||||
std::vector<std::vector<std::shared_ptr<Tile>>> groundTiles;
|
||||
};
|
||||
|
||||
struct SceneData {
|
||||
std::string id;
|
||||
std::string type;
|
||||
|
||||
MapData map;
|
||||
std::vector<EntityData> entities;
|
||||
};
|
||||
|
||||
struct WeaponData {
|
||||
std::string name;
|
||||
float fireSpeed = 250.0f;
|
||||
std::string sprite;
|
||||
bool animated = false;
|
||||
float frameSize;
|
||||
float sizeX = 50.f, sizeY = 50.f;
|
||||
float offsetX = 0.f, offsetY = 0.f;
|
||||
float bulletFrameSize;
|
||||
float bulletSizeX = 50.f, bulletSizeY = 50.f;
|
||||
std::string bulletSprite;
|
||||
bool bulletAnimated = false;
|
||||
float bulletSpread = 1.0f, bulletSpeed = 3.0f, bulletDrop = 500.f;
|
||||
float modMin = 0.5f, modMax = 1.0f;
|
||||
};
|
||||
|
||||
class XMLLoader
|
||||
{
|
||||
public:
|
||||
XMLLoader() {}
|
||||
bool loadScenes(const char* sceneFolder);
|
||||
bool loadWeapons(const char* weaponFolder);
|
||||
|
||||
const std::shared_ptr<SceneData> getSceneData(const std::string& id) const {
|
||||
try {
|
||||
return scenes.at(id);
|
||||
}
|
||||
catch (std::exception&) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
const WeaponData* getWeaponDataByName(const char* name) const;
|
||||
|
||||
void clearData() { scenes.clear(); weaponData.clear(); }
|
||||
protected:
|
||||
bool loadXmlScene(const char* xmlFile, SceneData* out);
|
||||
bool loadMap(const char* xmlFile, SceneData* out);
|
||||
bool loadEntityData(const char* xmlFile, SceneData* out);
|
||||
private:
|
||||
std::unordered_map<std::string, std::shared_ptr<SceneData>> scenes;
|
||||
|
||||
std::vector<WeaponData> weaponData;
|
||||
};
|
||||
|
||||
#endif // _H_XMLLOADER_H
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"requests":[{"kind":"cache","version":2},{"kind":"cmakeFiles","version":1},{"kind":"codemodel","version":2},{"kind":"toolchains","version":1}]}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
{
|
||||
"inputs" :
|
||||
[
|
||||
{
|
||||
"path" : "CMakeLists.txt"
|
||||
},
|
||||
{
|
||||
"isGenerated" : true,
|
||||
"path" : "out/build/x64-debug/CMakeFiles/3.28.0-msvc1/CMakeSystem.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeSystemSpecificInitialize.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Platform/Windows-Initialize.cmake"
|
||||
},
|
||||
{
|
||||
"isGenerated" : true,
|
||||
"path" : "out/build/x64-debug/CMakeFiles/3.28.0-msvc1/CMakeCCompiler.cmake"
|
||||
},
|
||||
{
|
||||
"isGenerated" : true,
|
||||
"path" : "out/build/x64-debug/CMakeFiles/3.28.0-msvc1/CMakeCXXCompiler.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeSystemSpecificInformation.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeGenericSystem.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeInitializeConfigs.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Platform/Windows.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Platform/WindowsPaths.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeCInformation.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeLanguageInformation.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Compiler/MSVC-C.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Compiler/MSVC.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Compiler/CMakeCommonCompilerMacros.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Platform/Windows-MSVC-C.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Platform/Windows-MSVC.cmake"
|
||||
},
|
||||
{
|
||||
"isGenerated" : true,
|
||||
"path" : "out/build/x64-debug/CMakeFiles/3.28.0-msvc1/CMakeRCCompiler.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeRCInformation.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeCommonLanguageInclude.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeCXXInformation.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeLanguageInformation.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Compiler/MSVC-CXX.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Compiler/MSVC.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Compiler/CMakeCommonCompilerMacros.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Platform/Windows-MSVC-CXX.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/Platform/Windows-MSVC.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeCommonLanguageInclude.cmake"
|
||||
},
|
||||
{
|
||||
"path" : "YuppleMayham/CMakeLists.txt"
|
||||
},
|
||||
{
|
||||
"isExternal" : true,
|
||||
"path" : "C:/sdks/sdl2/cmake/sdl2-config-version.cmake"
|
||||
},
|
||||
{
|
||||
"isExternal" : true,
|
||||
"path" : "C:/sdks/sdl2/cmake/sdl2-config.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/FeatureSummary.cmake"
|
||||
},
|
||||
{
|
||||
"isExternal" : true,
|
||||
"path" : "C:/sdks/SDL2_image-2.8.2/cmake/sdl2_image-config-version.cmake"
|
||||
},
|
||||
{
|
||||
"isExternal" : true,
|
||||
"path" : "C:/sdks/SDL2_image-2.8.2/cmake/sdl2_image-config.cmake"
|
||||
},
|
||||
{
|
||||
"isCMake" : true,
|
||||
"isExternal" : true,
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/FeatureSummary.cmake"
|
||||
}
|
||||
],
|
||||
"kind" : "cmakeFiles",
|
||||
"paths" :
|
||||
{
|
||||
"build" : "C:/Users/Ethan/source/repos/YuppleMayham/out/build/x64-debug",
|
||||
"source" : "C:/Users/Ethan/source/repos/YuppleMayham"
|
||||
},
|
||||
"version" :
|
||||
{
|
||||
"major" : 1,
|
||||
"minor" : 0
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"configurations" :
|
||||
[
|
||||
{
|
||||
"directories" :
|
||||
[
|
||||
{
|
||||
"build" : ".",
|
||||
"childIndexes" :
|
||||
[
|
||||
1
|
||||
],
|
||||
"jsonFile" : "directory-.-Debug-d0094a50bb2071803777.json",
|
||||
"minimumCMakeVersion" :
|
||||
{
|
||||
"string" : "3.8"
|
||||
},
|
||||
"projectIndex" : 0,
|
||||
"source" : "."
|
||||
},
|
||||
{
|
||||
"build" : "YuppleMayham",
|
||||
"jsonFile" : "directory-YuppleMayham-Debug-644acecf2c7ac18c0945.json",
|
||||
"minimumCMakeVersion" :
|
||||
{
|
||||
"string" : "3.0"
|
||||
},
|
||||
"parentIndex" : 0,
|
||||
"projectIndex" : 0,
|
||||
"source" : "YuppleMayham",
|
||||
"targetIndexes" :
|
||||
[
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"name" : "Debug",
|
||||
"projects" :
|
||||
[
|
||||
{
|
||||
"directoryIndexes" :
|
||||
[
|
||||
0,
|
||||
1
|
||||
],
|
||||
"name" : "YuppleMayham",
|
||||
"targetIndexes" :
|
||||
[
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"targets" :
|
||||
[
|
||||
{
|
||||
"directoryIndex" : 1,
|
||||
"id" : "YuppleMayham::@9b7a613ce340ec559f6e",
|
||||
"jsonFile" : "target-YuppleMayham-Debug-328e7d72836934c76d1f.json",
|
||||
"name" : "YuppleMayham",
|
||||
"projectIndex" : 0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"kind" : "codemodel",
|
||||
"paths" :
|
||||
{
|
||||
"build" : "C:/Users/Ethan/source/repos/YuppleMayham/out/build/x64-debug",
|
||||
"source" : "C:/Users/Ethan/source/repos/YuppleMayham"
|
||||
},
|
||||
"version" :
|
||||
{
|
||||
"major" : 2,
|
||||
"minor" : 6
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"backtraceGraph" :
|
||||
{
|
||||
"commands" : [],
|
||||
"files" : [],
|
||||
"nodes" : []
|
||||
},
|
||||
"installers" : [],
|
||||
"paths" :
|
||||
{
|
||||
"build" : ".",
|
||||
"source" : "."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"backtraceGraph" :
|
||||
{
|
||||
"commands" : [],
|
||||
"files" : [],
|
||||
"nodes" : []
|
||||
},
|
||||
"installers" : [],
|
||||
"paths" :
|
||||
{
|
||||
"build" : "YuppleMayham",
|
||||
"source" : "YuppleMayham"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
{
|
||||
"cmake" :
|
||||
{
|
||||
"generator" :
|
||||
{
|
||||
"multiConfig" : false,
|
||||
"name" : "Ninja"
|
||||
},
|
||||
"paths" :
|
||||
{
|
||||
"cmake" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/cmake.exe",
|
||||
"cpack" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/cpack.exe",
|
||||
"ctest" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/ctest.exe",
|
||||
"root" : "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28"
|
||||
},
|
||||
"version" :
|
||||
{
|
||||
"isDirty" : false,
|
||||
"major" : 3,
|
||||
"minor" : 28,
|
||||
"patch" : 0,
|
||||
"string" : "3.28.0-msvc1",
|
||||
"suffix" : "msvc1"
|
||||
}
|
||||
},
|
||||
"objects" :
|
||||
[
|
||||
{
|
||||
"jsonFile" : "codemodel-v2-b051cbca90ed5f2969ed.json",
|
||||
"kind" : "codemodel",
|
||||
"version" :
|
||||
{
|
||||
"major" : 2,
|
||||
"minor" : 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"jsonFile" : "cache-v2-40ca1042058e3be860b7.json",
|
||||
"kind" : "cache",
|
||||
"version" :
|
||||
{
|
||||
"major" : 2,
|
||||
"minor" : 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"jsonFile" : "cmakeFiles-v1-20fe43637e91d7e7285b.json",
|
||||
"kind" : "cmakeFiles",
|
||||
"version" :
|
||||
{
|
||||
"major" : 1,
|
||||
"minor" : 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"jsonFile" : "toolchains-v1-59c84e7e9823f39a3470.json",
|
||||
"kind" : "toolchains",
|
||||
"version" :
|
||||
{
|
||||
"major" : 1,
|
||||
"minor" : 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"reply" :
|
||||
{
|
||||
"client-MicrosoftVS" :
|
||||
{
|
||||
"query.json" :
|
||||
{
|
||||
"requests" :
|
||||
[
|
||||
{
|
||||
"kind" : "cache",
|
||||
"version" : 2
|
||||
},
|
||||
{
|
||||
"kind" : "cmakeFiles",
|
||||
"version" : 1
|
||||
},
|
||||
{
|
||||
"kind" : "codemodel",
|
||||
"version" : 2
|
||||
},
|
||||
{
|
||||
"kind" : "toolchains",
|
||||
"version" : 1
|
||||
}
|
||||
],
|
||||
"responses" :
|
||||
[
|
||||
{
|
||||
"jsonFile" : "cache-v2-40ca1042058e3be860b7.json",
|
||||
"kind" : "cache",
|
||||
"version" :
|
||||
{
|
||||
"major" : 2,
|
||||
"minor" : 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"jsonFile" : "cmakeFiles-v1-20fe43637e91d7e7285b.json",
|
||||
"kind" : "cmakeFiles",
|
||||
"version" :
|
||||
{
|
||||
"major" : 1,
|
||||
"minor" : 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"jsonFile" : "codemodel-v2-b051cbca90ed5f2969ed.json",
|
||||
"kind" : "codemodel",
|
||||
"version" :
|
||||
{
|
||||
"major" : 2,
|
||||
"minor" : 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"jsonFile" : "toolchains-v1-59c84e7e9823f39a3470.json",
|
||||
"kind" : "toolchains",
|
||||
"version" :
|
||||
{
|
||||
"major" : 1,
|
||||
"minor" : 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,342 @@
|
|||
{
|
||||
"artifacts" :
|
||||
[
|
||||
{
|
||||
"path" : "YuppleMayham/YuppleMayham.exe"
|
||||
},
|
||||
{
|
||||
"path" : "YuppleMayham/YuppleMayham.pdb"
|
||||
}
|
||||
],
|
||||
"backtrace" : 1,
|
||||
"backtraceGraph" :
|
||||
{
|
||||
"commands" :
|
||||
[
|
||||
"add_executable",
|
||||
"target_link_libraries",
|
||||
"include_directories",
|
||||
"set_property"
|
||||
],
|
||||
"files" :
|
||||
[
|
||||
"YuppleMayham/CMakeLists.txt"
|
||||
],
|
||||
"nodes" :
|
||||
[
|
||||
{
|
||||
"file" : 0
|
||||
},
|
||||
{
|
||||
"command" : 0,
|
||||
"file" : 0,
|
||||
"line" : 16,
|
||||
"parent" : 0
|
||||
},
|
||||
{
|
||||
"command" : 1,
|
||||
"file" : 0,
|
||||
"line" : 24,
|
||||
"parent" : 0
|
||||
},
|
||||
{
|
||||
"command" : 2,
|
||||
"file" : 0,
|
||||
"line" : 11,
|
||||
"parent" : 0
|
||||
},
|
||||
{
|
||||
"command" : 2,
|
||||
"file" : 0,
|
||||
"line" : 12,
|
||||
"parent" : 0
|
||||
},
|
||||
{
|
||||
"command" : 2,
|
||||
"file" : 0,
|
||||
"line" : 13,
|
||||
"parent" : 0
|
||||
},
|
||||
{
|
||||
"command" : 2,
|
||||
"file" : 0,
|
||||
"line" : 8,
|
||||
"parent" : 0
|
||||
},
|
||||
{
|
||||
"command" : 2,
|
||||
"file" : 0,
|
||||
"line" : 9,
|
||||
"parent" : 0
|
||||
},
|
||||
{
|
||||
"command" : 3,
|
||||
"file" : 0,
|
||||
"line" : 21,
|
||||
"parent" : 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"compileGroups" :
|
||||
[
|
||||
{
|
||||
"compileCommandFragments" :
|
||||
[
|
||||
{
|
||||
"fragment" : "/DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Ob0 /Od /RTC1 -std:c++20 -ZI"
|
||||
}
|
||||
],
|
||||
"includes" :
|
||||
[
|
||||
{
|
||||
"backtrace" : 3,
|
||||
"path" : "C:/Users/Ethan/source/repos/YuppleMayham/YupplyMayham/gameplay"
|
||||
},
|
||||
{
|
||||
"backtrace" : 4,
|
||||
"path" : "C:/Users/Ethan/source/repos/YuppleMayham/YupplyMayham/graphics"
|
||||
},
|
||||
{
|
||||
"backtrace" : 5,
|
||||
"path" : "C:/Users/Ethan/source/repos/YuppleMayham/YupplyMayham"
|
||||
},
|
||||
{
|
||||
"backtrace" : 6,
|
||||
"isSystem" : true,
|
||||
"path" : "c:/sdks/glad/include"
|
||||
},
|
||||
{
|
||||
"backtrace" : 7,
|
||||
"isSystem" : true,
|
||||
"path" : "c:/sdks/glm"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"isSystem" : true,
|
||||
"path" : "C:/sdks/sdl2/cmake/../include"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"isSystem" : true,
|
||||
"path" : "C:/sdks/SDL2_image-2.8.2/cmake/../include"
|
||||
}
|
||||
],
|
||||
"language" : "CXX",
|
||||
"languageStandard" :
|
||||
{
|
||||
"backtraces" :
|
||||
[
|
||||
8
|
||||
],
|
||||
"standard" : "20"
|
||||
},
|
||||
"sourceIndexes" :
|
||||
[
|
||||
0,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
10
|
||||
]
|
||||
},
|
||||
{
|
||||
"compileCommandFragments" :
|
||||
[
|
||||
{
|
||||
"fragment" : "/DWIN32 /D_WINDOWS /W3 /MDd /Ob0 /Od /RTC1 -ZI"
|
||||
}
|
||||
],
|
||||
"includes" :
|
||||
[
|
||||
{
|
||||
"backtrace" : 3,
|
||||
"path" : "C:/Users/Ethan/source/repos/YuppleMayham/YupplyMayham/gameplay"
|
||||
},
|
||||
{
|
||||
"backtrace" : 4,
|
||||
"path" : "C:/Users/Ethan/source/repos/YuppleMayham/YupplyMayham/graphics"
|
||||
},
|
||||
{
|
||||
"backtrace" : 5,
|
||||
"path" : "C:/Users/Ethan/source/repos/YuppleMayham/YupplyMayham"
|
||||
},
|
||||
{
|
||||
"backtrace" : 6,
|
||||
"isSystem" : true,
|
||||
"path" : "c:/sdks/glad/include"
|
||||
},
|
||||
{
|
||||
"backtrace" : 7,
|
||||
"isSystem" : true,
|
||||
"path" : "c:/sdks/glm"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"isSystem" : true,
|
||||
"path" : "C:/sdks/sdl2/cmake/../include"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"isSystem" : true,
|
||||
"path" : "C:/sdks/SDL2_image-2.8.2/cmake/../include"
|
||||
}
|
||||
],
|
||||
"language" : "C",
|
||||
"sourceIndexes" :
|
||||
[
|
||||
1
|
||||
]
|
||||
}
|
||||
],
|
||||
"id" : "YuppleMayham::@9b7a613ce340ec559f6e",
|
||||
"link" :
|
||||
{
|
||||
"commandFragments" :
|
||||
[
|
||||
{
|
||||
"fragment" : "/DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Ob0 /Od /RTC1 -ZI",
|
||||
"role" : "flags"
|
||||
},
|
||||
{
|
||||
"fragment" : "/machine:x64 /debug /INCREMENTAL /subsystem:console",
|
||||
"role" : "flags"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"fragment" : "C:\\sdks\\sdl2\\cmake\\..\\lib\\x64\\SDL2main.lib",
|
||||
"role" : "libraries"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"fragment" : "C:\\sdks\\sdl2\\cmake\\..\\lib\\x64\\SDL2.lib",
|
||||
"role" : "libraries"
|
||||
},
|
||||
{
|
||||
"backtrace" : 2,
|
||||
"fragment" : "C:\\sdks\\SDL2_image-2.8.2\\cmake\\..\\lib\\x64\\SDL2_image.lib",
|
||||
"role" : "libraries"
|
||||
},
|
||||
{
|
||||
"fragment" : "kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib",
|
||||
"role" : "libraries"
|
||||
}
|
||||
],
|
||||
"language" : "CXX"
|
||||
},
|
||||
"name" : "YuppleMayham",
|
||||
"nameOnDisk" : "YuppleMayham.exe",
|
||||
"paths" :
|
||||
{
|
||||
"build" : "YuppleMayham",
|
||||
"source" : "YuppleMayham"
|
||||
},
|
||||
"sourceGroups" :
|
||||
[
|
||||
{
|
||||
"name" : "Source Files",
|
||||
"sourceIndexes" :
|
||||
[
|
||||
0,
|
||||
1,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
10
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "Header Files",
|
||||
"sourceIndexes" :
|
||||
[
|
||||
2,
|
||||
9,
|
||||
11,
|
||||
12
|
||||
]
|
||||
}
|
||||
],
|
||||
"sources" :
|
||||
[
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "YuppleMayham/src/main.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 1,
|
||||
"path" : "C:/sdks/glad/src/glad.c",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"path" : "YuppleMayham/graphics/glwindow.h",
|
||||
"sourceGroupIndex" : 1
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "YuppleMayham/src/graphics/sprite.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "YuppleMayham/src/graphics/mesh.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "YuppleMayham/src/gameplay/entity.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "YuppleMayham/src/gameplay/gameactor.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "YuppleMayham/src/graphics/shader.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "YuppleMayham/src/util.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"path" : "YuppleMayham/gameplay/camera.h",
|
||||
"sourceGroupIndex" : 1
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"compileGroupIndex" : 0,
|
||||
"path" : "YuppleMayham/src/gameplay/camera.cpp",
|
||||
"sourceGroupIndex" : 0
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"path" : "YuppleMayham/gameplay/command.h",
|
||||
"sourceGroupIndex" : 1
|
||||
},
|
||||
{
|
||||
"backtrace" : 1,
|
||||
"path" : "YuppleMayham/gameplay/input.h",
|
||||
"sourceGroupIndex" : 1
|
||||
}
|
||||
],
|
||||
"type" : "EXECUTABLE"
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
{
|
||||
"kind" : "toolchains",
|
||||
"toolchains" :
|
||||
[
|
||||
{
|
||||
"compiler" :
|
||||
{
|
||||
"id" : "MSVC",
|
||||
"implicit" :
|
||||
{
|
||||
"includeDirectories" : [],
|
||||
"linkDirectories" : [],
|
||||
"linkFrameworkDirectories" : [],
|
||||
"linkLibraries" : []
|
||||
},
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostx64/x64/cl.exe",
|
||||
"version" : "19.39.33523.0"
|
||||
},
|
||||
"language" : "C",
|
||||
"sourceFileExtensions" :
|
||||
[
|
||||
"c",
|
||||
"m"
|
||||
]
|
||||
},
|
||||
{
|
||||
"compiler" :
|
||||
{
|
||||
"id" : "MSVC",
|
||||
"implicit" :
|
||||
{
|
||||
"includeDirectories" : [],
|
||||
"linkDirectories" : [],
|
||||
"linkFrameworkDirectories" : [],
|
||||
"linkLibraries" : []
|
||||
},
|
||||
"path" : "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostx64/x64/cl.exe",
|
||||
"version" : "19.39.33523.0"
|
||||
},
|
||||
"language" : "CXX",
|
||||
"sourceFileExtensions" :
|
||||
[
|
||||
"C",
|
||||
"M",
|
||||
"c++",
|
||||
"cc",
|
||||
"cpp",
|
||||
"cxx",
|
||||
"mm",
|
||||
"mpp",
|
||||
"CPP",
|
||||
"ixx",
|
||||
"cppm",
|
||||
"ccm",
|
||||
"cxxm",
|
||||
"c++m"
|
||||
]
|
||||
},
|
||||
{
|
||||
"compiler" :
|
||||
{
|
||||
"implicit" : {},
|
||||
"path" : "C:/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64/rc.exe"
|
||||
},
|
||||
"language" : "RC",
|
||||
"sourceFileExtensions" :
|
||||
[
|
||||
"rc",
|
||||
"RC"
|
||||
]
|
||||
}
|
||||
],
|
||||
"version" :
|
||||
{
|
||||
"major" : 1,
|
||||
"minor" : 0
|
||||
}
|
||||
}
|
||||