我的世界地下城DLC开发的第二天
(这几天换了个引擎,所以代码换成C++了)
// PeeperCreeper.h
#pragma once
#include "GameEntity.h"
#include "DamageSystem.h"
#include "PathPredictor.h"
class PeeperCreeper : public GameEntity {
public:
enum class State { Burrowed, Emerging, Chasing, Exploding, PlantingTNT };
PeeperCreeper(DifficultyLevel difficulty);
void Update(float deltaTime) override;
void TakeDamage(float amount) override;
void DrawUI() const override;
private:
// 状态管理
State currentState = State::Burrowed;
float stateTimer = 0.0f;
Vector3 lastPlayerPosition;
// 核心属性
struct {
float maxHealth;
float moveSpeed;
float explosionRadius;
float explosionDamage;
float tntDuration;
} difficultyParams;
// 爆炸系统
struct ExplosionProfile {
float radius;
float baseDamage;
float damageFalloff;
};
void UpdateBurrowedState(float deltaTime);
void UpdateChasingState(float deltaTime);
void TriggerExplosion(bool successfulHit);
void PlantTNT();
bool CanSeePlayer() const;
float CalculateDamageFalloff(float distance) const;
// 血条UI
mutable float healthDisplay = 0.0f;
const float UI_SMOOTH_SPEED = 5.0f;
};
// 难度配置
namespace PeeperDifficulty {
const std::map<DifficultyLevel, std::tuple<float, float, float, float, float>> params = {
{DifficultyLevel::Default, {300.0f, 8.0f, 4.0f, 300.0f, 5.0f}},
{DifficultyLevel::Adventure,{450.0f, 9.5f, 5.0f, 450.0f, 5.5f}},
{DifficultyLevel::Apocalypse,{600.0f, 11.0f, 6.0f, 600.0f, 6.25f}}
};
}
// PeeperCreeper.cpp
#include "PeeperCreeper.h"
PeeperCreeper::PeeperCreeper(DifficultyLevel difficulty) {
auto& [health, speed, radius, damage, tnt] = PeeperDifficulty::params.at(difficulty);
difficultyParams = {health, speed, radius, damage, tnt};
SetMaxHealth(health);
SetMovementSpeed(speed);
}
void PeeperCreeper::Update(float deltaTime) {
UpdateHealthDisplay(deltaTime);
switch(currentState) {
case State::Burrowed:
UpdateBurrowedState(deltaTime);
break;
case State::Chasing:
UpdateChasingState(deltaTime);
break;
// ...其他状态处理
}
}
void PeeperCreeper::UpdateBurrowedState(float deltaTime) {
if (stateTimer > 3.0f) {
Vector3 spawnPos = Player::Get().GetPosition() +
Player::Get().GetForwardVector() * -3.0f;
SetPosition(spawnPos);
currentState = State::Emerging;
PlayAnimation("emerge");
}
stateTimer += deltaTime;
}
void PeeperCreeper::TriggerExplosion(bool successfulHit) {
ExplosionProfile profile;
profile.radius = difficultyParams.explosionRadius;
profile.baseDamage = difficultyParams.explosionDamage;
if (successfulHit) {
ModifyHealth(GetMaxHealth() / 3.0f);
DamageSystem::ApplyRadialDamage(
GetPosition(), profile.radius, profile.baseDamage,
[this](float d){ return d * 0.7f; } // 伤害衰减
);
currentState = State::Burrowed;
} else {
TakeDamage(GetMaxHealth() / 7.0f);
if (GetDistanceToPlayer() >= 12.0f) {
PlantTNT();
}
}
}
void PeeperCreeper::PlantTNT() {
Vector3 predictedPath = PathPredictor::PredictPlayerPosition(
difficultyParams.tntDuration
);
World::SpawnEntity<ExplosiveTNT>(
predictedPath,
difficultyParams.tntDuration,
difficultyParams.explosionDamage * 0.5f
);
}
void PeeperCreeper::DrawUI() const {
Vector2 screenPos = WorldToScreen(GetPosition());
UI::DrawHealthBar(
screenPos + Vector2(0, 2.0f),
Vector2(1.5f, 0.3f),
healthDisplay,
Color::Red
);
}
// 其他实现细节...
// 生成系统(PeeperSpawnSystem.h)
class PeeperSpawnSystem : public ISystem {
public:
void Configure(World& world) override {
world.AddSpawnCondition([](const SpawnContext& ctx){
return ctx.player.GetThreatLevel() > 0.7f &&
ctx.performanceScore > 50.0f;
});
}
void Update(World& world) override {
if (ShouldSpawnBoss(world)) {
Vector3 safePosition = FindSpawnPosition(
world.GetPlayer().position,
world.GetNavMesh()
);
world.SpawnEntity<PeeperCreeper>(
GetCurrentDifficulty(),
safePosition
);
StartCooldown(300.0f); // 5分钟生成间隔
}
}
private:
bool ShouldSpawnBoss(World& world) const {
return GetCooldown() <= 0.0f &&
world.GetEntityCount<PeeperCreeper>() == 0 &&
world.GetPlayer().GetPlayTime() > 600.0f;
}
Vector3 FindSpawnPosition(Vector3 playerPos, const NavMesh& mesh) {
// 使用八叉树空间分区查询安全位置
return mesh.FindHiddenPosition(
playerPos,
8.0f, // 最小距离
15.0f // 最大距离
);
}
};
关键系统说明:
-
自适应生成系统:
-
基于玩家威胁值和性能分数动态调整生成频率
-
使用八叉树空间分区优化位置查询
-
5分钟强制生成冷却期
-
行为逻辑增强:
void PeeperCreeper::UpdateChasingState(float deltaTime) { if (GetDistanceToPlayer() < 3.0f) { TriggerExplosion(CheckPlayerInRadius()); } else { Vector3 evasionPoint = CalculateEvasionPath( Player::Get().position, GetMovementSpeed() * 1.2f ); MoveTowards(evasionPoint, deltaTime); if (stateTimer > 10.0f) { PlantTNT(); stateTimer = 0.0f; } } }
-
死亡特殊处理:
void PeeperCreeper::OnDeath() { ExplosionProfile deathExplosion; deathExplosion.radius = difficultyParams.explosionRadius * 2.0f; deathExplosion.baseDamage = difficultyParams.explosionDamage * 0.4f; deathExplosion.damageFalloff = [](float d){ return d * 0.3f; }; DamageSystem::ApplyRadialDamage( GetPosition(), deathExplosion.radius, deathExplosion.baseDamage, deathExplosion.damageFalloff ); SpawnLoot(Player::Get().GetLuckMultiplier()); }
-
性能优化措施:
-
使用对象池管理爆炸特效
-
基于帧时间的LOD系统:
void UpdateLOD() { float distance = GetDistanceToCamera(); SetUpdateRate(distance > 50.0f ? 0.5f : 1.0f); SetPhysicsQuality(distance > 30.0f ? PhysicsQuality::Simple : PhysicsQuality::Full); }
-
可视化血条系统:
void PeeperCreeper::UpdateHealthDisplay(float deltaTime) { float targetHealth = GetHealth() / GetMaxHealth(); healthDisplay = Math::Lerp(healthDisplay, targetHealth, UI_SMOOTH_SPEED * deltaTime); if (fabs(healthDisplay - targetHealth) < 0.01f) { healthDisplay = targetHealth; } }
数值平衡表(天启难度):
属性 基础值 增强系数 最终值 生命值 600 ×1.2 720 移动速度(潜地) 11 ×0.7 7.7 爆炸半径(死亡) 12 ×2.0 24 TNT触发距离 12 ×1.3 15.6 伤害衰减率 30% +10% 40% 该实现包含:
-
基于ECS架构的状态管理系统
-
四叉树空间分区优化的生成逻辑
-
伤害衰减曲线控制系统
-
自适应LOD渲染机制
-
平滑过渡的血条UI