Added sparks
This commit is contained in:
1 parent
2bb7da2e37
commit
393ebcd831
6 files changed
+202
-27
No files matched your search
+62
-3
@@ -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
|
||||
Reference in new issue
Block a user