Add very basic gameplay

This commit is contained in:
MrLetsplay 2023-09-14 13:54:28 +02:00
parent 413f4831a5
commit 4c1de8a405
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg

View File

@ -1,6 +1,12 @@
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <glm/geometric.hpp>
#include <iostream>
#include <map>
#include <memory>
#include <tuple>
#include <vector>
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btBoxShape.h"
@ -22,8 +28,103 @@
using namespace kek;
#define CHUNK_SIZE 64
#define CHUNK_RADIUS 2
#define WALLS_PER_CHUNK 20
#define WALL_HEIGHT 9
static ButtonElement *buttonPlay;
static SpotLight *flashlight;
struct Chunk {
int x, z;
GameObject *floor;
GameObject *ceiling;
std::vector<GameObject *> walls;
};
std::map<long int, Chunk> loadedChunks;
Mesh *floorMesh;
TextElement *debugText;
std::shared_ptr<Texture> red;
std::shared_ptr<Texture> gray;
void gameLoop(GLFWwindow *window, void *) {
Player *player = Engine::getPlayer();
Camera *camera = Engine::getActiveCamera();
glm::vec3 playerPos = player->getPosition();
Scene *scene = Engine::getActiveScene();
SpotLight *fl = (SpotLight *) flashlight;
glm::vec3 playerRight = glm::cross(camera->direction, glm::vec3(0, 1, 0));
fl->moveTo(playerPos + glm::normalize(playerRight) * 0.3f);
fl->lookAt(camera->direction);
int chunkX = (int) playerPos.x / CHUNK_SIZE;
int chunkZ = (int) playerPos.z / CHUNK_SIZE;
debugText->setText("CX: " + std::to_string(chunkX) + ", CZ: " + std::to_string(chunkZ));
for(auto it = loadedChunks.cbegin(); it != loadedChunks.cend();) {
const Chunk *ch = &it->second;
if(std::abs(ch->x - chunkX) > CHUNK_RADIUS || abs(ch->z - chunkZ) > CHUNK_RADIUS) {
scene->removeObject(ch->floor);
for(auto w : ch->walls) {
scene->removeObject(w);
}
it = loadedChunks.erase(it);
continue;
}
it = std::next(it);
}
std::shared_ptr<Texture> wallpaper = Texture::load("image/wallpaper.png");
for(int x = chunkX - CHUNK_RADIUS; x <= chunkX + CHUNK_RADIUS; x++) {
for(int z = chunkZ - CHUNK_RADIUS; z <= chunkZ + CHUNK_RADIUS; z++) {
long int chunkID = ((long int) x & 0xFFFF) << 16 | ((long int) z & 0xFFFF);
auto chunk = loadedChunks.find(chunkID);
if(chunk == loadedChunks.end()) {
GameObject *floor = new GameObject();
floor->addMesh(genCubeMesh(CHUNK_SIZE, 2, CHUNK_SIZE, gray, gray, gray));
floor->addPhysics(new btBoxShape(btVector3(CHUNK_SIZE / 2, 1, CHUNK_SIZE / 2)), 0, btCollisionObject::CF_STATIC_OBJECT);
floor->moveTo(glm::vec3(x * CHUNK_SIZE, 0, z * CHUNK_SIZE));
scene->addObject(floor);
GameObject *ceiling = new GameObject();
ceiling->addMesh(genCubeMesh(CHUNK_SIZE, 2, CHUNK_SIZE, gray, gray, gray));
ceiling->addPhysics(new btBoxShape(btVector3(CHUNK_SIZE / 2, 1, CHUNK_SIZE / 2)), 0, btCollisionObject::CF_STATIC_OBJECT);
ceiling->moveTo(glm::vec3(x * CHUNK_SIZE, WALL_HEIGHT, z * CHUNK_SIZE));
scene->addObject(ceiling);
std::vector<GameObject *> walls;
std::srand(chunkID);
for(unsigned int i = 0; i < WALLS_PER_CHUNK; i++) {
double wallLength = (double) std::rand() / RAND_MAX * 20 + 10;
bool rotated = std::rand() < RAND_MAX / 2;
GameObject *wall = new GameObject();
wall->addMesh(genCubeMesh(wallLength, WALL_HEIGHT, 1, wallpaper, wallpaper, wallpaper));
wall->addPhysics(new btBoxShape(btVector3(wallLength / 2, WALL_HEIGHT / 2, 0.5)), 0, btCollisionObject::CF_STATIC_OBJECT);
wall->moveTo(glm::vec3(x * CHUNK_SIZE + ((double) rand() / RAND_MAX * CHUNK_SIZE), WALL_HEIGHT / 2, z * CHUNK_SIZE + ((double) rand() / RAND_MAX * CHUNK_SIZE)));
if(rotated) {
wall->rotate(glm::radians(90.0f), glm::vec3(0, 1, 0));
}
scene->addObject(wall);
walls.push_back(wall);
}
Chunk newChunk{x, z, floor, ceiling, walls};
loadedChunks.emplace(chunkID, newChunk);
}
}
}
}
void startGame(void *) {
buttonPlay->visible = false;
@ -31,23 +132,19 @@ void startGame(void *) {
std::shared_ptr<Texture> wallpaper = Texture::load("image/wallpaper.png");
std::shared_ptr<Texture> white = Texture::generateColor(glm::vec3(1));
red = Texture::generateColor(glm::vec3(1, 0, 0));
gray = Texture::generateColor(glm::vec3(0.2, 0.2, 0.2));
SpotLight *flashlight = new SpotLight(glm::vec3(1), glm::vec3(0), 2, 5, 5, 0.5, 0.7);
flashlight->moveTo(Engine::getPlayer()->getPosition());
flashlight = new SpotLight(glm::vec3(1), glm::vec3(0), 2, 3, 5, 0.5, 0.6);
flashlight->moveTo(Engine::getPlayer()->getPosition() + glm::vec3(0, KEK_PLAYER_EYE_OFFSET, 0));
Input::addPeriodicCallback(PeriodicCallback([](GLFWwindow *window, void *light) {
SpotLight *fl = (SpotLight *) light;
glm::vec3 playerRight = glm::cross(Engine::getActiveCamera()->direction, glm::vec3(0, 1, 0));
fl->moveTo(Engine::getPlayer()->getPosition() + glm::normalize(playerRight) * 0.3f);
fl->lookAt(Engine::getActiveCamera()->direction);
},
flashlight));
Input::addPeriodicCallback(PeriodicCallback(gameLoop, nullptr));
std::shared_ptr<Texture> cubeTexture = Texture::generateColor(glm::vec3(1, 0, 0));
GameObject *floor = new GameObject();
floor->addPhysics(new btBoxShape(btVector3(50, 0.5, 50)), 0, btCollisionObject::CF_STATIC_OBJECT);
floor->addMesh(genCubeMesh(100, 1, 100, cubeTexture, cubeTexture, white));
scene->addObject(floor);
GameObject *floorObject = new GameObject();
floorObject->addPhysics(new btBoxShape(btVector3(CHUNK_SIZE / 2, 0.5, CHUNK_SIZE / 2)), 0, btCollisionObject::CF_STATIC_OBJECT);
floorObject->addMesh(genCubeMesh(CHUNK_SIZE, 1, CHUNK_SIZE, cubeTexture, cubeTexture, white));
scene->addObject(floorObject);
for(unsigned int i = 0; i < 10; i++) {
GameObject *cube = new GameObject();
@ -58,7 +155,11 @@ void startGame(void *) {
}
scene->lights->add(flashlight);
scene->lights->add(new DirectionalLight(glm::vec3(0.001), glm::vec3(-0.1, -1, 0.1)));
scene->lights->add(new DirectionalLight(glm::vec3(0.005), glm::vec3(-0.1, -1, 0.1)));
debugText = new TextElement(uiPx(10), uiPx(100));
debugText->setText("Hello!");
UI::addElement(debugText);
Engine::setActiveScene(scene);