pull
This commit is contained in:
+74
-8
@@ -128,6 +128,7 @@ void Engine::Initiate()
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
Font* arial = new Font("assets/ft/arial.ttf");
|
Font* arial = new Font("assets/ft/arial.ttf");
|
||||||
Texture* blanktex = new Texture("assets/blanktexture.png");
|
Texture* blanktex = new Texture("assets/blanktexture.png");
|
||||||
|
Texture* blacktex = new Texture("assets/blacktexture.png");
|
||||||
Texture* magic = new Texture("assets/itsmagicbitch.jpg");
|
Texture* magic = new Texture("assets/itsmagicbitch.jpg");
|
||||||
Texture* snowflake = new Texture("assets/snowflake.png");
|
Texture* snowflake = new Texture("assets/snowflake.png");
|
||||||
Texture* shockwavetex = new Texture("assets/shockwave.png");
|
Texture* shockwavetex = new Texture("assets/shockwave.png");
|
||||||
@@ -193,6 +194,8 @@ void Engine::Initiate()
|
|||||||
Character* character = nullptr;
|
Character* character = nullptr;
|
||||||
double lastSeen = 0.0;
|
double lastSeen = 0.0;
|
||||||
p* body = nullptr; // host only: lets the host's cubes collide with this player
|
p* body = nullptr; // host only: lets the host's cubes collide with this player
|
||||||
|
glm::vec3 targetPos = glm::vec3(0.0f); // latest pose received; the model eases toward it every frame
|
||||||
|
glm::quat targetRot = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
|
||||||
};
|
};
|
||||||
std::map<int, RemotePlayer> remotes;
|
std::map<int, RemotePlayer> remotes;
|
||||||
auto SpawnRemote = [&]() -> Character* {
|
auto SpawnRemote = [&]() -> Character* {
|
||||||
@@ -331,6 +334,23 @@ void Engine::Initiate()
|
|||||||
grappleText->t2d.size = { 0.0f, 0.0f, 560.0f, 40.0f };
|
grappleText->t2d.size = { 0.0f, 0.0f, 560.0f, 40.0f };
|
||||||
grappleText->BindToRenderSystem();
|
grappleText->BindToRenderSystem();
|
||||||
|
|
||||||
|
// Shot cooldown bar at the bottom of the screen: full and white when ready, empties on a shot
|
||||||
|
// and refills as the cooldown runs down.
|
||||||
|
const float shotBarWidth = 300.0f, shotBarHeight = 8.0f;
|
||||||
|
Box* shotBarBack = new Box();
|
||||||
|
shotBarBack->Color = { 0.0f, 0.0f, 0.0f };
|
||||||
|
shotBarBack->Opacity = 0.45f;
|
||||||
|
shotBarBack->t2d.position = { 0.5f, 1.0f, 0.0f, -30.0f };
|
||||||
|
shotBarBack->t2d.center = { 0.5f, 1.0f };
|
||||||
|
shotBarBack->t2d.size = { 0.0f, 0.0f, shotBarWidth + 4.0f, shotBarHeight + 4.0f };
|
||||||
|
shotBarBack->BindToRenderSystem();
|
||||||
|
Box* shotBar = new Box();
|
||||||
|
shotBar->Color = { 1.0f, 1.0f, 1.0f };
|
||||||
|
shotBar->t2d.position = { 0.5f, 1.0f, -shotBarWidth * 0.5f, -32.0f };
|
||||||
|
shotBar->t2d.center = { 0.0f, 1.0f };
|
||||||
|
shotBar->t2d.size = { 0.0f, 0.0f, shotBarWidth, shotBarHeight };
|
||||||
|
shotBar->BindToRenderSystem();
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// World meshes
|
// World meshes
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@@ -446,6 +466,17 @@ void Engine::Initiate()
|
|||||||
float shockedTime = 0.0f;
|
float shockedTime = 0.0f;
|
||||||
const float grappleRange = 30.0f; // metres from the player
|
const float grappleRange = 30.0f; // metres from the player
|
||||||
const float grappleSpeed = 28.0f; // launch speed toward the hit point
|
const float grappleSpeed = 28.0f; // launch speed toward the hit point
|
||||||
|
// Visible grapple rope: a thin black box stretched from the hand to the latch point
|
||||||
|
const float grappleLineShowTime = 0.5f;
|
||||||
|
float grappleLineTime = 0.0f;
|
||||||
|
glm::vec3 grappleLineEnd(0.0f);
|
||||||
|
Mesh* grappleLine = CreateCubeMesh();
|
||||||
|
grappleLine->name = "grappleline";
|
||||||
|
grappleLine->meshTexture = blacktex;
|
||||||
|
grappleLine->t.TranslateTo({ 0.0f, -1000.0f, 0.0f }); // hidden until a grapple latches
|
||||||
|
grappleLine->BindToRenderSystem();
|
||||||
|
mainf->AddChild(grappleLine);
|
||||||
|
const float grappleLift = 10.0f; // extra upward speed added on top of the pull
|
||||||
const float grappleCooldownTime = 2.5f; // seconds
|
const float grappleCooldownTime = 2.5f; // seconds
|
||||||
float grappleCooldown = 0.0f;
|
float grappleCooldown = 0.0f;
|
||||||
|
|
||||||
@@ -817,8 +848,12 @@ void Engine::Initiate()
|
|||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
characterBody->linearvelocity = glm::normalize(bestPoint - ray.origin) * grappleSpeed;
|
characterBody->linearvelocity = glm::normalize(bestPoint - ray.origin) * grappleSpeed;
|
||||||
|
// Extra upward fling so the grapple gains height instead of just pulling sideways
|
||||||
|
characterBody->linearvelocity.y = std::max(characterBody->linearvelocity.y, 0.0f) + grappleLift;
|
||||||
characterBody->WakeUp();
|
characterBody->WakeUp();
|
||||||
grappleCooldown = grappleCooldownTime;
|
grappleCooldown = grappleCooldownTime;
|
||||||
|
grappleLineTime = grappleLineShowTime;
|
||||||
|
grappleLineEnd = bestPoint;
|
||||||
camera->AddScreenshake(0.1f);
|
camera->AddScreenshake(0.1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -984,6 +1019,25 @@ void Engine::Initiate()
|
|||||||
}
|
}
|
||||||
fpsCounter->text = std::to_string(measuredFps) + " FPS";
|
fpsCounter->text = std::to_string(measuredFps) + " FPS";
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const float ready = 1.0f - glm::clamp(shootCooldown / shootCooldownTime, 0.0f, 1.0f);
|
||||||
|
shotBar->t2d.size = { 0.0f, 0.0f, shotBarWidth * ready, shotBarHeight };
|
||||||
|
shotBar->Opacity = ready > 0.0f ? 1.0f : 0.0f;
|
||||||
|
}
|
||||||
|
// Grapple rope: starts at the hand (follows the camera), ends on the latch point
|
||||||
|
grappleLineTime = std::max(grappleLineTime - deltatime, 0.0f);
|
||||||
|
if (grappleLineTime > 0.0f) {
|
||||||
|
const glm::vec3 handPos = camera->t.GetTranslation() + camera->t.GetFrontVector() * 0.6f
|
||||||
|
+ camera->t.GetRightVector() * 0.3f - camera->t.GetUpVector() * 0.3f;
|
||||||
|
const glm::vec3 delta = grappleLineEnd - handPos;
|
||||||
|
const float len = glm::length(delta);
|
||||||
|
if (len > 0.01f) {
|
||||||
|
grappleLine->t.TranslateTo(handPos + delta * 0.5f);
|
||||||
|
grappleLine->t.ScaleTo({ 0.05f, 0.05f, len });
|
||||||
|
grappleLine->t.RotateToQuaternion(LookAt(delta));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else grappleLine->t.TranslateTo(hiddenPos);
|
||||||
hitMarkerTime = std::max(hitMarkerTime - deltatime, 0.0f);
|
hitMarkerTime = std::max(hitMarkerTime - deltatime, 0.0f);
|
||||||
for (Box* b : hitMarker) b->Opacity = hitMarkerTime / hitMarkerDuration;
|
for (Box* b : hitMarker) b->Opacity = hitMarkerTime / hitMarkerDuration;
|
||||||
// Damage flash: any HP loss restarts a short green fade-out
|
// Damage flash: any HP loss restarts a short green fade-out
|
||||||
@@ -1150,6 +1204,8 @@ void Engine::Initiate()
|
|||||||
rp.character = SpawnRemote();
|
rp.character = SpawnRemote();
|
||||||
rp.character->body->t.TranslateTo(u.state.position);
|
rp.character->body->t.TranslateTo(u.state.position);
|
||||||
rp.character->body->t.RotateToQuaternion(u.state.rotation);
|
rp.character->body->t.RotateToQuaternion(u.state.rotation);
|
||||||
|
rp.targetPos = u.state.position;
|
||||||
|
rp.targetRot = u.state.rotation;
|
||||||
if (lan->GetMode() == Lan::Mode::Host) {
|
if (lan->GetMode() == Lan::Mode::Host) {
|
||||||
// Solid for the host's cubes (kinematic: moved by the client's stream only)
|
// Solid for the host's cubes (kinematic: moved by the client's stream only)
|
||||||
rp.body = new p(rp.character->body);
|
rp.body = new p(rp.character->body);
|
||||||
@@ -1159,14 +1215,10 @@ void Engine::Initiate()
|
|||||||
it = remotes.emplace(u.id, rp).first;
|
it = remotes.emplace(u.id, rp).first;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Smooth over the 60 Hz updates
|
// Packets arrive in bursts (several in one frame, then none), so just remember the
|
||||||
t& rt = it->second.character->body->t;
|
// newest pose here; the per-frame smoothing below does the actual moving.
|
||||||
const glm::vec3 before = rt.GetTranslation();
|
it->second.targetPos = u.state.position;
|
||||||
rt.TranslateTo(glm::mix(rt.GetTranslation(), u.state.position, 0.5f));
|
it->second.targetRot = u.state.rotation;
|
||||||
// Kinematic body: its velocity makes it push cubes like the client's own body does there
|
|
||||||
if (it->second.body && deltatime > 0.0f)
|
|
||||||
it->second.body->linearvelocity = (rt.GetTranslation() - before) / deltatime;
|
|
||||||
rt.RotateToQuaternion(glm::slerp(rt.GetRotationQuaternion(), u.state.rotation, 0.5f));
|
|
||||||
}
|
}
|
||||||
it->second.lastSeen = now;
|
it->second.lastSeen = now;
|
||||||
}
|
}
|
||||||
@@ -1180,6 +1232,20 @@ void Engine::Initiate()
|
|||||||
it = remotes.erase(it);
|
it = remotes.erase(it);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Frame-rate independent ease toward the latest pose (no matter how packets were batched)
|
||||||
|
t& rt = it->second.character->body->t;
|
||||||
|
const glm::vec3 before = rt.GetTranslation();
|
||||||
|
if (glm::distance(before, it->second.targetPos) > 6.0f)
|
||||||
|
rt.TranslateTo(it->second.targetPos); // respawn / big jump: snap
|
||||||
|
else {
|
||||||
|
const float k = 1.0f - std::exp(-deltatime * 25.0f);
|
||||||
|
rt.TranslateTo(glm::mix(before, it->second.targetPos, k));
|
||||||
|
}
|
||||||
|
rt.RotateToQuaternion(glm::slerp(rt.GetRotationQuaternion(), it->second.targetRot,
|
||||||
|
1.0f - std::exp(-deltatime * 25.0f)));
|
||||||
|
// Kinematic body: its velocity makes cubes get pushed like the client's own body does there
|
||||||
|
if (it->second.body && deltatime > 0.0f)
|
||||||
|
it->second.body->linearvelocity = (rt.GetTranslation() - before) / deltatime;
|
||||||
it->second.character->Step(deltatime);
|
it->second.character->Step(deltatime);
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 70 B |
Reference in New Issue
Block a user