From 5161bb75ba76c70972aaec407fd59b6f1b0652b6 Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 4 Jun 2025 21:39:15 +0200 Subject: [PATCH 01/13] 3d cube more or less working --- main.cpp | 175 ++++++++++++++++++++++++++++++++++++++------ shaders/vertex.vert | 4 +- 2 files changed, 156 insertions(+), 23 deletions(-) diff --git a/main.cpp b/main.cpp index 69562c7..ca448ba 100644 --- a/main.cpp +++ b/main.cpp @@ -1,3 +1,5 @@ +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE #include #include #include @@ -5,6 +7,7 @@ #include #include #include +#include #include #include @@ -20,6 +23,12 @@ struct vertex glm::vec3 color; }; +struct vertex_3d +{ + glm::vec3 position; + glm::vec3 color; +}; + struct bounding_box { float x; @@ -161,6 +170,16 @@ std::vector convert_quad_to_triangles(std::vector vertices) return vertices; } +std::vector convert_quad_to_triangles(std::vector vertices) +{ + const vertex_3d end_vertex = vertices[3]; + vertices.pop_back(); + vertices.push_back(vertices[0]); + vertices.push_back(vertices[2]); + vertices.push_back(end_vertex); + return vertices; +} + glm::mat4 rotate(float angle) { float c = glm::cos(glm::radians(angle)); @@ -238,6 +257,54 @@ std::pair create_buffer(const vk::Device &device, return std::make_pair(vertex_buffer_memory, vertex_buffer); } +std::pair create_image(vk::Device &device, size_t width, size_t height, size_t depth, vk::Format format, vk::ImageUsageFlags usage) +{ + vk::Extent3D extent(width, height, depth); + vk::ImageCreateInfo image_create_info(vk::ImageCreateFlags(), vk::ImageType::e2D, format, extent, 1, + 1, vk::SampleCountFlagBits::e1, vk::ImageTiling::eOptimal, + usage); + vk::Image image = device.createImage(image_create_info); + + vk::MemoryRequirements memory_requirements; + device.getImageMemoryRequirements(image, &memory_requirements); + vk::MemoryAllocateInfo memory_allocate_info(memory_requirements.size, 0x0); + vk::DeviceMemory memory = device.allocateMemory(memory_allocate_info, nullptr); + device.bindImageMemory(image, memory, 0); + + return std::make_pair(memory, image); +} + +vk::ImageView create_image_view(vk::Device &device, vk::Image image, vk::Format format, vk::ImageAspectFlagBits aspect) +{ + vk::ImageViewCreateInfo image_view_info = {}; + image_view_info.image = image; + image_view_info.viewType = vk::ImageViewType::e2D; + image_view_info.format = format; + image_view_info.components.r = vk::ComponentSwizzle::eIdentity; + image_view_info.components.g = vk::ComponentSwizzle::eIdentity; + image_view_info.components.b = vk::ComponentSwizzle::eIdentity; + image_view_info.components.a = vk::ComponentSwizzle::eIdentity; + image_view_info.subresourceRange.aspectMask = aspect; + image_view_info.subresourceRange.baseMipLevel = 0; + image_view_info.subresourceRange.levelCount = 1; + image_view_info.subresourceRange.baseArrayLayer = 0; + image_view_info.subresourceRange.layerCount = 1; + + return device.createImageView(image_view_info); +} + +void add_quad_to_vertices(std::vector &vertices, std::vector new_quad) +{ + new_quad = convert_quad_to_triangles(new_quad); + + for (auto vert: new_quad) + { + std::println("Vertex pos x: {}, y: {}, z: {}", vert.position.x, vert.position.y, vert.position.z); + vertices.push_back(vert); + } +} + + int main() { using clock = std::chrono::system_clock; @@ -374,20 +441,20 @@ int main() vk::VertexInputBindingDescription binding_description = {}; binding_description.binding = 0; - binding_description.stride = sizeof(vertex); + binding_description.stride = sizeof(vertex_3d); binding_description.inputRate = vk::VertexInputRate::eVertex; vk::VertexInputAttributeDescription att_description_pos = {}; att_description_pos.binding = 0; att_description_pos.location = 0; - att_description_pos.format = vk::Format::eR32G32Sfloat; - att_description_pos.offset = offsetof(vertex, position); + att_description_pos.format = vk::Format::eR32G32B32Sfloat; + att_description_pos.offset = offsetof(vertex_3d, position); vk::VertexInputAttributeDescription att_description_color = {}; att_description_color.binding = 0; att_description_color.location = 1; att_description_color.format = vk::Format::eR32G32B32Sfloat; - att_description_color.offset = offsetof(vertex, color); + att_description_color.offset = offsetof(vertex_3d, color); std::vector att_descriptions = {att_description_pos, att_description_color}; vk::PipelineVertexInputStateCreateInfo vertex_input_info = {}; @@ -442,7 +509,7 @@ int main() vk::PipelineLayout pipeline_layout = device.createPipelineLayout(layout_info); uniform u{}; - u.transform = glm::mat4(1.0f); + u.transform = glm::mat4{1.0f}; auto rec = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eUniformBuffer, sizeof(uniform)); vk::DeviceMemory uniform_buffer_data = rec.first; vk::Buffer uniform_buffer = rec.second; @@ -455,21 +522,34 @@ int main() vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR); vk::AttachmentReference attachment_ref = vk::AttachmentReference(0, vk::ImageLayout::eColorAttachmentOptimal); + + auto image_ret = create_image(device, framebuffer_extension.width, framebuffer_extension.height, 1,vk::Format::eD32Sfloat, vk::ImageUsageFlags(vk::ImageUsageFlagBits::eDepthStencilAttachment)); + vk::Image depth_image = image_ret.second; + vk::DeviceMemory depht_image_memory = image_ret.first; + vk::ImageView depth_image_view = create_image_view(device, depth_image, vk::Format::eD32Sfloat, vk::ImageAspectFlagBits::eDepth); + vk::AttachmentDescription depth_attachment_desc(vk::AttachmentDescriptionFlags(), vk::Format::eD32Sfloat, + vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare, + vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined, + vk::ImageLayout::eDepthStencilAttachmentOptimal); + vk::AttachmentReference depth_attachment_ref(1, vk::ImageLayout::eDepthStencilAttachmentOptimal); + vk::SubpassDescription subpass_description = {}; subpass_description.pipelineBindPoint = vk::PipelineBindPoint::eGraphics; subpass_description.colorAttachmentCount = 1; subpass_description.pColorAttachments = &attachment_ref; + subpass_description.pDepthStencilAttachment = &depth_attachment_ref; vk::SubpassDependency subpass_dependency = {}; subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL; subpass_dependency.dstSubpass = 0; - subpass_dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput; - subpass_dependency.dstStageMask = vk::PipelineStageFlags(vk::PipelineStageFlagBits::eColorAttachmentOutput); - subpass_dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite; + subpass_dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests; + subpass_dependency.dstStageMask = vk::PipelineStageFlags(vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests); + subpass_dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite; + std::vector attachments = {color_attachment, depth_attachment_desc}; vk::RenderPassCreateInfo render_pass_info = {}; - render_pass_info.attachmentCount = 1; - render_pass_info.pAttachments = &color_attachment; + render_pass_info.attachmentCount = attachments.size(); + render_pass_info.pAttachments = attachments.data(); render_pass_info.subpassCount = 1; render_pass_info.pSubpasses = &subpass_description; render_pass_info.dependencyCount = 1; @@ -477,6 +557,13 @@ int main() vk::RenderPass render_pass = device.createRenderPass(render_pass_info); + vk::PipelineDepthStencilStateCreateInfo depht_stencil_info; + depht_stencil_info.depthTestEnable = VK_TRUE; + depht_stencil_info.depthWriteEnable = VK_TRUE; + depht_stencil_info.depthCompareOp = vk::CompareOp::eLessOrEqual; + depht_stencil_info.depthBoundsTestEnable = VK_FALSE; + depht_stencil_info.stencilTestEnable = VK_FALSE; + vk::GraphicsPipelineCreateInfo pipeline_info = {}; pipeline_info.stageCount = 2; pipeline_info.pStages = pipeline_shaders.data(); @@ -486,6 +573,7 @@ int main() pipeline_info.pRasterizationState = &raster_info; pipeline_info.pMultisampleState = &multisampling_info; pipeline_info.pColorBlendState = &color_blend_info; + pipeline_info.pDepthStencilState = &depht_stencil_info; pipeline_info.layout = pipeline_layout; pipeline_info.renderPass = render_pass; pipeline_info.subpass = 0; @@ -507,19 +595,54 @@ int main() for (auto &view: image_views) { + std::vector view_attachments = {view, depth_image_view}; vk::FramebufferCreateInfo framebuffer_info = vk::FramebufferCreateInfo(vk::FramebufferCreateFlags(), render_pass, view, framebuffer_extension.width, framebuffer_extension.height, 1); + framebuffer_info.attachmentCount = view_attachments.size(); + framebuffer_info.pAttachments = view_attachments.data(); framebuffers.push_back(device.createFramebuffer(framebuffer_info)); } - std::vector vertices = { - {{-0.1f, -0.1f}, {1.0f, 0.0f, 0.0f}}, - {{0.1f, -0.1f}, {1.0f, 0.0f, 0.0f}}, - {{0.1f, 0.1f}, {0.0f, 1.0f, 0.0f}}, - {{-0.1f, 0.1f}, {0.0f, 0.0f, 1.0f}} + std::vector vertices; + + std::vector front_quad + { + {{-0.2f, -0.2f, 0.0f}, {1.0f, 0.0f, 0.0f}}, + {{ 0.0f, -0.2f, 0.0f}, {1.0f, 0.0f, 0.0f}}, + {{ 0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}}, + {{-0.2f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}} }; - vertices = convert_quad_to_triangles(vertices); + add_quad_to_vertices(vertices, front_quad); + + std::vector back_quad + { + {{-0.15f, -0.15f, 0.2f}, {1.0f, 0.0f, 1.0f}}, + {{ 0.05f, -0.15f, 0.2f}, {1.0f, 0.0f, 1.0f}}, + {{ 0.05f, 0.05f, 0.2f}, {1.0f, 0.0f, 1.0f}}, + {{-0.15f, 0.05f, 0.2f}, {1.0f, 0.0f, 1.0f}} + }; + add_quad_to_vertices(vertices, back_quad); + + std::vector right_quad + { + {{0.0f, -0.2f, 0.0f}, {0.0f, 1.0f, 0.0f}}, + {{ 0.05f, -0.15f, 0.2f}, {0.0f, 1.0f, 0.0f}}, + {{ 0.05f, 0.05f, 0.2f}, {0.0f, 1.0f, 0.0f}}, + {{0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}} + }; + add_quad_to_vertices(vertices, right_quad); + + std::vector bottom_quad + { + {front_quad[3].position, {1.0f, 1.0f, 0.0f}}, + {front_quad[2].position, {1.0f, 1.0f, 0.0f}}, + {back_quad[2].position, {1.0f, 1.0f, 0.0f}}, + {back_quad[3].position, {1.0f, 1.0f, 0.0f}} + }; + std::println("Bottom quad"); + add_quad_to_vertices(vertices, bottom_quad); + auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertices[0]) * vertices.size()); vk::DeviceMemory vertex_buffer_memory = ret.first; vk::Buffer vertex_buffer = ret.second; @@ -536,6 +659,7 @@ int main() vk::CommandBufferLevel::ePrimary, 1); auto command_buffers = device.allocateCommandBuffers(cmd_alloc_info); + vk::DescriptorPoolSize descriptor_pool_size(vk::DescriptorType::eUniformBuffer, sizeof(uniform)); vk::DescriptorPoolCreateInfo descriptor_pool_info; descriptor_pool_info.maxSets = 1; @@ -577,7 +701,7 @@ int main() player.height = 0.2f; player.width = 0.2f; //velocityX = 0.008f; - std::vector render_vertices = vertices; + std::vector render_vertices = vertices; float angle = 0.0f; float vel2 = 0.005f; //std::thread phy_thread(simple_physics); @@ -601,18 +725,22 @@ int main() auto time_elapsed = clock::now() - before; simple_physics_step(std::chrono::duration_cast>(time_elapsed).count()); before = clock::now(); - u.transform = move({player.x, player.y}) * rotate(angle); - memcpy(uniform_data, &u, sizeof(uniform)); + + //u.transform = glm::rotate(u.transform, 0.01f, glm::vec3(1.0f, 0.0f, 1.0f)); + //u.transform = move({player.x, player.y}) * rotate(angle); + //memcpy(uniform_data, &u, sizeof(uniform)); angle -= 1.0f; memcpy(data, render_vertices.data(), sizeof(vertices[0]) * vertices.size()); vk::CommandBufferBeginInfo begin_info = {}; - vk::ClearValue clear_color = vk::ClearValue({0.0f, 0.0f, 0.0f, 1.0f}); + std::array clear_values; + clear_values[0].color = vk::ClearColorValue(0.0f, 0.0f, 0.0f, 1.0f); + clear_values[1].depthStencil = {{1.0f, 0}}; vk::Rect2D render_area = {{0, 0}, framebuffer_extension}; vk::RenderPassBeginInfo render_pass_begin = vk::RenderPassBeginInfo(render_pass, framebuffers[image_index], - render_area, 1, &clear_color); + render_area, clear_values.size(), clear_values.data()); vk::DeviceSize offset = 0; command_buffers[0].begin(begin_info); command_buffers[0].beginRenderPass(render_pass_begin, vk::SubpassContents::eInline); @@ -655,6 +783,11 @@ int main() //phy_thread.join(); device.unmapMemory(vertex_buffer_memory); device.waitIdle(); + device.freeMemory(uniform_buffer_data); + device.freeMemory(depht_image_memory); + device.destroyBuffer(uniform_buffer); + device.destroyImageView(depth_image_view); + device.destroyImage(depth_image); device.destroyDescriptorPool(descriptor_pool); device.destroyDescriptorSetLayout(descriptor_layout); device.destroyBuffer(vertex_buffer); diff --git a/shaders/vertex.vert b/shaders/vertex.vert index 0ff624b..aaf0aef 100644 --- a/shaders/vertex.vert +++ b/shaders/vertex.vert @@ -7,13 +7,13 @@ layout(binding = 0) uniform un{ mat4 transform; } trans; -layout(location = 0) in vec2 in_position; +layout(location = 0) in vec3 in_position; layout(location = 1) in vec3 in_color; layout(location = 0) out vec3 frag_color; void main() { - gl_Position = trans.transform * vec4(in_position, 0.0, 1.0); + gl_Position = trans.transform * vec4(in_position, 1.0); frag_color = in_color; } \ No newline at end of file From 8265015529aff24b201a365147eba2b2a27a497b Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 6 Jun 2025 17:26:09 +0200 Subject: [PATCH 02/13] added keyboard input --- main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/main.cpp b/main.cpp index 69562c7..55f6841 100644 --- a/main.cpp +++ b/main.cpp @@ -238,6 +238,13 @@ std::pair create_buffer(const vk::Device &device, return std::make_pair(vertex_buffer_memory, vertex_buffer); } +void keyboard_handle(GLFWwindow *window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) + std::println("JUMP!"); + std::println("Key {} pressed!", key); +} + int main() { using clock = std::chrono::system_clock; @@ -581,6 +588,7 @@ int main() float angle = 0.0f; float vel2 = 0.005f; //std::thread phy_thread(simple_physics); + glfwSetKeyCallback(window, keyboard_handle); auto before = clock::now(); while(!glfwWindowShouldClose(window)) { From 3625ce7d86d6600097d07e19ce9a0bf11e13eb80 Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 6 Jun 2025 21:03:43 +0200 Subject: [PATCH 03/13] improved physics, added velocity based on input --- main.cpp | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/main.cpp b/main.cpp index 55f6841..131358f 100644 --- a/main.cpp +++ b/main.cpp @@ -26,6 +26,10 @@ struct bounding_box float y; float width; float height; + float velocityX; + float velocityY; + float accX; + float accY; }; struct uniform @@ -197,16 +201,29 @@ void simple_physics() } } -void simple_physics_step(float t) +void simple_physics_step(float t, bounding_box &box) { - bool collision_x = player.x + player.width / 2 >= 1.0f || player.x - player.width / 2 <= -1.0f; - bool collision_y = player.y + player.height / 2 >=1.0f || player.y - player.height / 2 <= -1.0f; + box.y += box.velocityY * t + 0.5 * box.accY * (t * t); + box.velocityY += box.accY * t; + + box.x += box.velocityX * t + 0.5 * box.accX * (t * t); + box.velocityX += box.accX * 0.002; + bool collision_x = box.x + box.width / 2 >= 1.0f || box.x - box.width / 2 <= -1.0f; + //bool collision_y = box.y + box.height / 2 >=1.0f || box.y - box.height / 2 <= -1.0f; + bool collision_top_y = box.y - box.height / 2 <= -1.0f; + bool collision_bottom_y = box.y + box.height / 2 >=1.0f; if (collision_x) - velocityX = -velocityX; - else if (collision_y) - velocityY = -velocityY; - player.x = player.x + (velocityX * t); - player.y = player.y + (velocityY * t); + box.velocityX = 0; + else if (collision_top_y) + { + box.velocityY = 0; + box.y = -1.0f + box.height/2; + } + else if (collision_bottom_y) + { + box.velocityY = 0.0f; + box.y = 1.0f - box.height/2; + } } std::pair create_buffer(const vk::Device &device, vk::PhysicalDevice selected_physical_device, vk::BufferUsageFlagBits usage, size_t size) @@ -241,7 +258,10 @@ std::pair create_buffer(const vk::Device &device, void keyboard_handle(GLFWwindow *window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) + { std::println("JUMP!"); + player.velocityY = -1.0f; + } std::println("Key {} pressed!", key); } @@ -590,6 +610,7 @@ int main() //std::thread phy_thread(simple_physics); glfwSetKeyCallback(window, keyboard_handle); auto before = clock::now(); + player.accY = 0.5f; while(!glfwWindowShouldClose(window)) { glfwPollEvents(); @@ -607,9 +628,9 @@ int main() uint32_t image_index = image_result.value; vkResetCommandBuffer(command_buffers[0], 0); auto time_elapsed = clock::now() - before; - simple_physics_step(std::chrono::duration_cast>(time_elapsed).count()); + simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), player); before = clock::now(); - u.transform = move({player.x, player.y}) * rotate(angle); + u.transform = move({player.x, player.y}); memcpy(uniform_data, &u, sizeof(uniform)); angle -= 1.0f; From 949e03c9c5b601b9aa893e61cd944e2ad580e44e Mon Sep 17 00:00:00 2001 From: Luna Date: Mon, 9 Jun 2025 06:05:30 +0200 Subject: [PATCH 04/13] unfinished enemy implementation --- main.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/main.cpp b/main.cpp index 131358f..efdf164 100644 --- a/main.cpp +++ b/main.cpp @@ -7,6 +7,7 @@ #include #include #include +#include bool skip_rendering = false; vk::SurfaceFormatKHR format; @@ -201,7 +202,7 @@ void simple_physics() } } -void simple_physics_step(float t, bounding_box &box) +void simple_physics_step(float t, bounding_box &box, std::vector boxes = {}) { box.y += box.velocityY * t + 0.5 * box.accY * (t * t); box.velocityY += box.accY * t; @@ -260,16 +261,56 @@ void keyboard_handle(GLFWwindow *window, int key, int scancode, int action, int if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { std::println("JUMP!"); - player.velocityY = -1.0f; + player.velocityY = -1.2f; } std::println("Key {} pressed!", key); } +bounding_box spawn_enemy(std::mt19937 rng) +{ + std::uniform_real_distribution dist(0.05, 0.3); + std::uniform_real_distribution y_dist(-0.7, -0.5); + std::uniform_real_distribution vel_dist(-1.0, -0.5);// TODO: Shader for enemies + bounding_box ret{0}; + ret.height = dist(rng); + ret.width = dist(rng); + ret.x = 0.8; + ret.y = y_dist(rng); + ret.velocityX = vel_dist(rng); + return ret; +} + +void add_quad_to_vertices(std::vector &vertices, std::vector new_quad) +{ + new_quad = convert_quad_to_triangles(new_quad); + + for (auto vert: new_quad) + { + //std::println("Vertex pos x: {}, y: {}, z: {}", vert.position.x, vert.position.y, vert.position.z); + vertices.push_back(vert); + } +} + +std::vector bounding_box_to_vertices(const bounding_box &box) +{ + float half_width = box.width/2; + float half_height = box.height/2; + std::vector vertices = { + {{-half_width, -half_height}, {1.0f, 0.0f, 0.0f}}, + {{half_width, -half_height}, {1.0f, 0.0f, 0.0f}}, + {{half_width, half_height}, {0.0f, 1.0f, 0.0f}}, + {{-half_width, half_height}, {0.0f, 0.0f, 1.0f}} + }; + return vertices; +} + int main() { using clock = std::chrono::system_clock; using ms = std::chrono::duration; GLFWwindow *window = create_window(1000, 800, "hello"); + std::random_device dev; + std::mt19937 rng(dev()); if (!window) return -1; @@ -542,8 +583,8 @@ int main() std::vector vertices = { {{-0.1f, -0.1f}, {1.0f, 0.0f, 0.0f}}, - {{0.1f, -0.1f}, {1.0f, 0.0f, 0.0f}}, - {{0.1f, 0.1f}, {0.0f, 1.0f, 0.0f}}, + {{0.0f, -0.1f}, {1.0f, 0.0f, 0.0f}}, + {{0.0f, 0.1f}, {0.0f, 1.0f, 0.0f}}, {{-0.1f, 0.1f}, {0.0f, 0.0f, 1.0f}} }; vertices = convert_quad_to_triangles(vertices); @@ -610,7 +651,10 @@ int main() //std::thread phy_thread(simple_physics); glfwSetKeyCallback(window, keyboard_handle); auto before = clock::now(); - player.accY = 0.5f; + player.accY = 1.3f; + player.x = -0.8; + player.y = -0.5; + std::vector enemies; while(!glfwWindowShouldClose(window)) { glfwPollEvents(); @@ -627,6 +671,12 @@ int main() } uint32_t image_index = image_result.value; vkResetCommandBuffer(command_buffers[0], 0); + if (enemies.empty()) + { + bounding_box enemy = spawn_enemy(rng); + add_quad_to_vertices(vertices, bounding_box_to_vertices(enemy)); + + } auto time_elapsed = clock::now() - before; simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), player); before = clock::now(); From 7c4ec2e6164b2e647b7cfed72d69bfbfc6f8dc44 Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 10 Jun 2025 14:45:47 +0200 Subject: [PATCH 05/13] improved enemy implementation --- main.cpp | 55 ++++++++++++++++++++++++++++++++----------- shaders/fragment.spv | Bin 572 -> 0 bytes shaders/vertex.spv | Bin 1084 -> 0 bytes shaders/vertex.vert | 8 +++++-- 4 files changed, 47 insertions(+), 16 deletions(-) delete mode 100644 shaders/fragment.spv delete mode 100644 shaders/vertex.spv diff --git a/main.cpp b/main.cpp index efdf164..7d5ab6b 100644 --- a/main.cpp +++ b/main.cpp @@ -34,6 +34,11 @@ struct bounding_box }; struct uniform +{ + glm::mat4 view; +}; + +struct push { glm::mat4 transform; }; @@ -202,15 +207,24 @@ void simple_physics() } } -void simple_physics_step(float t, bounding_box &box, std::vector boxes = {}) +void simple_physics_step(float t, bounding_box &box, std::vector &boxes) { box.y += box.velocityY * t + 0.5 * box.accY * (t * t); box.velocityY += box.accY * t; box.x += box.velocityX * t + 0.5 * box.accX * (t * t); box.velocityX += box.accX * 0.002; + + for (auto &b: boxes) + { + b.y += b.velocityY * t + 0.5 * b.accY * (t * t); + b.velocityY += b.accY * t; + + b.x += b.velocityX * t + 0.5 * b.accX * (t * t); + b.velocityX += b.accX * 0.002; + } + bool collision_x = box.x + box.width / 2 >= 1.0f || box.x - box.width / 2 <= -1.0f; - //bool collision_y = box.y + box.height / 2 >=1.0f || box.y - box.height / 2 <= -1.0f; bool collision_top_y = box.y - box.height / 2 <= -1.0f; bool collision_bottom_y = box.y + box.height / 2 >=1.0f; if (collision_x) @@ -269,8 +283,8 @@ void keyboard_handle(GLFWwindow *window, int key, int scancode, int action, int bounding_box spawn_enemy(std::mt19937 rng) { std::uniform_real_distribution dist(0.05, 0.3); - std::uniform_real_distribution y_dist(-0.7, -0.5); - std::uniform_real_distribution vel_dist(-1.0, -0.5);// TODO: Shader for enemies + std::uniform_real_distribution y_dist(0.7, 0.5); + std::uniform_real_distribution vel_dist(-1.0, -0.5); bounding_box ret{0}; ret.height = dist(rng); ret.width = dist(rng); @@ -504,13 +518,17 @@ int main() vk::DescriptorSetLayoutCreateInfo descriptor_layout_info(vk::DescriptorSetLayoutCreateFlags(), 1, &descriptor_binding); vk::DescriptorSetLayout descriptor_layout = device.createDescriptorSetLayout(descriptor_layout_info); + vk::PushConstantRange push_constant(vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(push)); + vk::PipelineLayoutCreateInfo layout_info = {}; layout_info.setLayoutCount = 1; layout_info.pSetLayouts = &descriptor_layout; + layout_info.pushConstantRangeCount = 1; + layout_info.pPushConstantRanges = &push_constant; vk::PipelineLayout pipeline_layout = device.createPipelineLayout(layout_info); uniform u{}; - u.transform = glm::mat4(1.0f); + u.view = glm::mat4(1.0f); auto rec = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eUniformBuffer, sizeof(uniform)); vk::DeviceMemory uniform_buffer_data = rec.first; vk::Buffer uniform_buffer = rec.second; @@ -588,10 +606,10 @@ int main() {{-0.1f, 0.1f}, {0.0f, 0.0f, 1.0f}} }; vertices = convert_quad_to_triangles(vertices); - auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertices[0]) * vertices.size()); + auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertices[0]) * 100); vk::DeviceMemory vertex_buffer_memory = ret.first; vk::Buffer vertex_buffer = ret.second; - char *data = (char *)device.mapMemory(vertex_buffer_memory, 0, sizeof(vertices[0]) * vertices.size()); + char *data = (char *)device.mapMemory(vertex_buffer_memory, 0, sizeof(vertices[0]) * 100); memcpy(data, vertices.data(), sizeof(vertices[0]) * vertices.size()); @@ -674,17 +692,20 @@ int main() if (enemies.empty()) { bounding_box enemy = spawn_enemy(rng); - add_quad_to_vertices(vertices, bounding_box_to_vertices(enemy)); - + add_quad_to_vertices(render_vertices, bounding_box_to_vertices(enemy)); + enemies.push_back(enemy); } auto time_elapsed = clock::now() - before; - simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), player); + simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), player, enemies); before = clock::now(); - u.transform = move({player.x, player.y}); - memcpy(uniform_data, &u, sizeof(uniform)); + push first_transform{}; + first_transform.transform = move({player.x, player.y}); + push second_transform{}; + second_transform.transform = move({enemies[0].x, enemies[0].y}); + //memcpy(uniform_data, &u, sizeof(uniform)); angle -= 1.0f; - memcpy(data, render_vertices.data(), sizeof(vertices[0]) * vertices.size()); + memcpy(data, render_vertices.data(), sizeof(vertices[0]) * render_vertices.size()); vk::CommandBufferBeginInfo begin_info = {}; @@ -700,7 +721,10 @@ int main() //command_buffers[0].setScissor(0, scissor); command_buffers[0].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline_layout, 0, descriptor_sets, nullptr); command_buffers[0].bindVertexBuffers(0, 1, &vertex_buffer, &offset); - command_buffers[0].draw(vertices.size(), 1, 0, 0); + command_buffers[0].pushConstants(pipeline_layout, vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(push), &first_transform); + command_buffers[0].draw(6, 1, 0, 0); + command_buffers[0].pushConstants(pipeline_layout, vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(push), &second_transform); + command_buffers[0].draw(6, 1, 6, 0); command_buffers[0].endRenderPass(); if (vkEndCommandBuffer(command_buffers[0]) != VK_SUCCESS) { @@ -732,12 +756,15 @@ int main() } thread = false; //phy_thread.join(); + device.unmapMemory(uniform_buffer_data); device.unmapMemory(vertex_buffer_memory); device.waitIdle(); device.destroyDescriptorPool(descriptor_pool); device.destroyDescriptorSetLayout(descriptor_layout); device.destroyBuffer(vertex_buffer); + device.destroyBuffer(uniform_buffer); device.freeMemory(vertex_buffer_memory); + device.freeMemory(uniform_buffer_data); for (auto &framebuffer: framebuffers) { device.destroyFramebuffer(framebuffer); diff --git a/shaders/fragment.spv b/shaders/fragment.spv deleted file mode 100644 index 692e6c1eab87c30dbfd16d8f1994b55f4ec762cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 572 zcmYk2%}T>i6oijW)7IAhS6M^Qqhj&KDEO zg~_>R?wmVw<226NW_#ANzD?|JjjbWZ#I=g*`Op4rn@6+Ds|yqZa|$7vp|!243f`7U z#=*XDAdIAgmw|SUZZ-STP}92R`GL1sc>Y5WuGhgf|48E?O|m$Ml1&`u$$N~hQ`03` znC_ywz?Guz>zZ45uXcG5uF};;esE-Y*(_fx($f?fPXrb{nyQ~DDOpd8)K=_|v~P)< z3dhp(CVKp*`gTDy) z6frm}b{X5wmF;HDB#e47HbCq(j(agr_vG#zPY*k=NzidK!Pv=D+I$YecHB;jJa(kK z5;4YCAMV2Z8`WTQoOW38jre;1dDM^xKbMCM#=d;L;k7B@;KQlkhYvn|=fr}Z+v-Rk z>_u5a(sjv_>h%NVKK&Quk4V=goZZsrFQMPM{4r_j!8T>V&GjIL)Ri|O?YN(mKKlh@ z&QzXP^koiyO~QfKv@~g -1 (left) 1(right) // y -> -1 (top) 1(bottom) -layout(binding = 0) uniform un{ +layout( push_constant ) uniform push{ mat4 transform; -} trans; +}trans; + +layout(binding = 0) uniform un{ + mat4 view; +} view; layout(location = 0) in vec2 in_position; layout(location = 1) in vec3 in_color; From 19bd0e616a0deeb3ccf7563f33ae90a4e06b57a0 Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 10 Jun 2025 21:18:22 +0200 Subject: [PATCH 06/13] remade all the quad logic and added game logic to the enemies --- main.cpp | 79 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/main.cpp b/main.cpp index 7d5ab6b..be4477a 100644 --- a/main.cpp +++ b/main.cpp @@ -33,6 +33,8 @@ struct bounding_box float accY; }; + + struct uniform { glm::mat4 view; @@ -43,6 +45,13 @@ struct push glm::mat4 transform; }; +struct quad +{ + bounding_box box; + std::vector vertices; + push trans; +}; + bounding_box player; float velocityX = 1.0f; float velocityY = 0.50f; @@ -207,7 +216,7 @@ void simple_physics() } } -void simple_physics_step(float t, bounding_box &box, std::vector &boxes) +void simple_physics_step(float t, bounding_box &box, std::vector &boxes) { box.y += box.velocityY * t + 0.5 * box.accY * (t * t); box.velocityY += box.accY * t; @@ -217,11 +226,11 @@ void simple_physics_step(float t, bounding_box &box, std::vector & for (auto &b: boxes) { - b.y += b.velocityY * t + 0.5 * b.accY * (t * t); - b.velocityY += b.accY * t; + b.box.y += b.box.velocityY * t + 0.5 * b.box.accY * (t * t); + b.box.velocityY += b.box.accY * t; - b.x += b.velocityX * t + 0.5 * b.accX * (t * t); - b.velocityX += b.accX * 0.002; + b.box.x += b.box.velocityX * t + 0.5 * b.box.accX * (t * t); + b.box.velocityX += b.box.accX * 0.002; } bool collision_x = box.x + box.width / 2 >= 1.0f || box.x - box.width / 2 <= -1.0f; @@ -598,19 +607,20 @@ int main() framebuffer_extension.height, 1); framebuffers.push_back(device.createFramebuffer(framebuffer_info)); } - - std::vector vertices = { + quad play{}; + play.box = player; + play.vertices = { {{-0.1f, -0.1f}, {1.0f, 0.0f, 0.0f}}, {{0.0f, -0.1f}, {1.0f, 0.0f, 0.0f}}, {{0.0f, 0.1f}, {0.0f, 1.0f, 0.0f}}, {{-0.1f, 0.1f}, {0.0f, 0.0f, 1.0f}} }; - vertices = convert_quad_to_triangles(vertices); - auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertices[0]) * 100); - vk::DeviceMemory vertex_buffer_memory = ret.first; + play.vertices = convert_quad_to_triangles(play.vertices); + auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertex) * 6 * 100); + vk::DeviceMemory vertex_memory = ret.first; vk::Buffer vertex_buffer = ret.second; - char *data = (char *)device.mapMemory(vertex_buffer_memory, 0, sizeof(vertices[0]) * 100); - memcpy(data, vertices.data(), sizeof(vertices[0]) * vertices.size()); + char *vertex_data = (char *)device.mapMemory(vertex_memory, 0, sizeof(vertex) * 6 * 100); // 100 quads + memcpy(vertex_data, play.vertices.data(), sizeof(play.vertices[0]) * play.vertices.size()); vk::CommandPoolCreateInfo command_pool_info = {}; @@ -663,7 +673,7 @@ int main() player.height = 0.2f; player.width = 0.2f; //velocityX = 0.008f; - std::vector render_vertices = vertices; + float angle = 0.0f; float vel2 = 0.005f; //std::thread phy_thread(simple_physics); @@ -672,10 +682,11 @@ int main() player.accY = 1.3f; player.x = -0.8; player.y = -0.5; - std::vector enemies; + std::vector enemies; while(!glfwWindowShouldClose(window)) { glfwPollEvents(); + std::vector render_vertices = play.vertices; auto res_wait = device.waitForFences(next_frame_fence, VK_TRUE, UINT64_MAX); if (res_wait != vk::Result::eSuccess) throw std::runtime_error("failed waiting!"); @@ -691,21 +702,31 @@ int main() vkResetCommandBuffer(command_buffers[0], 0); if (enemies.empty()) { - bounding_box enemy = spawn_enemy(rng); - add_quad_to_vertices(render_vertices, bounding_box_to_vertices(enemy)); + quad enemy{}; + std::mt19937 rng2(dev()); + enemy.box = spawn_enemy(rng2); + enemy.vertices = bounding_box_to_vertices(enemy.box); + enemy.trans.transform = glm::mat4{1.0f}; enemies.push_back(enemy); } auto time_elapsed = clock::now() - before; simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), player, enemies); before = clock::now(); - push first_transform{}; - first_transform.transform = move({player.x, player.y}); - push second_transform{}; - second_transform.transform = move({enemies[0].x, enemies[0].y}); + play.trans.transform = move({player.x, player.y}); + for (auto &e: enemies) + { + if (e.box.x <= -1.0f) + { + enemies.clear(); + break; + } + e.trans.transform = move({e.box.x, e.box.y}); + add_quad_to_vertices(render_vertices, e.vertices); + } //memcpy(uniform_data, &u, sizeof(uniform)); angle -= 1.0f; - memcpy(data, render_vertices.data(), sizeof(vertices[0]) * render_vertices.size()); + memcpy(vertex_data, render_vertices.data(), sizeof(render_vertices[0]) * render_vertices.size()); vk::CommandBufferBeginInfo begin_info = {}; @@ -721,10 +742,16 @@ int main() //command_buffers[0].setScissor(0, scissor); command_buffers[0].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline_layout, 0, descriptor_sets, nullptr); command_buffers[0].bindVertexBuffers(0, 1, &vertex_buffer, &offset); - command_buffers[0].pushConstants(pipeline_layout, vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(push), &first_transform); + command_buffers[0].pushConstants(pipeline_layout, vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(push), &play.trans); command_buffers[0].draw(6, 1, 0, 0); - command_buffers[0].pushConstants(pipeline_layout, vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(push), &second_transform); - command_buffers[0].draw(6, 1, 6, 0); + uint32_t offset_vertex = 6; + for (auto &e: enemies) + { + command_buffers[0].pushConstants(pipeline_layout, vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(push), &e.trans); + command_buffers[0].draw(6, 1, offset_vertex, 0); + offset_vertex += 6; + } + command_buffers[0].endRenderPass(); if (vkEndCommandBuffer(command_buffers[0]) != VK_SUCCESS) { @@ -757,13 +784,13 @@ int main() thread = false; //phy_thread.join(); device.unmapMemory(uniform_buffer_data); - device.unmapMemory(vertex_buffer_memory); + device.unmapMemory(vertex_memory); device.waitIdle(); device.destroyDescriptorPool(descriptor_pool); device.destroyDescriptorSetLayout(descriptor_layout); device.destroyBuffer(vertex_buffer); device.destroyBuffer(uniform_buffer); - device.freeMemory(vertex_buffer_memory); + device.freeMemory(vertex_memory); device.freeMemory(uniform_buffer_data); for (auto &framebuffer: framebuffers) { From 48b938c8962d03d5cd8516c468bf7d07a19f60db Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 13 Jun 2025 05:52:31 +0200 Subject: [PATCH 07/13] added enemy collision detection, doesnt work properly yet --- main.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/main.cpp b/main.cpp index be4477a..4b8fd95 100644 --- a/main.cpp +++ b/main.cpp @@ -216,13 +216,14 @@ void simple_physics() } } -void simple_physics_step(float t, bounding_box &box, std::vector &boxes) +bool simple_physics_step(float t, bounding_box &box, std::vector &boxes) { box.y += box.velocityY * t + 0.5 * box.accY * (t * t); box.velocityY += box.accY * t; box.x += box.velocityX * t + 0.5 * box.accX * (t * t); - box.velocityX += box.accX * 0.002; + box.velocityX += box.accX * t; + bool end_game = false; for (auto &b: boxes) { @@ -230,7 +231,11 @@ void simple_physics_step(float t, bounding_box &box, std::vector &boxes) b.box.velocityY += b.box.accY * t; b.box.x += b.box.velocityX * t + 0.5 * b.box.accX * (t * t); - b.box.velocityX += b.box.accX * 0.002; + b.box.velocityX += b.box.accX * t; + + bool collision_x = b.box.x + b.box.width / 2 >= box.x - box.width /2 && b.box.x - b.box.width / 2 <= box.x + box.width /2; + bool collision_y = b.box.y + b.box.height / 2 >= box.y - box.height /2 && b.box.y - b.box.height / 2 <= box.y + box.height /2; + end_game = collision_x && collision_y; } bool collision_x = box.x + box.width / 2 >= 1.0f || box.x - box.width / 2 <= -1.0f; @@ -248,6 +253,7 @@ void simple_physics_step(float t, bounding_box &box, std::vector &boxes) box.velocityY = 0.0f; box.y = 1.0f - box.height/2; } + return end_game; } std::pair create_buffer(const vk::Device &device, vk::PhysicalDevice selected_physical_device, vk::BufferUsageFlagBits usage, size_t size) @@ -286,13 +292,15 @@ void keyboard_handle(GLFWwindow *window, int key, int scancode, int action, int std::println("JUMP!"); player.velocityY = -1.2f; } + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + exit(0); std::println("Key {} pressed!", key); } bounding_box spawn_enemy(std::mt19937 rng) { std::uniform_real_distribution dist(0.05, 0.3); - std::uniform_real_distribution y_dist(0.7, 0.5); + std::uniform_real_distribution y_dist(0.9, 0.6); std::uniform_real_distribution vel_dist(-1.0, -0.5); bounding_box ret{0}; ret.height = dist(rng); @@ -710,12 +718,17 @@ int main() enemies.push_back(enemy); } auto time_elapsed = clock::now() - before; - simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), player, enemies); + bool end_game = simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), player, enemies); + if (end_game == true) + { + std::println("You lost!"); + skip_rendering = true; + } before = clock::now(); play.trans.transform = move({player.x, player.y}); for (auto &e: enemies) { - if (e.box.x <= -1.0f) + if (e.box.x + e.box.width/2 <= -1.0f) { enemies.clear(); break; @@ -758,7 +771,7 @@ int main() throw std::runtime_error("Command buffer creation failed!"); } - vk::PipelineStageFlags flags = vk::PipelineStageFlags(vk::PipelineStageFlagBits::eColorAttachmentOutput); + vk::PipelineStageFlags flags(vk::PipelineStageFlagBits::eColorAttachmentOutput); vk::SubmitInfo submit_info = vk::SubmitInfo(); submit_info.waitSemaphoreCount = 1; submit_info.pWaitSemaphores = &image_semaphore; From b663af374f48d66519cc241ca34a8c866123969b Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 13 Jun 2025 05:58:05 +0200 Subject: [PATCH 08/13] added readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..7a3c954 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +This is a prototype for a game engine im doing, its very messy and imperfect, but its a working vulkan renderer (and an small minigame that doesnt work yet) made in c++23 that works in basically any system that supports vulkan (with some changes to the CMakeLists.txt file) + +I'm learning while writing this so expect some bad practices and weird stuff! \ No newline at end of file From 01ebd44a4c3ce2b87cdd19d8e4b364d130e8b4a9 Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 13 Jun 2025 23:08:26 +0200 Subject: [PATCH 09/13] Fixed bounding box of player and made input polled each frame, also centered the vertexes of player --- main.cpp | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/main.cpp b/main.cpp index 4b8fd95..9bb3dbb 100644 --- a/main.cpp +++ b/main.cpp @@ -10,6 +10,7 @@ #include bool skip_rendering = false; +bool stop_physics = false; vk::SurfaceFormatKHR format; vk::Extent2D framebuffer_extension; @@ -236,6 +237,12 @@ bool simple_physics_step(float t, bounding_box &box, std::vector &boxes) bool collision_x = b.box.x + b.box.width / 2 >= box.x - box.width /2 && b.box.x - b.box.width / 2 <= box.x + box.width /2; bool collision_y = b.box.y + b.box.height / 2 >= box.y - box.height /2 && b.box.y - b.box.height / 2 <= box.y + box.height /2; end_game = collision_x && collision_y; + if (end_game) + { + std::println("Collision between pos x: {} y: {} and pos x: {} and pos y: {} ", box.x, box.y, b.box.x, b.box.y); + std::println("With width: {} and height: {} and width: {} and height: {}", box.width, box.height, b.box.width, b.box.height); + std::println("Rightmost vertex in position {} collided with leftmost vertex in position {}", box.x + box.width/2, b.box.x - b.box.width/2); + } } bool collision_x = box.x + box.width / 2 >= 1.0f || box.x - box.width / 2 <= -1.0f; @@ -618,10 +625,10 @@ int main() quad play{}; play.box = player; play.vertices = { - {{-0.1f, -0.1f}, {1.0f, 0.0f, 0.0f}}, - {{0.0f, -0.1f}, {1.0f, 0.0f, 0.0f}}, - {{0.0f, 0.1f}, {0.0f, 1.0f, 0.0f}}, - {{-0.1f, 0.1f}, {0.0f, 0.0f, 1.0f}} + {{-0.05f, -0.1f}, {1.0f, 0.0f, 0.0f}}, + {{0.05f, -0.1f}, {1.0f, 0.0f, 0.0f}}, + {{0.05f, 0.1f}, {0.0f, 1.0f, 0.0f}}, + {{-0.05f, 0.1f}, {0.0f, 0.0f, 1.0f}} }; play.vertices = convert_quad_to_triangles(play.vertices); auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertex) * 6 * 100); @@ -679,17 +686,18 @@ int main() player.x = 0.0f; player.y = 0.0f; player.height = 0.2f; - player.width = 0.2f; + player.width = 0.1f; //velocityX = 0.008f; float angle = 0.0f; float vel2 = 0.005f; //std::thread phy_thread(simple_physics); - glfwSetKeyCallback(window, keyboard_handle); + glfwSetInputMode(window, GLFW_STICKY_KEYS, GLFW_TRUE); auto before = clock::now(); player.accY = 1.3f; player.x = -0.8; player.y = -0.5; + play.box = player; std::vector enemies; while(!glfwWindowShouldClose(window)) { @@ -700,7 +708,9 @@ int main() throw std::runtime_error("failed waiting!"); device.resetFences(next_frame_fence); if (skip_rendering) + { continue; + } auto image_result = device.acquireNextImageKHR(swapchain, UINT64_MAX, image_semaphore); if (image_result.result != vk::Result::eSuccess) { @@ -718,14 +728,25 @@ int main() enemies.push_back(enemy); } auto time_elapsed = clock::now() - before; - bool end_game = simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), player, enemies); + int state = glfwGetKey(window, GLFW_KEY_SPACE); + if (state == GLFW_PRESS) + { + std::println("JUMP!"); + play.box.velocityY = -1.2f; + } + bool end_game = false; + if (stop_physics == false) + end_game = simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), play.box, enemies); if (end_game == true) { std::println("You lost!"); - skip_rendering = true; + stop_physics = true; + std::println("Collision between pos x: {} y: {} and pos x: {} and pos y: {} ", play.box.x, play.box.y, enemies[0].box.x, enemies[0].box.y); + std::println("With width: {} and height: {} and width: {} and height: {}", play.box.width, play.box.height, enemies[0].box.width, enemies[0].box.height); + std::println("Rightmost vertex in position {} collided with leftmost vertex in position {}", play.box.x + play.box.width/2, enemies[0].box.x - enemies[0].box.width/2); } before = clock::now(); - play.trans.transform = move({player.x, player.y}); + play.trans.transform = move({play.box.x, play.box.y}); for (auto &e: enemies) { if (e.box.x + e.box.width/2 <= -1.0f) @@ -738,7 +759,7 @@ int main() } //memcpy(uniform_data, &u, sizeof(uniform)); - angle -= 1.0f; + angle -= 0.01f; memcpy(vertex_data, render_vertices.data(), sizeof(render_vertices[0]) * render_vertices.size()); From 1ef68e04feed7a852361f08c14cf9875eb1bf0c4 Mon Sep 17 00:00:00 2001 From: Luna Date: Sun, 15 Jun 2025 17:02:28 +0200 Subject: [PATCH 10/13] added score and the you cant infinite jump anymore --- main.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/main.cpp b/main.cpp index 9bb3dbb..216744e 100644 --- a/main.cpp +++ b/main.cpp @@ -217,7 +217,7 @@ void simple_physics() } } -bool simple_physics_step(float t, bounding_box &box, std::vector &boxes) +bool simple_physics_step(float t, bounding_box &box, std::vector &boxes, bool &on_ground) { box.y += box.velocityY * t + 0.5 * box.accY * (t * t); box.velocityY += box.accY * t; @@ -239,9 +239,11 @@ bool simple_physics_step(float t, bounding_box &box, std::vector &boxes) end_game = collision_x && collision_y; if (end_game) { + #ifdef NDEBUG std::println("Collision between pos x: {} y: {} and pos x: {} and pos y: {} ", box.x, box.y, b.box.x, b.box.y); std::println("With width: {} and height: {} and width: {} and height: {}", box.width, box.height, b.box.width, b.box.height); std::println("Rightmost vertex in position {} collided with leftmost vertex in position {}", box.x + box.width/2, b.box.x - b.box.width/2); + #endif } } @@ -259,6 +261,7 @@ bool simple_physics_step(float t, bounding_box &box, std::vector &boxes) { box.velocityY = 0.0f; box.y = 1.0f - box.height/2; + on_ground = true; } return end_game; } @@ -306,9 +309,9 @@ void keyboard_handle(GLFWwindow *window, int key, int scancode, int action, int bounding_box spawn_enemy(std::mt19937 rng) { - std::uniform_real_distribution dist(0.05, 0.3); + std::uniform_real_distribution dist(0.05, 0.4); std::uniform_real_distribution y_dist(0.9, 0.6); - std::uniform_real_distribution vel_dist(-1.0, -0.5); + std::uniform_real_distribution vel_dist(-1.5, -0.5); bounding_box ret{0}; ret.height = dist(rng); ret.width = dist(rng); @@ -699,6 +702,8 @@ int main() player.y = -0.5; play.box = player; std::vector enemies; + bool on_ground = true; + int score = 0; while(!glfwWindowShouldClose(window)) { glfwPollEvents(); @@ -731,19 +736,28 @@ int main() int state = glfwGetKey(window, GLFW_KEY_SPACE); if (state == GLFW_PRESS) { + #ifndef NDEBUG std::println("JUMP!"); - play.box.velocityY = -1.2f; + #endif + if (on_ground) + { + play.box.velocityY = -1.2f; + on_ground = false; + } } bool end_game = false; if (stop_physics == false) - end_game = simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), play.box, enemies); + end_game = simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), play.box, enemies, on_ground); if (end_game == true) { std::println("You lost!"); + std::println("Your score was {}", score); stop_physics = true; + #ifndef NDEBUG std::println("Collision between pos x: {} y: {} and pos x: {} and pos y: {} ", play.box.x, play.box.y, enemies[0].box.x, enemies[0].box.y); std::println("With width: {} and height: {} and width: {} and height: {}", play.box.width, play.box.height, enemies[0].box.width, enemies[0].box.height); std::println("Rightmost vertex in position {} collided with leftmost vertex in position {}", play.box.x + play.box.width/2, enemies[0].box.x - enemies[0].box.width/2); + #endif } before = clock::now(); play.trans.transform = move({play.box.x, play.box.y}); @@ -751,6 +765,7 @@ int main() { if (e.box.x + e.box.width/2 <= -1.0f) { + score += (int)(abs((e.box.width * 10)) + abs((e.box.height * 10)) + abs((e.box.velocityX * 10))); enemies.clear(); break; } From 0ebabbcb4627fa68925d9e7d7769580295af90e8 Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 21 Jun 2025 05:10:05 +0200 Subject: [PATCH 11/13] mobility improvments and also made input a callback again --- main.cpp | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/main.cpp b/main.cpp index 216744e..b2b5b89 100644 --- a/main.cpp +++ b/main.cpp @@ -11,6 +11,8 @@ bool skip_rendering = false; bool stop_physics = false; +std::atomic_bool pressed_space = false; +std::atomic_bool pressed_shift = false; vk::SurfaceFormatKHR format; vk::Extent2D framebuffer_extension; @@ -299,12 +301,15 @@ void keyboard_handle(GLFWwindow *window, int key, int scancode, int action, int { if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { - std::println("JUMP!"); - player.velocityY = -1.2f; + //std::println("JUMP!"); + pressed_space = true; + } + else if (key == GLFW_KEY_LEFT_SHIFT && action == GLFW_PRESS) + { + pressed_shift = true; } if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) exit(0); - std::println("Key {} pressed!", key); } bounding_box spawn_enemy(std::mt19937 rng) @@ -695,7 +700,7 @@ int main() float angle = 0.0f; float vel2 = 0.005f; //std::thread phy_thread(simple_physics); - glfwSetInputMode(window, GLFW_STICKY_KEYS, GLFW_TRUE); + glfwSetKeyCallback(window, keyboard_handle); auto before = clock::now(); player.accY = 1.3f; player.x = -0.8; @@ -703,6 +708,7 @@ int main() play.box = player; std::vector enemies; bool on_ground = true; + int jumps = 0; int score = 0; while(!glfwWindowShouldClose(window)) { @@ -733,21 +739,31 @@ int main() enemies.push_back(enemy); } auto time_elapsed = clock::now() - before; - int state = glfwGetKey(window, GLFW_KEY_SPACE); - if (state == GLFW_PRESS) + if (pressed_space == true) { #ifndef NDEBUG - std::println("JUMP!"); + //std::println("JUMP!"); #endif - if (on_ground) + if (on_ground || jumps <= 1) { - play.box.velocityY = -1.2f; + if (jumps <= 1) + play.box.velocityY = -1.2f; on_ground = false; + jumps++; + std::println("Jumps {}", jumps); } + pressed_space = false; + } + if (pressed_shift == true) + { + play.box.velocityY = 3.0f; + pressed_shift = false; } bool end_game = false; if (stop_physics == false) end_game = simple_physics_step(std::chrono::duration_cast>(time_elapsed).count(), play.box, enemies, on_ground); + if (on_ground) + jumps = 0; if (end_game == true) { std::println("You lost!"); @@ -757,6 +773,7 @@ int main() std::println("Collision between pos x: {} y: {} and pos x: {} and pos y: {} ", play.box.x, play.box.y, enemies[0].box.x, enemies[0].box.y); std::println("With width: {} and height: {} and width: {} and height: {}", play.box.width, play.box.height, enemies[0].box.width, enemies[0].box.height); std::println("Rightmost vertex in position {} collided with leftmost vertex in position {}", play.box.x + play.box.width/2, enemies[0].box.x - enemies[0].box.width/2); + std::println("Jumps {}", jumps); #endif } before = clock::now(); From b2e5360a6d879bb401ed69cc793b745fbcc8aa63 Mon Sep 17 00:00:00 2001 From: Luna Date: Mon, 23 Jun 2025 22:39:56 +0200 Subject: [PATCH 12/13] Made it work on linux --- main.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index b2b5b89..30fbe0e 100644 --- a/main.cpp +++ b/main.cpp @@ -315,7 +315,7 @@ void keyboard_handle(GLFWwindow *window, int key, int scancode, int action, int bounding_box spawn_enemy(std::mt19937 rng) { std::uniform_real_distribution dist(0.05, 0.4); - std::uniform_real_distribution y_dist(0.9, 0.6); + std::uniform_real_distribution y_dist(0.6, 0.9); std::uniform_real_distribution vel_dist(-1.5, -0.5); bounding_box ret{0}; ret.height = dist(rng); @@ -382,7 +382,10 @@ int main() #endif vk::InstanceCreateInfo createinfo = vk::InstanceCreateInfo( - vk::InstanceCreateFlags(VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR), + #ifdef __APPLE__ + vk::InstanceCreateFlags(VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR), + #endif + vk::InstanceCreateFlags(), &appinfo,layers.size(), layers.data(), extensions.size(), extensions.data()); vk::Instance instance = vk::createInstance(createinfo); From 7ec6c4aa33dbf46a8c193fbb2f2c2174d911fb92 Mon Sep 17 00:00:00 2001 From: Luna Date: Sun, 27 Jul 2025 05:11:06 +0200 Subject: [PATCH 13/13] tiny fix (idk how i didnt see it but it made it unusable on macos) --- main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main.cpp b/main.cpp index 30fbe0e..f711a3b 100644 --- a/main.cpp +++ b/main.cpp @@ -385,7 +385,9 @@ int main() #ifdef __APPLE__ vk::InstanceCreateFlags(VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR), #endif + #ifdef __linux__ vk::InstanceCreateFlags(), + #endif &appinfo,layers.size(), layers.data(), extensions.size(), extensions.data()); vk::Instance instance = vk::createInstance(createinfo);