Skip to content

Commit

Permalink
Game Design pre release
Browse files Browse the repository at this point in the history
  • Loading branch information
TroyNeubauer committed Dec 3, 2019
1 parent f594551 commit 9804603
Show file tree
Hide file tree
Showing 24 changed files with 685 additions and 163 deletions.
Binary file modified GameDesign/assets/textures/Rocket.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions GameDesign/src/GameDesign.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

#include "GameDesign.h"
#include "layers/WorldLayer.h"
#include "layers/SandboxLayer.h"

#include "Hazel.h"

GameDesign::GameDesign()
{
PushOverlay(new Hazel::DebugLayer());
PushLayer(new WorldLayer(new World()));
PushLayer(new SandboxLayer(new World()));
}

void GameDesign::Update()
Expand All @@ -17,7 +17,7 @@ void GameDesign::Update()

void GameDesign::Render()
{
Hazel::RenderCommand::SetClearColor(glm::vec4(1.0f, 0.0f, 0.5f, 1.0f));
Hazel::RenderCommand::SetClearColor(glm::vec4(glm::vec3(0.6f), 1.0f));
Hazel::RenderCommand::Clear();
if (Hazel::Input::IsMouseButtonPressed(HZ_MOUSE_BUTTON_5) || Hazel::Input::IsKeyPressed(HZ_KEY_H))
{
Expand Down
186 changes: 186 additions & 0 deletions GameDesign/src/layers/SandboxLayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
#include "SandboxLayer.h"

#include <imgui.h>
#include <random>

void SandboxLayer::OnAttach()
{
std::default_random_engine gen;
std::uniform_real_distribution<float> pos(-12.0f, 12.0f);
Part& part = m_World->AddPart({ 0.0f, 0.0f }, Parts::StaticShip);

for (int i = 0; i < 2; i++)
{
Part& part = m_World->AddPart({ pos(gen), pos(gen) }, Parts::MK1Capsule);
}
m_World->SetBodyRemovedCallback([this](Body* body) {
if (body == m_SelectedBody) m_SelectedBody = nullptr;
if (body == m_DraggedBody)
{
m_DraggedBody = nullptr;
m_MouseDragged = false;
}

});
}

void SandboxLayer::OnDetach()
{

}

float lastMoved = 0.0f;

void SandboxLayer::OnUpdate()
{
if (Hazel::Input::GetMouseDelta().x || Hazel::Input::GetMouseDelta().y) lastMoved = Hazel::Engine::GetTime();

if (m_Paused)
m_World->GetCamera().Update();
else
m_World->Update();

if (m_DraggedBody && m_MouseDragged)
{
b2Vec2 velocity = {0.0f, 0.0f};
if (Hazel::Input::DidMouseMove()) {
glm::vec2 delta = { Hazel::Input::GetMouseDelta().x, Hazel::Input::GetMouseDelta().y };
delta /= Hazel::Engine::GetDeltaTime();
glm::vec2 result = m_World->GetCamera().GetWorldDelta(delta);
velocity = { result.x, result.y };
}

m_DraggedBody->GetBody()->SetLinearVelocity(velocity);
}

}

void SandboxLayer::OnEvent(Hazel::Event* event)
{
Hazel::EventDispatcher dispatcher(event);
dispatcher.Dispatch<Hazel::MouseMovedEvent>(HZ_BIND_EVENT_FN(SandboxLayer::OnMouseMoved));
dispatcher.Dispatch<Hazel::MouseButtonPressedEvent>(HZ_BIND_EVENT_FN(SandboxLayer::OnMousePressed));
dispatcher.Dispatch<Hazel::MouseButtonReleasedEvent>(HZ_BIND_EVENT_FN(SandboxLayer::OnMouseReleased));
}

bool SandboxLayer::OnMouseMoved(Hazel::MouseMovedEvent* event)
{
if (m_DraggedBody)
m_MouseDragged = true;
return false;
}

template<typename T>
class QueryCallback : public b2QueryCallback
{
public:
QueryCallback(T func) : m_Func(func) {}

bool ReportFixture(b2Fixture* fixture)
{
b2Body* body = fixture->GetBody();
m_Func(World::ToBody(body));

return false;// Return true to continue the query.
}
private:
T m_Func;
};

bool SandboxLayer::OnMousePressed(Hazel::MouseButtonPressedEvent* event)
{
glm::vec2 worldCoords = m_World->GetCamera().ToWorldCoordinates(Hazel::Input::GetMousePosition());
b2AABB aabb;
aabb.lowerBound.Set(worldCoords.x, worldCoords.y);
aabb.upperBound.Set(worldCoords.x + 0.001f, worldCoords.y + 0.001f);
bool found = false;
auto callback = QueryCallback([this, &found](Body* body) {
found = true;
m_SelectedBody = body;
m_DraggedBody = body;
m_MouseDragged = false;
});
if (!found)
{
m_SelectedBody = nullptr;
m_DraggedBody = nullptr;
m_MouseDragged = false;
}
m_World->GetWorld()->QueryAABB(&callback, aabb);
return false;
}

bool SandboxLayer::OnMouseReleased(Hazel::MouseButtonReleasedEvent* event)
{
m_DraggedBody = nullptr;
m_MouseDragged = false;
return false;
}

static bool SliderDouble(const char* label, double* v, double v_min, double v_max, const char* format, float power)
{
return ImGui::SliderScalar(label, ImGuiDataType_Double, v, &v_min, &v_max, format, power);
}

static void Tooltip(const char* text)
{
if (ImGui::IsItemHovered() && (Hazel::Engine::GetTime() - lastMoved) > 0.05f)
{
ImGui::BeginTooltip();
ImGui::Text(text);
ImGui::EndTooltip();
}
}

void SandboxLayer::OnImGuiRender()
{
ImGui::Begin("World Settings");

SliderDouble("G", &World::Constants::G, -0.01f, 10.0f, "%.5f", 3.0f); Tooltip("G is a universal constant like PI that determines how much objects attract each other");
ImGui::Checkbox("Paused", &m_Paused); Tooltip("Pauses the simulation");
int count = 0;
for (b2Body* body = m_World->GetWorld()->GetBodyList(); body != nullptr; body = body->GetNext())
{
count++;
}

ImGui::Text("%d bodies exist", count);
if (ImGui::Button("Stop all bodies"))
{
m_World->ForEachBody([](b2Body* body) { body->SetLinearVelocity({ 0.0f, 0.0f }); });
}
if (ImGui::Button("Delete all bodies"))
{
m_World->ForEachBody([this](b2Body* body) { m_World->Remove(World::ToBody(body)); });
}
ImGui::End();

ImGui::Begin("Selected Body");
if (m_SelectedBody == nullptr)
{
ImGui::Text("No body is currently selected");
}
else
{
ImGui::Text("mass %.2f kg", m_SelectedBody->GetBody()->GetMass());
ImGui::Text("speed %.3f m/s", m_SelectedBody->GetBody()->GetLinearVelocity().Length());
ImGui::Text("speed %.2f rad/s", m_SelectedBody->GetBody()->GetAngularVelocity());

if (ImGui::Button("Delete"))
{
m_World->Remove(m_SelectedBody);
}
}
ImGui::End();
}


void SandboxLayer::Render()
{
m_World->Render();
}

SandboxLayer::~SandboxLayer()
{

}
Expand Down
31 changes: 31 additions & 0 deletions GameDesign/src/layers/SandboxLayer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <Hazel.h>
#include "../world/World.h"

class SandboxLayer : public Hazel::Layer
{
public:
inline SandboxLayer(World* world) : Hazel::Layer("Sandbox Layer") { m_World.reset(world); }

virtual void OnAttach() override;
virtual void OnDetach() override;
virtual void OnUpdate() override;

virtual void OnEvent(Hazel::Event* event) override;

bool OnMouseMoved(Hazel::MouseMovedEvent* event);
bool OnMousePressed(Hazel::MouseButtonPressedEvent* event);
bool OnMouseReleased(Hazel::MouseButtonReleasedEvent* event);

virtual void OnImGuiRender() override;
virtual void Render() override;

virtual ~SandboxLayer() override;

private:
Hazel::Scope<World> m_World;
Body* m_SelectedBody = nullptr;
Body* m_DraggedBody = nullptr; bool m_MouseDragged = false;
bool m_Paused = false;
};
18 changes: 16 additions & 2 deletions GameDesign/src/layers/WorldLayer.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
#include "WorldLayer.h"

#include <imgui.h>
#include <random>


void WorldLayer::OnAttach()
{

std::default_random_engine gen;
std::uniform_real_distribution<float> pos(-6.0f, 6.0f);
for (int i = 0; i < 2; i++)
{
Part& part = m_World->AddPart({ pos(gen), pos(gen) }, Parts::MK1Capsule);

}
}

void WorldLayer::OnDetach()
Expand All @@ -22,11 +30,17 @@ void WorldLayer::OnEvent(Hazel::Event* event)

}

static bool SliderDouble(const char* label, double* v, double v_min, double v_max, const char* format, double power)
{
return ImGui::SliderScalar(label, ImGuiDataType_Double, v, &v_min, &v_max, format, power);
}

void WorldLayer::OnImGuiRender()
{
ImGui::SliderFloat("G", &World::Constants::G, -0.01f, 10.0f);
SliderDouble("G", &World::Constants::G, -0.01f, 10.0f, "%.5f", 1.0f);
}


void WorldLayer::Render()
{
m_World->Render();
Expand Down
35 changes: 35 additions & 0 deletions GameDesign/src/ship/Ship.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "Ship.h"
#include "world/World.h"


Part::Part(World& world, b2Vec2 pos, const Hazel::Ref<PartDef>& partDef) : m_Def(partDef), m_Animation(partDef->Animation)
{
b2BodyDef def;
def.position = pos;
def.userData = this;
def.type = b2_dynamicBody;
def.active = true;
m_Body = world.GetWorld()->CreateBody(&def);


b2PolygonShape shape;
shape.SetAsBox(partDef->Size.x / 2.0f, partDef->Size.y / 2.0f);

b2FixtureDef fixtureDef;
fixtureDef.shape = &shape;
fixtureDef.density = partDef->Density;
fixtureDef.friction = 0.2f;
fixtureDef.restitution = 0.1f;
b2Fixture* myFixture = m_Body->CreateFixture(&fixtureDef);
}

void Part::Render(const World& world)
{
float x = m_Body->GetPosition().x, y = m_Body->GetPosition().y;
Hazel::Renderer2D::DrawQuad( { x, y }, { m_Def->Size.x, m_Def->Size.y }, m_Animation, m_Body->GetAngle());
}

void Part::Update(const World& world)
{
m_Animation.Update();
}
55 changes: 55 additions & 0 deletions GameDesign/src/ship/Ship.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once
#include "world/Body.h"
#include "Hazel.h"

#include <Hazel/Renderer2D/Animation2D.h>
#include <Box2D/Box2D.h>

struct PartDef {
PartDef(const char* name, float density, float maxGForce, const Hazel::Ref<Hazel::AnimationDef2D> animation, float realWidth)
: Name(name), Density(density), MaxGForce(maxGForce), Animation(animation)
{
glm::vec2 spriteSize = { animation->m_Frames[0].Bottom - animation->m_Frames[0].Top };
Size.x = realWidth;
Size.y = realWidth * (spriteSize.y / spriteSize.x);
}

const char* Name;
float Density;
float MaxGForce;
glm::vec2 Size;

Hazel::Ref<Hazel::AnimationDef2D> Animation;
};

class Part : public Body
{
public:
Part(World& world, b2Vec2 pos, const Hazel::Ref<PartDef>& partDef);

virtual void Render(const World& world) override;
virtual void Update(const World& world) override;

const Hazel::Ref<PartDef>& GetDef() { return m_Def; }

virtual ~Part() {}

inline void SetSelected(bool selected) { m_IsSelected = selected; }
inline bool IsSelected() { return m_IsSelected; }

private:
Hazel::Ref<PartDef> m_Def;
Hazel::Animation2D m_Animation;
bool m_IsSelected = false;
};

class Ship
{
public:

std::vector<Part>& GetParts() { return m_Parts; }

private:
std::vector<Part> m_Parts;
};

11 changes: 6 additions & 5 deletions GameDesign/src/world/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ class Body
{
public:
//m_Body must be initalized in the child's constructor
Body() :m_Body(nullptr) {}
Body() : m_Body(nullptr) {}

inline b2Body* GetBody() { return m_Body; }
inline b2Body* GetBody() const { return m_Body; }

inline glm::vec2 GetPosition() { return { m_Body->GetPosition().x, m_Body->GetPosition().y }; }
inline glm::vec2 GetPosition() const { return { m_Body->GetPosition().x, m_Body->GetPosition().y }; }

//Returns the angle in radains
inline float GetRotation() { return m_Body->GetAngle(); }
//Returns the angle in degrees
inline float GetRotation() const { return glm::degrees(m_Body->GetAngle()); }
inline void SetRotation(float degrees) { m_Body->SetTransform(m_Body->GetWorldCenter(), glm::radians(degrees)); }

virtual void Render(const World& world) = 0;
virtual void Update(const World& world) = 0;
Expand Down
Loading

0 comments on commit 9804603

Please sign in to comment.