Merge pull request #41 from mephi1984/pavel

Pavel
This commit is contained in:
Pavel Makarov 2025-03-03 06:29:18 +06:00 committed by GitHub
commit f93a8586ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
54 changed files with 46708 additions and 337 deletions

View File

@ -16,46 +16,9 @@ struct ActiveObject {
ZL::VertexDataStruct activeObjectScreenMesh;
ZL::VertexRenderStruct activeObjectScreenMeshMutable;
std::shared_ptr<ZL::Texture> inventoryIconTexturePtr;
ZL::Vector3f objectPos;
bool highlighted = false;
};
class ActiveObjectManager {
public:
std::unordered_map<std::string, ActiveObject> activeObjectsEntities;
// Добавить или обновить объект в контейнере
void addActiveObject(const ActiveObject& object) {
activeObjectsEntities[object.name] = object;
}
// Найти объект по имени (возвращает указатель, nullptr — если не найден)
ActiveObject* findByName(const std::string& name) {
auto it = activeObjectsEntities.find(name);
if (it != activeObjectsEntities.end()) {
return &it->second;
}
return nullptr;
}
// Найти все объекты с нужным значением highlighted
// (возвращает список указателей на найденные объекты)
// ActiveObject.h
std::vector<const ActiveObject*> findByHighlighted(bool highlighted) const {
std::vector<const ActiveObject*> result;
result.reserve(activeObjectsEntities.size());
for (const auto& [key, object] : activeObjectsEntities) { // const auto&
if (object.highlighted == highlighted) {
result.push_back(&object);
}
}
return result;
}
void removeByName(const std::string& name) {
activeObjectsEntities.erase(name);
}
};
}

90
AudioPlayerAsync.cpp Normal file
View File

@ -0,0 +1,90 @@
#include "AudioPlayerAsync.h"
AudioPlayerAsync::AudioPlayerAsync() : worker(&AudioPlayerAsync::workerThread, this) {}
AudioPlayerAsync::~AudioPlayerAsync() {
{
std::unique_lock<std::mutex> lock(mtx);
stop = true;
cv.notify_all();
}
worker.join();
}
void AudioPlayerAsync::stopAsync() {
std::unique_lock<std::mutex> lock(mtx);
taskQueue.push([this]() {
//audioPlayerMutex.lock();
audioPlayer->stop();
std::this_thread::sleep_for(std::chrono::seconds(1));
//audioPlayerMutex.unlock();
});
cv.notify_one();
}
void AudioPlayerAsync::resetAsync() {
std::unique_lock<std::mutex> lock(mtx);
taskQueue.push([this]() {
//audioPlayerMutex.lock();
audioPlayer.reset();
audioPlayer = std::make_unique<AudioPlayer>();
//audioPlayerMutex.unlock();
});
cv.notify_one();
}
void AudioPlayerAsync::playSoundAsync(std::string soundName) {
soundNameMutex.lock();
latestSoundName = soundName;
soundNameMutex.unlock();
std::unique_lock<std::mutex> lock(mtx);
taskQueue.push([this]() {
//audioPlayerMutex.lock();
if (audioPlayer) {
audioPlayer->playSound(latestSoundName);
}
//audioPlayerMutex.unlock();
});
cv.notify_one();
}
void AudioPlayerAsync::playMusicAsync(std::string musicName) {
musicNameMutex.lock();
latestMusicName = musicName;
musicNameMutex.unlock();
std::unique_lock<std::mutex> lock(mtx);
taskQueue.push([this]() {
//audioPlayerMutex.lock();
if (audioPlayer) {
audioPlayer->playMusic(latestMusicName);
}
//audioPlayerMutex.unlock();
});
cv.notify_one();
}
void AudioPlayerAsync::workerThread() {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this]() { return !taskQueue.empty() || stop; });
if (stop && taskQueue.empty()) {
break;
}
task = taskQueue.front();
taskQueue.pop();
}
task();
}
}

47
AudioPlayerAsync.h Normal file
View File

@ -0,0 +1,47 @@
#pragma once
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <functional>
#include "cmakeaudioplayer/include/AudioPlayer.hpp"
class AudioPlayerAsync {
public:
AudioPlayerAsync();
~AudioPlayerAsync();
void resetAsync();
void playSoundAsync(std::string soundName);
void playMusicAsync(std::string musicName);
void stopAsync();
void exit()
{
stop = true;
}
std::thread worker;
private:
std::unique_ptr<AudioPlayer> audioPlayer;
//std::mutex audioPlayerMutex;
std::mutex soundNameMutex;
std::mutex musicNameMutex;
std::string latestSoundName;
std::string latestMusicName;
std::mutex mtx;
std::condition_variable cv;
std::queue<std::function<void()>> taskQueue;
bool stop = false;
void workerThread();
};

View File

@ -183,6 +183,11 @@ namespace ZL
{
bones[i].children.push_back(getIndexByValue(boneChildren[boneName][j], boneNames));
}
/*if (boneName == "Bone.020")
{
std::cout << i << std::endl;
}*/
}
startBones = bones;
@ -299,8 +304,6 @@ namespace ZL
localVerticesBoneWeight[i][j].weight = localVerticesBoneWeight[i][j].weight / sumWeights;
}
}
std::getline(f, tempLine);//=== Animation Keyframes ===
@ -376,8 +379,9 @@ namespace ZL
}
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[0] = floatValues[0];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[0 + 1 * 3] = floatValues[1];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[0 + 2 * 3] = floatValues[2];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[0 + 1 * 4] = floatValues[1];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[0 + 2 * 4] = floatValues[2];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[0 + 3 * 4] = floatValues[3];
std::getline(f, tempLine);
@ -390,8 +394,9 @@ namespace ZL
}
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[1] = floatValues[0];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[1 + 1 * 3] = floatValues[1];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[1 + 2 * 3] = floatValues[2];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[1 + 1 * 4] = floatValues[1];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[1 + 2 * 4] = floatValues[2];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[1 + 3 * 4] = floatValues[3];
std::getline(f, tempLine);
b = tempLine.cbegin();
@ -403,11 +408,26 @@ namespace ZL
}
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[2] = floatValues[0];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[2 + 1 * 3] = floatValues[1];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[2 + 2 * 3] = floatValues[2];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[2 + 1 * 4] = floatValues[1];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[2 + 2 * 4] = floatValues[2];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[2 + 3 * 4] = floatValues[3];
std::getline(f, tempLine);// ignore last matrix line
std::getline(f, tempLine);
b = tempLine.cbegin();
e = tempLine.cend();
floatValues.clear();
while (std::regex_search(b, e, match, pattern_float)) {
floatValues.push_back(std::stof(match.str()));
b = match.suffix().first;
}
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[3] = floatValues[0];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[3 + 1 * 4] = floatValues[1];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[3 + 2 * 4] = floatValues[2];
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.m[3 + 3 * 4] = floatValues[3];
//std::getline(f, tempLine);// ignore last matrix line
//=============== Matrix end ==================
@ -471,19 +491,48 @@ namespace ZL
currentBones[i].boneStartWorld.v[1] = oneFrameBones[i].boneStartWorld.v[1] + t * (nextFrameBones[i].boneStartWorld.v[1] - oneFrameBones[i].boneStartWorld.v[1]);
currentBones[i].boneStartWorld.v[2] = oneFrameBones[i].boneStartWorld.v[2] + t * (nextFrameBones[i].boneStartWorld.v[2] - oneFrameBones[i].boneStartWorld.v[2]);
Vector4f q1 = MatrixToQuat(oneFrameBones[i].boneMatrixWorld);
Vector4f q2 = MatrixToQuat(nextFrameBones[i].boneMatrixWorld);
Matrix3f oneFrameBonesMatrix;
oneFrameBonesMatrix.m[0] = oneFrameBones[i].boneMatrixWorld.m[0];
oneFrameBonesMatrix.m[1] = oneFrameBones[i].boneMatrixWorld.m[1];
oneFrameBonesMatrix.m[2] = oneFrameBones[i].boneMatrixWorld.m[2];
oneFrameBonesMatrix.m[3] = oneFrameBones[i].boneMatrixWorld.m[0 + 1*4];
oneFrameBonesMatrix.m[4] = oneFrameBones[i].boneMatrixWorld.m[1 + 1*4];
oneFrameBonesMatrix.m[5] = oneFrameBones[i].boneMatrixWorld.m[2 + 1*4];
oneFrameBonesMatrix.m[6] = oneFrameBones[i].boneMatrixWorld.m[0 + 2*4];
oneFrameBonesMatrix.m[7] = oneFrameBones[i].boneMatrixWorld.m[1 + 2*4];
oneFrameBonesMatrix.m[8] = oneFrameBones[i].boneMatrixWorld.m[2 + 2*4];
Matrix3f nextFrameBonesMatrix;
nextFrameBonesMatrix.m[0] = nextFrameBones[i].boneMatrixWorld.m[0];
nextFrameBonesMatrix.m[1] = nextFrameBones[i].boneMatrixWorld.m[1];
nextFrameBonesMatrix.m[2] = nextFrameBones[i].boneMatrixWorld.m[2];
nextFrameBonesMatrix.m[3] = nextFrameBones[i].boneMatrixWorld.m[0 + 1 * 4];
nextFrameBonesMatrix.m[4] = nextFrameBones[i].boneMatrixWorld.m[1 + 1 * 4];
nextFrameBonesMatrix.m[5] = nextFrameBones[i].boneMatrixWorld.m[2 + 1 * 4];
nextFrameBonesMatrix.m[6] = nextFrameBones[i].boneMatrixWorld.m[0 + 2 * 4];
nextFrameBonesMatrix.m[7] = nextFrameBones[i].boneMatrixWorld.m[1 + 2 * 4];
nextFrameBonesMatrix.m[8] = nextFrameBones[i].boneMatrixWorld.m[2 + 2 * 4];
Vector4f q1 = MatrixToQuat(oneFrameBonesMatrix);
Vector4f q2 = MatrixToQuat(nextFrameBonesMatrix);
Vector4f q1_norm = q1.normalized();
Vector4f q2_norm = q2.normalized();
Vector4f result = slerp(q1_norm, q2_norm, t);
currentBones[i].boneMatrixWorld = QuatToMatrix(result);
Matrix3f boneMatrixWorld3 = QuatToMatrix(result);
//skinningMatrixForEachBone[i] = MultMatrixMatrix(currentBones[i].boneMatrixWorld, InverseMatrix(animations[0].keyFrames[0].bones[i].boneMatrixWorld));
currentBones[i].boneMatrixWorld = MakeMatrix4x4(boneMatrixWorld3, currentBones[i].boneStartWorld);
Matrix4f currentBoneMatrixWorld4 = MakeMatrix4x4(currentBones[i].boneMatrixWorld, currentBones[i].boneStartWorld);
Matrix4f startBoneMatrixWorld4 = MakeMatrix4x4(animations[0].keyFrames[0].bones[i].boneMatrixWorld, animations[0].keyFrames[0].bones[i].boneStartWorld);
Matrix4f currentBoneMatrixWorld4 = currentBones[i].boneMatrixWorld;
Matrix4f startBoneMatrixWorld4 = animations[0].keyFrames[0].bones[i].boneMatrixWorld;
Matrix4f inverstedStartBoneMatrixWorld4 = InverseMatrix(startBoneMatrixWorld4);
skinningMatrixForEachBone[i] = MultMatrixMatrix(currentBoneMatrixWorld4, inverstedStartBoneMatrixWorld4);
@ -496,13 +545,19 @@ namespace ZL
{
currentBones[i].boneStartWorld = oneFrameBones[i].boneStartWorld;
currentBones[i].boneMatrixWorld = oneFrameBones[i].boneMatrixWorld;
Matrix4f currentBoneMatrixWorld4 = MakeMatrix4x4(currentBones[i].boneMatrixWorld, currentBones[i].boneStartWorld);
Matrix4f startBoneMatrixWorld4 = MakeMatrix4x4(animations[0].keyFrames[0].bones[i].boneMatrixWorld, animations[0].keyFrames[0].bones[i].boneStartWorld);
//Matrix4f currentBoneMatrixWorld4 = MakeMatrix4x4(currentBones[i].boneMatrixWorld, currentBones[i].boneStartWorld);
//Matrix4f startBoneMatrixWorld4 = MakeMatrix4x4(animations[0].keyFrames[0].bones[i].boneMatrixWorld, animations[0].keyFrames[0].bones[i].boneStartWorld);
Matrix4f currentBoneMatrixWorld4 = currentBones[i].boneMatrixWorld;
Matrix4f startBoneMatrixWorld4 = animations[0].keyFrames[0].bones[i].boneMatrixWorld;
Matrix4f inverstedStartBoneMatrixWorld4 = InverseMatrix(startBoneMatrixWorld4);
skinningMatrixForEachBone[i] = MultMatrixMatrix(currentBoneMatrixWorld4, inverstedStartBoneMatrixWorld4);
}
*/
if (i == 10)
{
std::cout << i << std::endl;
}
}*/
for (int i = 0; i < mesh.PositionData.size(); i++)
{
Vector4f originalPos = {

View File

@ -11,7 +11,7 @@ namespace ZL
{
Vector3f boneStartWorld;
float boneLength;
Matrix3f boneMatrixWorld;
Matrix4f boneMatrixWorld;
// boneVector = boneLength * (0, 1, 0) в осях блендера
// Then multiply by boneMatrixWorld и вы получите конечную точку

110
BoundaryBox.h Normal file
View File

@ -0,0 +1,110 @@
#pragma once
#include "Math.h"
#include <vector>
#include <memory>
namespace ZL {
// Базовый класс для всех коллизий
class Collidable {
public:
virtual bool checkCollision(const Vector3f& position) const = 0;
virtual ~Collidable() = default;
};
// Прямоугольная граница комнаты
class BoundaryBox {
public:
BoundaryBox()
{
}
BoundaryBox(float width, float height)
: halfWidth(width/2)
, halfHeight(height/2) {}
bool isInside(const Vector3f& position) const {
return (position.v[0] >= -halfWidth && position.v[0] <= halfWidth &&
position.v[2] >= -halfHeight && position.v[2] <= halfHeight);
}
private:
float halfWidth = 0;
float halfHeight = 0;
};
// Круглая коллизия для объектов
class CircleCollider : public Collidable {
public:
CircleCollider(const Vector3f& center, float radius)
: center(center)
, radius(radius) {}
bool checkCollision(const Vector3f& position) const override {
float dx = position.v[0] - center.v[0];
float dz = position.v[2] - center.v[2];
return (dx * dx + dz * dz) <= (radius * radius);
}
void setPosition(const Vector3f& newPos) { center = newPos; }
void setRadius(float newRadius) { radius = newRadius; }
private:
Vector3f center;
float radius;
};
// Прямоугольная коллизия для объектов
class RectangleCollider : public Collidable {
public:
RectangleCollider(const Vector3f& min, const Vector3f& max)
: minPoint(min)
, maxPoint(max) {}
bool checkCollision(const Vector3f& position) const override {
return (position.v[0] >= minPoint.v[0] && position.v[0] <= maxPoint.v[0] &&
position.v[2] >= minPoint.v[2] && position.v[2] <= maxPoint.v[2]);
}
private:
Vector3f minPoint;
Vector3f maxPoint;
};
// Менеджер коллизий
class CollisionManager {
public:
CollisionManager()
{
}
void setRoomBoundary(float width, float height) {
roomBoundary = BoundaryBox(width, height);
}
void addCollider(std::shared_ptr<Collidable> collider) {
colliders.push_back(collider);
}
bool checkCollision(const Vector3f& position) const {
// Проверяем границы комнаты
if (!roomBoundary.isInside(position)) {
return true;
}
// Проверяем коллизии с объектами
for (const auto& collider : colliders) {
if (collider->checkCollision(position)) {
return true;
}
}
return false;
}
private:
BoundaryBox roomBoundary;
std::vector<std::shared_ptr<Collidable>> colliders;
};
} // namespace ZL

View File

@ -40,4 +40,9 @@ bool Environment::showMouse = false;
bool Environment::exitGameLoop = false;
bool Environment::gameIsLoading = true;
float Environment::monsterTimer = 0.0;
int Environment::monsterState = 1;
} // namespace ZL

View File

@ -44,6 +44,11 @@ public:
static bool showMouse;
static bool exitGameLoop;
static bool gameIsLoading;
static float monsterTimer;
static int monsterState;
};

View File

@ -72,6 +72,24 @@ void Game::drawScene() {
}
void Game::processTickCount() {
if (Environment::gameIsLoading)
{
if (gameObjects.loadingFunctions.size() != 0)
{
bool result = gameObjects.loadingFunctions.begin()->operator()();
if (result)
{
gameObjects.loadingFunctions.erase(gameObjects.loadingFunctions.begin());
}
}
else
{
Environment::gameIsLoading = false;
}
return;
}
if (lastTickCount == 0) {
lastTickCount = SDL_GetTicks64();
return;
@ -105,9 +123,19 @@ void Game::update() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
if (gameObjects.loadingThread.joinable())
{
gameObjects.loadingThread.join();
}
gameObjects.audioPlayerAsync.exit();
Environment::exitGameLoop = true;
}
if (!Environment::gameIsLoading)
{
gameObjects.handleEvent(event);
}
gameObjects.handleEvent(event);
}
render();

View File

@ -7,168 +7,372 @@
namespace ZL {
const float GameObjectManager::INVENTORY_ICON_SIZE = 64.0f;
const float GameObjectManager::INVENTORY_MARGIN = 10.0f;
const float GameObjectManager::INVENTORY_ICON_SIZE = 44.0f;
const float GameObjectManager::INVENTORY_MARGIN = 44.0f;
const float GameObjectManager::SELECTED_CUBE_ICON_SIZE = 244.0f;
const float GameObjectManager::SELECTED_CUBE_MARGIN = 50.0f;
void GameObjectManager::initializeLoadingScreen()
{
loadingScreenTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./loading.bmp"));
loadingScreenMesh = CreateRect2D(
{ Environment::width / 2.f, Environment::height / 2.f },
{ Environment::width / 2.f, Environment::height / 2.f },
0.5f
);
loadingScreenMeshMutable.AssignFrom(loadingScreenMesh);
loadingScreenMeshMutable.RefreshVBO();
}
void GameObjectManager::initialize() {
initializeLoadingScreen();
if (!dialogTextures.empty()) { // Проверяем, есть ли диалоги
dialogTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24(dialogTextures[dialogIndex]));
isDialogActive = true;
}
std::function<bool()> loadingFunction1 = [this]()
{
current_room_index = 0;
objects_in_inventory = 0;
bearName = "";
current_room_index = 0;
objects_in_inventory = 0;
coneTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./conus.bmp"));
//coneTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./conus.bmp"));
// Load models
colorCubeMesh = CreateCube3D(5.0);
colorCubeMeshMutable.data = CreateCube3D(5.0);
colorCubeMeshMutable.RefreshVBO();
testObjMesh = LoadFromObjFile("./chair_01.obj");
testObjMesh.Scale(10);
testObjMesh.SwapZandY();
testObjMeshMutable.data = testObjMesh;
testObjMeshMutable.RefreshVBO();
textMesh = ZL::LoadFromTextFile("./textures/mesh_first_room.txt");
textMesh.Scale(10);
textMesh.SwapZandY();
textMesh.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundX(M_PI * 0.5)));
textMesh.Move(Vector3f{0, 93, 0});
coneMesh = ZL::LoadFromTextFile("./cone001.txt"); // Add ZL:: namespace
coneMesh.Scale(200);
// Load models
/*
colorCubeMesh = CreateCube3D(5.0);
colorCubeMeshMutable.data = CreateCube3D(5.0);
colorCubeMeshMutable.RefreshVBO();
*/
return true;
};
textMeshMutable.AssignFrom(textMesh);
textMeshMutable.RefreshVBO();
coneMeshMutable.AssignFrom(coneMesh);
coneMeshMutable.RefreshVBO();
loadingThread = std::thread([this]() {
preloadedRoomMeshArr.resize(2);
// Load bone animations
//bx.LoadFromFile("./violetta001.txt");
violaIdleModel.LoadFromFile("./idleviola001.txt");
violaWalkModel.LoadFromFile("./walkviolla001.txt");
// Create active object
ActiveObject ao1;
ao1.name = "book";
ao1.activeObjectMesh = ZL::LoadFromTextFile("./book001.txt"); // Add ZL:: namespace
ao1.activeObjectMesh.Scale(4);
ao1.activeObjectMeshMutable.AssignFrom(ao1.activeObjectMesh);
ao1.activeObjectMeshMutable.RefreshVBO();
ao1.objectPos = Vector3f{50, 0, -300};
ao1.activeObjectTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./book03.bmp"));
ao1.activeObjectScreenTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./aoscreen01.bmp"));
ao1.activeObjectScreenMesh = CreateRect2D({ 0.f, 0.f }, { 64.f, 64.f }, 0.5);
ao1.activeObjectScreenMeshMutable.AssignFrom(ao1.activeObjectScreenMesh);
ao1.activeObjectScreenMeshMutable.RefreshVBO();
preloadedRoomMeshArr[0] = ZL::LoadFromTextFile("./oneroom001.txt");
preloadedRoomMeshArr[0].Scale(10);
preloadedRoomMeshArr[0].Move(Vector3f{ 0, 93, 0 });
/*
ActiveObject ao2;
ao2.name = "superchair001";
ao2.activeObjectMesh = ZL::LoadFromTextFile("./superchair001.txt"); // Add ZL:: namespace
ao2.activeObjectMesh.Scale(400);
ao2.activeObjectMesh.SwapZandY();
ao2.activeObjectMeshMutable.AssignFrom(ao2.activeObjectMesh);
ao2.activeObjectMeshMutable.RefreshVBO();
ao2.objectPos = Vector3f{ 0, 0, 0 };
ao2.activeObjectTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./chair_01_Base_Color.bmp"));
ao2.activeObjectScreenTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./aoscreen01.bmp"));
ao2.activeObjectScreenMesh = CreateRect2D({ 0.f, 0.f }, { 64.f, 64.f }, 0.5);
ao2.activeObjectScreenMeshMutable.AssignFrom(ao2.activeObjectScreenMesh);
ao2.activeObjectScreenMeshMutable.RefreshVBO();
*/
preloadedRoomMeshArr[1] = ZL::LoadFromTextFile("./secondroom001.txt");
preloadedRoomMeshArr[1].Scale(10);
preloadedRoomMeshArr[1].Move(Vector3f{ 0, 93, 0 });
Room room_1;
room_1.roomTexture = std::make_shared<Texture>(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp"));
room_1.objects.push_back(ao1);
room_1.sound_name = "Symphony No.6 (1st movement).ogg";
room_1.roomLogic = createRoom1Logic();
rooms.push_back(room_1);
aoMgr.addActiveObject(ao1);
//violaIdleModel.LoadFromFile("./idleviola001.txt");
violaIdleModel.LoadFromFile("./idleviola008.txt");
Room room_2;
room_2.roomTexture = std::make_shared<Texture>(CreateTextureDataFromBmp24("./background.bmp"));
room_2.sound_name = "Symphony No.6 (1st movement).ogg";
room_2.roomLogic = createRoom2Logic();
rooms.push_back(room_2);
violaWalkModel.LoadFromFile("./walkviola008.txt");
sideThreadLoadingCompleted = true;
});
activeObjects = rooms[current_room_index].objects;
std::function<bool()> loadingFunction2 = [this]()
{
return sideThreadLoadingCompleted;
};
// Initialize audio
audioPlayer = std::make_unique<AudioPlayer>();
if (audioPlayer) {
audioPlayer->playMusic(rooms[current_room_index].sound_name);
}
std::function<bool()> loadingFunction3 = [this]()
{
// Initialize inventory
inventoryIconMesh = CreateRect2D(
{0.0f, 40.0f},
{INVENTORY_ICON_SIZE/2, INVENTORY_ICON_SIZE/2},
0.5f
);
inventoryIconMeshMutable.AssignFrom(inventoryIconMesh);
inventoryIconMeshMutable.RefreshVBO();
roomTexturePtr = rooms[current_room_index].roomTexture;
AddItemToInventory("book1", std::make_shared<Texture>(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp")), objects_in_inventory+1);
objects_in_inventory++;
AddItemToInventory("book2", std::make_shared<Texture>(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp")), objects_in_inventory+1);
objects_in_inventory++;
// Create active object
ActiveObject cubeForFirstRoomT;
cubeForFirstRoomT.name = "cube_T";
cubeForFirstRoomT.activeObjectMesh = ZL::LoadFromTextFile("./cube001.txt");
cubeForFirstRoomT.activeObjectMesh.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundZ(M_PI * 0.5)));
cubeForFirstRoomT.activeObjectMesh.Scale(10);
cubeForFirstRoomT.activeObjectMeshMutable.AssignFrom(cubeForFirstRoomT.activeObjectMesh);
cubeForFirstRoomT.activeObjectMeshMutable.RefreshVBO();
cubeForFirstRoomT.objectPos = Vector3f{ -190, 90 , 280 };
cubeForFirstRoomT.activeObjectTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./Material_Base_color_1001-_2_.bmp"));
cubeForFirstRoomT.activeObjectScreenTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./aoscreen01.bmp"));
cubeForFirstRoomT.activeObjectScreenMesh = CreateRect2D({ 0.f, 0.f }, { 64.f, 64.f }, 0.5);
cubeForFirstRoomT.activeObjectScreenMeshMutable.AssignFrom(cubeForFirstRoomT.activeObjectScreenMesh);
cubeForFirstRoomT.activeObjectScreenMeshMutable.RefreshVBO();
cubeForFirstRoomT.inventoryIconTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp32("./textures/inventory_objects/cubic_T_icon.bmp32"));
//SDL_ShowCursor(SDL_DISABLE);
SDL_SetRelativeMouseMode(SDL_TRUE);
ActiveObject cubeForFirstRoomO;
cubeForFirstRoomO.name = "cube_O";
cubeForFirstRoomO.activeObjectMesh = ZL::LoadFromTextFile("./cube001.txt");
cubeForFirstRoomO.activeObjectMesh.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundZ(M_PI * 0.5)));
cubeForFirstRoomO.activeObjectMesh.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundX(M_PI * 1.5)));
cubeForFirstRoomO.activeObjectMesh.Scale(10);
cubeForFirstRoomO.activeObjectMeshMutable.AssignFrom(cubeForFirstRoomO.activeObjectMesh);
cubeForFirstRoomO.activeObjectMeshMutable.RefreshVBO();
cubeForFirstRoomO.objectPos = Vector3f{ 185, 90 , -365 };
cubeForFirstRoomO.activeObjectTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./Material_Base_color_1001-_3.bmp"));
cubeForFirstRoomO.activeObjectScreenTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./aoscreen01.bmp"));
cubeForFirstRoomO.activeObjectScreenMesh = CreateRect2D({ 0.f, 0.f }, { 64.f, 64.f }, 0.5);
cubeForFirstRoomO.activeObjectScreenMeshMutable.AssignFrom(cubeForFirstRoomO.activeObjectScreenMesh);
cubeForFirstRoomO.activeObjectScreenMeshMutable.RefreshVBO();
cubeForFirstRoomO.inventoryIconTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp32("./textures/inventory_objects/cubic_O_icon.bmp32"));
ActiveObject cubeForFirstRoomM;
cubeForFirstRoomM.name = "cube_M";
cubeForFirstRoomM.activeObjectMesh = ZL::LoadFromTextFile("./cube001.txt");
cubeForFirstRoomO.activeObjectMesh.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundZ(M_PI * 0.5)));
cubeForFirstRoomO.activeObjectMesh.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundX(M_PI)));
cubeForFirstRoomM.activeObjectMesh.Scale(10);
cubeForFirstRoomM.activeObjectMeshMutable.AssignFrom(cubeForFirstRoomO.activeObjectMesh);
cubeForFirstRoomM.activeObjectMeshMutable.RefreshVBO();
cubeForFirstRoomM.objectPos = Vector3f{ 200, 95 , 230 };
cubeForFirstRoomM.activeObjectTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./Material_Base_color_1001_4.bmp"));
cubeForFirstRoomM.activeObjectScreenTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./aoscreen01.bmp"));
cubeForFirstRoomM.activeObjectScreenMesh = CreateRect2D({ 0.f, 0.f }, { 64.f, 64.f }, 0.5);
cubeForFirstRoomM.activeObjectScreenMeshMutable.AssignFrom(cubeForFirstRoomO.activeObjectScreenMesh);
cubeForFirstRoomM.activeObjectScreenMeshMutable.RefreshVBO();
cubeForFirstRoomM.inventoryIconTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp32("./textures/inventory_objects/cubic_M_icon.bmp32"));
ActiveObject lampe;
lampe.name = "lampe";
lampe.activeObjectMesh = ZL::LoadFromTextFile("./lighter.txt"); // Add ZL:: namespace
lampe.activeObjectMesh.Scale(7);
lampe.activeObjectMeshMutable.AssignFrom(lampe.activeObjectMesh);
lampe.activeObjectMeshMutable.RefreshVBO();
lampe.objectPos = Vector3f{ 85, 30, 43 };
lampe.activeObjectTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./temno.bmp"));
lampe.activeObjectScreenTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./aoscreen01.bmp"));
lampe.activeObjectScreenMesh = CreateRect2D({ 0.f, 0.f }, { 64.f, 64.f }, 0.5);
lampe.activeObjectScreenMeshMutable.AssignFrom(lampe.activeObjectScreenMesh);
lampe.activeObjectScreenMeshMutable.RefreshVBO();
lampe.inventoryIconTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp32("./textures/inventory_objects/cubic_T_icon.bmp32"));
ActiveObject carToy;
carToy.name = "carToy";
carToy.activeObjectMesh = ZL::LoadFromTextFile("./car.txt"); // Add ZL:: namespace
carToy.activeObjectMesh.Scale(12);
carToy.activeObjectMeshMutable.AssignFrom(carToy.activeObjectMesh);
carToy.activeObjectMeshMutable.RefreshVBO();
carToy.objectPos = Vector3f{ 300, 0, 315 };
carToy.activeObjectTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./Material.001_Base_color_1001_5.bmp"));
carToy.activeObjectScreenTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./aoscreen01.bmp"));
carToy.activeObjectScreenMesh = CreateRect2D({ 0.f, 0.f }, { 64.f, 64.f }, 0.5);
carToy.activeObjectScreenMeshMutable.AssignFrom(carToy.activeObjectScreenMesh);
carToy.activeObjectScreenMeshMutable.RefreshVBO();
carToy.inventoryIconTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp32("./textures/inventory_objects/battery.bmp32"));
Room room_1;
room_1.roomTexture = std::make_shared<Texture>(CreateTextureDataFromBmp24("./Material_Base_color_1001.bmp"));
room_1.objects.push_back(cubeForFirstRoomT);
room_1.objects.push_back(cubeForFirstRoomO);
room_1.objects.push_back(cubeForFirstRoomM);
room_1.sound_name = "lullaby-music-vol20-186394--online-audio-convert.com.ogg";
room_1.roomLogic = createRoom1Logic();
room_1.textMesh = preloadedRoomMeshArr[0];
room_1.textMeshMutable.AssignFrom(room_1.textMesh);
room_1.collisionMgr.setRoomBoundary(790, 790);
room_1.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ 80, 0, 200 }, Vector3f{ 400, 0, 400 }));
room_1.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ -220, 0, 165 }, Vector3f{ -143, 0, 230 }));
room_1.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ -400, 0, 125 }, Vector3f{ -121, 0, 400 }));
room_1.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ -380, 0, -92 }, Vector3f{ -240, 0, 100 }));
room_1.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ -399, 0, -390 }, Vector3f{ -236, 0, -100 }));
room_1.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ -220, 0, -400 }, Vector3f{ -150, 0, -230 }));
room_1.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ 156, 0, -400 }, Vector3f{ 380, 0, -360 }));
rooms.push_back(room_1);
//aoMgr.addActiveObject(ao1);
Room room_2;
room_2.roomTexture = std::make_shared<Texture>(CreateTextureDataFromBmp24("./seconroom.bmp"));
room_2.objects.push_back(lampe);
room_2.objects.push_back(carToy);
room_2.sound_name = "unholy-choir-1-279337--online-audio-convert.com.ogg";
room_2.roomLogic = createRoom2Logic();
room_2.textMesh = preloadedRoomMeshArr[1];
room_2.textMeshMutable.AssignFrom(room_2.textMesh);
room_2.collisionMgr.setRoomBoundary(790, 790);
room_2.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ -227, 0, -166 }, Vector3f{ 398, 0, -154 }));
room_2.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ -328, 0, 182 }, Vector3f{ -216, 0, 332 }));
room_2.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ -227, 0, -400 }, Vector3f{ -208, 0, -165}));
room_2.collisionMgr.addCollider(std::make_shared<RectangleCollider>(Vector3f{ 263, 0, 295 }, Vector3f{ 303, 0, 335 }));
rooms.push_back(room_2);
activeObjects = rooms[current_room_index].objects;
// Initialize audio
/*
audioPlayer = std::make_unique<AudioPlayer>();
if (audioPlayer) {
audioPlayer->playMusic(rooms[current_room_index].sound_name);
}*/
audioPlayerAsync.resetAsync();
audioPlayerAsync.playMusicAsync(rooms[current_room_index].sound_name);
// Initialize inventory
inventoryIconMesh = CreateRect2D(
{ 0.0f, 40.0f },
{ INVENTORY_ICON_SIZE / 2, INVENTORY_ICON_SIZE / 2 },
0.5f
);
inventoryIconMeshMutable.AssignFrom(inventoryIconMesh);
inventoryIconMeshMutable.RefreshVBO();
//roomTexturePtr = rooms[current_room_index].roomTexture;
monsterTexturePtr1 = std::make_shared<Texture>(CreateTextureDataFromBmp32("./monster001.bmp32"));
monsterTexturePtr2 = std::make_shared<Texture>(CreateTextureDataFromBmp32("./monster002.bmp32"));
monsterScreenMesh = CreateRect2D({ 0.f, 0.f }, { 300.f, 300.f }, 0.5);
monsterScreenMeshMutable.AssignFrom(monsterScreenMesh);
monsterScreenMeshMutable.RefreshVBO();
//SDL_ShowCursor(SDL_DISABLE);
SDL_SetRelativeMouseMode(SDL_TRUE);
return true;
};
loadingFunctions.push_back(loadingFunction1);
loadingFunctions.push_back(loadingFunction2);
loadingFunctions.push_back(loadingFunction3);
}
void GameObjectManager::switch_room(int index){
current_room_index = index;
roomTexturePtr = rooms[current_room_index].roomTexture;
//roomTexturePtr = rooms[current_room_index].roomTexture;
audioPlayer.reset(); // This deletes the current AudioPlayer
//audioPlayer.reset(); // This deletes the current AudioPlayer
// Reinitialize it
audioPlayer = std::make_unique<AudioPlayer>();
/*audioPlayer = std::make_unique<AudioPlayer>();
if (audioPlayer) {
audioPlayer->playMusic(rooms[current_room_index].sound_name);
}
}*/
audioPlayerAsync.stopAsync();
audioPlayerAsync.resetAsync();
audioPlayerAsync.playMusicAsync(rooms[current_room_index].sound_name);
activeObjects = rooms[current_room_index].objects;
std::cout << "Current music" << rooms[current_room_index].sound_name << std::endl;
}
void GameObjectManager::handleEvent(const SDL_Event& event) {
// debug room switching
// debug room switching
if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_RIGHT) {
switch_room(1);
if (isDialogActive) {
dialogIndex++;
if (dialogIndex < dialogTextures.size()) {
dialogTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24(dialogTextures[dialogIndex]));
} else {
isDialogActive = false;
}
}
}
else if (event.type == SDL_MOUSEBUTTONDOWN) {
if (InventoryItem* item = GetItemSelected(true)) {
const auto highlightedObjects = rooms[current_room_index].findByHighlighted(true);
if (InventoryItem* item = GetItemSelected(true)) {
std::cout << item->name << std::endl;
if (current_room_index==0) {
if (bearName.length() <= 3) {
if (item->name == "cube_T"){
bearName += "T";
selectedCubes.push_back(*item);
gInventoryMap.erase(item->name);
objects_in_inventory--;
}
else if (item->name == "cube_O"){
bearName += "O";
selectedCubes.push_back(*item);
gInventoryMap.erase(item->name);
objects_in_inventory--;
}
else if (item->name == "cube_M"){
bearName += "M";
selectedCubes.push_back(*item);
gInventoryMap.erase(item->name);
objects_in_inventory--;
}
}
else if (bearName.length() >= 3 && !(bearName.compare("TOM") == 0)) {
bearName = "";
for (const auto& cube : selectedCubes) {
gInventoryMap[cube.name] = cube;
}
selectedCubes.clear();
}
}
else if (current_room_index==1) {
if (InventoryItem* item = GetItemSelected(true)){
std::cout << item->name << std::endl;
if (item->name == "carToy") {
std::cout << item->name << std::endl;
// Проверить, наведена ли мышь на лампу
const auto highlightedObjects = rooms[current_room_index].findByHighlighted(true);
std::cout << highlightedObjects.size() << std::endl;
for (auto* ao : highlightedObjects) {
if (ao && ao->name == "lampe") {
// Create a new lamp object with updated texture
ActiveObject updatedLamp = *ao;
// Change from dark to lit texture
updatedLamp.activeObjectTexturePtr = std::make_shared<Texture>(CreateTextureDataFromBmp24("./base_Base_color_1001.bmp"));
// Replace the old lamp with updated one
rooms[current_room_index].removeByPtr(ao);
rooms[current_room_index].objects.push_back(updatedLamp);
activeObjects = rooms[current_room_index].objects;
// Remove car from inventory
gInventoryMap.erase(item->name);
objects_in_inventory--;
// Play sound effect
audioPlayerAsync.playSoundAsync("lamp_on.ogg");
break;
}
}
}
}
}
}
else {
const auto highlightedObjects = aoMgr.findByHighlighted(true);
const auto highlightedObjects = rooms[current_room_index].findByHighlighted(true);
for (auto* ao : highlightedObjects) {
if (!ao) {
continue;
for (auto* ao : highlightedObjects) {
if (!ao) {
continue;
}
if (ao->name != "lampe") {
AddItemToInventory(ao->name, ao->inventoryIconTexturePtr, objects_in_inventory+1);
objects_in_inventory++;
rooms[current_room_index].removeByPtr(ao);
activeObjects = rooms[current_room_index].objects;
}
//aoMgr.removeByName(ao->name);
}
AddItemToInventory(ao->name, ao->activeObjectTexturePtr, objects_in_inventory+1);
objects_in_inventory++;
aoMgr.removeByName(ao->name);
}
}
// bx.Interpolate(animationCounter);
// animationCounter += 2;
// bx.Interpolate(animationCounter);
// animationCounter += 2;
}
}
else if (event.type == SDL_MOUSEWHEEL) {
@ -182,40 +386,39 @@ void GameObjectManager::handleEvent(const SDL_Event& event) {
if (Environment::zoom < zoomstep) {
Environment::zoom = zoomstep;
}
if (Environment::zoom > 4)
{
if (Environment::zoom > 4) {
Environment::zoom = 4;
}
}
else if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_SPACE:
Environment::showMouse = !Environment::showMouse;
case SDLK_SPACE:
Environment::showMouse = !Environment::showMouse;
if (Environment::showMouse)
{
SDL_SetRelativeMouseMode(SDL_FALSE);
}
else
{
SDL_SetRelativeMouseMode(SDL_TRUE);
lastMouseX = 0;
lastMouseY = 0;
}
break;
if (Environment::showMouse) {
SDL_SetRelativeMouseMode(SDL_FALSE);
}
else {
SDL_SetRelativeMouseMode(SDL_TRUE);
lastMouseX = 0;
lastMouseY = 0;
}
break;
case SDLK_ESCAPE:
case SDLK_q:
if (loadingThread.joinable())
{
loadingThread.join();
}
audioPlayerAsync.exit();
Environment::exitGameLoop = true;
break;
case SDLK_LEFT:
case SDLK_a:
Environment::leftPressed = true;
if (audioPlayer) {
audioPlayer->playSound("Звук-Идут-по-земле.ogg");
}
if (Environment::violaCurrentAnimation == 0)
{
audioPlayerAsync.playSoundAsync("walk.ogg"); // Заменено
if (Environment::violaCurrentAnimation == 0) {
Environment::violaCurrentAnimation = 1;
Environment::violaLastWalkFrame = -1;
}
@ -223,11 +426,8 @@ void GameObjectManager::handleEvent(const SDL_Event& event) {
case SDLK_RIGHT:
case SDLK_d:
Environment::rightPressed = true;
if (audioPlayer) {
audioPlayer->playSound("Звук-Идут-по-земле.ogg");
}
if (Environment::violaCurrentAnimation == 0)
{
audioPlayerAsync.playSoundAsync("walk.ogg"); // Заменено
if (Environment::violaCurrentAnimation == 0) {
Environment::violaCurrentAnimation = 1;
Environment::violaLastWalkFrame = -1;
}
@ -235,11 +435,8 @@ void GameObjectManager::handleEvent(const SDL_Event& event) {
case SDLK_UP:
case SDLK_w:
Environment::upPressed = true;
if (audioPlayer) {
audioPlayer->playSound("Звук-Идут-по-земле.ogg");
}
if (Environment::violaCurrentAnimation == 0)
{
audioPlayerAsync.playSoundAsync("walk.ogg"); // Заменено
if (Environment::violaCurrentAnimation == 0) {
Environment::violaCurrentAnimation = 1;
Environment::violaLastWalkFrame = -1;
}
@ -247,16 +444,12 @@ void GameObjectManager::handleEvent(const SDL_Event& event) {
case SDLK_DOWN:
case SDLK_s:
Environment::downPressed = true;
if (audioPlayer) {
audioPlayer->playSound("Звук-Идут-по-земле.ogg");
}
if (Environment::violaCurrentAnimation == 0)
{
audioPlayerAsync.playSoundAsync("walk.ogg"); // Заменено
if (Environment::violaCurrentAnimation == 0) {
Environment::violaCurrentAnimation = 1;
Environment::violaLastWalkFrame = -1;
}
break;
case SDLK_1:
case SDLK_2:
case SDLK_3:
@ -273,9 +466,7 @@ void GameObjectManager::handleEvent(const SDL_Event& event) {
item->isSelected = true;
}
}
break;
// ...handle other keys...
}
}
@ -284,10 +475,8 @@ void GameObjectManager::handleEvent(const SDL_Event& event) {
case SDLK_LEFT:
case SDLK_a:
Environment::leftPressed = false;
if (Environment::leftPressed == false && Environment::rightPressed == false && Environment::upPressed == false && Environment::downPressed == false)
{
if (Environment::violaCurrentAnimation == 1)
{
if (!Environment::leftPressed && !Environment::rightPressed && !Environment::upPressed && !Environment::downPressed) {
if (Environment::violaCurrentAnimation == 1) {
Environment::violaCurrentAnimation = 0;
Environment::violaCurrentIdleFrame = -1;
}
@ -296,10 +485,8 @@ void GameObjectManager::handleEvent(const SDL_Event& event) {
case SDLK_RIGHT:
case SDLK_d:
Environment::rightPressed = false;
if (Environment::leftPressed == false && Environment::rightPressed == false && Environment::upPressed == false && Environment::downPressed == false)
{
if (Environment::violaCurrentAnimation == 1)
{
if (!Environment::leftPressed && !Environment::rightPressed && !Environment::upPressed && !Environment::downPressed) {
if (Environment::violaCurrentAnimation == 1) {
Environment::violaCurrentAnimation = 0;
Environment::violaCurrentIdleFrame = -1;
}
@ -308,10 +495,8 @@ void GameObjectManager::handleEvent(const SDL_Event& event) {
case SDLK_UP:
case SDLK_w:
Environment::upPressed = false;
if (Environment::leftPressed == false && Environment::rightPressed == false && Environment::upPressed == false && Environment::downPressed == false)
{
if (Environment::violaCurrentAnimation == 1)
{
if (!Environment::leftPressed && !Environment::rightPressed && !Environment::upPressed && !Environment::downPressed) {
if (Environment::violaCurrentAnimation == 1) {
Environment::violaCurrentAnimation = 0;
Environment::violaCurrentIdleFrame = -1;
}
@ -320,10 +505,8 @@ void GameObjectManager::handleEvent(const SDL_Event& event) {
case SDLK_DOWN:
case SDLK_s:
Environment::downPressed = false;
if (Environment::leftPressed == false && Environment::rightPressed == false && Environment::upPressed == false && Environment::downPressed == false)
{
if (Environment::violaCurrentAnimation == 1)
{
if (!Environment::leftPressed && !Environment::rightPressed && !Environment::upPressed && !Environment::downPressed) {
if (Environment::violaCurrentAnimation == 1) {
Environment::violaCurrentAnimation = 0;
Environment::violaCurrentIdleFrame = -1;
}
@ -332,49 +515,39 @@ void GameObjectManager::handleEvent(const SDL_Event& event) {
}
}
if (event.type == SDL_MOUSEMOTION) {
if (Environment::showMouse == false)
{
if (!Environment::showMouse) {
int mouseX, mouseY;
SDL_GetRelativeMouseState(&mouseX, &mouseY);
float diffX = 0.01f * mouseX;
float diffY = 0.01f * mouseY;
Environment::cameraPhi += diffX;
if (Environment::settings_inverseVertical)
{
if (Environment::settings_inverseVertical) {
Environment::cameraAlpha -= diffY;
}
else
{
else {
Environment::cameraAlpha += diffY;
}
if (Environment::cameraAlpha < 0.1 * M_PI / 2.0)
{
if (Environment::cameraAlpha < 0.1 * M_PI / 2.0) {
Environment::cameraAlpha = 0.1 * M_PI / 2.0;
}
else if (Environment::cameraAlpha > 0.9 * M_PI / 2.0)
{
else if (Environment::cameraAlpha > 0.9 * M_PI / 2.0) {
Environment::cameraAlpha = 0.9 * M_PI / 2.0;
}
}
else
{
else {
lastMouseX = event.motion.x;
lastMouseY = event.motion.y;
}
}
}
void GameObjectManager::updateScene(size_t ms) {
const float SPEED = 0.1f;
Vector2f directionVector = { 0.f, SPEED }; //x and z
Vector2f directionVector = { 0.f, SPEED }; // x and z
// Вычисляем новые координаты вектора
float x_new = directionVector.v[0] * cos(Environment::cameraPhi) - directionVector.v[1] * sin(Environment::cameraPhi);
@ -384,7 +557,7 @@ void GameObjectManager::updateScene(size_t ms) {
directionVector.v[0] = x_new;
directionVector.v[1] = y_new;
//Only forward is allowed
// Only forward is allowed
/*
if (Environment::leftPressed) {
Environment::cameraShift.v[0] += SPEED * ms;
@ -397,29 +570,57 @@ void GameObjectManager::updateScene(size_t ms) {
}
if (Environment::downPressed) {
Environment::cameraShift.v[2] -= SPEED * ms;
}*/
}
*/
Vector3f newPosition = Environment::cameraShift;
if (Environment::upPressed) {
Environment::cameraShift.v[0] += directionVector.v[0] * ms;
Environment::cameraShift.v[2] += directionVector.v[1] * ms;
newPosition.v[0] += directionVector.v[0] * ms;
newPosition.v[2] += directionVector.v[1] * ms;
}
if (Environment::downPressed) {
Environment::cameraShift.v[0] -= directionVector.v[0] * ms;
Environment::cameraShift.v[2] -= directionVector.v[1] * ms;
newPosition.v[0] -= directionVector.v[0] * ms;
newPosition.v[2] -= directionVector.v[1] * ms;
}
if (Environment::rightPressed) {
Environment::cameraShift.v[2] += directionVector.v[0] * ms;
Environment::cameraShift.v[0] -= directionVector.v[1] * ms;
newPosition.v[2] += directionVector.v[0] * ms;
newPosition.v[0] -= directionVector.v[1] * ms;
}
if (Environment::leftPressed) {
Environment::cameraShift.v[2] -= directionVector.v[0] * ms;
Environment::cameraShift.v[0] += directionVector.v[1] * ms;
newPosition.v[2] -= directionVector.v[0] * ms;
newPosition.v[0] += directionVector.v[1] * ms;
}
Environment::characterPos.v[0] = -Environment::cameraShift.v[0];
Environment::characterPos.v[1] = -Environment::cameraShift.v[1];
Environment::characterPos.v[2] = -Environment::cameraShift.v[2];
Vector3f characterNewPos{-newPosition.v[0], -newPosition.v[1], -newPosition.v[2]};
std::cout << "Player position: x=" << characterNewPos.v[0]
<< ", y=" << characterNewPos.v[1]
<< ", z=" << characterNewPos.v[2] << "\r";
std::cout.flush();
// Заменяем проверку walkArea.isInside() на проверку через collisionMgr
if (rooms[current_room_index].collisionMgr.checkCollision(characterNewPos) == false) {
Environment::cameraShift = newPosition;
Environment::characterPos = characterNewPos;
/*
std::cout << "Player position: x=" << characterNewPos.v[0]
<< ", y=" << characterNewPos.v[1]
<< ", z=" << characterNewPos.v[2] << "\r";
std::cout.flush(); // Чтобы обновлялось в той же строке*/
}
for (auto& obj : rooms[current_room_index].objects)
{
float dist = sqrtf(
pow(Environment::characterPos.v[0] - obj.objectPos.v[0], 2) +
pow(Environment::characterPos.v[1] - obj.objectPos.v[1], 2) +
pow(Environment::characterPos.v[2] - obj.objectPos.v[2], 2)
);
obj.highlighted = (dist < 150.f);
}
/*
for (auto& [key, obj] : aoMgr.activeObjectsEntities) {
float dist = sqrtf(
pow(Environment::characterPos.v[0] - obj.objectPos.v[0], 2) +
@ -427,55 +628,70 @@ void GameObjectManager::updateScene(size_t ms) {
pow(Environment::characterPos.v[2] - obj.objectPos.v[2], 2)
);
obj.highlighted = (dist < 50.f);
}
}*/
if (rooms[current_room_index].roomLogic) {
rooms[current_room_index].roomLogic(*this, ms);
}
if (Environment::violaCurrentAnimation == 0)
{
if (Environment::violaCurrentAnimation == 0) {
Environment::violaCurrentIdleFrame += ms / 24.f;
//Environment::violaCurrentIdleFrame = 0;
while (Environment::violaCurrentIdleFrame >= 40)
{
while (Environment::violaCurrentIdleFrame >= 40) {
Environment::violaCurrentIdleFrame -= 40;
}
if (int(Environment::violaCurrentIdleFrame) != Environment::violaLastIdleFrame)
{
if (int(Environment::violaCurrentIdleFrame) != Environment::violaLastIdleFrame) {
violaIdleModel.Interpolate(int(Environment::violaCurrentIdleFrame));
Environment::violaLastIdleFrame = int(Environment::violaCurrentIdleFrame);
}
}
else if (Environment::violaCurrentAnimation == 1)
{
else if (Environment::violaCurrentAnimation == 1) {
Environment::violaCurrentWalkFrame += ms / 24.f;
while (Environment::violaCurrentWalkFrame >= 30)
{
while (Environment::violaCurrentWalkFrame >= 30) {
Environment::violaCurrentWalkFrame -= 30;
}
if (int(Environment::violaCurrentWalkFrame) != Environment::violaLastWalkFrame)
{
if (int(Environment::violaCurrentWalkFrame) != Environment::violaLastWalkFrame) {
violaWalkModel.Interpolate(int(Environment::violaCurrentWalkFrame));
Environment::violaLastWalkFrame = int(Environment::violaCurrentWalkFrame);
}
}
if (Environment::monsterState == 0)
{
Environment::monsterTimer += ms;
if (Environment::monsterTimer > 500)
{
Environment::monsterTimer = 0;
Environment::monsterState = 1;
}
}
else
{
Environment::monsterTimer += ms;
if (Environment::monsterTimer > 500)
{
Environment::monsterTimer = 0;
Environment::monsterState = 0;
}
}
//float Environment::monsterTimer = 0.0;
//int Environment::monsterState = 1;
}
bool GameObjectManager::isPointInObject(int screenX, int screenY, int objectScreenX, int objectScreenY) const {
const int baseObjectSize = 32; // Base half-size
const float scale = 1.0f; // Get scale from item if needed
const int scaledObjectSize = static_cast<int>(baseObjectSize * scale);
return (screenX >= objectScreenX - scaledObjectSize &&
screenX <= objectScreenX + scaledObjectSize &&
screenY >= objectScreenY - scaledObjectSize &&
screenY <= objectScreenY + scaledObjectSize);
// Простая проверка попадания точки в квадрат 64x64 вокруг центра объекта
const int objectSize = 32; // Половина размера области выделения
return (screenX >= objectScreenX - objectSize &&
screenX <= objectScreenX + objectSize &&
screenY >= objectScreenY - objectSize &&
screenY <= objectScreenY + objectSize);
}
void GameObjectManager::checkMouseIntersection(int mouseX, int mouseY, const Matrix4f& projectionModelView) {
@ -501,7 +717,7 @@ void GameObjectManager::worldToScreenCoordinates(Vector3f objectPos,
int screenWidth, int screenHeight,
int& screenX, int& screenY) {
Vector4f inx = { objectPos.v[0], objectPos.v[1], objectPos.v[2], 1.0f};
Vector4f inx = { objectPos.v[0], objectPos.v[1], objectPos.v[2], 1.0f };
Vector4f clipCoords = MultMatrixVector(projectionModelView, inx);
float ndcX = clipCoords.v[0] / clipCoords.v[3];

View File

@ -1,20 +1,28 @@
#pragma once
#include "TextureManager.h"
#include "BoneAnimatedModel.h"
#include "cmakeaudioplayer/include/AudioPlayer.hpp"
#include "AudioPlayerAsync.h"
#include <memory>
#include <vector>
#include "ActiveObject.h"
#include "Room.h"
#include "RenderSystem.h"
#include "Inventory.h"
#ifdef __linux__
#include <SDL2/SDL.h>
#endif
#include "OpenGlExtensions.h"
#include <thread>
#include <list>
#include "BoundaryBox.h" // Добавляем новый include
namespace ZL {
class GameObjectManager {
public:
void initializeLoadingScreen();
void initialize();
void switch_room(int index);
@ -24,14 +32,14 @@ public:
void checkMouseIntersection(int mouseX, int mouseY, const Matrix4f& projectionModelView); // Добавляем новый метод
std::shared_ptr<ZL::Texture> testObjTexturePtr;
std::shared_ptr<ZL::Texture> roomTexturePtr;
//std::shared_ptr<ZL::Texture> roomTexturePtr;
std::shared_ptr<ZL::Texture> coneTexturePtr;
ZL::VertexDataStruct colorCubeMesh;
ZL::VertexRenderStruct colorCubeMeshMutable;
//ZL::VertexDataStruct colorCubeMesh;
//ZL::VertexRenderStruct colorCubeMeshMutable;
ZL::VertexDataStruct testObjMesh;
ZL::VertexRenderStruct testObjMeshMutable;
//ZL::VertexDataStruct testObjMesh;
//ZL::VertexRenderStruct testObjMeshMutable;
ZL::BoneSystem violaIdleModel;
ZL::VertexRenderStruct violaIdleModelMutable;
@ -39,34 +47,65 @@ public:
ZL::BoneSystem violaWalkModel;
ZL::VertexRenderStruct violaWalkModelMutable;
ZL::VertexDataStruct textMesh;
ZL::VertexRenderStruct textMeshMutable;
std::vector<ZL::VertexDataStruct> preloadedRoomMeshArr;
ZL::VertexDataStruct coneMesh;
ZL::VertexRenderStruct coneMeshMutable;
//ZL::VertexDataStruct coneMesh; // Раскомментировали
//ZL::VertexRenderStruct coneMeshMutable; // Раскомментировали
std::vector<ZL::ActiveObject> activeObjects;
std::vector<ZL::Room> rooms;
std::unique_ptr<AudioPlayer> audioPlayer;
std::vector<InventoryItem> selectedCubes;
std::string bearName;
AudioPlayerAsync audioPlayerAsync;
ZL::VertexDataStruct inventoryIconMesh;
ZL::VertexRenderStruct inventoryIconMeshMutable;
static const float INVENTORY_ICON_SIZE;
static const float INVENTORY_MARGIN;
ActiveObjectManager aoMgr;
static const float SELECTED_CUBE_ICON_SIZE;
static const float SELECTED_CUBE_MARGIN;
//ActiveObjectManager aoMgr;
int objects_in_inventory;
std::shared_ptr<ZL::Texture> loadingScreenTexturePtr;
ZL::VertexDataStruct loadingScreenMesh;
ZL::VertexRenderStruct loadingScreenMeshMutable;
std::list<std::function<bool()>> loadingFunctions;
std::thread loadingThread;
bool sideThreadLoadingCompleted = false;
int current_room_index;
std::shared_ptr<ZL::Texture> monsterTexturePtr1;
std::shared_ptr<ZL::Texture> monsterTexturePtr2;
ZL::VertexDataStruct monsterScreenMesh;
ZL::VertexRenderStruct monsterScreenMeshMutable;
std::vector<std::string> dialogTextures = { // Список диалогов
"./start_dialog.bmp",
"./next_dialog.bmp",
};
int dialogIndex = 0; // Текущий индекс диалога
std::shared_ptr<Texture> dialogTexturePtr; // Активная текстура диалога
bool isDialogActive = false; // Флаг активности диалога
private:
//int animationCounter = 0;
int lastMouseX = 0; // Добавляем переменные для хранения позиции мыши
int lastMouseY = 0;
int current_room_index;
bool isPointInObject(int screenX, int screenY, int objectScreenX, int objectScreenY) const;
void worldToScreenCoordinates(Vector3f objectPos, // Добавляем метод
Matrix4f projectionModelView,
int screenWidth, int screenHeight,
int& screenX, int& screenY);
BoundaryBox walkArea{800.0f, 800.0f}; // Зона для ходьбы 800x800
};
} // namespace ZL

View File

@ -27,7 +27,7 @@ namespace ZL
}
InventoryItem* GetItemByName(const std::string name)
InventoryItem* GetItemByName(const std::string& name)
{
// Пытаемся найти элемент по ключу
auto it = gInventoryMap.find(name);

View File

@ -32,7 +32,7 @@ namespace ZL
// Поиск предмета по индексу (возвращает указатель или nullptr)
InventoryItem* GetItemByHotkey(int hot_key);
InventoryItem* GetItemSelected(bool isSelected);
InventoryItem* GetItemByName(std::string name);
InventoryItem* GetItemByName(const std::string& name);
// Вывести весь инвентарь в консоль
void PrintInventory();

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

View File

@ -2,23 +2,39 @@
#include "GameObjectManager.h"
#include "Inventory.h"
#include <iostream>
#include <chrono>
#include <thread>
namespace ZL
{
std::function<void(GameObjectManager&, size_t)> createRoom1Logic()
{
return [](GameObjectManager& gom, size_t ms)
// Simple test logic
return [elapsedTime = 0u](GameObjectManager& gom, size_t ms) mutable
{
if (GetItemByName("book")) {
std::cout << "[Room 1] Игрок поднял книгу!\n";
gom.switch_room(1);
if (gom.bearName.compare("TOM") == 0) {
elapsedTime += ms;
if (elapsedTime >= 2000) {
gInventoryMap.clear();
gom.switch_room(1);
}
} else if (gom.selectedCubes.size() >= 3 && gom.bearName.compare("TOM") != 0) {
std::cout << "Else" << std::endl;
elapsedTime += ms;
if (elapsedTime >= 2000) {
gom.bearName = "";
for (const auto& cube : gom.selectedCubes) {
gInventoryMap[cube.name] = cube;
}
gom.selectedCubes.clear();
elapsedTime = 0;
}
}
};
}
std::function<void(GameObjectManager&, size_t)> createRoom2Logic()
{
return [](GameObjectManager& gom, size_t ms)

View File

@ -26,20 +26,16 @@ void RenderSystem::drawScene(GameObjectManager& gameObjects) {
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glViewport(0, 0, Environment::width, Environment::height);
/*
renderer.shaderManager.PushShader(defaultShaderName);
renderer.RenderUniform1i(textureUniformName, 0);
renderer.EnableVertexAttribArray(vPositionName);
renderer.EnableVertexAttribArray(vTexCoordName);
*/
drawWorld(gameObjects);
drawUI(gameObjects);
/*renderer.DisableVertexAttribArray(vPositionName);
renderer.DisableVertexAttribArray(vTexCoordName);
renderer.shaderManager.PopShader();*/
if (Environment::gameIsLoading)
{
drawLoadingScreen(gameObjects);
}
else
{
drawWorld(gameObjects);
drawUI(gameObjects);
}
CheckGlError();
}
@ -65,7 +61,6 @@ void RenderSystem::drawViola(GameObjectManager& gameObjects)
renderer.TranslateMatrix({ 0,0, -100 * Environment::zoom });
renderer.RotateMatrix(QuatFromRotateAroundX(Environment::cameraAlpha));
//renderer.RotateMatrix(QuatFromRotateAroundY(Environment::cameraPhi));
//Go a little bit up to make camera at the position of Viola
renderer.TranslateMatrix({ 0, Environment::cameraDefaultVerticalShift, 0 });
@ -74,6 +69,7 @@ void RenderSystem::drawViola(GameObjectManager& gameObjects)
//Viola stuff
renderer.ScaleMatrix(10);
renderer.RotateMatrix(QuatFromRotateAroundX(-M_PI / 2.0));
renderer.RotateMatrix(QuatFromRotateAroundZ(M_PI));
@ -125,8 +121,11 @@ void RenderSystem::drawWorld(GameObjectManager& gameObjects) {
//glBindTexture(GL_TEXTURE_2D, gameObjects.coneTexturePtr->getTexID());
//renderer.DrawVertexRenderStruct(gameObjects.coneMeshMutable);
//drawMonster(gameObjects);
//glClear(GL_DEPTH_BUFFER_BIT);
drawViola(gameObjects);
renderer.shaderManager.PushShader(hideCamShaderName);
renderer.RenderUniform1i(textureUniformName, 0);
@ -166,17 +165,17 @@ void RenderSystem::drawWorld(GameObjectManager& gameObjects) {
renderer.TranslateMatrix({ 0, Environment::cameraDefaultVerticalShift, 0 });
// Draw active objects
for (const auto& ao : gameObjects.activeObjects) {
renderer.PushMatrix();
renderer.TranslateMatrix(ao.objectPos);
glBindTexture(GL_TEXTURE_2D, ao.activeObjectTexturePtr->getTexID());
renderer.DrawVertexRenderStruct(ao.activeObjectMeshMutable);
renderer.PopMatrix();
}
drawObjects(gameObjects);
// Draw room
glBindTexture(GL_TEXTURE_2D, gameObjects.roomTexturePtr->getTexID());
renderer.DrawVertexRenderStruct(gameObjects.textMeshMutable);
glBindTexture(GL_TEXTURE_2D, gameObjects.rooms[gameObjects.current_room_index].roomTexture->getTexID());
renderer.DrawVertexRenderStruct(gameObjects.rooms[gameObjects.current_room_index].textMeshMutable);
if (gameObjects.current_room_index == 1)
{
drawMonster(gameObjects);
}
drawViola(gameObjects);
Matrix4f latestProjectionModelView = renderer.GetProjectionModelViewMatrix();
@ -211,13 +210,29 @@ void RenderSystem::drawUI(const GameObjectManager& gameObjects) {
renderer.PushMatrix();
renderer.LoadIdentity();
for (const auto* ao : gameObjects.aoMgr.findByHighlighted(true)) {
// Отрисовка диалогового окна, если оно активно
if (gameObjects.isDialogActive && gameObjects.dialogTexturePtr) {
renderer.PushMatrix();
float xPos = Environment::width / 2.0f - 250; // Центрируем
float yPos = Environment::height / 2.0f - 125; // Центрируем
renderer.TranslateMatrix(Vector3f{xPos, yPos, 0.0f});
renderer.ScaleMatrix(Vector3f{1.5f, 1.5f, 1.0f}); // Увеличиваем размер
glBindTexture(GL_TEXTURE_2D, gameObjects.dialogTexturePtr->getTexID());
renderer.DrawVertexRenderStruct(gameObjects.inventoryIconMeshMutable); // Используем 2D меш инвентаря
renderer.PopMatrix();
}
//for (const auto* ao : gameObjects.aoMgr.findByHighlighted(true)) {
for (auto& ao : gameObjects.rooms[gameObjects.current_room_index].findByHighlighted(true)) {
std::cout << ao->name << std::endl;
std::cout << "Draw" << std::endl;
if (ao->activeObjectScreenTexturePtr) {
std::cout << "Found activeObjectScreenTexturePtr" << std::endl;
int screenX, screenY;
worldToScreenCoordinates(ao->objectPos, currentProjectionModelView,
Vector3f objectPosPlusShift = ao->objectPos + Vector3f{ 0, -Environment::cameraDefaultVerticalShift, 0 };
worldToScreenCoordinates(objectPosPlusShift, currentProjectionModelView,
Environment::width, Environment::height, screenX, screenY);
renderer.PushMatrix();
// Здесь можно использовать вычисленные screenX, screenY,
@ -237,11 +252,12 @@ void RenderSystem::drawUI(const GameObjectManager& gameObjects) {
if (item.isSelected) {
float xPos = Environment::width
- gameObjects.INVENTORY_MARGIN
- gameObjects.INVENTORY_ICON_SIZE+25;
- gameObjects.INVENTORY_ICON_SIZE;
float yPos = gameObjects.INVENTORY_MARGIN
+ i * (gameObjects.INVENTORY_ICON_SIZE+25
+ i * (gameObjects.INVENTORY_ICON_SIZE
+ gameObjects.INVENTORY_MARGIN);
renderer.TranslateMatrix(Vector3f{xPos, yPos, 0.0f});
renderer.ScaleMatrix(Vector3f{1.5f, 1.5f, 1.0f});
glBindTexture(GL_TEXTURE_2D, item.texture->getTexID());
}
else {
@ -263,6 +279,25 @@ void RenderSystem::drawUI(const GameObjectManager& gameObjects) {
i++;
}
// Отрисовка кубиков
if (gameObjects.current_room_index == 0) {
for (int j = gameObjects.selectedCubes.size() - 1; j >= 0; j--) {
auto& cube = gameObjects.selectedCubes[j];
renderer.PushMatrix();
float xPos = (gameObjects.SELECTED_CUBE_MARGIN + 300.0f)
+ j * (gameObjects.SELECTED_CUBE_ICON_SIZE + gameObjects.SELECTED_CUBE_MARGIN);
float yPos = 500.0f;
renderer.TranslateMatrix(Vector3f{xPos, yPos, 0.0f});
renderer.ScaleMatrix(Vector3f{2.8f, 2.8f, 1.0f});
glBindTexture(GL_TEXTURE_2D, cube.texture->getTexID());
renderer.DrawVertexRenderStruct(gameObjects.inventoryIconMeshMutable);
renderer.PopMatrix();
}
}
renderer.PopMatrix();
renderer.PopProjectionMatrix();
@ -274,6 +309,84 @@ void RenderSystem::drawUI(const GameObjectManager& gameObjects) {
renderer.shaderManager.PopShader();
}
void RenderSystem::drawLoadingScreen(const GameObjectManager& gameObjects)
{
renderer.shaderManager.PushShader("default");
// Если шейдер ожидает атрибуты вершин, их нужно включить
static const std::string vPositionName = "vPosition";
static const std::string vTexCoordName = "vTexCoord";
renderer.EnableVertexAttribArray(vPositionName);
renderer.EnableVertexAttribArray(vTexCoordName);
renderer.PushProjectionMatrix(static_cast<float>(Environment::width),
static_cast<float>(Environment::height));
renderer.PushMatrix();
renderer.LoadIdentity();
glBindTexture(GL_TEXTURE_2D, gameObjects.loadingScreenTexturePtr->getTexID());
renderer.DrawVertexRenderStruct(gameObjects.loadingScreenMeshMutable);
renderer.PopMatrix();
renderer.PopProjectionMatrix();
// Выключаем атрибуты, чтобы сохранить баланс
renderer.DisableVertexAttribArray(vPositionName);
renderer.DisableVertexAttribArray(vTexCoordName);
// Снимаем шейдер, тем самым балансируя стек
renderer.shaderManager.PopShader();
}
void RenderSystem::drawMonster(const GameObjectManager& gameObjects)
{
renderer.shaderManager.PushShader("default");
static const std::string vPositionName = "vPosition";
static const std::string vTexCoordName = "vTexCoord";
renderer.EnableVertexAttribArray(vPositionName);
renderer.EnableVertexAttribArray(vTexCoordName);
renderer.PushProjectionMatrix(static_cast<float>(Environment::width),
static_cast<float>(Environment::height), -10, 10);
renderer.PushMatrix();
renderer.LoadIdentity();
std::cout << "Found activeObjectScreenTexturePtr" << std::endl;
int screenX, screenY;
Vector3f objectPosPlusShift = Vector3f{ -300, 50, -70 };
worldToScreenCoordinates(objectPosPlusShift, currentProjectionModelView,
Environment::width, Environment::height, screenX, screenY);
renderer.PushMatrix();
// Здесь можно использовать вычисленные screenX, screenY,
// но для теста оставляем фиксированное значение
renderer.TranslateMatrix(Vector3f{ screenX + 0.f, screenY + 0.f, 0.0f });
if (Environment::monsterState == 0)
{
glBindTexture(GL_TEXTURE_2D, gameObjects.monsterTexturePtr1->getTexID());
}
else
{
glBindTexture(GL_TEXTURE_2D, gameObjects.monsterTexturePtr2->getTexID());
}
renderer.DrawVertexRenderStruct(gameObjects.monsterScreenMeshMutable);
renderer.PopMatrix();
renderer.PopMatrix();
renderer.PopProjectionMatrix();
// Выключаем атрибуты, чтобы сохранить баланс
renderer.DisableVertexAttribArray(vPositionName);
renderer.DisableVertexAttribArray(vTexCoordName);
// Снимаем шейдер, тем самым балансируя стек
renderer.shaderManager.PopShader();
}
void RenderSystem::worldToScreenCoordinates(Vector3f objectPos,
Matrix4f projectionModelView,
@ -290,4 +403,14 @@ void RenderSystem::worldToScreenCoordinates(Vector3f objectPos,
screenY = (int)((1.0f + ndcY) * 0.5f * screenHeight);
}
void RenderSystem::drawObjects(GameObjectManager& gameObjects){
for (const auto& ao : gameObjects.activeObjects) {
renderer.PushMatrix();
renderer.TranslateMatrix(ao.objectPos);
glBindTexture(GL_TEXTURE_2D, ao.activeObjectTexturePtr->getTexID());
renderer.DrawVertexRenderStruct(ao.activeObjectMeshMutable);
renderer.PopMatrix();
}
}
} // namespace ZL

View File

@ -9,6 +9,7 @@ namespace ZL {
class RenderSystem {
public:
RenderSystem() = default;
Renderer renderer;
void initialize();
void drawScene(GameObjectManager& gameObjects);
Renderer& getRenderer() { return renderer; }
@ -18,13 +19,18 @@ public:
int screenWidth, int screenHeight,
int& screenX, int& screenY);
void drawObjects(GameObjectManager& gameObjects);
void drawDialog(GameObjectManager& gameObjects);
private:
void drawWorld(GameObjectManager& gameObjects);
void drawUI(const GameObjectManager& gameObjects);
void drawViola(GameObjectManager& gameObjects);
Renderer renderer;
void drawLoadingScreen(const GameObjectManager& gameObjects);
void drawMonster(const GameObjectManager& gameObjects);
ShaderManager shaderManager;
Matrix4f currentProjectionModelView; // Добавлено для хранения матрицы между drawWorld и drawUI
int lastMouseX = 0;

37
Room.h
View File

@ -4,8 +4,9 @@
#include "Math.h"
#include <memory>
#include "ActiveObject.h"
#include <functional>
#include <functional>
#include "BoundaryBox.h"
namespace ZL
{
struct Room{
@ -13,7 +14,41 @@ struct Room{
std::vector<ActiveObject> objects;
std::string sound_name;
ZL::VertexDataStruct textMesh;
ZL::VertexRenderStruct textMeshMutable;
CollisionManager collisionMgr;
std::function<void(class GameObjectManager&, size_t)> roomLogic;
Room()
{
objects.reserve(30);
}
std::vector<const ActiveObject*> findByHighlighted(bool highlighted) const {
std::vector<const ActiveObject*> result;
for (auto& o : objects)
{
if (o.highlighted == highlighted) {
result.push_back(&o);
}
}
return result;
}
void removeByPtr(const ActiveObject* ptr) {
for (int i = 0; i < objects.size(); i++)
{
if (ptr == &objects[i])
{
objects.erase(objects.begin() + i);
return;
}
}
}
};
}

View File

@ -146,6 +146,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="AudioPlayerAsync.cpp" />
<ClCompile Include="BoneAnimatedModel.cpp" />
<ClCompile Include="Environment.cpp" />
<ClCompile Include="Game.cpp" />
@ -170,7 +171,9 @@
<ItemGroup>
<ClInclude Include="ActiveObject.h" />
<ClInclude Include="AnimatedModel.h" />
<ClInclude Include="AudioPlayerAsync.h" />
<ClInclude Include="BoneAnimatedModel.h" />
<ClInclude Include="BoundaryBox.h" />
<ClInclude Include="Environment.h" />
<ClInclude Include="Game.h" />
<ClInclude Include="GameObjectManager.h" />

View File

@ -75,6 +75,9 @@
<ClCompile Include="QuestScripts.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="AudioPlayerAsync.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="TextureManager.h">
@ -140,5 +143,11 @@
<ClInclude Include="QuestScripts.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="AudioPlayerAsync.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BoundaryBox.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

BIN
base_Base_color_1001.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB

1325
car.txt Normal file

File diff suppressed because it is too large Load Diff

93
cube001.txt Normal file
View File

@ -0,0 +1,93 @@
===Vertices: 8
Vertex 0: <Vector (1.0000, 1.0000, 1.0000)>
Vertex 1: <Vector (1.0000, 1.0000, -1.0000)>
Vertex 2: <Vector (1.0000, -1.0000, 1.0000)>
Vertex 3: <Vector (1.0000, -1.0000, -1.0000)>
Vertex 4: <Vector (-1.0000, 1.0000, 1.0000)>
Vertex 5: <Vector (-1.0000, 1.0000, -1.0000)>
Vertex 6: <Vector (-1.0000, -1.0000, 1.0000)>
Vertex 7: <Vector (-1.0000, -1.0000, -1.0000)>
===UV Coordinates:
Face count: 12
Face 0
UV Count: 3
UV <Vector (0.8750, 0.5000)>
UV <Vector (0.6250, 0.7500)>
UV <Vector (0.6250, 0.5000)>
Face 1
UV Count: 3
UV <Vector (0.6250, 0.7500)>
UV <Vector (0.3750, 1.0000)>
UV <Vector (0.3750, 0.7500)>
Face 2
UV Count: 3
UV <Vector (0.6250, 0.0000)>
UV <Vector (0.3750, 0.2500)>
UV <Vector (0.3750, 0.0000)>
Face 3
UV Count: 3
UV <Vector (0.3750, 0.5000)>
UV <Vector (0.1250, 0.7500)>
UV <Vector (0.1250, 0.5000)>
Face 4
UV Count: 3
UV <Vector (0.6250, 0.5000)>
UV <Vector (0.3750, 0.7500)>
UV <Vector (0.3750, 0.5000)>
Face 5
UV Count: 3
UV <Vector (0.6250, 0.2500)>
UV <Vector (0.3750, 0.5000)>
UV <Vector (0.3750, 0.2500)>
Face 6
UV Count: 3
UV <Vector (0.8750, 0.5000)>
UV <Vector (0.8750, 0.7500)>
UV <Vector (0.6250, 0.7500)>
Face 7
UV Count: 3
UV <Vector (0.6250, 0.7500)>
UV <Vector (0.6250, 1.0000)>
UV <Vector (0.3750, 1.0000)>
Face 8
UV Count: 3
UV <Vector (0.6250, 0.0000)>
UV <Vector (0.6250, 0.2500)>
UV <Vector (0.3750, 0.2500)>
Face 9
UV Count: 3
UV <Vector (0.3750, 0.5000)>
UV <Vector (0.3750, 0.7500)>
UV <Vector (0.1250, 0.7500)>
Face 10
UV Count: 3
UV <Vector (0.6250, 0.5000)>
UV <Vector (0.6250, 0.7500)>
UV <Vector (0.3750, 0.7500)>
Face 11
UV Count: 3
UV <Vector (0.6250, 0.2500)>
UV <Vector (0.6250, 0.5000)>
UV <Vector (0.3750, 0.5000)>
===Normals:
Vertex 0: Normal <Vector (0.5774, 0.5773, 0.5773)>
Vertex 1: Normal <Vector (0.5773, 0.5774, -0.5774)>
Vertex 2: Normal <Vector (0.5773, -0.5774, 0.5774)>
Vertex 3: Normal <Vector (0.5774, -0.5773, -0.5773)>
Vertex 4: Normal <Vector (-0.5773, 0.5774, 0.5774)>
Vertex 5: Normal <Vector (-0.5774, 0.5773, -0.5773)>
Vertex 6: Normal <Vector (-0.5774, -0.5773, 0.5773)>
Vertex 7: Normal <Vector (-0.5773, -0.5774, -0.5774)>
===Triangles: 12
Triangle: [4, 2, 0]
Triangle: [2, 7, 3]
Triangle: [6, 5, 7]
Triangle: [1, 7, 5]
Triangle: [0, 3, 1]
Triangle: [4, 1, 5]
Triangle: [4, 6, 2]
Triangle: [2, 6, 7]
Triangle: [6, 4, 5]
Triangle: [1, 3, 7]
Triangle: [0, 2, 3]
Triangle: [4, 0, 1]

BIN
cubic_icon2.bmp32 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 KiB

View File

@ -20,7 +20,7 @@ void main()
//float distanceToCamera = length(vWorldPos - targetPos);
if ((dotProduct > 0.1) && vWorldPos.y > 30.0)
if ((distanceX > 380.0 || distanceZ > 380.0) && (dotProduct > 0.0) && vWorldPos.y > 10.0)
{
//color.rgba = vec4(1,0,0,1);
discard;

17612
idleviola008.txt Normal file

File diff suppressed because it is too large Load Diff

261
lighter.txt Normal file
View File

@ -0,0 +1,261 @@
===Vertices: 20
Vertex 0: <Vector (-1.0000, -1.0000, 1.0000)>
Vertex 1: <Vector (-1.0000, 1.0000, 1.0000)>
Vertex 2: <Vector (1.0000, -1.0000, 1.0000)>
Vertex 3: <Vector (1.0000, 1.0000, 1.0000)>
Vertex 4: <Vector (0.0000, 1.0000, -1.3168)>
Vertex 5: <Vector (0.0000, 1.0000, 3.2597)>
Vertex 6: <Vector (0.0000, -1.0000, -1.3168)>
Vertex 7: <Vector (0.0000, -1.0000, 3.2597)>
Vertex 8: <Vector (2.9516, -1.0000, 1.0000)>
Vertex 9: <Vector (2.9516, 1.0000, 1.0000)>
Vertex 10: <Vector (-3.0111, -1.0000, 1.0000)>
Vertex 11: <Vector (-3.0111, 1.0000, 1.0000)>
Vertex 12: <Vector (-1.6367, 1.0000, -0.3668)>
Vertex 13: <Vector (-1.6367, -1.0000, -0.3668)>
Vertex 14: <Vector (1.6107, -1.0000, -0.3742)>
Vertex 15: <Vector (1.6107, 1.0000, -0.3742)>
Vertex 16: <Vector (-1.6367, 1.0000, -3.1173)>
Vertex 17: <Vector (-1.6367, -1.0000, -3.1173)>
Vertex 18: <Vector (1.6107, -1.0000, -3.1246)>
Vertex 19: <Vector (1.6107, 1.0000, -3.1246)>
===UV Coordinates:
Face count: 36
Face 0
UV Count: 3
UV <Vector (0.6779, 0.5670)>
UV <Vector (0.8298, 0.5670)>
UV <Vector (0.6779, 0.7197)>
Face 1
UV Count: 3
UV <Vector (0.3743, 0.6470)>
UV <Vector (0.2225, 0.6470)>
UV <Vector (0.2225, 0.5670)>
Face 2
UV Count: 3
UV <Vector (0.5261, 0.5670)>
UV <Vector (0.5261, 0.7506)>
UV <Vector (0.3743, 0.5670)>
Face 3
UV Count: 3
UV <Vector (0.5261, 0.7506)>
UV <Vector (0.6779, 0.5670)>
UV <Vector (0.6779, 0.7506)>
Face 4
UV Count: 3
UV <Vector (0.6779, 0.8715)>
UV <Vector (0.8261, 0.7197)>
UV <Vector (0.8261, 0.8715)>
Face 5
UV Count: 3
UV <Vector (0.3418, 0.0686)>
UV <Vector (0.3595, 0.2554)>
UV <Vector (0.2155, 0.2073)>
Face 6
UV Count: 3
UV <Vector (0.0707, 0.5670)>
UV <Vector (0.2225, 0.5670)>
UV <Vector (0.0707, 0.6480)>
Face 7
UV Count: 3
UV <Vector (0.0707, 0.6480)>
UV <Vector (0.2225, 0.8523)>
UV <Vector (0.0707, 0.8523)>
Face 8
UV Count: 3
UV <Vector (0.3743, 0.6470)>
UV <Vector (0.3743, 0.8512)>
UV <Vector (0.2225, 0.8512)>
Face 9
UV Count: 3
UV <Vector (0.4833, 0.7506)>
UV <Vector (0.5913, 0.7506)>
UV <Vector (0.4833, 0.9024)>
Face 10
UV Count: 3
UV <Vector (0.3743, 0.9024)>
UV <Vector (0.3743, 0.7506)>
UV <Vector (0.4833, 0.9024)>
Face 11
UV Count: 3
UV <Vector (0.3704, 0.3690)>
UV <Vector (0.3595, 0.2554)>
UV <Vector (0.5000, 0.3023)>
Face 12
UV Count: 3
UV <Vector (0.3043, 0.5670)>
UV <Vector (0.2318, 0.3981)>
UV <Vector (0.3704, 0.3690)>
Face 13
UV Count: 3
UV <Vector (0.0707, 0.4884)>
UV <Vector (0.1368, 0.2904)>
UV <Vector (0.2318, 0.3981)>
Face 14
UV Count: 3
UV <Vector (0.0707, 0.1589)>
UV <Vector (0.2155, 0.2073)>
UV <Vector (0.1368, 0.2904)>
Face 15
UV Count: 3
UV <Vector (0.1368, 0.2904)>
UV <Vector (0.2155, 0.2073)>
UV <Vector (0.2318, 0.3981)>
Face 16
UV Count: 3
UV <Vector (0.2155, 0.2073)>
UV <Vector (0.3595, 0.2554)>
UV <Vector (0.2318, 0.3981)>
Face 17
UV Count: 3
UV <Vector (0.3595, 0.2554)>
UV <Vector (0.3704, 0.3690)>
UV <Vector (0.2318, 0.3981)>
Face 18
UV Count: 3
UV <Vector (0.9293, 0.1589)>
UV <Vector (0.8632, 0.2904)>
UV <Vector (0.7845, 0.2073)>
Face 19
UV Count: 3
UV <Vector (0.2225, 0.5670)>
UV <Vector (0.3743, 0.5670)>
UV <Vector (0.3743, 0.6470)>
Face 20
UV Count: 3
UV <Vector (0.0707, 0.6480)>
UV <Vector (0.2225, 0.5670)>
UV <Vector (0.2225, 0.6480)>
Face 21
UV Count: 3
UV <Vector (0.2225, 0.8523)>
UV <Vector (0.0707, 0.6480)>
UV <Vector (0.2225, 0.6480)>
Face 22
UV Count: 3
UV <Vector (0.2225, 0.8512)>
UV <Vector (0.2225, 0.6470)>
UV <Vector (0.3743, 0.6470)>
Face 23
UV Count: 3
UV <Vector (0.5913, 0.7506)>
UV <Vector (0.5913, 0.9024)>
UV <Vector (0.4833, 0.9024)>
Face 24
UV Count: 3
UV <Vector (0.6779, 0.7197)>
UV <Vector (0.8298, 0.5670)>
UV <Vector (0.8298, 0.7197)>
Face 25
UV Count: 3
UV <Vector (0.4833, 0.9024)>
UV <Vector (0.3743, 0.7506)>
UV <Vector (0.4833, 0.7506)>
Face 26
UV Count: 3
UV <Vector (0.3743, 0.5670)>
UV <Vector (0.5261, 0.7506)>
UV <Vector (0.3743, 0.7506)>
Face 27
UV Count: 3
UV <Vector (0.6779, 0.5670)>
UV <Vector (0.5261, 0.7506)>
UV <Vector (0.5261, 0.5670)>
Face 28
UV Count: 3
UV <Vector (0.8261, 0.7197)>
UV <Vector (0.6779, 0.8715)>
UV <Vector (0.6779, 0.7197)>
Face 29
UV Count: 3
UV <Vector (0.6582, 0.0686)>
UV <Vector (0.7845, 0.2073)>
UV <Vector (0.6405, 0.2554)>
Face 30
UV Count: 3
UV <Vector (0.5000, 0.3023)>
UV <Vector (0.6405, 0.2554)>
UV <Vector (0.6296, 0.3690)>
Face 31
UV Count: 3
UV <Vector (0.6957, 0.5670)>
UV <Vector (0.6296, 0.3690)>
UV <Vector (0.7682, 0.3981)>
Face 32
UV Count: 3
UV <Vector (0.9293, 0.4884)>
UV <Vector (0.7682, 0.3981)>
UV <Vector (0.8632, 0.2904)>
Face 33
UV Count: 3
UV <Vector (0.8632, 0.2904)>
UV <Vector (0.7682, 0.3981)>
UV <Vector (0.7845, 0.2073)>
Face 34
UV Count: 3
UV <Vector (0.6296, 0.3690)>
UV <Vector (0.6405, 0.2554)>
UV <Vector (0.7682, 0.3981)>
Face 35
UV Count: 3
UV <Vector (0.6405, 0.2554)>
UV <Vector (0.7845, 0.2073)>
UV <Vector (0.7682, 0.3981)>
===Normals:
Vertex 0: Normal <Vector (-0.2851, -0.8526, 0.4379)>
Vertex 1: Normal <Vector (-0.2851, 0.8526, 0.4380)>
Vertex 2: Normal <Vector (0.2851, -0.8526, 0.4379)>
Vertex 3: Normal <Vector (0.2851, 0.8526, 0.4380)>
Vertex 4: Normal <Vector (-0.0020, 0.9166, -0.3998)>
Vertex 5: Normal <Vector (0.0000, 0.5482, 0.8364)>
Vertex 6: Normal <Vector (-0.0020, -0.9166, -0.3998)>
Vertex 7: Normal <Vector (0.0000, -0.5482, 0.8364)>
Vertex 8: Normal <Vector (0.7713, -0.5472, 0.3250)>
Vertex 9: Normal <Vector (0.7713, 0.5473, 0.3250)>
Vertex 10: Normal <Vector (-0.7739, -0.5468, 0.3193)>
Vertex 11: Normal <Vector (-0.7739, 0.5469, 0.3193)>
Vertex 12: Normal <Vector (-0.5484, 0.8045, -0.2280)>
Vertex 13: Normal <Vector (-0.5484, -0.8045, -0.2280)>
Vertex 14: Normal <Vector (0.5525, -0.8026, -0.2249)>
Vertex 15: Normal <Vector (0.5525, 0.8026, -0.2249)>
Vertex 16: Normal <Vector (-0.3021, 0.5458, -0.7816)>
Vertex 17: Normal <Vector (-0.3021, -0.5458, -0.7816)>
Vertex 18: Normal <Vector (0.2983, -0.5455, -0.7832)>
Vertex 19: Normal <Vector (0.2983, 0.5455, -0.7832)>
===Triangles: 36
Triangle: [0, 1, 10]
Triangle: [12, 13, 10]
Triangle: [5, 1, 7]
Triangle: [3, 7, 2]
Triangle: [3, 8, 9]
Triangle: [5, 3, 1]
Triangle: [9, 8, 15]
Triangle: [15, 18, 19]
Triangle: [12, 16, 17]
Triangle: [6, 17, 4]
Triangle: [6, 4, 18]
Triangle: [15, 3, 9]
Triangle: [19, 4, 15]
Triangle: [16, 12, 4]
Triangle: [11, 1, 12]
Triangle: [12, 1, 4]
Triangle: [1, 3, 4]
Triangle: [3, 15, 4]
Triangle: [10, 13, 0]
Triangle: [10, 11, 12]
Triangle: [15, 8, 14]
Triangle: [18, 15, 14]
Triangle: [17, 13, 12]
Triangle: [17, 16, 4]
Triangle: [10, 1, 11]
Triangle: [18, 4, 19]
Triangle: [7, 1, 0]
Triangle: [7, 3, 5]
Triangle: [8, 3, 2]
Triangle: [7, 0, 2]
Triangle: [8, 2, 14]
Triangle: [18, 14, 6]
Triangle: [17, 6, 13]
Triangle: [13, 6, 0]
Triangle: [14, 2, 6]
Triangle: [2, 0, 6]

BIN
loading.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB

BIN
monster001.bmp32 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
monster002.bmp32 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
next_dialog.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 MiB

4833
oneroom001.txt Normal file

File diff suppressed because it is too large Load Diff

2679
secondroom001.txt Normal file

File diff suppressed because it is too large Load Diff

BIN
seconroom.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 MiB

8
shaders/fragment.glsl Normal file
View File

@ -0,0 +1,8 @@
#version 130
in vec2 texCoord;
uniform sampler2D textureSampler;
void main() {
gl_FragColor = texture2D(textureSampler, texCoord);
}

14
shaders/vertex.glsl Normal file
View File

@ -0,0 +1,14 @@
#version 130
in vec3 position;
in vec2 texcoord;
uniform mat4 projection;
uniform mat4 modelView;
out vec2 texCoord;
void main() {
gl_Position = projection * modelView * vec4(position, 1.0);
texCoord = texcoord;
}

Binary file not shown.

View File

@ -2,7 +2,8 @@ g++ Game.cpp main.cpp Math.cpp OpenGlExtensions.cpp Physics.cpp Renderer.cpp \
ShaderManager.cpp TextureManager.cpp Utils.cpp BoneAnimatedModel.cpp \
ObjLoader.cpp cmakeaudioplayer/src/AudioPlayer.cpp TextModel.cpp \
Inventory.cpp Environment.cpp GameObjectManager.cpp RenderSystem.cpp QuestScripts.cpp \
-o sdl_app -O2 -std=c++17 \
AudioPlayerAsync.cpp \
-o sdl_app -O2 -std=c++17 -pthread \
-I cmakeaudioplayer/include \
$(pkg-config --cflags --libs sdl2 gl) \
$(pkg-config --cflags --libs vorbis vorbisfile ogg) \

BIN
start_dialog.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 MiB

BIN
temno.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 KiB

18795
walkviola008.txt Normal file

File diff suppressed because it is too large Load Diff