diff --git a/content/map/0x0.png b/content/map/0x0.png new file mode 100644 index 0000000..fa32c71 Binary files /dev/null and b/content/map/0x0.png differ diff --git a/content/sprites/player.ase b/content/sprites/player.ase index 0d785f0..2ebbb89 100644 Binary files a/content/sprites/player.ase and b/content/sprites/player.ase differ diff --git a/content/tilesets/castle.ase b/content/tilesets/castle.ase index cc9e9dd..767066b 100644 Binary files a/content/tilesets/castle.ase and b/content/tilesets/castle.ase differ diff --git a/src/assets/tileset.cpp b/src/assets/tileset.cpp index e69de29..9c64fcb 100644 --- a/src/assets/tileset.cpp +++ b/src/assets/tileset.cpp @@ -0,0 +1,9 @@ +#include "tileset.h" + +using namespace TL; + +const Subtexture& Tileset::random_tile() const +{ + int i = Calc::rand_int(columns * rows); + return tiles[i]; +} diff --git a/src/assets/tileset.h b/src/assets/tileset.h index 5f0a00e..334f2bb 100644 --- a/src/assets/tileset.h +++ b/src/assets/tileset.h @@ -14,5 +14,7 @@ namespace TL int columns = 0; int rows = 0; Subtexture tiles[max_columns * max_rows]; + + const Subtexture& random_tile() const; }; } \ No newline at end of file diff --git a/src/components/animator.cpp b/src/components/animator.cpp index ef41913..92f198a 100644 --- a/src/components/animator.cpp +++ b/src/components/animator.cpp @@ -55,7 +55,7 @@ void Animator::render(Batch& batch) if (in_valid_state()) { batch.push_matrix( - Mat3x2::create_transform(entity()->position, m_sprite->origin, Vec2::one, 0)); + Mat3x2::create_transform(entity()->position, m_sprite->origin, scale, 0)); auto& anim = m_sprite->animations[m_animation_index]; auto& frame = anim.frames[m_frame_index]; diff --git a/src/components/animator.h b/src/components/animator.h index 3ff92d4..c0515d3 100644 --- a/src/components/animator.h +++ b/src/components/animator.h @@ -16,6 +16,7 @@ namespace TL float m_frame_counter = 0; public: + Vec2 scale = Vec2::one; Animator() = default; Animator(const String& sprite); diff --git a/src/components/player.cpp b/src/components/player.cpp index 3cac268..b460e12 100644 --- a/src/components/player.cpp +++ b/src/components/player.cpp @@ -1,5 +1,6 @@ #include "player.h" #include "mover.h" +#include "animator.h" using namespace TL; @@ -34,31 +35,50 @@ void Player::update() input_jump.update(); auto mover = get(); - auto on_ground = mover->on_ground(); + auto anim = get(); + auto was_on_ground = m_on_ground; + m_on_ground = mover->on_ground(); int input = input_move.value_i().x; + // Sprite Stuff + { + // land squish + if (!was_on_ground && m_on_ground) + anim->scale = Vec2(facing * 1.5f, 0.7f); + + // lerp scale back to one + anim->scale = Calc::approach(anim->scale, Vec2(facing, 1.0f), Time::delta * 4); + + // set facing + anim->scale.x = Calc::abs(anim->scale.x) * facing; + } + // Horizontal Movement { - // Acceleration - mover->speed.x += input * (on_ground ? ground_accel : air_accel) * Time::delta; + mover->speed.x += input * (m_on_ground ? ground_accel : air_accel) * Time::delta; // Maxspeed - auto maxspd = (on_ground ? max_ground_speed : max_air_speed); + auto maxspd = (m_on_ground ? max_ground_speed : max_air_speed); if (Calc::abs(mover->speed.x) > maxspd) { mover->speed.x = Calc::approach( - mover->speed.x, + mover->speed.x, Calc::sign(mover->speed.x) * maxspd, 2000 * Time::delta); } - if (input == 0 && on_ground) + // Friction + if (input == 0 && m_on_ground) mover->speed.x = Calc::approach(mover->speed.x, 0, friction * Time::delta); + + // Facing Direction + if (input != 0 && m_on_ground) + facing = input; } // Gravity - if (!on_ground) + if (!m_on_ground) { float grav = gravity; if (Calc::abs(mover->speed.y) < 20 && input_jump.down()) @@ -71,6 +91,7 @@ void Player::update() { if (input_jump.pressed() && mover->on_ground()) { + anim->scale = Vec2(facing * 0.65f, 1.4f); mover->speed.x = input * max_air_speed; m_jump_timer = jump_time; } diff --git a/src/components/player.h b/src/components/player.h index e707308..c66bbd6 100644 --- a/src/components/player.h +++ b/src/components/player.h @@ -16,6 +16,8 @@ namespace TL void update() override; private: + int facing = 1; float m_jump_timer = 0; + bool m_on_ground; }; } \ No newline at end of file diff --git a/src/content.cpp b/src/content.cpp index b2e3320..8e2088d 100644 --- a/src/content.cpp +++ b/src/content.cpp @@ -7,11 +7,11 @@ using namespace TL; namespace { - FilePath root; - Vector sprites; - Vector tilesets; - Vector subtextures; - TextureRef sprite_atlas; + struct RoomInfo + { + Image image; + Point cell; + }; struct SpriteInfo { @@ -19,6 +19,13 @@ namespace Aseprite aseprite; uint64_t pack_index; }; + + FilePath root; + Vector sprites; + Vector tilesets; + Vector subtextures; + Vector rooms; + TextureRef sprite_atlas; } SpriteFont Content::font; @@ -164,6 +171,28 @@ void Content::load() i++; } } + + // load the rooms + for (auto& it : Directory::enumerate(path() + "/map", false)) + { + if (!it.ends_with(".png")) + continue; + + auto name = Path::get_file_name_no_ext(it); + auto point = name.split('x'); + if (point.size() != 2) + continue; + + RoomInfo info; + info.cell.x = strtol(point[0].cstr(), nullptr, 0); + info.cell.y = strtol(point[1].cstr(), nullptr, 0); + info.image = Image(it); + + BLAH_ASSERT(info.image.width == Game::columns, "Room is incorrect width!"); + BLAH_ASSERT(info.image.height == Game::rows, "Room is incorrect height!"); + + rooms.push_back(info); + } } void Content::unload() @@ -192,4 +221,13 @@ const Tileset* Content::find_tileset(const char* name) return ⁢ return nullptr; -} \ No newline at end of file +} + +const Image* Content::find_room(const Point& cell) +{ + for (auto& it : rooms) + if (it.cell == cell) + return &it.image; + + return nullptr; +} diff --git a/src/content.h b/src/content.h index 90016bc..4c7463e 100644 --- a/src/content.h +++ b/src/content.h @@ -20,5 +20,6 @@ namespace TL static const Sprite* find_sprite(const char* name); static const Tileset* find_tileset(const char* name); + static const Image* find_room(const Point& cell); }; } \ No newline at end of file diff --git a/src/game.cpp b/src/game.cpp index e19769e..83a676c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -19,31 +19,57 @@ void Game::startup() // set batcher to use Nearest Filter batch.default_sampler = TextureSampler(TextureFilter::Nearest); - m_draw_colliders = true; + m_draw_colliders = false; - load_map(); + load_room(Point(0, 0)); } -void Game::load_map() +void Game::load_room(Point cell) { - world.clear(); + const Image* grid = Content::find_room(cell); + BLAH_ASSERT(grid, "Room doesn't exist!"); + room = cell; - // add a test player - Factory::player(&world, Point(width / 2, height - 32)); + // destroy all the entities + world.clear(); // get the castle tileset for now auto castle = Content::find_tileset("castle"); // make the floor auto floor = world.add_entity(); - auto tm = floor->add(Tilemap(8, 8, 40, 23)); - tm->set_cells(0, 20, 40, 3, &castle->tiles[0]); - tm->set_cells(0, 18, 10, 2, &castle->tiles[0]); + auto tilemap = floor->add(Tilemap(8, 8, columns, rows)); + auto solids = floor->add(Collider::make_grid(8, 40, 23)); + solids->mask = Mask::solid; - auto c2 = floor->add(Collider::make_grid(8, 40, 23)); - c2->set_cells(0, 20, 40, 3, true); - c2->set_cells(0, 18, 10, 2, true); - c2->mask = Mask::solid; + // loop over the room grid + for (int x = 0; x < columns; x ++) + for (int y = 0; y < rows; y++) + { + Color col = grid->pixels[x + y * columns]; + uint32_t rgb = + ((uint32_t)col.r << 16) | + ((uint32_t)col.g << 8) | + ((uint32_t)col.b); + + switch (rgb) + { + // black does nothing + case 0x000000: + break; + + // solids + case 0xffffff: + tilemap->set_cell(x, y, &castle->random_tile()); + solids->set_cell(x, y, true); + break; + + // player + case 0x6abe30: + Factory::player(&world, Point(x * tile_width + tile_width / 2, (y + 1) * tile_height)); + break; + } + } } void Game::shutdown() @@ -56,7 +82,7 @@ void Game::update() if (Input::pressed(Key::F1)) m_draw_colliders = !m_draw_colliders; if (Input::pressed(Key::F2)) - load_map(); + load_room(room); world.update(); } @@ -65,7 +91,7 @@ void Game::render() { // draw gameplay stuff { - buffer->clear(0x4488aa); + buffer->clear(0x150e22); world.render(batch); @@ -79,7 +105,6 @@ void Game::render() } } - batch.tex(Content::atlas()); batch.render(buffer); batch.clear(); } diff --git a/src/game.h b/src/game.h index 6038a85..af06765 100644 --- a/src/game.h +++ b/src/game.h @@ -9,16 +9,19 @@ namespace TL class Game { public: - static constexpr int width = 320; - static constexpr int height = 180; + static constexpr int width = 240; + static constexpr int height = 135; static constexpr int tile_width = 8; static constexpr int tile_height = 8; + static constexpr int columns = width / tile_width; + static constexpr int rows = height / tile_height + 1; World world; FrameBufferRef buffer; Batch batch; + Point room; - void load_map(); + void load_room(Point cell); void startup(); void shutdown(); void update();