diff --git a/CMakeLists.txt b/CMakeLists.txt index e63fa81..25f85c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ include_directories( set(SRCS src/event_manager.c src/main.c + src/planet.c src/ship.c src/starfield.c) diff --git a/TODO b/TODO deleted file mode 100644 index b8224b5..0000000 --- a/TODO +++ /dev/null @@ -1,2 +0,0 @@ -TODO: - - Add presets with stellar masses (for gravity simulation). diff --git a/src/globals.h b/src/globals.h index 8c61883..08cbbba 100644 --- a/src/globals.h +++ b/src/globals.h @@ -26,7 +26,7 @@ # define FPS 60.0f #endif #ifndef ACCEL -# define ACCEL 0.1f +# define ACCEL 0.3f #endif #ifndef TURN_ACCEL # define TURN_ACCEL (M_PI / FPS) // turn at pi radians / sec diff --git a/src/main.c b/src/main.c index ab55428..b8d1d5a 100644 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,7 @@ #include "event_manager.h" #include "ship.h" #include "starfield.h" +#include "planet.h" int run; int redraw; @@ -106,6 +107,10 @@ int main() { struct ship ship; ship_init(&ship, 400, 300); + // initialize the planet + struct planet planet; + planet_init(&planet, 400.0f, 300.0f, 250.0f); + ALLEGRO_FONT *font = al_create_builtin_font(); // begin running the simulation @@ -140,7 +145,11 @@ int main() { if(key_is_down(KEY_RESET)) ship_init(&ship, (float)WINDOW_WIDTH / 2, (float)WINDOW_HEIGHT / 2); else - ship_update(&ship); + { + float gravity_x, gravity_y; + planet_get_gravity(&planet, ship.x, ship.y, &gravity_x, &gravity_y); + ship_update(&ship, gravity_x, gravity_y); + } } if (key_is_down(KEY_FULLSCREEN) && !just_toggled_fullscreen) @@ -190,6 +199,7 @@ int main() { al_use_transform(&transform); starfield_draw(ship.x, ship.y, zoom, display_width, display_height); + planet_draw(&planet); ship_draw(&ship); al_identity_transform(&transform); diff --git a/src/planet.c b/src/planet.c new file mode 100644 index 0000000..28bb371 --- /dev/null +++ b/src/planet.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2026 Ortega Froysa, Nicolás + * Author: Ortega Froysa, Nicolás + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "planet.h" +#include +#include +#include + +#define GRAVITY_CONSTANT 1.0f // Gravitational constant scaled for simulation +#define SHIP_MASS 1.0f // Assumed constant ship mass +#define MASS_TO_RADIUS 1.5f // Radius scale factor: radius = MASS_TO_RADIUS * mass^(1/3) + +void planet_init(struct planet *planet, float x, float y, float mass) { + assert(planet); + + planet->x = x; + planet->y = y; + planet->mass = mass; + planet->radius = MASS_TO_RADIUS * cbrtf(planet->mass); +} + +void planet_get_gravity(struct planet *planet, float ship_x, float ship_y, + float *accel_x, float *accel_y) { + assert(planet); + assert(accel_x); + assert(accel_y); + + float dx = planet->x - ship_x; + float dy = planet->y - ship_y; + float distance = sqrtf(dx * dx + dy * dy); + + if(distance < planet->radius) { + *accel_x = 0.0f; + *accel_y = 0.0f; + return; + } + + // F = G * m1 * m2 / r^2 + float force = GRAVITY_CONSTANT * SHIP_MASS * planet->mass / (distance * distance); + + // a = F / m_ship = G * m_planet / r^2 + float acceleration = force / SHIP_MASS; + + // Normalize direction and apply acceleration + float norm_x = dx / distance; + float norm_y = dy / distance; + + *accel_x = norm_x * acceleration; + *accel_y = norm_y * acceleration; +} + +void planet_draw(struct planet *planet) { + assert(planet); + + // Color intensity based on mass (brighter = more massive) + float color_scale = fminf(1.0f, planet->mass / 1000.0f); + int r = (int)(100 + 155 * color_scale); + int g = (int)(100 + 50 * color_scale); + int b = (int)(150 - 100 * color_scale); + + al_draw_filled_circle(planet->x, planet->y, planet->radius, + al_map_rgb(r, g, b)); +} diff --git a/src/planet.h b/src/planet.h new file mode 100644 index 0000000..caaa833 --- /dev/null +++ b/src/planet.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2026 Ortega Froysa, Nicolás + * Author: Ortega Froysa, Nicolás + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +/** + * Function pointer type for calculating planet mass. + * Takes no parameters and returns the mass value. + */ +typedef float (*planet_mass_func)(void); + +struct planet { + float x, y; ///< The x and y coordinates of the planet center. + float mass; ///< The mass of the planet. + float radius; ///< The radius of the planet (derived from mass). +}; + +/** + * @brief Initialize a planet at a position with a specified mass. + * + * @param planet A pointer to the planet object. + * @param x Initial x position of the planet center. + * @param y Initial y position of the planet center. + * @param mass The mass of the planet. + */ +void planet_init(struct planet *planet, float x, float y, float mass); + +/** + * @brief Calculate the gravitational acceleration on a ship at a given position. + * + * Returns the acceleration vector components due to the planet's gravity. + * + * @param planet A pointer to the planet object. + * @param ship_x X position of the ship. + * @param ship_y Y position of the ship. + * @param accel_x Pointer to store the x component of acceleration. + * @param accel_y Pointer to store the y component of acceleration. + */ +void planet_get_gravity(struct planet *planet, float ship_x, float ship_y, + float *accel_x, float *accel_y); + +/** + * @brief Draw the planet. + * + * @param planet Planet object to draw. + */ +void planet_draw(struct planet *planet); diff --git a/src/ship.c b/src/ship.c index d563acf..c1e2dfd 100644 --- a/src/ship.c +++ b/src/ship.c @@ -34,7 +34,7 @@ void ship_init(struct ship *ship, float x, float y) { ship->direction = 0; } -void ship_update(struct ship *ship) { +void ship_update(struct ship *ship, float gravity_x, float gravity_y) { assert(ship); if(key_is_down(KEY_RIGHT)) @@ -60,6 +60,10 @@ void ship_update(struct ship *ship) { ship->velY -= sin(ship->direction) * (ACCEL / 2); } + // Apply gravitational acceleration + ship->velX += gravity_x; + ship->velY += gravity_y; + ship->x += ship->velX; ship->y += ship->velY; } diff --git a/src/ship.h b/src/ship.h index 2072332..6108d4b 100644 --- a/src/ship.h +++ b/src/ship.h @@ -41,11 +41,13 @@ void ship_init(struct ship *ship, float x, float y); /** * @brief Updates the ship's variables according to keyboard - * input. + * input and gravitational forces. * * @param ship A pointer to the ship object. + * @param gravity_x Gravitational acceleration in x direction. + * @param gravity_y Gravitational acceleration in y direction. */ -void ship_update(struct ship *ship); +void ship_update(struct ship *ship, float gravity_x, float gravity_y); /** * @brief Draw the ship.