basic player movement

This commit is contained in:
Noel Berry 2021-01-02 17:05:12 -08:00
parent 4e05170023
commit c38b1e1418
11 changed files with 179 additions and 19 deletions

View File

@ -28,6 +28,8 @@ add_executable(game
src/components/mover.h src/components/mover.h
src/components/mover.cpp src/components/mover.cpp
src/masks.h src/masks.h
src/factory.h
src/factory.cpp
) )
# Reference blah # Reference blah

View File

@ -71,8 +71,20 @@ void Mover::stop()
m_remainder.y = 0; m_remainder.y = 0;
} }
bool Mover::on_ground(int dist) const
{
if (!collider)
return false;
return collider->check(Mask::solid, Point(0, dist));
}
void Mover::update() void Mover::update()
{ {
// apply gravity
if (gravity != 0 && (!collider || !collider->check(Mask::solid, Point(0, 1))))
speed.y += gravity * Time::delta;
// get the amount we should move, including remainder from the previous frame // get the amount we should move, including remainder from the previous frame
Vec2 total = m_remainder + speed * Time::delta; Vec2 total = m_remainder + speed * Time::delta;

View File

@ -13,8 +13,9 @@ namespace TL
Vec2 m_remainder; Vec2 m_remainder;
public: public:
Collider* collider; Collider* collider = nullptr;
Vec2 speed; Vec2 speed;
float gravity = 0;
bool move_x(int amount); bool move_x(int amount);
bool move_y(int amount); bool move_y(int amount);
@ -23,6 +24,8 @@ namespace TL
void stop_y(); void stop_y();
void stop(); void stop();
bool on_ground(int dist = 1) const;
void update() override; void update() override;
}; };
} }

View File

@ -0,0 +1,86 @@
#include "player.h"
#include "mover.h"
using namespace TL;
namespace
{
constexpr float max_ground_speed = 60;
constexpr float max_air_speed = 70;
constexpr float ground_accel = 500;
constexpr float air_accel = 20;
constexpr float friction = 800;
constexpr float gravity = 450;
constexpr float jump_force = -105;
constexpr float jump_time = 0.18f;
}
Player::Player()
{
input_move = VirtualStick()
.add_keys(Key::Left, Key::Right, Key::Up, Key::Down)
.add_buttons(0, Button::Left, Button::Right, Button::Up, Button::Down)
.add_axes(0, Axis::LeftX, Axis::LeftY, 0.2f);
input_jump = VirtualButton()
.press_buffer(0.15f)
.add_key(Key::X)
.add_button(0, Button::A);
}
void Player::update()
{
input_move.update();
input_jump.update();
auto mover = get<Mover>();
auto on_ground = mover->on_ground();
int input = input_move.value_i().x;
// Horizontal Movement
{
// Acceleration
mover->speed.x += input * (on_ground ? ground_accel : air_accel) * Time::delta;
// Maxspeed
auto maxspd = (on_ground ? max_ground_speed : max_air_speed);
if (Calc::abs(mover->speed.x) > maxspd)
{
mover->speed.x = Calc::approach(
mover->speed.x,
Calc::sign(mover->speed.x) * maxspd,
2000 * Time::delta);
}
if (input == 0 && on_ground)
mover->speed.x = Calc::approach(mover->speed.x, 0, friction * Time::delta);
}
// Gravity
if (!on_ground)
{
float grav = gravity;
if (Calc::abs(mover->speed.y) < 20 && input_jump.down())
grav *= 0.4f;
mover->speed.y += grav * Time::delta;
}
// Jumping
{
if (input_jump.pressed() && mover->on_ground())
{
mover->speed.x = input * max_air_speed;
m_jump_timer = jump_time;
}
if (m_jump_timer > 0)
{
mover->speed.y = -100;
m_jump_timer -= Time::delta;
if (!input_jump.down())
m_jump_timer = 0;
}
}
}

View File

@ -9,6 +9,13 @@ namespace TL
class Player : public Component class Player : public Component
{ {
public: public:
VirtualStick input_move;
VirtualButton input_jump;
Player();
void update() override; void update() override;
private:
float m_jump_timer = 0;
}; };
} }

23
src/factory.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "factory.h"
#include "components/animator.h"
#include "components/collider.h"
#include "components/mover.h"
#include "components/player.h"
using namespace TL;
Entity* Factory::player(World* world, Point position)
{
auto en = world->add_entity(position);
auto an = en->add(Animator("player"));
an->play("idle");
auto hitbox = en->add(Collider::make_rect(RectI(-4, -8, 8, 8)));
auto mover = en->add(Mover());
mover->collider = hitbox;
en->add(Player());
return en;
}

13
src/factory.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include <blah.h>
#include "world.h"
using namespace Blah;
namespace TL
{
namespace Factory
{
Entity* player(World* world, Point position);
}
}

View File

@ -1,9 +1,8 @@
#include "game.h" #include "game.h"
#include "content.h" #include "content.h"
#include "masks.h" #include "masks.h"
#include "components/animator.h"
#include "components/collider.h" #include "components/collider.h"
#include "components/mover.h" #include "factory.h"
using namespace TL; using namespace TL;
@ -18,21 +17,21 @@ 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);
// add a test entity
auto en = world.add_entity(Point(100, 60));
auto an = en->add(Animator("player"));
auto col = en->add(Collider::make_rect(RectI(-4, -8, 8, 8)));
auto mover = en->add(Mover());
mover->collider = col;
mover->speed = Vec2(5, 20);
an->play("idle");
auto floor = world.add_entity(Point(50, 100));
auto c2 = floor->add(Collider::make_rect(RectI(0, 0, 100, 16)));
c2->mask = Mask::solid;
m_draw_colliders = true; m_draw_colliders = true;
load_map();
}
void Game::load_map()
{
world.clear();
// add a test player
Factory::player(&world, Point(50, 50));
auto floor = world.add_entity(Point(0, 100));
auto c2 = floor->add(Collider::make_rect(RectI(0, 0, 320, 16)));
c2->mask = Mask::solid;
} }
void Game::shutdown() void Game::shutdown()
@ -44,6 +43,8 @@ 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))
load_map();
world.update(); world.update();
} }

View File

@ -13,6 +13,7 @@ namespace TL
FrameBufferRef buffer; FrameBufferRef buffer;
Batch batch; Batch batch;
void load_map();
void startup(); void startup();
void shutdown(); void shutdown();
void update(); void update();

View File

@ -219,6 +219,17 @@ void World::destroy(Component* component)
} }
} }
void World::clear()
{
Entity* entity = first_entity();
while (entity)
{
auto next = entity->next();
destroy_entity(entity);
entity = next;
}
}
void World::update() void World::update()
{ {
for (int i = 0; i < Component::Types::count(); i++) for (int i = 0; i < Component::Types::count(); i++)

View File

@ -143,6 +143,7 @@ namespace TL
const T* last() const; const T* last() const;
void destroy(Component* component); void destroy(Component* component);
void clear();
void update(); void update();
@ -170,14 +171,14 @@ namespace TL
T* Component::get() T* Component::get()
{ {
BLAH_ASSERT(m_entity, "Component must be assigned to an Entity"); BLAH_ASSERT(m_entity, "Component must be assigned to an Entity");
return entity->get<T>(); return m_entity->get<T>();
} }
template<class T> template<class T>
const T* Component::get() const const T* Component::get() const
{ {
BLAH_ASSERT(m_entity, "Component must be assigned to an Entity"); BLAH_ASSERT(m_entity, "Component must be assigned to an Entity");
return entity->get<T>(); return m_entity->get<T>();
} }
template<class T> template<class T>