grafika_komputerowa/grk/project/Spaceship.h

206 lines
6.5 KiB
C
Raw Permalink Normal View History

2024-01-03 20:51:29 +01:00
#include "glm.hpp"
#include "ext.hpp"
2024-01-08 16:17:25 +01:00
#include <GLFW/glfw3.h>
2024-01-16 22:15:26 +01:00
#include <list>
#include "Bullet.h"
2024-01-30 21:13:23 +01:00
#include "ParticleSystem.h"
2024-02-03 20:20:01 +01:00
#include "GameEntity.h"
2024-01-03 20:51:29 +01:00
#pragma once
2024-01-16 22:15:26 +01:00
2024-02-03 20:20:01 +01:00
class Spaceship : public GameEntity
2024-01-03 20:51:29 +01:00
{
2024-01-03 22:06:27 +01:00
private:
2024-01-16 22:15:26 +01:00
std::list<Bullet*> bullets;
float lastShootTime = 0.f;
float shootInterval = 0.3f;
2024-01-30 21:13:23 +01:00
ParticleSystem* leftParticle;
ParticleSystem* rightParticle;
2024-01-16 22:15:26 +01:00
2024-02-03 20:20:01 +01:00
// Prywatny konstruktor, aby zapobiec zewn<77>trznemu tworzeniu instancji
Spaceship() : GameEntity(100.0f, 100.0f, 10.0f)
{
2024-01-30 21:13:23 +01:00
2024-01-16 22:15:26 +01:00
}
2024-01-03 22:06:27 +01:00
// Prywatny destruktor, aby zapobiec przypadkowemu usuwaniu instancji
~Spaceship() {}
2024-01-03 20:51:29 +01:00
public:
2024-01-03 22:06:27 +01:00
2024-01-10 21:20:52 +01:00
static Spaceship* getInstance()
2024-01-03 22:06:27 +01:00
{
static Spaceship instance; // Jedna i jedyna instancja
2024-01-10 21:20:52 +01:00
return &instance;
2024-01-03 22:06:27 +01:00
}
glm::vec3 color = glm::vec3(0.3, 0.3, 0.5);
float roughness = 0.2;
float metallic = 1.0;
2024-01-30 21:13:23 +01:00
glm::vec3 spaceshipPos /*= glm::vec3(0.065808f, 1.250000f, -2.189549f)*/;
2024-01-03 20:51:29 +01:00
glm::vec3 spaceshipDir = glm::vec3(-0.490263f, 0.000000f, 0.871578f);
2024-01-03 20:56:56 +01:00
glm::vec3 spotlightPos = glm::vec3(0, 0, 0);
glm::vec3 spotlightConeDir = glm::vec3(0, 0, 0);
glm::vec3 spotlightColor = glm::vec3(0.4, 0.4, 0.9) * 3;
float spotlightPhi = 3.14 / 4;
2024-01-03 20:59:48 +01:00
glm::vec3 cameraPos = glm::vec3(0.479490f, 1.250000f, -2.124680f);
glm::vec3 cameraDir = glm::vec3(-0.354510f, 0.000000f, 0.935054f);
2024-01-03 20:51:29 +01:00
glm::mat4 calculateModelMatrix() {
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir));
glm::mat4 specshipCameraRotrationMatrix = glm::mat4({
spaceshipSide.x,spaceshipSide.y,spaceshipSide.z,0,
spaceshipUp.x,spaceshipUp.y,spaceshipUp.z ,0,
-spaceshipDir.x,-spaceshipDir.y,-spaceshipDir.z,0,
0.,0.,0.,1.,
});
2024-01-22 18:46:06 +01:00
return glm::translate(spaceshipPos) * specshipCameraRotrationMatrix * glm::eulerAngleY(glm::pi<float>()) * glm::scale(glm::vec3(0.02f));
2024-01-03 20:51:29 +01:00
}
2024-01-30 21:13:23 +01:00
void setPerticlesParameters(float speed, float generationInterval) {
leftParticle->speed = speed;
leftParticle->generationInterval = generationInterval;
rightParticle->speed = speed;
rightParticle->generationInterval = generationInterval;
}
2024-01-16 22:15:26 +01:00
void processInput(GLFWwindow* window, float deltaTime, float time) {
static bool mouseButtonCallbackSet = false;
if (!mouseButtonCallbackSet) {
}
2024-01-03 20:51:29 +01:00
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
glm::vec3 spaceshipUp = glm::vec3(0.f, 1.f, 0.f);
float angleSpeed = 0.05f * deltaTime * 60;
float moveSpeed = 0.05f * deltaTime * 60;
2024-01-30 21:13:23 +01:00
int w = glfwGetKey(window, GLFW_KEY_W);
int s = glfwGetKey(window, GLFW_KEY_S);
if (w == GLFW_PRESS) {
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
moveSpeed *= 2;
setPerticlesParameters(200.f, 0.00005f);
}
else {
setPerticlesParameters(100.f, 0.0001f);
}
}
else {
setPerticlesParameters(50.f, 0.0002f);
}
2024-01-03 20:51:29 +01:00
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
2024-01-30 21:13:23 +01:00
if (w == GLFW_PRESS)
2024-01-03 20:51:29 +01:00
spaceshipPos += spaceshipDir * moveSpeed;
2024-01-30 21:13:23 +01:00
if (s == GLFW_PRESS)
2024-01-03 20:51:29 +01:00
spaceshipPos -= spaceshipDir * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS)
spaceshipPos += spaceshipSide * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS)
spaceshipPos -= spaceshipSide * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
spaceshipPos += spaceshipUp * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
spaceshipPos -= spaceshipUp * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
spaceshipDir = glm::vec3(glm::eulerAngleY(angleSpeed) * glm::vec4(spaceshipDir, 0));
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
spaceshipDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(spaceshipDir, 0));
2024-01-16 22:15:26 +01:00
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
requestShoot(time);
2024-01-03 20:56:56 +01:00
2024-01-30 21:13:23 +01:00
cameraPos = spaceshipPos - 1.f * spaceshipDir + glm::vec3(0, 1, 0) * 0.2f;
2024-01-03 20:59:48 +01:00
cameraDir = spaceshipDir;
2024-01-30 21:13:23 +01:00
glm::vec3 perpendicularVector = 0.04f * glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.0f, 1.0f, 0.0f)));
if (leftParticle != nullptr && rightParticle != nullptr) {
leftParticle->sourcePosition = spaceshipPos + perpendicularVector - (0.25f * spaceshipDir);
rightParticle->sourcePosition = spaceshipPos - perpendicularVector - (0.25f * spaceshipDir);
leftParticle->sourceDirection = -spaceshipDir;
rightParticle->sourceDirection = -spaceshipDir;
}
2024-01-03 20:59:48 +01:00
2024-01-03 20:56:56 +01:00
spotlightPos = spaceshipPos + 0.2 * spaceshipDir;
spotlightConeDir = spaceshipDir;
2024-01-03 20:51:29 +01:00
}
2024-01-03 20:59:48 +01:00
2024-01-30 21:13:23 +01:00
void renderParticles(GLuint program, glm::mat4 view, glm::mat4 projection, float time) {
if (leftParticle != nullptr && rightParticle != nullptr) {
leftParticle->drawParticles(program, view, projection, time);
rightParticle->drawParticles(program, view, projection, time);
}
}
void createParticles() {
if (leftParticle != nullptr && rightParticle != nullptr) {
delete leftParticle;
delete rightParticle;
}
leftParticle = new ParticleSystem();
rightParticle = new ParticleSystem();
}
2024-01-03 20:59:48 +01:00
glm::mat4 createCameraMatrix()
{
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0.f, 1.f, 0.f)));
glm::vec3 cameraUp = glm::normalize(glm::cross(cameraSide, cameraDir));
glm::mat4 cameraRotrationMatrix = glm::mat4({
cameraSide.x,cameraSide.y,cameraSide.z,0,
cameraUp.x,cameraUp.y,cameraUp.z ,0,
-cameraDir.x,-cameraDir.y,-cameraDir.z,0,
0.,0.,0.,1.,
});
cameraRotrationMatrix = glm::transpose(cameraRotrationMatrix);
glm::mat4 cameraMatrix = cameraRotrationMatrix * glm::translate(-cameraPos);
return cameraMatrix;
}
2024-01-16 22:15:26 +01:00
2024-02-03 20:20:01 +01:00
void renderBullets(float time, GLuint program, std::vector<GameEntity*>& gameEntities) {
2024-01-16 22:15:26 +01:00
for (auto it = bullets.begin(); it != bullets.end();) {
Bullet* bullet = *it;
2024-02-03 20:20:01 +01:00
if (bullet->shouldBeDestroyed(time, program, gameEntities, dmg)) {
2024-01-16 22:15:26 +01:00
delete bullet;
it = bullets.erase(it);
}
else {
it++;
}
}
}
void requestShoot(float time) {
if (canShoot(time)) {
shoot(time);
}
}
bool canShoot(float time) {
return lastShootTime == 0 || time - lastShootTime > shootInterval;
}
void shoot(float time) {
glm::vec3 perpendicularVector = 0.25f * glm::normalize(glm::cross(cameraDir, glm::vec3(0.0f, 1.0f, 0.0f)));
bullets.push_back(Bullet::createSimpleBullet(cameraDir, spaceshipPos - perpendicularVector, time));
bullets.push_back(Bullet::createSimpleBullet(cameraDir, spaceshipPos + perpendicularVector, time));
lastShootTime = time;
}
2024-02-03 20:20:01 +01:00
glm::vec3 getPosition() const override {
return spaceshipPos;
}
glm::mat4 getModelMatrix() override {
return calculateModelMatrix();
}
2024-01-03 20:51:29 +01:00
};