room transition + attack anim

This commit is contained in:
Noel Berry
2021-01-03 14:08:22 -08:00
parent a8b78214f9
commit fb9cebd8ff
15 changed files with 249 additions and 54 deletions

View File

@ -4,10 +4,16 @@
#include "assets/tileset.h"
#include "components/collider.h"
#include "components/tilemap.h"
#include "components/player.h"
#include "factory.h"
using namespace TL;
namespace
{
constexpr float transition_duration = 0.75f;
}
void Game::startup()
{
// load our content
@ -21,6 +27,8 @@ void Game::startup()
m_draw_colliders = false;
// camera setup
camera = Vec2::zero;
load_room(Point(0, 0));
}
@ -30,14 +38,16 @@ void Game::load_room(Point cell)
BLAH_ASSERT(grid, "Room doesn't exist!");
room = cell;
// destroy all the entities
world.clear();
// get room offset
auto offset = Point(cell.x * width, cell.y * height);
// get the castle tileset for now
auto castle = Content::find_tileset("castle");
auto grass = Content::find_tileset("grass");
auto plants = Content::find_tileset("plants");
// make the floor
auto floor = world.add_entity();
auto floor = world.add_entity(offset);
auto tilemap = floor->add(Tilemap(8, 8, columns, rows));
auto solids = floor->add(Collider::make_grid(8, 40, 23));
solids->mask = Mask::solid;
@ -46,6 +56,7 @@ void Game::load_room(Point cell)
for (int x = 0; x < columns; x ++)
for (int y = 0; y < rows; y++)
{
Point world_position = offset + Point(x * tile_width, y * tile_height);
Color col = grid->pixels[x + y * columns];
uint32_t rgb =
((uint32_t)col.r << 16) |
@ -58,15 +69,27 @@ void Game::load_room(Point cell)
case 0x000000:
break;
// solids
// castle tiles
case 0xffffff:
tilemap->set_cell(x, y, &castle->random_tile());
solids->set_cell(x, y, true);
break;
// player
// grass tiles
case 0x8f974a:
tilemap->set_cell(x, y, &grass->random_tile());
solids->set_cell(x, y, true);
break;
// plants tiles
case 0x4b692f:
tilemap->set_cell(x, y, &plants->random_tile());
break;
// player (only if it doesn't already exist)
case 0x6abe30:
Factory::player(&world, Point(x * tile_width + tile_width / 2, (y + 1) * tile_height));
if (!world.first<Player>())
Factory::player(&world, world_position + Point(tile_width / 2, tile_height));
break;
}
}
@ -79,12 +102,87 @@ void Game::shutdown()
void Game::update()
{
// Toggle Collider Render
if (Input::pressed(Key::F1))
m_draw_colliders = !m_draw_colliders;
if (Input::pressed(Key::F2))
load_room(room);
world.update();
// Reload Current Room
if (Input::pressed(Key::F2))
{
m_transition = false;
world.clear();
load_room(room);
}
// Normal Update
if (!m_transition)
{
world.update();
auto player = world.first<Player>();
if (player)
{
auto pos = player->entity()->position;
auto bounds = RectI(room.x * width, room.y * height, width, height);
if (!bounds.contains(pos))
{
// target room
Point next_room = Point(pos.x / width, pos.y / height);
if (pos.x < 0) next_room.x--;
if (pos.y < 0) next_room.y--;
// see if room exists
if (Content::find_room(next_room))
{
// transiton to it!
m_transition = true;
m_next_ease = 0;
m_next_room = next_room;
m_last_room = room;
// store entities from the previous room
m_last_entities.clear();
Entity* e = world.first_entity();
while (e)
{
m_last_entities.push_back(e);
e = e->next();
}
// load contents of the next room
load_room(next_room);
}
// doesn't exist, clamp player
else
{
player->entity()->position = Point(
Calc::clamp_int(pos.x, bounds.x, bounds.x + bounds.w),
Calc::clamp_int(pos.y, bounds.y, bounds.y + bounds.h));
}
}
}
}
// Room Transition routine
else
{
auto last_cam = Vec2(m_last_room.x * width, m_last_room.y * height);
auto next_cam = Vec2(m_next_room.x * width, m_next_room.y * height);
m_next_ease = Calc::approach(m_next_ease, 1.0f, Time::delta / transition_duration);
camera = last_cam + (next_cam - last_cam) * Ease::cube_in_out(m_next_ease);
if (m_next_ease >= 1.0f)
{
// delete old objects (except player!)
for (auto& it : m_last_entities)
{
if (!it->get<Player>())
world.destroy_entity(it);
}
m_transition = false;
}
}
}
void Game::render()
@ -93,6 +191,7 @@ void Game::render()
{
buffer->clear(0x150e22);
batch.push_matrix(Mat3x2::create_translation(-camera));
world.render(batch);
if (m_draw_colliders)
@ -105,6 +204,7 @@ void Game::render()
}
}
batch.pop_matrix();
batch.render(buffer);
batch.clear();
}