Add project files.

This commit is contained in:
Ethan Adams 2024-06-21 16:59:06 -04:00
parent 595f761123
commit 57289ca732
137 changed files with 10083 additions and 0 deletions

15
CMakeLists.txt Normal file
View 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
View 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

Binary file not shown.

BIN
Resources/fonts/comicbd.ttf Normal file

Binary file not shown.

BIN
Resources/fonts/comici.ttf Normal file

Binary file not shown.

BIN
Resources/fonts/comicz.ttf Normal file

Binary file not shown.

Binary file not shown.

View file

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

Binary file not shown.

View 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

View 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

View 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);
}

View 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);
}

View file

@ -0,0 +1,11 @@
#version 330 core
in vec2 texCoord;
out vec4 FragColor;
uniform sampler2D sprite;
void main()
{
FragColor = texture(sprite, texCoord);
}

View 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);
}
}

View 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);
}

View 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);
}

View 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);
}

View 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;
}

View file

@ -0,0 +1,7 @@
#version 330 core
in vec3 pos;
void main()
{
gl_FragColor = vec4(pos.xyz, 1.0);
}

View 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);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

View 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>

View 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.

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View file

@ -0,0 +1,9 @@
#ifndef _H_MOUSESTATE_H
#define _H_MOUSESTATE_H
struct MouseState {
float x = 0.0f;
float y = 0.0f;
};
#endif

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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;
}
}

View 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;
}

View 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);
}

View 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();
}

View 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;
}

View 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);
}

View 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();
}

View 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();
}

View 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();
}

View 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();
}

View 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);
}
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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();
}

View 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);
}

View 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
View 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
View 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);
}
}

View 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); }

View 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);
}

View 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);
}

View 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();
}

View 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);
}

View 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
View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View file

@ -0,0 +1 @@
{"requests":[{"kind":"cache","version":2},{"kind":"cmakeFiles","version":1},{"kind":"codemodel","version":2},{"kind":"toolchains","version":1}]}

File diff suppressed because it is too large Load diff

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -0,0 +1,14 @@
{
"backtraceGraph" :
{
"commands" : [],
"files" : [],
"nodes" : []
},
"installers" : [],
"paths" :
{
"build" : ".",
"source" : "."
}
}

View file

@ -0,0 +1,14 @@
{
"backtraceGraph" :
{
"commands" : [],
"files" : [],
"nodes" : []
},
"installers" : [],
"paths" :
{
"build" : "YuppleMayham",
"source" : "YuppleMayham"
}
}

View file

@ -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
}
}
]
}
}
}
}

View file

@ -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"
}

View file

@ -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
}
}

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more