simple level loading

This commit is contained in:
Noel Berry 2021-01-03 13:04:11 -08:00
parent eefc0547eb
commit a8b78214f9
13 changed files with 135 additions and 33 deletions

BIN
content/map/0x0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Binary file not shown.

View File

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

View File

@ -14,5 +14,7 @@ namespace TL
int columns = 0; int columns = 0;
int rows = 0; int rows = 0;
Subtexture tiles[max_columns * max_rows]; Subtexture tiles[max_columns * max_rows];
const Subtexture& random_tile() const;
}; };
} }

View File

@ -55,7 +55,7 @@ void Animator::render(Batch& batch)
if (in_valid_state()) if (in_valid_state())
{ {
batch.push_matrix( 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& anim = m_sprite->animations[m_animation_index];
auto& frame = anim.frames[m_frame_index]; auto& frame = anim.frames[m_frame_index];

View File

@ -16,6 +16,7 @@ namespace TL
float m_frame_counter = 0; float m_frame_counter = 0;
public: public:
Vec2 scale = Vec2::one;
Animator() = default; Animator() = default;
Animator(const String& sprite); Animator(const String& sprite);

View File

@ -1,5 +1,6 @@
#include "player.h" #include "player.h"
#include "mover.h" #include "mover.h"
#include "animator.h"
using namespace TL; using namespace TL;
@ -34,17 +35,31 @@ void Player::update()
input_jump.update(); input_jump.update();
auto mover = get<Mover>(); auto mover = get<Mover>();
auto on_ground = mover->on_ground(); auto anim = get<Animator>();
auto was_on_ground = m_on_ground;
m_on_ground = mover->on_ground();
int input = input_move.value_i().x; 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 // Horizontal Movement
{ {
// Acceleration // 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 // 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) if (Calc::abs(mover->speed.x) > maxspd)
{ {
mover->speed.x = Calc::approach( mover->speed.x = Calc::approach(
@ -53,12 +68,17 @@ void Player::update()
2000 * Time::delta); 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); mover->speed.x = Calc::approach(mover->speed.x, 0, friction * Time::delta);
// Facing Direction
if (input != 0 && m_on_ground)
facing = input;
} }
// Gravity // Gravity
if (!on_ground) if (!m_on_ground)
{ {
float grav = gravity; float grav = gravity;
if (Calc::abs(mover->speed.y) < 20 && input_jump.down()) if (Calc::abs(mover->speed.y) < 20 && input_jump.down())
@ -71,6 +91,7 @@ void Player::update()
{ {
if (input_jump.pressed() && mover->on_ground()) if (input_jump.pressed() && mover->on_ground())
{ {
anim->scale = Vec2(facing * 0.65f, 1.4f);
mover->speed.x = input * max_air_speed; mover->speed.x = input * max_air_speed;
m_jump_timer = jump_time; m_jump_timer = jump_time;
} }

View File

@ -16,6 +16,8 @@ namespace TL
void update() override; void update() override;
private: private:
int facing = 1;
float m_jump_timer = 0; float m_jump_timer = 0;
bool m_on_ground;
}; };
} }

View File

@ -7,11 +7,11 @@ using namespace TL;
namespace namespace
{ {
FilePath root; struct RoomInfo
Vector<Sprite> sprites; {
Vector<Tileset> tilesets; Image image;
Vector<Subtexture> subtextures; Point cell;
TextureRef sprite_atlas; };
struct SpriteInfo struct SpriteInfo
{ {
@ -19,6 +19,13 @@ namespace
Aseprite aseprite; Aseprite aseprite;
uint64_t pack_index; uint64_t pack_index;
}; };
FilePath root;
Vector<Sprite> sprites;
Vector<Tileset> tilesets;
Vector<Subtexture> subtextures;
Vector<RoomInfo> rooms;
TextureRef sprite_atlas;
} }
SpriteFont Content::font; SpriteFont Content::font;
@ -164,6 +171,28 @@ void Content::load()
i++; 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() void Content::unload()
@ -193,3 +222,12 @@ const Tileset* Content::find_tileset(const char* name)
return nullptr; return nullptr;
} }
const Image* Content::find_room(const Point& cell)
{
for (auto& it : rooms)
if (it.cell == cell)
return &it.image;
return nullptr;
}

View File

@ -20,5 +20,6 @@ namespace TL
static const Sprite* find_sprite(const char* name); static const Sprite* find_sprite(const char* name);
static const Tileset* find_tileset(const char* name); static const Tileset* find_tileset(const char* name);
static const Image* find_room(const Point& cell);
}; };
} }

View File

@ -19,31 +19,57 @@ void Game::startup()
// set batcher to use Nearest Filter // set batcher to use Nearest Filter
batch.default_sampler = TextureSampler(TextureFilter::Nearest); 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 // destroy all the entities
Factory::player(&world, Point(width / 2, height - 32)); world.clear();
// get the castle tileset for now // get the castle tileset for now
auto castle = Content::find_tileset("castle"); auto castle = Content::find_tileset("castle");
// make the floor // make the floor
auto floor = world.add_entity(); auto floor = world.add_entity();
auto tm = floor->add(Tilemap(8, 8, 40, 23)); auto tilemap = floor->add(Tilemap(8, 8, columns, rows));
tm->set_cells(0, 20, 40, 3, &castle->tiles[0]); auto solids = floor->add(Collider::make_grid(8, 40, 23));
tm->set_cells(0, 18, 10, 2, &castle->tiles[0]); solids->mask = Mask::solid;
auto c2 = floor->add(Collider::make_grid(8, 40, 23)); // loop over the room grid
c2->set_cells(0, 20, 40, 3, true); for (int x = 0; x < columns; x ++)
c2->set_cells(0, 18, 10, 2, true); for (int y = 0; y < rows; y++)
c2->mask = Mask::solid; {
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() void Game::shutdown()
@ -56,7 +82,7 @@ void Game::update()
if (Input::pressed(Key::F1)) if (Input::pressed(Key::F1))
m_draw_colliders = !m_draw_colliders; m_draw_colliders = !m_draw_colliders;
if (Input::pressed(Key::F2)) if (Input::pressed(Key::F2))
load_map(); load_room(room);
world.update(); world.update();
} }
@ -65,7 +91,7 @@ void Game::render()
{ {
// draw gameplay stuff // draw gameplay stuff
{ {
buffer->clear(0x4488aa); buffer->clear(0x150e22);
world.render(batch); world.render(batch);
@ -79,7 +105,6 @@ void Game::render()
} }
} }
batch.tex(Content::atlas());
batch.render(buffer); batch.render(buffer);
batch.clear(); batch.clear();
} }

View File

@ -9,16 +9,19 @@ namespace TL
class Game class Game
{ {
public: public:
static constexpr int width = 320; static constexpr int width = 240;
static constexpr int height = 180; static constexpr int height = 135;
static constexpr int tile_width = 8; static constexpr int tile_width = 8;
static constexpr int tile_height = 8; static constexpr int tile_height = 8;
static constexpr int columns = width / tile_width;
static constexpr int rows = height / tile_height + 1;
World world; World world;
FrameBufferRef buffer; FrameBufferRef buffer;
Batch batch; Batch batch;
Point room;
void load_map(); void load_room(Point cell);
void startup(); void startup();
void shutdown(); void shutdown();
void update(); void update();