Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/target)

include(cmake/get_cpm.cmake)
CPMAddPackage("gh:adsgames/asw@0.8.0")
CPMAddPackage("gh:adsgames/asw@0.9.1")
CPMAddPackage("gh:nlohmann/json@3.11.3")

# Source code
Expand Down
6 changes: 4 additions & 2 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
"name": "debug",
"description": "Build a debug build",
"displayName": "debug",
"configurePreset": "debug"
"configurePreset": "debug",
"jobs": 0
},
{
"name": "release",
"description": "Build a release build",
"displayName": "release",
"configurePreset": "release"
"configurePreset": "release",
"jobs": 0
}
]
}
4 changes: 4 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
display: flex;
margin: 0 auto;
}

canvas {
image-rendering: pixelated;
}
</style>
</head>

Expand Down
7 changes: 4 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <asw/asw.h>

#include "./scenes/game.h"
#include "./scenes/init.h"
#include "./scenes/intro.h"
#include "./scenes/level_select.h"
#include "./scenes/menu.h"
Expand All @@ -20,17 +21,17 @@ int main()

// Initializing
asw::core::init(1280, 960);
asw::display::set_title("Mazes");
asw::display::set_icon("assets/mazes.ico");
asw::core::print_info();

// Starts Game
auto app = asw::scene::SceneManager<GameState>();
app.register_scene<InitScene>(Init, app);
app.register_scene<GameScene>(Game, app);
app.register_scene<MenuScene>(Menu, app);
app.register_scene<WinScene>(Win, app);
app.register_scene<LevelSelectScene>(LevelSelect, app);
app.register_scene<IntroScene>(Intro, app);
app.set_next_scene(Intro);
app.set_next_scene(Init);
app.start();

return 0;
Expand Down
94 changes: 49 additions & 45 deletions src/scenes/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class GameScene : public asw::scene::Scene<GameState> {
move_acc = 0.0F;
paused = false;
lives = DEFAULT_LIVES;
position = asw::Vec2<int>(40, 40);
position = asw::Vec2i(40, 40);
rotation = 0;
has_broom = false;
broom_active = false;
Expand Down Expand Up @@ -72,7 +72,7 @@ class GameScene : public asw::scene::Scene<GameState> {
{ .tile_size = 40, .render_size = 60, .offset_x = 0, .offset_y = 0 });

// Background Music
fade_in_music(song, 1.0F, 1000);
asw::sound::play_music(song, 1.0F, 1000);
}

void update(float dt) override
Expand All @@ -82,14 +82,14 @@ class GameScene : public asw::scene::Scene<GameState> {
Scene::update(dt);

// Toggle pause
if (get_key_down(Key::Escape)) {
if (is_action_pressed("pause")) {
paused = !paused;
}

// Skip updates when paused
if (paused) {
// TO menu
if (get_key_down(Key::M)) {
if (is_action_pressed("back")) {
manager.set_next_scene(GameState::Menu);
}
return;
Expand All @@ -104,7 +104,7 @@ class GameScene : public asw::scene::Scene<GameState> {
}

// Use broom
broom_active = get_key(Key::Space) && has_broom;
broom_active = is_action_down("interact") && has_broom;

// Character movement
character_move();
Expand All @@ -118,7 +118,7 @@ class GameScene : public asw::scene::Scene<GameState> {
}

// Restart Map
if (get_key_down(Key::R)) {
if (is_action_pressed("restart")) {
changeMap();
}

Expand Down Expand Up @@ -155,11 +155,11 @@ class GameScene : public asw::scene::Scene<GameState> {
}

// Draws Stats
rect_fill(asw::Quad<float>(0, 0, 1280, 20), asw::Color(0, 0, 0, 200));
rect_fill(asw::Quadf(0, 0, 1280, 20), asw::Color(0, 0, 0, 200));

text(font, std::format("Score: {}", score), asw::Vec2<float>(0, 0), palette::white);
text(font, std::format("Lives: {}", lives), asw::Vec2<float>(100, 0), palette::white);
text(font, tilemap.getLevelText(), asw::Vec2<float>(640, 0), palette::white,
text(font, std::format("Score: {}", score), asw::Vec2f(0, 0), palette::white);
text(font, std::format("Lives: {}", lives), asw::Vec2f(100, 0), palette::white);
text(font, tilemap.getLevelText(), asw::Vec2f(640, 0), palette::white,
asw::TextJustify::Center);

// Robot progress meter
Expand All @@ -172,29 +172,27 @@ class GameScene : public asw::scene::Scene<GameState> {
const float progress = tilemap.getProgress();

// Background
rect_fill(
asw::Quad<float>(meterX, meterY, meterWidth, meterHeight), palette::dark_gray);
rect_fill(asw::Quadf(meterX, meterY, meterWidth, meterHeight), palette::dark_gray);

// Filled portion (red when robots remain, green when cleared)
const auto barColor = tilemap.getCompleted() ? palette::green : palette::red;

rect_fill(
asw::Quad<float>(meterX, meterY, meterWidth * progress, meterHeight), barColor);
rect_fill(asw::Quadf(meterX, meterY, meterWidth * progress, meterHeight), barColor);

// Border
rect(asw::Quad<float>(meterX, meterY, meterWidth, meterHeight), palette::white);
rect(asw::Quadf(meterX, meterY, meterWidth, meterHeight), palette::white);

// Label
text(font,
std::format("Robots: {}/{}", tilemap.getRobotsCaptured(), tilemap.getRobotsTotal()),
asw::Vec2<float>(meterX - 5.0F, 0), palette::white, asw::TextJustify::Right);
asw::Vec2f(meterX - 5.0F, 0), palette::white, asw::TextJustify::Right);
}

// Pause Game
if (paused) {
rect_fill(asw::Quad<float>(300, 300, 680, 360), palette::very_dark_green);
rect_fill(asw::Quadf(300, 300, 680, 360), palette::very_dark_green);
text(font_pause, "Paused press ESC to resume. Press M to go to the Menu.",
asw::Vec2<float>(640, 480), palette::white, asw::TextJustify::Center);
asw::Vec2f(640, 480), palette::white, asw::TextJustify::Center);
}
}

Expand All @@ -204,7 +202,7 @@ class GameScene : public asw::scene::Scene<GameState> {
using namespace asw::input;

const auto float_pos
= asw::Vec2<float>(static_cast<float>(position.x), static_cast<float>(position.y));
= asw::Vec2f(static_cast<float>(position.x), static_cast<float>(position.y));

// Draws Character
if (rotation == 0) {
Expand All @@ -219,7 +217,7 @@ class GameScene : public asw::scene::Scene<GameState> {

// Draws broom if needed
if (broom_active) {
rotate_sprite(broom, float_pos + asw::Vec2<float>(10, 10), rotation);
rotate_sprite(broom, float_pos + asw::Vec2f(10, 10), rotation);
}
}

Expand All @@ -229,22 +227,25 @@ class GameScene : public asw::scene::Scene<GameState> {
{
using namespace asw::input;

if (get_key(Key::Up) || get_key(Key::W)) {
if (is_action_down("up")) {
rotation = 128;
move_towards({ 0, -1 });
} else if (get_key(Key::Down) || get_key(Key::S)) {
}
if (is_action_down("down")) {
rotation = 0;
move_towards({ 0, 1 });
} else if (get_key(Key::Left) || get_key(Key::A)) {
}
if (is_action_down("left")) {
rotation = 64;
move_towards({ -1, 0 });
} else if (get_key(Key::Right) || get_key(Key::D)) {
}
if (is_action_down("right")) {
rotation = 192;
move_towards({ 1, 0 });
}
}

void move_towards(const asw::Vec2<int>& target)
void move_towards(const asw::Vec2i& target)
{
using namespace asw::input;

Expand All @@ -254,12 +255,10 @@ class GameScene : public asw::scene::Scene<GameState> {

move_acc = 0;

auto player_pos = asw::Vec2<int>(position.x / 40, position.y / 40);
auto player_pos = asw::Vec2i(position.x / 40, position.y / 40);
auto tile_pos = player_pos + target;
auto tile_next_pos = player_pos + target * 2;

auto tile = tilemap.at(tile_pos);
auto next_tile = tilemap.at(tile_next_pos);

// Allow walking into
if (tile == TileType::Empty || tile == TileType::WallWalkable || tile == TileType::Robot) {
Expand All @@ -272,6 +271,22 @@ class GameScene : public asw::scene::Scene<GameState> {
return;
}

if (tile == TileType::JanitorRoom && !has_broom) {
asw::sound::play(door);
has_broom = true;
tilemap.setValue(tile_pos, TileType::JanitorRoomOpen);
return;
}

if (tile == TileType::JanitorRoomOpen && tilemap.getCompleted()) {
level_complete = true;
return;
}

// Check for box pushing or broom sweeping
auto tile_next_pos = player_pos + target * 2;
auto next_tile = tilemap.at(tile_next_pos);

if (tile == TileType::Box && next_tile == TileType::Empty) {
asw::sound::play(boxslide);
tilemap.setValue(tile_pos, TileType::Empty);
Expand Down Expand Up @@ -307,26 +322,14 @@ class GameScene : public asw::scene::Scene<GameState> {
asw::sound::play(trash);
return;
}

if (tile == TileType::JanitorRoom && !has_broom) {
asw::sound::play(door);
has_broom = true;
tilemap.setValue(tile_pos, TileType::JanitorRoomOpen);
return;
}

if (tile == TileType::JanitorRoomOpen && tilemap.getCompleted()) {
level_complete = true;
return;
}
}

void update_robots()
{
const auto player_pos = position / 40;

// Collect all robot positions first to avoid double-processing
std::vector<asw::Vec2<int>> robots;
std::vector<asw::Vec2i> robots;

for (int i = 0; i < TileMap::WIDTH; i++) {
for (int t = 0; t < TileMap::HEIGHT; t++) {
Expand All @@ -343,8 +346,9 @@ class GameScene : public asw::scene::Scene<GameState> {
}

// Build list of valid moves
std::array<asw::Vec2<int>, 4> moves = { { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } } };
std::vector<asw::Vec2<int>> valid;
const std::array<asw::Vec2i, 4> moves
= { { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } } };
std::vector<asw::Vec2i> valid;

for (const auto& m : moves) {
const auto next_pos = r + m;
Expand All @@ -364,7 +368,7 @@ class GameScene : public asw::scene::Scene<GameState> {

// 50% chance to move toward the player, 50% random
const int random_index = asw::random::between(0, valid.size() - 1);
asw::Vec2<int> chosen = valid[random_index];
asw::Vec2i chosen = valid[random_index];

if (asw::random::chance()) {
auto bestDist = player_pos.distance(r + chosen);
Expand Down Expand Up @@ -405,7 +409,7 @@ class GameScene : public asw::scene::Scene<GameState> {
float move_acc;

// Player
asw::Vec2<int> position;
asw::Vec2i position;
int rotation;
bool has_broom;
bool broom_active;
Expand Down
55 changes: 55 additions & 0 deletions src/scenes/init.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

#pragma once

#include <asw/asw.h>

#include "./scenes.h"

class InitScene : public asw::scene::Scene<GameState> {
public:
using asw::scene::Scene<GameState>::Scene;

void init() override
{
using namespace asw::input;

asw::display::set_title("Mazes");
asw::display::set_icon("assets/mazes.ico");

// Bind global actions
bind_action("right", KeyBinding { Key::Right });
bind_action("right", KeyBinding { Key::D });
bind_action("right", ControllerButtonBinding { ControllerButton::DPadRight, 0 });
bind_action("right", ControllerAxisBinding { ControllerAxis::LeftX, 0, 0.5F, true });

bind_action("left", KeyBinding { Key::Left });
bind_action("left", KeyBinding { Key::A });
bind_action("left", ControllerButtonBinding { ControllerButton::DPadLeft, 0 });
bind_action("left", ControllerAxisBinding { ControllerAxis::LeftX, 0, 0.5F, false });

bind_action("up", KeyBinding { Key::Up });
bind_action("up", KeyBinding { Key::W });
bind_action("up", ControllerButtonBinding { ControllerButton::DPadUp, 0 });
bind_action("up", ControllerAxisBinding { ControllerAxis::LeftY, 0, 0.5F, false });

bind_action("down", KeyBinding { Key::Down });
bind_action("down", KeyBinding { Key::S });
bind_action("down", ControllerButtonBinding { ControllerButton::DPadDown, 0 });
bind_action("down", ControllerAxisBinding { ControllerAxis::LeftY, 0, 0.5F, true });

bind_action("interact", KeyBinding { Key::Return });
bind_action("interact", KeyBinding { Key::Space });
bind_action("interact", ControllerButtonBinding { ControllerButton::A, 0 });

bind_action("back", KeyBinding { Key::Escape });
bind_action("back", ControllerButtonBinding { ControllerButton::Back, 0 });

bind_action("pause", KeyBinding { Key::P });
bind_action("pause", ControllerButtonBinding { ControllerButton::Start, 0 });
}

void update(float dt) override
{
manager.set_next_scene(GameState::Intro);
}
};
6 changes: 3 additions & 3 deletions src/scenes/intro.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ class IntroScene : public asw::scene::Scene<GameState> {

// Show the appropriate image for this frame
if (frame == 0) {
asw::draw::sprite(background_, asw::Vec2<float>(0, 0));
asw::draw::sprite(intro_, asw::Vec2<float>(0, 0));
asw::draw::sprite(background_, asw::Vec2f(0, 0));
asw::draw::sprite(intro_, asw::Vec2f(0, 0));
} else {
asw::draw::sprite(splash_, asw::Vec2<float>(0, 0));
asw::draw::sprite(splash_, asw::Vec2f(0, 0));
}

// Compute alpha: fade in → hold → fade out
Expand Down
Loading
Loading