mirror of
https://github.com/NoelFB/tiny_link.git
synced 2024-11-25 18:18:56 +08:00
basic player movement
This commit is contained in:
parent
4e05170023
commit
c38b1e1418
|
@ -28,6 +28,8 @@ add_executable(game
|
|||
src/components/mover.h
|
||||
src/components/mover.cpp
|
||||
src/masks.h
|
||||
src/factory.h
|
||||
src/factory.cpp
|
||||
)
|
||||
|
||||
# Reference blah
|
||||
|
|
|
@ -71,8 +71,20 @@ void Mover::stop()
|
|||
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()
|
||||
{
|
||||
// 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
|
||||
Vec2 total = m_remainder + speed * Time::delta;
|
||||
|
||||
|
|
|
@ -13,8 +13,9 @@ namespace TL
|
|||
Vec2 m_remainder;
|
||||
|
||||
public:
|
||||
Collider* collider;
|
||||
Collider* collider = nullptr;
|
||||
Vec2 speed;
|
||||
float gravity = 0;
|
||||
|
||||
bool move_x(int amount);
|
||||
bool move_y(int amount);
|
||||
|
@ -23,6 +24,8 @@ namespace TL
|
|||
void stop_y();
|
||||
void stop();
|
||||
|
||||
bool on_ground(int dist = 1) const;
|
||||
|
||||
void update() override;
|
||||
};
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,13 @@ namespace TL
|
|||
class Player : public Component
|
||||
{
|
||||
public:
|
||||
VirtualStick input_move;
|
||||
VirtualButton input_jump;
|
||||
|
||||
Player();
|
||||
void update() override;
|
||||
|
||||
private:
|
||||
float m_jump_timer = 0;
|
||||
};
|
||||
}
|
23
src/factory.cpp
Normal file
23
src/factory.cpp
Normal 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
13
src/factory.h
Normal 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);
|
||||
}
|
||||
}
|
33
src/game.cpp
33
src/game.cpp
|
@ -1,9 +1,8 @@
|
|||
#include "game.h"
|
||||
#include "content.h"
|
||||
#include "masks.h"
|
||||
#include "components/animator.h"
|
||||
#include "components/collider.h"
|
||||
#include "components/mover.h"
|
||||
#include "factory.h"
|
||||
|
||||
using namespace TL;
|
||||
|
||||
|
@ -18,21 +17,21 @@ void Game::startup()
|
|||
// set batcher to use Nearest Filter
|
||||
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;
|
||||
|
||||
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()
|
||||
|
@ -44,6 +43,8 @@ void Game::update()
|
|||
{
|
||||
if (Input::pressed(Key::F1))
|
||||
m_draw_colliders = !m_draw_colliders;
|
||||
if (Input::pressed(Key::F2))
|
||||
load_map();
|
||||
|
||||
world.update();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace TL
|
|||
FrameBufferRef buffer;
|
||||
Batch batch;
|
||||
|
||||
void load_map();
|
||||
void startup();
|
||||
void shutdown();
|
||||
void update();
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
for (int i = 0; i < Component::Types::count(); i++)
|
||||
|
|
|
@ -143,6 +143,7 @@ namespace TL
|
|||
const T* last() const;
|
||||
|
||||
void destroy(Component* component);
|
||||
void clear();
|
||||
|
||||
void update();
|
||||
|
||||
|
@ -170,14 +171,14 @@ namespace TL
|
|||
T* Component::get()
|
||||
{
|
||||
BLAH_ASSERT(m_entity, "Component must be assigned to an Entity");
|
||||
return entity->get<T>();
|
||||
return m_entity->get<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T* Component::get() const
|
||||
{
|
||||
BLAH_ASSERT(m_entity, "Component must be assigned to an Entity");
|
||||
return entity->get<T>();
|
||||
return m_entity->get<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
|
Loading…
Reference in New Issue
Block a user