RASMUS GÖRANSSON

GAME PROGRAMMER

Primitive Engine

Primitive Engine is a project I started to improve my C++ skills. Aside from C++ I am also using SDL2 for window management and rendering as well as GLM for math, that way I can focus more on gameplay features and less on the underlaying math.

This project is still a work in progress, and I have many more features planned. I'm focusing on implementing a solid foundation without making it too generalized, while also refining important aspects like collision resolution and player movement to create a more enjoyable experience.

My goal is to continually evolve the game and add new features as I progress.

                        
#pragma once

#include "iostream"
#include "SDL_image.h"
#include "SDL.h"
#include "vector"

#define NOMINMAX
#include "windows.h"

static constexpr int max_Actors = 50;

// Forward declarations
class Actor;
enum class ECollision_Type;
class Camera;
class WorldGenerator;

class Game {

public:

	Game(const Game&) = delete;
	Game& operator=(const Game&) = delete;

	static Game& Instance()
	{
		static Game instance;
		return instance;
	}


	void Init(const char* title, int xPos, int yPos, int width, int height, bool fullscreen);

	void HandleEvents();

	void Update();

	void Render();


	void Clean();

	bool Running() { return isRunning; }

	void SetRenderColor();
	void FillRenderRect(int x, int y, int width, int height);
	void RenderRect(int x, int y, int width, int height);

	Actor* GetCollidingActor(Actor* other, ECollision_Type collisionType);
	std::vector<Actor*> GetAllCollidingActors(Actor* other, ECollision_Type collisionType);

	SDL_Renderer* GetRenderer();

	// getter functions
	Actor* GetPlayer();
	Camera* GetCamera();
	WorldGenerator* GetWorldGenerator();

private:

	Game();
	~Game();

	SDL_Window* window;
	SDL_Renderer* renderer;

	bool isRunning;

	static constexpr float BACKGROUND_GRID_SIZE = 50.f;

	Actor* actors[max_Actors] = { nullptr };


	WorldGenerator* worldGenerator = nullptr;


	Actor* player = nullptr;

	Camera* camera = nullptr;

};


// game time
float Get_DeltaTime();

float Get_CurrentTime();

float Get_TimePassedSince(float time);

int GetFrameCount();


                        
                    

Input Manager

The InputManager class handles keyboard and mouse input using SDL events.

It tracks key and mouse button states, detecting if its pressed, held or released. It also keeps track of the mouse position.

All inputs are frame-accurate, ensuring accurate and responsive input handling.

                        
#pragma once

#include "SDL.h"
#include "SDL_image.h"
#include "string"
#include "unordered_map"

class TextureManager
{
public:

	TextureManager(const TextureManager&) = delete;
	TextureManager& operator=(const TextureManager&) = delete;

	static TextureManager& Instance()
	{
		static TextureManager instance;
		return instance;
	}

	//SDL_Texture* LoadTexture(const char* textureName, SDL_Renderer* renderer);

	bool Load(const std::string& id, const std::string fileName, SDL_Renderer* renderer);
	void Render(const std::string& id, int x, int y, int width, int height, SDL_Renderer* renderer);
	void Clean();

private:

	TextureManager() { }

	std::unordered_map<std::string, SDL_Texture*> textureMap;
};

                        
                    

Collision

The AABB (Axis-Aligned Bounding Box) struct represent a 2D rectangle used for collision detection.

FromPositionSize takes a position and a size and converts it into an AABB by calculating the min and max corners.

aabbOverlap is an overlap check that compare two AABB and return if they are overlapping or not.

                        
#pragma once

#include "glm.hpp"

class Camera
{
public:
	void Update();

	glm::vec2 WorldToScreen(glm::vec2 vector);
	glm::vec2 ScreenToWorld(glm::vec2 vector);

	glm::vec2 position;
	
};

                        
                    

Player Class

The Player class represents the player character and inherits from the Actor class.

Player movement includes horizontal movement, jumping and gravity.

To resolve collisions, the player's position is adjusted based on the smallest overlap with other objects.

The player can interact with the world using mouse inputs to either place or break blocks.

                        
#pragma once

#include "Actor.h"

class Block : public Actor
{
public:

	Block(glm::vec2 position);

	void Update() override;
	void Render() override;

	void Hit(int damage) override;

};