Skip to content

Commit

Permalink
Release!
Browse files Browse the repository at this point in the history
  • Loading branch information
cheyao committed Jan 3, 2025
1 parent da2f145 commit a29c4e8
Show file tree
Hide file tree
Showing 17 changed files with 247 additions and 23 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ src/components/inventory.cpp
src/components/playerInventory.cpp
src/components/crafting.cpp
src/components/noise.cpp
src/components/furnace.cpp

src/opengl/mesh.cpp
src/opengl/shader.cpp
Expand Down Expand Up @@ -85,6 +86,7 @@ include/components/inventory.hpp
include/components/playerInventory.hpp
include/components/crafting.hpp
include/components/noise.hpp
include/components/furnace.hpp

include/misc/sparse_set.hpp
include/misc/sparse_set_view.hpp
Expand Down
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h1 align="center" style="text-shadow: 2px 2px 5px red;">Cyao Game Engine</h1>
<h1 align="center" style="text-shadow: 2px 2px 5px red;">2D Minecraft + Cyao Game Engine</h2>
<h2 align="center">Features</h2>

- **Cross-Platorm** 💻📱: **MacOS**, **Linux**, **Windows**, **Web**, **Android** and **IOS** all supported!
Expand All @@ -9,16 +9,18 @@
- **Debuggable** 🔍: Custom asserts and **Debug menu** helps you identify any bugs 🐛!
- **Custom Saves** 📝: Easily save **any** data on any platform you want in a json file, the game engine will manage it for you!

Controls:
WASD for movement
E to open Inventory
ESC to close
Everything else like Minecraft
<h2 align="center">Controls</h2>
- WASD for movement
- E to open Inventory
- ESC to close
- Everything else like Minecraft

<h3 align="center"><a href="https://cyao.hackclub.app">Try out web version now!</a></h3>
<h3 align="center"><a href="https://opengl.pages.dev">Try out web version now!</a></h3>

<div align="center">
<img src="https://cloud-l0r4ps4t3-hack-club-bot.vercel.app/0image.png" width="auto" height="auto" alt="Demo pic of the game">
<img src="https://cloud-27xm3qrn9-hack-club-bot.vercel.app/0image.png" width="auto" height="auto" alt="Demo pic of the game">
<img src="https://cloud-27xm3qrn9-hack-club-bot.vercel.app/1image.png" width="auto" height="auto" alt="Demo pic of the game">
<img src="https://cloud-89ohmxlnj-hack-club-bot.vercel.app/0image.png" width="auto" height="auto" alt="Demo pic of the game">
</div>

<h2 align="center">Inner workings</h2>
Expand Down
4 changes: 2 additions & 2 deletions assets/strings/strings.csv
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
id,comment,en,fr,zh-CN
AD0,,Did you know? This game was developed during 7+ months!,Tu savais ? Cette jeux été déveloper dans plus de 7 mois!,你知道吗?这个游戏的开发周期长于7个月!
AD1,,Did you know? This game uses it's cusiom engine!,Tu savais ? Cette jeux utilise sa propre moteur de jeux!,你知道吗?这个游戏用的是自己的引擎!
AD1,,Did you know? This game uses its custom engine!,Tu savais ? Cette jeux utilise sa propre moteur de jeux!,你知道吗?这个游戏用的是自己的引擎!
AD2,,Did you know? This game was coded entirely in C++!,Tu savais ? Cette jeux été crée entièrement avec C++!,你知道吗?这个游戏是完全用C++写的!
AD3,,Did you know? This game handles (almost) everything by itself!,Tu savais ? Cette jeux fait tout par lui même!,你知道吗?这个游戏自己掌控所有东西!
AD4,,Did you know? This game gets 1000+ FPS on natively!,Tu savais ? Cette jeux fait plus de 1000+ FPS!,你知道吗?这个游戏有1000+ FPS!
AD4,,Did you know? This game gets 1000+ FPS natively!,Tu savais ? Cette jeux fait plus de 1000+ FPS!,你知道吗?这个游戏有1000+ FPS!
File renamed without changes
Binary file modified assets/textures/crosshair.bmp
Binary file not shown.
3 changes: 3 additions & 0 deletions assets/textures/ui/furnace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion cmake/index.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
<p class="bottom-note">
Download native versions at
<a href="https://github.com/cheyao/opengl/releases" target="_blank" rel="noopener noreferrer">GitHub</a>
for better performance.
for better performance. <a href="https://youtu.be/4TOIlzZYmBc" target="_blank">Video demo here</a>
</p>
</div>

Expand Down
39 changes: 39 additions & 0 deletions include/components/furnace.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include "components.hpp"
#include "components/inventory.hpp"
#include "screens/screen.hpp"

#include <cstdint>

struct furnace_t {};

class FurnaceInventory : public Inventory {
public:
explicit FurnaceInventory(struct furnace_t);
FurnaceInventory(FurnaceInventory&&) = delete;
FurnaceInventory(const FurnaceInventory&) = delete;
FurnaceInventory& operator=(FurnaceInventory&&) = delete;
FurnaceInventory& operator=(const FurnaceInventory&) = delete;
~FurnaceInventory() override = default;

bool update(class Scene* scene, float delta) override;
void draw(class Scene* scene) override;

private:
void craft();
void placeGrid();
bool checkRecipie(std::uint64_t r);

std::vector<Components::Item> mSmeltingItems;
std::vector<std::uint64_t> mSmeltingCount;

std::size_t mLastCraft;

constexpr const static inline double mAX = 56;
constexpr const static inline double mAY = 97;
constexpr const static inline double mBX = 0;
constexpr const static inline double mBY = 36;
constexpr const static inline double mOutX = 57;
constexpr const static inline double mOutY = 23;
};
3 changes: 3 additions & 0 deletions include/registers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ extern const std::unordered_map<Components::Item, std::pair<int, std::uint64_t>>
extern const std::unordered_map<Components::Item, int> MINING_LEVEL;
extern const std::unordered_map<Components::Item, registers::MiningSystem> MINING_SYSTEM;

extern const std::unordered_map<Components::Item, std::uint64_t> BURNING_TIME;
extern const std::unordered_map<Components::Item, Components::Item> SMELTING_RECIPIE;

extern const std::vector<std::pair<float, std::vector<std::pair<Components::Item, Eigen::Vector2i>>>>
SURFACE_STRUCTURES;
extern const std::unordered_map<Components::Item, std::vector<std::pair<float, Components::Item>>> LOOT_TABLES;
Expand Down
4 changes: 2 additions & 2 deletions include/systems/textSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ class TextSystem {
// Size in 1/64 of a pixel
void setFontSize(const unsigned int size);
void draw(class Scene* scene);
void draw(std::string_view str, const Eigen::Vector2f& offset, bool translate);
void draw(std::string_view str, const Eigen::Vector2f& offset, bool translate, const Eigen::Vector3f& color = COLOR);

private:
const static inline Eigen::Vector3f color = Eigen::Vector3f(0.0f, 0.0f, 0.0f);
const static inline Eigen::Vector3f COLOR = Eigen::Vector3f(0.0f, 0.0f, 0.0f);

struct Glyph {
class Texture* texture;
Expand Down
9 changes: 6 additions & 3 deletions src/components/crafting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ bool CraftingInventory::update(class Scene* const scene, const float delta) {
scene->mMouse.item = mCraftingItems[slot] = item;
scene->mMouse.count = mCraftingCount[slot] = half;
scene->mMouse.count += round;
if (scene->mMouse.count == 0) {
scene->mMouse.item = Components::AIR();
}

// Same block: add one to stack
} else if (mCraftingCount[slot] == 0 || mCraftingItems[slot] == scene->mMouse.item) {
mCraftingCount[slot] += 1;
Expand Down Expand Up @@ -206,11 +210,10 @@ bool CraftingInventory::update(class Scene* const scene, const float delta) {
continue;
}

if (mCraftingCount[i] == 1) {
--mCraftingCount[i];
if (mCraftingCount[i] == 0) {
mCraftingItems[i] = Components::AIR();
}

--mCraftingCount[i];
}

scene->getSignal(EventManager::LEFT_CLICK_DOWN_SIGNAL) = false;
Expand Down
150 changes: 150 additions & 0 deletions src/components/furnace.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#include "components/furnace.hpp"

#include "game.hpp"
#include "managers/eventManager.hpp"
#include "managers/systemManager.hpp"
#include "opengl/mesh.hpp"
#include "opengl/texture.hpp"
#include "registers.hpp"
#include "scene.hpp"
#include "systems/UISystem.hpp"

#include <SDL3/SDL.h>
#include <algorithm>
#include <cstddef>
#include <cstdint>

// Crafting table
FurnaceInventory::FurnaceInventory(struct furnace_t)
: Inventory(Eigen::Vector2f(8, 8), "ui/furnace.png"), mSmeltingItems(2, Components::AIR()),
mSmeltingCount(2, 0), mLastCraft(0) {
mCountRegister[getID<FurnaceInventory>()] = &mSmeltingCount;
mItemRegister[getID<FurnaceInventory>()] = &mSmeltingItems;
}

bool FurnaceInventory::update(class Scene* const, const float) { return true; }

void FurnaceInventory::craft() {}

bool FurnaceInventory::checkRecipie(const std::uint64_t r) { return r; }

void FurnaceInventory::draw(class Scene* scene) {
Inventory::drawInventory(scene);
Inventory::drawItems(scene);

SystemManager* const systemManager = mGame->getSystemManager();
const Eigen::Vector2f dimensions = systemManager->getDemensions();
Shader* const shader = systemManager->getShader("ui.vert", "ui.frag");
Mesh* const mesh = systemManager->getUISystem()->getMesh();

float sx, sy;
float ox, oy;
float scale;
if (dimensions.x() <= dimensions.y()) {
sx = dimensions.x() / 4 * 3;
sy = sx / INVENTORY_TEXTURE_WIDTH * INVENTORY_TEXTURE_HEIGHT;
ox = sx / 6;
oy = (dimensions.y() - sy) / 2;

scale = sx / INVENTORY_TEXTURE_WIDTH;
} else {
sy = dimensions.y() / 4 * 3;
sx = sy / INVENTORY_TEXTURE_HEIGHT * INVENTORY_TEXTURE_WIDTH;
ox = (dimensions.x() - sx) / 2;
oy = sy / 6;

scale = sy / INVENTORY_TEXTURE_HEIGHT;
}

ox += (INVENTORY_SLOTS_OFFSET_X + mAX) * scale - (INVENTORY_SLOT_X * scale - sx / INVENTORY_INV_SCALE);
oy += (INVENTORY_SLOTS_OFFSET_Y + mAY) * scale - (INVENTORY_SLOT_Y * scale - sy / INVENTORY_INV_SCALE);

shader->activate();
shader->set("texture_diffuse"_u, 0);
shader->set("size"_u, sx / INVENTORY_INV_SCALE, sy / INVENTORY_INV_SCALE);

const bool virtItems =
scene->getSignal(EventManager::RIGHT_HOLD_SIGNAL) || scene->getSignal(EventManager::LEFT_HOLD_SIGNAL);

std::uint64_t vcount = 0;
if (scene->getSignal(EventManager::LEFT_HOLD_SIGNAL)) {
if (!mPath.empty()) {
vcount = scene->mMouse.count / mPath.size();
}
} else {
vcount = 1;
}

// Fuel spot
if (!(mSmeltingCount[0] == 0 && !virtItems)) {
auto type = mSmeltingItems[0];
auto count = mSmeltingCount[0];
if (virtItems) {
if (auto s = std::ranges::find(mPath, std::make_pair(getID<FurnaceInventory>(), 0));
s != mPath.end()) {
count += vcount;
type = scene->mMouse.item;
} else if (count == 0) {
// This slot isn't in our path
goto e1;
}
}

Texture* const texture = systemManager->getTexture(registers::TEXTURES.at(type));
texture->activate(0);

shader->set("offset"_u, ox + 5, oy);

mesh->draw(shader);

if (count > 1) {
mGame->getSystemManager()->getTextSystem()->draw(
std::to_string(count), Eigen::Vector2f(ox + INVENTORY_SLOT_X / 2 * scale - 2, oy - 5),
false);
}

shader->activate();
}
e1:

ox += mBX * scale;
oy += mBY * scale;
// Item spot
if (!(mSmeltingCount[1] == 0 && !virtItems)) {
auto type = mSmeltingItems[1];
auto count = mSmeltingCount[1];
if (virtItems) {
if (auto s = std::ranges::find(mPath, std::make_pair(getID<FurnaceInventory>(), 1));
s != mPath.end()) {
count += vcount;
type = scene->mMouse.item;
} else if (count == 0) {
// This slot isn't in our path
goto e2;
}
}

Texture* const texture = systemManager->getTexture(registers::TEXTURES.at(type));
texture->activate(0);

shader->set("offset"_u, ox + 5, oy);

mesh->draw(shader);

if (count > 1) {
mGame->getSystemManager()->getTextSystem()->draw(
std::to_string(count), Eigen::Vector2f(ox + INVENTORY_SLOT_X / 2 * scale - 2, oy - 5),
false);
}

shader->activate();
}
e2:

// Draw output slot
// 57x9
ox += mOutX * scale;
oy += mOutY * scale;

Inventory::drawMouse(scene);
}
3 changes: 3 additions & 0 deletions src/components/inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ bool Inventory::update(class Scene* scene, float) {
scene->mMouse.item = mItems[slot] = item;
scene->mMouse.count = mCount[slot] = half;
scene->mMouse.count += round;
if (scene->mMouse.count == 0) {
scene->mMouse.item = Components::AIR();
}
// Same block: add one to stack
} else if (mCount[slot] == 0 || mItems[slot] == scene->mMouse.item) {
mCount[slot] += 1;
Expand Down
1 change: 1 addition & 0 deletions src/components/playerInventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ void PlayerInventory::tryPlace(class Scene* scene, const Eigen::Vector2i& pos) {
mItems[mSelect] = Components::AIR();
}
}

19 changes: 18 additions & 1 deletion src/registers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "components.hpp"
#include "components/crafting.hpp"
#include "components/furnace.hpp"
#include "items.hpp"
#include "screens/screen.hpp"

Expand Down Expand Up @@ -96,6 +97,10 @@ const std::unordered_map<Components::Item, std::vector<std::pair<float, Componen
{
{1.1f, Item::DIRT},
}},
{Item::STONE,
{
{1.1f, Item::COBBLESTONE},
}},
};

// NOLINTBEGIN
Expand Down Expand Up @@ -205,13 +210,25 @@ const std::vector<std::tuple<std::pair<std::uint64_t, std::uint64_t>, std::vecto
};
// NOLINTEND

const std::unordered_map<Components::Item, std::uint64_t> BURNING_TIME = {
{Item::OAK_LOG, 160},
{Item::OAK_PLANKS, 40},
{Item::STICK, 10},
};

const std::unordered_map<Components::Item, Components::Item> SMELTING_RECIPIE = {
{Item::COBBLESTONE, Item::STONE},
};

template <typename T, typename... Args> T* staticHelper(Args&&... args) {
static T t(std::forward<Args>(args)...);
return &t;
};

const std::unordered_map<Components::Item, Screen* (*)(void)> CLICKABLES = {
{Item::CRAFTING_TABLE, [] -> Screen* { return staticHelper<CraftingInventory>(crafting_table_t()); }}};
{Item::CRAFTING_TABLE, [] -> Screen* { return staticHelper<CraftingInventory>(crafting_table_t()); }},
{Item::CRAFTING_TABLE, [] -> Screen* { return staticHelper<FurnaceInventory>(furnace_t()); }},
};

const std::vector<std::string> BACKGROUND_SOUNDS = {
"sweden.wav",
Expand Down
9 changes: 5 additions & 4 deletions src/systems/renderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ EM_JS(int, browserWidth, (), { return window.innerWidth; });
RenderSystem::RenderSystem() noexcept
: mGame(Game::getInstance()), mWindow(nullptr, SDL_DestroyWindow), mCursor(nullptr, SDL_DestroyCursor),
mIcon(nullptr, SDL_DestroySurface), mGL(nullptr), mFramebuffer(nullptr), mMatricesUBO(nullptr),
mTextures(std::make_unique<TextureManager>()),
mShaders(std::make_unique<ShaderManager>()), mMesh(nullptr), mWidth(0), mHeight(0) {
mTextures(std::make_unique<TextureManager>()), mShaders(std::make_unique<ShaderManager>()), mMesh(nullptr),
mWidth(0), mHeight(0) {
const SDL_DisplayMode* const DM = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay());

SDL_Log("\n");
Expand Down Expand Up @@ -504,7 +504,7 @@ void RenderSystem::drawHUD(Scene* scene) {
Texture* const itemTexture = systemManager->getTexture(registers::TEXTURES.at(inventory->mItems[i]));
itemTexture->activate(0);

shader->set("offset"_u, offset.x() + i * x / 9 + y / 4, y / 4);
shader->set("offset"_u, offset.x() + i * x / 9.1 + y / 4, y / 4);

mMesh->draw(shader);

Expand All @@ -513,7 +513,8 @@ void RenderSystem::drawHUD(Scene* scene) {
float yoffset = inventory->mCount[i] >= 10 ? (y / 5 * 3) : (y / 4 * 3);
mGame->getSystemManager()->getTextSystem()->draw(
std::to_string(inventory->mCount[i]),
Eigen::Vector2f(offset.x() + i * x / 9 + yoffset, y / 9), false);
Eigen::Vector2f(offset.x() + i * x / 9 + yoffset, y / 9), false,
Eigen::Vector3f(0.9f, 0.9f, 0.9f));
}

shader->activate();
Expand Down
Loading

0 comments on commit a29c4e8

Please sign in to comment.