Added sparks

This commit is contained in:
Vladislav Khorev committed 2026-04-24 19:53:18 +03:00
1 parent 2bb7da2e37
commit 393ebcd831
6 files changed
+202 -27

No files matched your search

+62 -3
View File
@@ -1,6 +1,7 @@
#include "Character.h"
#include <cmath>
#include <iostream>
#include <random>
#include "GameConstants.h"
#include "Environment.h"
@@ -268,6 +269,10 @@ void Character::update(int64_t deltaMs) {
if (hitSparkEmitter.isConfigured()) {
hitSparkEmitter.update(static_cast<float>(deltaMs));
}
auto it = animations.find(currentState);
if (it == animations.end()) return;
@@ -304,13 +309,22 @@ void Character::update(int64_t deltaMs) {
showWeapon = false;
}
auto attackDirectionToTarget = [this]() {
Eigen::Vector3f dir = attackTarget->position - position;
dir.y() = 0.f;
float n = dir.norm();
if (n > 1e-3f) dir /= n;
else dir = Eigen::Vector3f::Zero();
return dir;
};
if (isPlayer)
{
if (prevFrame == 18 && static_cast<int>(anim.currentFrame) != 18 && (currentState == AnimationState::ACTION_ATTACK || currentState == AnimationState::ACTION_ATTACK_2))
{
if (attackTarget != nullptr)
{
attackTarget->applyDamage(10.f);
attackTarget->applyDamage(10.f, attackDirectionToTarget());
}
}
}
@@ -320,7 +334,7 @@ void Character::update(int64_t deltaMs) {
{
if (attackTarget != nullptr)
{
attackTarget->applyDamage(10.f);
attackTarget->applyDamage(10.f, attackDirectionToTarget());
}
}
}
@@ -365,6 +379,11 @@ void Character::update(int64_t deltaMs) {
}
void Character::draw(Renderer& renderer) {
// Sparks are world-space billboards — render under the caller's camera matrices.
if (hitSparkEmitter.isConfigured() && hitSparkEmitter.getActiveParticleCount() > 0) {
hitSparkEmitter.draw(renderer, 1.0f, Environment::width, Environment::height, false);
}
if (!isPlayer && hp <= 0)
{
return;
@@ -624,6 +643,11 @@ void Character::drawShadowDepthGpuSkinning(Renderer& renderer) {
// ==================== Main pass with shadows ====================
void Character::drawWithShadow(Renderer& renderer, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera) {
// Sparks are world-space billboards — render under the caller's camera matrices.
if (hitSparkEmitter.isConfigured() && hitSparkEmitter.getActiveParticleCount() > 0) {
hitSparkEmitter.draw(renderer, 1.0f, Environment::width, Environment::height, false);
}
if (!isPlayer && hp <= 0)
{
return;
@@ -755,10 +779,45 @@ void Character::drawGpuSkinningWithShadow(Renderer& renderer, const Eigen::Matri
CheckGlError(__FILE__, __LINE__);
}
void Character::applyDamage(float damageAmount)
void Character::setupHitSparks(std::shared_ptr<Texture> sparkTexture)
{
hitSparkEmitter.setTexture(sparkTexture);
hitSparkEmitter.setShaderProgramName("spark");
hitSparkEmitter.setMaxParticles(64);
hitSparkEmitter.setParticleSize(0.08f);
hitSparkEmitter.setBiasX(0.0f);
hitSparkEmitter.setEmissionRate(1.0e9f); // effectively disables auto-emission
hitSparkEmitter.setSpeedRange(2.0f, 4.0f);
hitSparkEmitter.setZSpeedRange(0.5f, 2.0f);
hitSparkEmitter.setScaleRange(0.8f, 1.2f);
hitSparkEmitter.setLifeTimeRange(300.0f, 600.0f);
hitSparkEmitter.setIsActive(false);
hitSparkEmitter.markConfigured();
}
void Character::applyDamage(float damageAmount, const Eigen::Vector3f& attackDirection)
{
hp = hp - damageAmount;
if (hp < 0) hp = 0;
if (!hitSparkEmitter.isConfigured()) return;
Eigen::Vector3f emitPos = position + Eigen::Vector3f(0.f, 1.f, 0.f);
hitSparkEmitter.resetEmissionPoints({ emitPos });
hitSparkEmitter.setEmissionDirection(attackDirection);
static std::mt19937 gen(std::random_device{}());
std::uniform_int_distribution<int> countDist(10, 15);
int count = countDist(gen);
for (int i = 0; i < count; ++i) {
hitSparkEmitter.emit();
}
}
void Character::prepareHitSparksForDraw(const Eigen::Matrix4f& cameraViewMatrix)
{
if (!hitSparkEmitter.isConfigured()) return;
hitSparkEmitter.prepareForDraw(cameraViewMatrix);
}
} // namespace ZL