added projectile
This commit is contained in:
parent
d57112be35
commit
ff3946a019
@ -442,6 +442,8 @@ add_executable(space-game001
|
||||
PlanetObject.h
|
||||
UiManager.cpp
|
||||
UiManager.h
|
||||
Projectile.h
|
||||
Projectile.cpp
|
||||
)
|
||||
|
||||
# Установка проекта по умолчанию для Visual Studio
|
||||
|
||||
91
Game.cpp
91
Game.cpp
@ -123,11 +123,10 @@ namespace ZL
|
||||
, newTickCount(0)
|
||||
, lastTickCount(0)
|
||||
{
|
||||
std::vector<Vector3f> emissionPoints = {
|
||||
Vector3f{-2.1f, 0.9f, 5.0f},
|
||||
Vector3f{2.1f, 0.9f, 5.0f}
|
||||
};
|
||||
sparkEmitter = SparkEmitter(emissionPoints, 100.0f);
|
||||
projectiles.reserve(maxProjectiles);
|
||||
for (int i = 0; i < maxProjectiles; ++i) {
|
||||
projectiles.emplace_back(std::make_unique<Projectile>());
|
||||
}
|
||||
}
|
||||
|
||||
Game::~Game() {
|
||||
@ -163,6 +162,8 @@ namespace ZL
|
||||
#endif
|
||||
|
||||
bool cfgLoaded = sparkEmitter.loadFromJsonFile("../config/spark_config.json", renderer, CONST_ZIP_FILE);
|
||||
bool projCfgLoaded = projectileEmitter.loadFromJsonFile("../config/spark_projectile_config.json", renderer, CONST_ZIP_FILE);
|
||||
projectileEmitter.setEmissionPoints(std::vector<Vector3f>());
|
||||
uiManager.loadFromFile("../config/ui.json", renderer, CONST_ZIP_FILE);
|
||||
|
||||
uiManager.setButtonCallback("playButton", [this](const std::string& name) {
|
||||
@ -364,10 +365,18 @@ namespace ZL
|
||||
renderer.LoadIdentity();
|
||||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
||||
|
||||
|
||||
renderer.TranslateMatrix({ 0, -Environment::zoom * 0.03f, 0 });
|
||||
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(spaceship);
|
||||
|
||||
for (const auto& p : projectiles) {
|
||||
if (p && p->isActive()) {
|
||||
p->draw(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||
projectileEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
@ -584,14 +593,74 @@ namespace ZL
|
||||
{
|
||||
Vector3f velocityDirection = { 0,0, -Environment::shipVelocity * delta / 1000.f };
|
||||
Vector3f velocityDirectionAdjusted = MultMatrixVector(Environment::shipMatrix, velocityDirection);
|
||||
|
||||
Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted;
|
||||
}
|
||||
|
||||
for (auto& p : projectiles) {
|
||||
if (p && p->isActive()) {
|
||||
p->update(static_cast<float>(delta), renderer);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Vector3f> projCameraPoints;
|
||||
for (const auto& p : projectiles) {
|
||||
if (p && p->isActive()) {
|
||||
Vector3f worldPos = p->getPosition();
|
||||
Vector3f rel = worldPos - Environment::shipPosition;
|
||||
Vector3f camPos = MultMatrixVector(Environment::inverseShipMatrix, rel);
|
||||
projCameraPoints.push_back(camPos);
|
||||
}
|
||||
}
|
||||
if (!projCameraPoints.empty()) {
|
||||
projectileEmitter.setEmissionPoints(projCameraPoints);
|
||||
projectileEmitter.emit();
|
||||
}
|
||||
else {
|
||||
projectileEmitter.setEmissionPoints(std::vector<Vector3f>());
|
||||
}
|
||||
|
||||
std::vector<Vector3f> shipCameraPoints;
|
||||
for (const auto& lp : shipLocalEmissionPoints) {
|
||||
Vector3f adjusted = lp + Vector3f{ 0.0f, -Environment::zoom * 0.03f, 0.0f };
|
||||
shipCameraPoints.push_back(adjusted);
|
||||
}
|
||||
if (!shipCameraPoints.empty()) {
|
||||
sparkEmitter.setEmissionPoints(shipCameraPoints);
|
||||
}
|
||||
|
||||
sparkEmitter.update(static_cast<float>(delta));
|
||||
projectileEmitter.update(static_cast<float>(delta));
|
||||
|
||||
lastTickCount = newTickCount;
|
||||
}
|
||||
}
|
||||
|
||||
void Game::fireProjectiles() {
|
||||
std::vector<Vector3f> localOffsets = {
|
||||
Vector3f{ -1.5f, 0.9f, 5.0f },
|
||||
Vector3f{ 1.5f, 0.9f, 5.0f }
|
||||
};
|
||||
|
||||
const float projectileSpeed = 60.0f;
|
||||
const float lifeMs = 5000.0f;
|
||||
const float size = 0.5f;
|
||||
|
||||
Vector3f localForward = { 0,0,-1 };
|
||||
Vector3f worldForward = MultMatrixVector(Environment::shipMatrix, localForward).normalized();
|
||||
|
||||
for (const auto& lo : localOffsets) {
|
||||
Vector3f worldPos = Environment::shipPosition + MultMatrixVector(Environment::shipMatrix, lo);
|
||||
Vector3f worldVel = worldForward * projectileSpeed;
|
||||
|
||||
for (auto& p : projectiles) {
|
||||
if (!p->isActive()) {
|
||||
p->init(worldPos, worldVel, lifeMs, size, projectileTexture, renderer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::render() {
|
||||
SDL_GL_MakeCurrent(ZL::Environment::window, glContext);
|
||||
ZL::CheckGlError();
|
||||
@ -622,6 +691,14 @@ namespace ZL
|
||||
|
||||
bool uiHandled = false;
|
||||
|
||||
if (event.button.button == SDL_BUTTON_LEFT && !uiManager.isUiInteraction()) {
|
||||
uint64_t now = SDL_GetTicks64();
|
||||
if (now - lastProjectileFireTime >= static_cast<uint64_t>(projectileCooldownMs)) {
|
||||
lastProjectileFireTime = now;
|
||||
fireProjectiles();
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& button : uiManager.findButton("") ? std::vector<std::shared_ptr<UiButton>>{} : std::vector<std::shared_ptr<UiButton>>{}) {
|
||||
(void)button;
|
||||
}
|
||||
|
||||
11
Game.h
11
Game.h
@ -7,6 +7,7 @@
|
||||
#include "SparkEmitter.h"
|
||||
#include "PlanetObject.h"
|
||||
#include "UiManager.h"
|
||||
#include "Projectile.h"
|
||||
|
||||
namespace ZL {
|
||||
|
||||
@ -38,6 +39,8 @@ namespace ZL {
|
||||
void drawBoxes();
|
||||
void drawUI();
|
||||
|
||||
void fireProjectiles();
|
||||
|
||||
SDL_Window* window;
|
||||
SDL_GLContext glContext;
|
||||
Renderer renderer;
|
||||
@ -88,8 +91,16 @@ namespace ZL {
|
||||
VertexDataStruct boxBase;
|
||||
|
||||
SparkEmitter sparkEmitter;
|
||||
SparkEmitter projectileEmitter;
|
||||
PlanetObject planetObject;
|
||||
UiManager uiManager;
|
||||
|
||||
std::vector<std::unique_ptr<Projectile>> projectiles;
|
||||
std::shared_ptr<Texture> projectileTexture;
|
||||
float projectileCooldownMs = 500.0f;
|
||||
uint64_t lastProjectileFireTime = 0;
|
||||
int maxProjectiles = 32;
|
||||
std::vector<Vector3f> shipLocalEmissionPoints;
|
||||
};
|
||||
|
||||
|
||||
|
||||
71
Projectile.cpp
Normal file
71
Projectile.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include "Projectile.h"
|
||||
|
||||
namespace ZL {
|
||||
|
||||
Projectile::Projectile()
|
||||
: pos({ 0,0,0 })
|
||||
, vel({ 0,0,0 })
|
||||
, life(0.0f)
|
||||
, maxLife(0.0f)
|
||||
, active(false)
|
||||
, size(0.5f)
|
||||
, texture(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void Projectile::init(const Vector3f& startPos, const Vector3f& startVel, float lifeMs, float s, std::shared_ptr<Texture> tex, Renderer& renderer) {
|
||||
pos = startPos;
|
||||
vel = startVel;
|
||||
life = 0.0f;
|
||||
maxLife = lifeMs;
|
||||
size = s;
|
||||
texture = tex;
|
||||
active = true;
|
||||
|
||||
rebuildMesh(renderer);
|
||||
mesh.RefreshVBO();
|
||||
}
|
||||
|
||||
void Projectile::update(float deltaMs, Renderer& renderer) {
|
||||
if (!active) return;
|
||||
|
||||
pos = pos + vel * (deltaMs / 1000.0f);
|
||||
life += deltaMs;
|
||||
if (life >= maxLife) {
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
rebuildMesh(renderer);
|
||||
mesh.RefreshVBO();
|
||||
}
|
||||
|
||||
void Projectile::rebuildMesh(Renderer&) {
|
||||
float half = size * 0.5f;
|
||||
|
||||
mesh.data.PositionData.clear();
|
||||
mesh.data.TexCoordData.clear();
|
||||
|
||||
mesh.data.PositionData.push_back({ pos.v[0] - half, pos.v[1] - half, pos.v[2] });
|
||||
mesh.data.PositionData.push_back({ pos.v[0] - half, pos.v[1] + half, pos.v[2] });
|
||||
mesh.data.PositionData.push_back({ pos.v[0] + half, pos.v[1] + half, pos.v[2] });
|
||||
|
||||
mesh.data.PositionData.push_back({ pos.v[0] - half, pos.v[1] - half, pos.v[2] });
|
||||
mesh.data.PositionData.push_back({ pos.v[0] + half, pos.v[1] + half, pos.v[2] });
|
||||
mesh.data.PositionData.push_back({ pos.v[0] + half, pos.v[1] - half, pos.v[2] });
|
||||
|
||||
mesh.data.TexCoordData.push_back({ 0.0f, 0.0f });
|
||||
mesh.data.TexCoordData.push_back({ 0.0f, 1.0f });
|
||||
mesh.data.TexCoordData.push_back({ 1.0f, 1.0f });
|
||||
mesh.data.TexCoordData.push_back({ 0.0f, 0.0f });
|
||||
mesh.data.TexCoordData.push_back({ 1.0f, 1.0f });
|
||||
mesh.data.TexCoordData.push_back({ 1.0f, 0.0f });
|
||||
}
|
||||
|
||||
void Projectile::draw(Renderer& renderer) const {
|
||||
if (!active || !texture) return;
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(mesh);
|
||||
}
|
||||
|
||||
} // namespace ZL
|
||||
36
Projectile.h
Normal file
36
Projectile.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "ZLMath.h"
|
||||
#include "Renderer.h"
|
||||
#include "TextureManager.h"
|
||||
#include <memory>
|
||||
|
||||
namespace ZL {
|
||||
|
||||
class Projectile {
|
||||
public:
|
||||
Projectile();
|
||||
~Projectile() = default;
|
||||
|
||||
void init(const Vector3f& startPos, const Vector3f& startVel, float lifeMs, float size, std::shared_ptr<Texture> tex, Renderer& renderer);
|
||||
void update(float deltaMs, Renderer& renderer);
|
||||
void draw(Renderer& renderer) const;
|
||||
|
||||
bool isActive() const { return active; }
|
||||
|
||||
Vector3f getPosition() const { return pos; }
|
||||
|
||||
private:
|
||||
Vector3f pos;
|
||||
Vector3f vel;
|
||||
float life;
|
||||
float maxLife;
|
||||
bool active;
|
||||
float size;
|
||||
VertexRenderStruct mesh;
|
||||
std::shared_ptr<Texture> texture;
|
||||
|
||||
void rebuildMesh(Renderer& renderer);
|
||||
};
|
||||
|
||||
} // namespace ZL
|
||||
@ -5,10 +5,10 @@
|
||||
"biasX": 0.3,
|
||||
"emissionPoints": [
|
||||
{
|
||||
"position": [-2.1, 0.9, 5.0]
|
||||
"position": [-2.1, 0.4, 5.0]
|
||||
},
|
||||
{
|
||||
"position": [2.1, 0.9, 5.0]
|
||||
"position": [2.1, 0.4, 5.0]
|
||||
}
|
||||
],
|
||||
"speedRange": [0.5, 2.0],
|
||||
|
||||
15
config/spark_projectile_config.json
Normal file
15
config/spark_projectile_config.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"emissionPoints": [
|
||||
{ "position": [0.0, 0.0, 0.0] }
|
||||
],
|
||||
"texture": "./resources/sand.png",
|
||||
"speedRange": [10.0, 30.0],
|
||||
"zSpeedRange": [-1.0, 1.0],
|
||||
"scaleRange": [0.5, 1.0],
|
||||
"lifeTimeRange": [200.0, 800.0],
|
||||
"emissionRate": 50.0,
|
||||
"maxParticles": 10,
|
||||
"particleSize": 0.09,
|
||||
"biasX": 0.1,
|
||||
"shaderProgramName": "default"
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user