Player collision response and movement physics v1.
This commit is contained in:
@@ -25,6 +25,7 @@ namespace CaveGame::Client {
|
||||
|
||||
Event<std::string> OnInput;
|
||||
|
||||
|
||||
void OnInputEvent(const std::string& msg);
|
||||
|
||||
explicit Console(Widget* parent);
|
||||
@@ -39,6 +40,7 @@ namespace CaveGame::Client {
|
||||
JUI::ScrollingRect* message_log_box;
|
||||
JUI::VerticalListLayout* message_log_layout;
|
||||
bool console_open = false;
|
||||
std::vector<std::string> history;
|
||||
private:
|
||||
};
|
||||
}
|
@@ -33,7 +33,6 @@ CaveGame::Client::Console::Console(JUI::Widget *parent) : JUI::Window(parent)
|
||||
|
||||
input_box->OnReturn += [this] (const std::string& msg) {
|
||||
OnInputEvent(msg);
|
||||
|
||||
};
|
||||
|
||||
CaveGame::Logs::Info.OnLog += [this](std::string m, Color4 c) {Log(m, c); };
|
||||
|
@@ -7,8 +7,9 @@
|
||||
// TODO: Move this shit to Client/Player.cpp
|
||||
void CaveGame::Core::Player::Draw() {
|
||||
auto myAsset = Client::AssetService::Get()->player_sprite;
|
||||
JGL::J2D::DrawPartialSprite(myAsset, position, {0,0}, {16, 24});
|
||||
JGL::J2D::OutlineRect(Colors::Red, position, bounding_box);
|
||||
JGL::J2D::DrawPartialSprite(myAsset, RenderTopLeft(), {0,0}, {16, 24}, 0);
|
||||
JGL::J2D::OutlineRect(Colors::Red, RenderTopLeft(), texture_center * 2.f);
|
||||
JGL::J2D::OutlineRect(Colors::Blue, TopLeft(), bounding_box);
|
||||
J2D::DrawString(Colors::White, std::format("vel: {},{}", Math::Round(velocity.x, 2), Math::Round(velocity.y, 2)), position.x, position.y-8, 0.5f, 8);
|
||||
J2D::DrawString(Colors::White, std::format("ct: {} cd: {}", coll_tests, coll_hits), position.x, position.y-16, 0.5f, 8);
|
||||
}
|
||||
@@ -25,6 +26,6 @@ void CaveGame::Core::Player::Update(float elapsed) {
|
||||
if (InputService::IsKeyDown(Keys::W))
|
||||
Jump();
|
||||
|
||||
if (InputService::IsKeyDown(Keys::S))
|
||||
Accelerate({0, -1});
|
||||
//if (InputService::IsKeyDown(Keys::S))
|
||||
//Accelerate({0, -1});
|
||||
}
|
@@ -17,6 +17,7 @@ void CaveGame::Client::TileHotbar::Load(CaveGame::Client::LocalWorld *world) {
|
||||
hotbar_root->BorderMode(JUI::BorderMode::Outline);
|
||||
|
||||
item_label = new JUI::TextRect(hotbar_root);
|
||||
item_label->BorderWidth(0);
|
||||
item_label->BGColor({0,0,0,0});
|
||||
item_label->AnchorPoint({1,0});
|
||||
item_label->SetContent("Item Name Here");
|
||||
@@ -75,6 +76,7 @@ void CaveGame::Client::TileHotbar::Load(CaveGame::Client::LocalWorld *world) {
|
||||
amount_label->Size({30_px, 30_px});
|
||||
amount_label->Position({95_percent, 95_percent});
|
||||
amount_label->AlignRight();
|
||||
amount_label->BorderWidth(0);
|
||||
|
||||
hotbar_elements[i] = cell;
|
||||
}
|
||||
|
@@ -28,8 +28,6 @@ namespace CaveGame::ClientApp {
|
||||
std::function<void(CommandArgs)> callback;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// The main program class. Everything originates here.
|
||||
/// This class is derived from RWindow class.
|
||||
class CaveGameWindow : public ReWindow::OpenGLWindow, public SceneManager {
|
||||
|
@@ -41,6 +41,11 @@ namespace CaveGame::Core {
|
||||
|
||||
Vector2 Position() const;
|
||||
|
||||
Vector2 TopLeft() const { return Position()-(bounding_box/2.f);}
|
||||
Vector2 RenderTopLeft() const { return Position()-(texture_center);}
|
||||
Vector2 Centroid() const { return Position();}
|
||||
AABB2D TranslatedBoundingBoxAABB() const { }
|
||||
|
||||
Vector2 Size() const;
|
||||
|
||||
virtual void CollisionTest(ITileMap* map, float step) {}
|
||||
@@ -51,8 +56,12 @@ namespace CaveGame::Core {
|
||||
float age;
|
||||
Vector2 position;
|
||||
Vector2 bounding_box;
|
||||
Vector2 texture_center;
|
||||
Vector2 render_center;
|
||||
std::vector<StatusEffect> active_effects;
|
||||
Color4 color;
|
||||
bool on_ground;
|
||||
float climbing_skill = 15;
|
||||
private:
|
||||
|
||||
};
|
||||
|
@@ -29,20 +29,19 @@ namespace CaveGame::Core
|
||||
|
||||
virtual void PhysicsUpdate(float elapsed);
|
||||
|
||||
|
||||
// TODO: Mechanism for figuring out if you're already stuck inside of tiles: i.e. sand
|
||||
void CollisionTest(ITileMap* map, float elapsed) override {
|
||||
|
||||
// The current "collision system" is unstable,
|
||||
|
||||
// One problem in particular is sometimes the entity gets teleported too far out, in a nonsensical way.
|
||||
|
||||
// The AABB separation may not be ideal, given how small the tile colliders are.
|
||||
|
||||
coll_tests = 0;
|
||||
coll_hits = 0;
|
||||
|
||||
for (int x = -1; x <= bounding_box.x; x++) {
|
||||
for (int y = -1; y <= bounding_box.y; y++) {
|
||||
Vector2 tileBoxPos = Vector2(Math::Floor(position.x), Math::Floor(position.y)) + Vector2(x,y);
|
||||
|
||||
Vector2 coll_topleft = next_position - (bounding_box / 2.f);
|
||||
|
||||
Vector2 tileBoxPos = Vector2(Math::Floor(coll_topleft.x), Math::Floor(coll_topleft.y)) + Vector2(x,y);
|
||||
|
||||
TileID id = map->GetTile(tileBoxPos.x, tileBoxPos.y);
|
||||
|
||||
@@ -51,35 +50,66 @@ namespace CaveGame::Core
|
||||
|
||||
coll_tests++;
|
||||
|
||||
Vector2 entity_centroid = position + (bounding_box / 2.f);
|
||||
Vector2 entity_centroid = next_position; // + (bounding_box / 2.f);
|
||||
Vector2 entity_halfbox = bounding_box / 2.f;
|
||||
|
||||
Vector2 tile_centroid = tileBoxPos + Vector2{0.5f, 0.5f};
|
||||
Vector2 tile_halfbox = Vector2{0.5f, 0.5f};
|
||||
|
||||
|
||||
if (Solver::AABB2Dvs(entity_centroid, entity_halfbox, tile_centroid, tile_halfbox)) {
|
||||
|
||||
coll_hits++;
|
||||
Vector2 separation = Solver::SolveAABB(entity_centroid, entity_halfbox, tile_centroid, tile_halfbox);
|
||||
|
||||
Vector2 normal = Solver::GetNormalForAABB(separation, velocity);
|
||||
|
||||
next_position += separation;
|
||||
|
||||
|
||||
//std::cout << std::format("Solved: Sep: {},{}, Norm: {},{}", separation.x, separation.y, normal.x, normal.y) << std::endl;
|
||||
|
||||
if (normal.x == 0 && normal.y == 0)
|
||||
continue;
|
||||
|
||||
// Touched top.
|
||||
if (normal.y == -1)
|
||||
{
|
||||
velocity.y = 0;
|
||||
on_ground = true;
|
||||
//std::cout << "Touched your feet" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
if (normal.y == 1) {
|
||||
velocity.y = -velocity.y*0.5f;
|
||||
std::cout << "Touched your head" << std::endl;
|
||||
}
|
||||
|
||||
if (normal.x == -1)
|
||||
{
|
||||
//std::cout << "Touched your right" << std::endl;
|
||||
}
|
||||
|
||||
if (normal.x == 1)
|
||||
{
|
||||
//std::cout << "Touched your left" << std::endl;
|
||||
}
|
||||
|
||||
if (normal.y == 1)
|
||||
velocity.y = -velocity.y;
|
||||
|
||||
|
||||
// TODO: Refine condition for "step-up"s
|
||||
if (normal.x != 0 && velocity.y == 0)
|
||||
if (normal.x != 0 && Math::Abs(velocity.x) > 10 && on_ground) {// && Math::Abs(velocity.y) < 2 ) {
|
||||
//std::cout << "Step up" << std::endl;
|
||||
next_position.y -= 1;
|
||||
//next_position.x -= normal.x;
|
||||
velocity.y -= climbing_skill;
|
||||
velocity.x *= 0.75f;
|
||||
}
|
||||
|
||||
next_position += separation;
|
||||
return;
|
||||
|
||||
|
||||
//next_position += separation;
|
||||
//return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,6 +128,7 @@ namespace CaveGame::Core
|
||||
float mass;
|
||||
int coll_tests;
|
||||
int coll_hits;
|
||||
Vector2 last_normal;
|
||||
private:
|
||||
};
|
||||
|
||||
|
@@ -14,16 +14,22 @@ namespace CaveGame::Core
|
||||
void Update(float elapsed) override;
|
||||
void PhysicsUpdate(float elapsed) override;
|
||||
void Jump() {
|
||||
Accelerate({0, -2});
|
||||
// TODO: Make it so the player falls **slightly** slower
|
||||
if (on_ground)
|
||||
{
|
||||
Accelerate({0, -150});
|
||||
on_ground = false;
|
||||
} else
|
||||
Accelerate({0, -5});
|
||||
}
|
||||
void Climb();
|
||||
void Descend();
|
||||
void Crouch();
|
||||
void WalkLeft() {
|
||||
Accelerate({-1, 0});
|
||||
Accelerate({-4, 0});
|
||||
}
|
||||
void WalkRight() {
|
||||
Accelerate({1, 0});
|
||||
Accelerate({4, 0});
|
||||
}
|
||||
protected:
|
||||
};
|
||||
|
@@ -18,11 +18,15 @@ namespace CaveGame::Core
|
||||
void PhysicsEntity::PhysicsUpdate(float elapsed) {
|
||||
next_position += velocity * elapsed;
|
||||
|
||||
float friction = 3.45f;
|
||||
float air_resistance = 3.45f;
|
||||
float gravity = 9.81f;
|
||||
float mass = 32.f;
|
||||
float mass = 40.f;
|
||||
|
||||
velocity *= (1 - (elapsed*friction));
|
||||
if (Math::Abs(velocity.y) > 1e-2f)
|
||||
on_ground = false;
|
||||
|
||||
//
|
||||
velocity *= (1 - (elapsed * air_resistance));
|
||||
|
||||
velocity.y += (elapsed*gravity*mass);
|
||||
|
||||
|
@@ -4,7 +4,8 @@
|
||||
namespace CaveGame::Core {
|
||||
|
||||
Player::Player(const Vector2 &spawnPoint): Humanoid(spawnPoint) {
|
||||
bounding_box = {16, 24};
|
||||
bounding_box = {10, 24};
|
||||
texture_center = {8, 12};
|
||||
}
|
||||
|
||||
void Player::Draw() {}
|
||||
|
Reference in New Issue
Block a user