mirror of
https://github.com/NoelFB/tiny_link.git
synced 2024-11-25 18:18:56 +08:00
simple level loading
This commit is contained in:
parent
eefc0547eb
commit
a8b78214f9
BIN
content/map/0x0.png
Normal file
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.
|
@ -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];
|
||||||
|
}
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -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];
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,31 +35,50 @@ 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(
|
||||||
mover->speed.x,
|
mover->speed.x,
|
||||||
Calc::sign(mover->speed.x) * maxspd,
|
Calc::sign(mover->speed.x) * maxspd,
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -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()
|
||||||
|
@ -192,4 +221,13 @@ const Tileset* Content::find_tileset(const char* name)
|
||||||
return ⁢
|
return ⁢
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
57
src/game.cpp
57
src/game.cpp
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user