Migration to Codeberg

This commit is contained in:
Joaquin Gottlebe
2026-07-30 16:38:22 +02:00
commit 17048b703a
556 changed files with 3040 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# Visual Studio files
[Dd]ebug/
[Dd]ebug.DLL/
[R]elease/
[Rr]elease.DLL/
*.user
*.aps
.vs
# Clangd LSP
.cache
compile_commands.json
# Build folder
[Bb]uild
# Android
*apk*
android.*
+15
View File
@@ -0,0 +1,15 @@
CXX = clang++
FLAGS = -Wall -std=c++17 $(shell pkg-config --libs --cflags raylib)
TARGET = game
SRC = src/main.cpp
all: $(TARGET)
$(TARGET): $(SRC)
$(CXX) $(FLAGS) $(SRC) -o $(TARGET)
clean:
rm -f $(TARGET)
run: clean $(TARGET)
./$(TARGET)
+32
View File
@@ -0,0 +1,32 @@
# Father and Son
## Overview
This Jump and Run game is a 2D platformer built using the [raylib](https://www.raylib.com/) library. Players navigate through levels filled with obstacles and challenges, aiming to reach the end goal while collecting points.
## Prerequisites
To compile and run the game, ensure you have the following installed on your system:
- **Make**: A build tool for automating the compilation process.
- **C Compiler**: Ensure you have a C compiler like `gcc` or `clang` installed.
## Building and run the Game
To build the game, use the following command:
```bash
make run
```
## Troubleshooting
- Verify that all game files, including source code and assets, are in the correct directories.
- If the program does not run, ensure `make` and your C compiler are properly installed and configured.
## License
This project is distributed under the MIT License. See the `LICENSE` file for details.
## Contributions
Contributions are welcome! Fork the repository, make your changes, and submit a pull request.
## Credits
- **Developer:** Joaquin Gottlebe
- **Built With:** raylib and C
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.
BIN
View File
Binary file not shown.
@@ -0,0 +1,41 @@
#version 330 // Adjust version if needed
// Our uniforms (variables passed from the CPU code):
uniform vec2 lightPos; // Torch position in *screen* coordinates
uniform float radius; // How far the torch reaches
uniform float intensity; // Brightness at the center
// Varyings from raylib's default vertex shader
in vec2 fragTexCoord; // [0..1] texture coordinates
in vec4 fragColor; // Not often needed here
// The texture(s) we read from
uniform sampler2D texture0;
// Final color we output
out vec4 finalColor;
void main()
{
// Grab whatever is in the render texture at this pixel:
vec4 color = texture(texture0, fragTexCoord);
// Convert fragTexCoord from [0..1] range into actual screen coords.
// If your screen is 1280x720, for example:
vec2 screenCoord = vec2(fragTexCoord.x * 1280.0,
fragTexCoord.y * 720.0);
// Distance from this pixel to the torch center:
float dist = distance(screenCoord, lightPos);
// Basic “1 - distance/radius” falloff.
// Then clamp so it won’t go below 0 or above 1.
float factor = 1.0 - (dist / radius);
factor = clamp(factor, 0.0, 1.0);
// Multiply by intensity if you want the center brighter or dimmer.
factor *= intensity;
// Multiply the original color by our factor:
finalColor = vec4(color.rgb * factor, color.a);
}
+266
View File
@@ -0,0 +1,266 @@
#include <raylib.h>
class Player
{
private:
Vector2 position = {0, 0};
Vector2 spriteSize = {1.0f, 1.0f};
Texture2D texture = {0};
Rectangle frameRec = {0.0f, 0.0f, 0.0f, 0.0f};
float scale = 1.0f;
bool loaded = false;
int currentFrame = 0;
int framesCounter = 0;
int framesSpeed = 8;
public:
Player() = default;
Player(const char *path, Vector2 textureGrid)
{
load(path, textureGrid);
}
void load(const char *path, Vector2 textureGrid)
{
texture = LoadTexture(path);
spriteSize.x = texture.width / textureGrid.x;
spriteSize.y = texture.height / textureGrid.y;
frameRec = {0.0f, 0.0f, spriteSize.x, spriteSize.y};
scale = GetScreenHeight() / texture.height / 2.0f;
loaded = true;
position = {0,0};
}
~Player()
{
if (loaded)
{
UnloadTexture(texture);
}
}
void update()
{
framesCounter++;
if (framesCounter >= (60/framesSpeed))
{
framesCounter = 0;
currentFrame++;
if (currentFrame > 5) currentFrame = 0;
frameRec.x = (float)currentFrame * spriteSize.x;
}
if (IsKeyDown(KEY_RIGHT)){
position.x += 2.0f;
frameRec.width = spriteSize.x;
}
if (IsKeyDown(KEY_LEFT)){
position.x -= 2.0f;
frameRec.width = -spriteSize.x;
}
if (IsKeyDown(KEY_DOWN)){
position.y += 2.0f;
}
if (IsKeyDown(KEY_UP)){
position.y -= 2.0f;
}
scale = GetScreenHeight() / texture.height / 2.0f;
}
void draw()
{
if (loaded)
{
Rectangle dest = {position.x, position.y, spriteSize.x * scale, spriteSize.y * scale};
Vector2 origin = {0.0f, 0.0f};
DrawTexturePro(texture, frameRec, dest, origin, 0.0f, WHITE);
}
}
Vector2 getPosition() { return position; }
Vector2 getSpriteSize() { return spriteSize; }
float getScale() { return scale;}
};
///////////////////////////////////////////////////////////////////////////
class Background
{
private:
Texture2D texture = {0};
float scrolling = 0.0f;
float scale = 1.0f;
bool loaded = false;
public:
Background() = default;
Background(const char *path) { load(path); }
void load(const char *path)
{
texture = LoadTexture(path);
scale = GetScreenHeight() / texture.height;
loaded = true;
}
~Background()
{
if (loaded)
{
UnloadTexture(texture);
}
}
void update()
{
// updateScrolling();
scale = GetScreenHeight() / texture.height;
}
void draw()
{
if (!loaded)
return;
for (int i = -1; i <= 1; i++)
{
DrawTextureEx(texture, {scrolling + i * texture.width * scale, 0.0f}, 0.0f, scale, WHITE);
}
}
};
///////////////////////////////////////////////////////////////////////////
class CameraController
{
private:
Camera2D camera;
Vector2 center;
Vector2 targetOffset;
float transitionSpeed = 0.01f; // Speed of transition
public:
void initialize(Vector2 position, Vector2 spriteSize)
{
center = {(GetScreenWidth() / 2.0f) - (spriteSize.x / 2.0f), (GetScreenHeight() / 2.0f) - (spriteSize.y / 2.0f)};
camera = {
.offset = center,
.target = position,
.rotation = 0.0f,
.zoom = 1.0f};
targetOffset = camera.offset;
}
void update(Vector2 position, Vector2 spriteSize, float scale)
{
if (IsKeyDown(KEY_RIGHT))
targetOffset = {(GetScreenWidth() / 2.0f) - (spriteSize.x * scale / 2.0f) - (GetScreenWidth() / 4.0f), (GetScreenHeight() / 2.0f) - (spriteSize.y * scale / 2.0f)};
if (IsKeyDown(KEY_LEFT))
targetOffset = {(GetScreenWidth() / 2.0f) - (spriteSize.x * scale / 2.0f) + (GetScreenWidth() / 4.0f), (GetScreenHeight() / 2.0f) - (spriteSize.y * scale / 2.0f)};
if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN))
targetOffset = center; // Reset to center for vertical movement or no horizontal input.
// Smooth transition using LERP
camera.offset.x += (targetOffset.x - camera.offset.x) * transitionSpeed;
camera.offset.y += (targetOffset.y - camera.offset.y) * transitionSpeed;
camera.target = position;
}
Camera2D getCamera() const { return camera; }
};
///////////////////////////////////////////////////////////////////////////
class Game
{
private:
Player player;
Background background;
Background midground;
Background foreground;
CameraController camera;
public:
Game() = default;
void initialize()
{
player.load("assets/character.png", {4.0f, 12.0f});
// background.load("assets/background.png");
// midground.load("assets/midground.png");
// foreground.load("assets/foreground.png");
camera.initialize(player.getPosition(),player.getSpriteSize());
}
void update()
{
player.update();
camera.update(player.getPosition(),player.getSpriteSize(), player.getScale());
// background.update();
}
void render()
{
BeginDrawing();
ClearBackground(BLACK);
BeginMode2D(camera.getCamera());
background.draw();
midground.draw();
foreground.draw();
player.draw();
EndMode2D();
drawDebug();
EndDrawing();
}
void shutdown()
{
CloseWindow();
}
private:
void drawDebug (){
DrawCircle(camera.getCamera().offset.x,camera.getCamera().offset.y,20,RED);
DrawText(TextFormat("camera.offset.x: %f",camera.getCamera().offset.x),0,0,20,WHITE);
DrawText(TextFormat("camera.offset.y: %f",camera.getCamera().offset.y),0,20,20,WHITE);
DrawCircle(camera.getCamera().target.x,camera.getCamera().target.y,30,BLUE);
DrawText(TextFormat("camera.target.x: %f",camera.getCamera().target.x),0,40,20,WHITE);
DrawText(TextFormat("camera.target.y: %f",camera.getCamera().target.y),0,60,20,WHITE);
DrawCircle(player.getPosition().x,player.getPosition().y,20,GREEN);
DrawText(TextFormat("player.position.x: %f",player.getPosition().x),0,80,20,WHITE);
DrawText(TextFormat("player.position.y: %f",player.getPosition().y),0,100,20,WHITE);
}
};
///////////////////////////////////////////////////////////////////////////
int main()
{
InitWindow(1280, 720, "Father and Son");
SetTargetFPS(60);
Game game;
game.initialize();
while (!WindowShouldClose())
{
game.update();
game.render();
}
game.shutdown();
return 0;
}
+317
View File
@@ -0,0 +1,317 @@
#include "raylib.h"
#include <cmath>
// const char *title = "Father and son";
// int screenWidth = 1280;
// int screenHeight = 720;
// int FPS = 60;
float distanceBack = 40.0f;
float distanceMid = 20.0f;
float distanceFore = 10.0f;
float charSpriteHeight = 256.0f;
float bottomSpace = 64.0f;
Vector2 charPos = {
static_cast<float>(screenWidth) / 2.0f - 128.0f,
static_cast<float>(screenHeight) - (256.0f + 64.0f)
};
// Dialog & font
int fontSize = 20;
int steps = 0;
// Tints
Color backgroundTint = {171, 157, 146, 100};
Color midgroundTint = {171, 157, 146, 130};
Color foregroundTint = {171, 157, 146, 150};
Color characterTint = {171, 157, 146, 100};
// Dialog struct and list
typedef struct {
const char *text;
int next;
} Dialog;
Dialog dialogs[] = {
{"Son: Father?", 1},
{"Father: Everything ok?", 2},
{"Son: When do we reach the coast?", 3},
{"Father: It will take some time.", 4},
{"Son: I am tired.", -1}
};
const char *continueDialog = "[Press SPACE to continue]";
// Simple control structure for movement
struct Control {
int direction;
float speed;
};
// Get input function
Control getInput() {
int direction = 1;
float speed = 0.0f;
if (IsKeyDown(KEY_RIGHT)) {
direction = 1;
speed = 7.5f;
}
else if (IsKeyDown(KEY_LEFT)) {
direction = -1;
speed = 7.5f;
}
else {
direction = 1;
speed = 0.0f;
}
Control input;
input.direction = direction;
input.speed = speed;
return input;
}
// Character class
class Character {
private:
Texture2D sprite;
Rectangle frameRec;
Vector2 position;
int framesCounter;
int currentFrame;
int framesSpeed;
public:
Character(const char* filePath, Vector2 pos) {
sprite = LoadTexture(filePath);
position = pos;
frameRec = {0.0f, 0.0f, static_cast<float>(sprite.width) / 6, static_cast<float>(sprite.height)};
framesCounter = 0;
currentFrame = 0;
framesSpeed = 0;
}
~Character() {
UnloadTexture(sprite);
}
void Update(int direction, float speed) {
if (direction != 0) {
framesSpeed = 30;
}
else {
framesSpeed = 0;
currentFrame = 4;
}
framesCounter++;
if (framesSpeed > 0 && framesCounter >= (480 / framesSpeed)) {
framesCounter = 0;
currentFrame++;
if (currentFrame > 5) currentFrame = 0;
frameRec.x = static_cast<float>(currentFrame) * (sprite.width / 6.0f);
}
}
void Draw(int direction) {
Rectangle sourceRec = frameRec;
if (direction == -1) {
sourceRec.width *= -1;
}
DrawTextureRec(sprite, sourceRec, position, WHITE);
}
};
class Background {
private:
Texture2D texture;
float scrolling = 0.0f;
float scale;
public:
Background(const char* filePath, float initialScale = 1.0f) {
texture = LoadTexture(filePath);
scale = initialScale;
}
~Background() {
UnloadTexture(texture);
}
Texture2D GetTexture() const {
return texture;
}
void Update(int direction, float speed, float distance) {
scrolling -= direction * (speed / distance);
float textureWidth = static_cast<float>(texture.width) * scale;
if (scrolling <= -textureWidth) {
scrolling += textureWidth;
}
else if (scrolling >= textureWidth) {
scrolling -= textureWidth;
}
}
void Draw() {
float textureWidth = static_cast<float>(texture.width) * scale;
DrawTextureEx(texture, {scrolling - textureWidth, 0}, 0.0f, scale, WHITE);
DrawTextureEx(texture, {scrolling, 0}, 0.0f, scale, WHITE);
DrawTextureEx(texture, {scrolling + textureWidth,0}, 0.0f, scale, WHITE);
}
void SetScale(float newScale) {
scale = newScale;
}
};
void AdjustBackgroundScale(Background& bg) {
Texture2D texture = bg.GetTexture();
float scaleX = static_cast<float>(GetScreenWidth()) / texture.width;
float scaleY = static_cast<float>(GetScreenHeight()) / texture.height;
bg.SetScale(fmaxf(scaleX, scaleY));
}
int main(void) {
InitWindow(screenWidth, screenHeight, title);
SetTargetFPS(FPS);
Shader radialLightShader = LoadShader(NULL, "shaders/radial_light.fs");
int lightPosLoc = GetShaderLocation(radialLightShader, "lightPos");
int radiusLoc = GetShaderLocation(radialLightShader, "radius");
int intensityLoc = GetShaderLocation(radialLightShader, "intensity");
float torchRadius = 1200.0f;
float torchIntensity = 1.0f;
RenderTexture2D mainTarget = LoadRenderTexture(screenWidth, screenHeight);
InitAudioDevice();
Music music = LoadMusicStream("assets/soundtrack.mp3");
PlayMusicStream(music);
SetMusicVolume(music, 0.0f);
Character character("assets/father-and-son.png", charPos);
Background background("assets/background.png");
Background midground("assets/midground.png");
Background foreground("assets/foreground.png");
AdjustBackgroundScale(background);
AdjustBackgroundScale(midground);
AdjustBackgroundScale(foreground);
int currentDialog = 0;
bool dialogActive = true;
while (!WindowShouldClose()) {
UpdateMusicStream(music);
Control input = getInput();
if (input.direction == 1 && input.speed == 7.5f) {
steps++;
}
if (torchRadius > 1.0f) {
torchRadius -= 1.0f;
torchIntensity -= 0.001f;
}
else {
torchRadius = 0.01f;
torchIntensity = 0.001f;
}
character.Update(input.direction, input.speed);
background.Update(input.direction, input.speed, distanceBack);
midground.Update(input.direction, input.speed, distanceMid);
foreground.Update(input.direction, input.speed, distanceFore);
BeginTextureMode(mainTarget);
ClearBackground(BLACK);
background.Draw();
DrawRectangle(0, 0, screenWidth, screenHeight, backgroundTint);
midground.Draw();
DrawRectangle(0, 0, screenWidth, screenHeight, midgroundTint);
foreground.Draw();
DrawRectangle(0, 0, screenWidth, screenHeight, foregroundTint);
character.Draw(input.direction);
DrawRectangle(0, 0, screenWidth, screenHeight, characterTint);
EndTextureMode();
BeginDrawing();
ClearBackground(BLACK);
Vector2 torchPos;
if (input.direction == 1) {
torchPos = {charPos.x + 219.0f, charPos.y - 120.0f};
} else {
torchPos = {charPos.x + (256.0f - 219.0f), charPos.y - 120.0f};
}
SetShaderValue(radialLightShader, lightPosLoc, &torchPos, SHADER_UNIFORM_VEC2);
SetShaderValue(radialLightShader, radiusLoc, &torchRadius, SHADER_UNIFORM_FLOAT);
SetShaderValue(radialLightShader, intensityLoc, &torchIntensity, SHADER_UNIFORM_FLOAT);
BeginShaderMode(radialLightShader);
DrawTextureRec(
mainTarget.texture,
Rectangle{
0.0f,
0.0f,
static_cast<float>(mainTarget.texture.width),
static_cast<float>(-mainTarget.texture.height)
},
Vector2{0.0f, 0.0f},
WHITE
);
EndShaderMode();
if (dialogActive && IsKeyPressed(KEY_SPACE)) {
if (dialogs[currentDialog].next == -1) {
dialogActive = false;
} else {
currentDialog = dialogs[currentDialog].next;
}
}
int textWidthDialog = MeasureText(dialogs[currentDialog].text, fontSize);
int textWidthContinueDialog = MeasureText(continueDialog, fontSize);
if (torchRadius < 1.0f) {
DrawText(
dialogs[currentDialog].text,
(screenWidth / 2) - (textWidthDialog / 2),
screenHeight / 2,
fontSize,
WHITE
);
DrawText(
continueDialog,
(screenWidth / 2) - (textWidthContinueDialog / 2),
screenHeight - 50,
fontSize,
DARKGRAY
);
}
EndDrawing();
}
UnloadMusicStream(music);
CloseAudioDevice();
CloseWindow();
return 0;
}