Banjo API 0.0.1
C99 game development API
Loading...
Searching...
No Matches
physics_kinematics.c

2D kinematics for projectile motion simulation.

2D kinematics for projectile motion simulation.Kinematics calculates motion from initial conditions (position, velocity) and constant acceleration (like gravity). Use bj_compute_kinematics_2d() for:

  • Projectiles: thrown objects, bullets, jumping characters
  • Falling objects under gravity
  • Any motion with constant acceleration

The kinematics equation: position = p₀ + v₀*t + ½*a*t² This gives exact positions at any time t without step-by-step integration. Much more accurate than repeatedly adding velocity each frame.

#define BJ_AUTOMAIN_CALLBACKS
#include <banjo/draw.h>
#include <banjo/event.h>
#include <banjo/log.h>
#include <banjo/main.h>
#include <banjo/renderer.h>
#include <banjo/system.h>
#include <banjo/time.h>
#include <banjo/vec.h>
#include <banjo/window.h>
#include <stdlib.h>
#include <time.h>
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
#define BALLS_LEN 1000
#define BALLS_RADIUS BJ_F(3.0)
#define GRAVITY BJ_F(50.0)
// Each ball tracks its initial conditions and elapsed time. Kinematics needs:
// - initial_position (shared by all balls here)
// - initial_velocity (unique per ball)
// - acceleration (gravity, shared)
// - time_alive (how long since launch)
// From these, we can compute exact position at any time.
struct {
bj_vec2 initial_velocity;
bj_vec2 position;
uint32_t color;
double time_alive;
// Setting up a projectile: choose initial velocity based on desired direction
// and speed. For realistic projectile arcs, use angle and magnitude.
// Angle: -90° points straight up, 0° points right (here: -90° to 0° for fountain effect)
// Magnitude: initial speed in pixels/second
static void reset_ball(size_t at) {
const uint8_t r = (uint8_t)(128 + rand() % 128);
const uint8_t g = (uint8_t)(128 + rand() % 128);
const uint8_t b = (uint8_t)(128 + rand() % 128);
switch (rand() % 3) {
case 0: balls[at].color = bj_make_bitmap_pixel(framebuffer, 100, g, b); break;
case 1: balls[at].color = bj_make_bitmap_pixel(framebuffer, r, 100, b); break;
default: balls[at].color = bj_make_bitmap_pixel(framebuffer, r, g, 100); break;
}
// Random angle from -90° to 0° (straight up to straight right).
const bj_real angle_rand = (bj_real)rand() / (bj_real)RAND_MAX;
const bj_real angle = -BJ_PI / BJ_F(2.0) + angle_rand * (BJ_PI / BJ_F(2.0));
// Random speed between 100 and 200 pixels/second.
const bj_real magnitude = BJ_F(100.0) + ((bj_real)rand() / (bj_real)RAND_MAX) * BJ_F(100.0);
// Convert angle + magnitude to velocity vector (vx, vy).
balls[at].initial_velocity.x = bj_cos(angle) * magnitude;
balls[at].initial_velocity.y = bj_sin(angle) * magnitude;
balls[at].time_alive = 0;
}
static void initialize_balls() {
// Gravity acceleration: (0, 50) means 50 pixels/second² downward.
// Positive y is down in screen coordinates, so gravity pulls objects down.
// Adjust this value to make physics feel heavier or lighter.
// All balls start from the bottom-left corner.
for(size_t b = 0 ; b < BALLS_LEN ; ++b) {
}
}
// Update physics: accumulate time and compute exact positions using kinematics.
// dt is delta time (seconds since last frame) for frame-rate independence.
static void update(bj_real dt) {
for(size_t b = 0 ; b < BALLS_LEN ; ++b) {
// Track total time since this ball was launched.
balls[b].time_alive += dt;
// bj_compute_kinematics_2d() computes position from:
// - initial_position: where the ball started
// - initial_velocity: how fast it was moving at launch
// - gravity: constant acceleration
// - time_alive: elapsed time since launch
// Returns exact position using: p = p₀ + v₀*t + ½*a*t²
// This is more accurate than integrating velocity frame-by-frame.
balls[b].initial_velocity,
balls[b].time_alive
);
const bj_real x = balls[b].position.x;
const bj_real y = balls[b].position.y;
// Reset balls that leave the screen.
) {
}
}
}
static void draw() {
for(size_t b = 0 ; b < BALLS_LEN ; ++b) {
balls[b].position.x, balls[b].position.y, BALLS_RADIUS,
balls[b].color
);
}
}
int bj_app_begin(void** user_data, int argc, char* argv[]) {
(void)user_data; (void)argc; (void)argv;
srand((unsigned)time(NULL));
return bj_callback_exit_error;
}
window = bj_bind_window("2D Kinematics", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
return bj_callback_continue;
}
int bj_app_iterate(void* user_data) {
(void)user_data;
// bj_step_delay_stopwatch() returns delta time (seconds since last call).
// This ensures physics runs at the same speed regardless of frame rate.
// Critical for consistent projectile motion across different hardware.
draw();
bj_sleep(15);
? bj_callback_exit_success
: bj_callback_continue;
}
int bj_app_end(void* user_data, int status) {
(void)user_data;
bj_end();
return status;
}
int bj_app_begin(void **user_data, int argc, char *argv[])
Definition audio_pcm.c:25
int bj_app_iterate(void *user_data)
Definition audio_pcm.c:60
int bj_app_end(void *user_data, int status)
Definition audio_pcm.c:84
bj_renderer * renderer
Definition bitmap_blit.c:25
bj_window * window
Definition bitmap_blit.c:24
Header file for Bitmap drawing functions.
Sytem event management API.
void bj_clear_bitmap(struct bj_bitmap *bitmap)
Fills the entire bitmap with the clear color.
uint32_t bj_make_bitmap_pixel(struct bj_bitmap *bitmap, uint8_t red, uint8_t green, uint8_t blue)
Returns an opaque value representing a pixel color, given its RGB composition.
struct bj_bitmap bj_bitmap
Definition api.h:270
struct bj_renderer bj_renderer
Definition api.h:288
struct bj_window bj_window
Definition api.h:296
void bj_draw_filled_circle(struct bj_bitmap *bitmap, int cx, int cy, int radius, uint32_t color)
Draw a filled circle onto a bitmap.
void bj_dispatch_events(void)
Poll and dispatch all pending events.
void bj_close_on_escape(struct bj_window *window, const struct bj_key_event *event, void *user_data)
Handle the ESC key to close a window.
bj_key_callback_fn bj_set_key_callback(bj_key_callback_fn callback, void *user_data)
Set the global callback for keyboard key events.
#define BJ_PI
PI in the selected bj_real precision.
Definition math.h:86
#define bj_sin
Sine.
Definition math.h:221
#define bj_cos
Cosine.
Definition math.h:212
#define BJ_F(x)
Literal suffix helper for bj_real when float is selected.
Definition math.h:53
float bj_real
Selected real type for float configuration.
Definition math.h:51
struct bj_vec2: 2D vector of bj_real values.
Definition vec.h:26
struct bj_vec2 bj_compute_kinematics_2d(struct bj_vec2 position, struct bj_vec2 velocity, struct bj_vec2 acceleration, bj_real time)
Integrate constant-acceleration 2D kinematics: position at time t.
void bj_present(struct bj_renderer *renderer, struct bj_window *window)
Present the framebuffer to a window.
struct bj_renderer * bj_create_renderer(enum bj_renderer_type type, struct bj_error **error)
Create a new renderer instance.
struct bj_bitmap * bj_get_framebuffer(struct bj_renderer *renderer)
Get the renderer's framebuffer.
bj_bool bj_renderer_configure(struct bj_renderer *renderer, struct bj_window *window, struct bj_error **error)
Configure a renderer for a specific window.
void bj_destroy_renderer(struct bj_renderer *renderer)
Destroy a renderer and free associated resources.
@ BJ_RENDERER_TYPE_SOFTWARE
Software (CPU-based) renderer.
Definition renderer.h:35
bj_bool bj_begin(int systems, struct bj_error **error)
Initializes the system.
void bj_end(void)
De-initializes the system.
@ BJ_VIDEO_SYSTEM
Definition system.h:20
void bj_sleep(int milliseconds)
Suspends the current thread for a specified duration.
double bj_step_delay_stopwatch(struct bj_stopwatch *stopwatch)
Steps the stopwatch and returns the delay since the previous step.
Structure representing a simple stopwatch.
Definition time.h:97
struct bj_window * bj_bind_window(const char *title, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t flags, struct bj_error **error)
Create a new struct bj_window with the specified attributes.
bj_bool bj_should_close_window(struct bj_window *window)
Get the close flag state of a window.
void bj_unbind_window(struct bj_window *window)
Deletes a struct bj_window object and releases associated memory.
Logging utility functions.
Portable main substitution and application callback facilities.
Physics helpers (SI units, but dimensionally consistent with any unit system).
#define SCREEN_WIDTH
Definition physics_kinematics.c:30
#define BALLS_RADIUS
Definition physics_kinematics.c:38
bj_vec2 gravity
Definition physics_kinematics.c:53
static void initialize_balls()
Definition physics_kinematics.c:85
#define BALLS_LEN
Definition physics_kinematics.c:37
bj_stopwatch stopwatch
Definition physics_kinematics.c:55
static void draw()
Definition physics_kinematics.c:136
#define GRAVITY
Definition physics_kinematics.c:39
struct @211014007150303203366236112264240244270225066002 balls[1000]
#define SCREEN_HEIGHT
Definition physics_kinematics.c:31
static void reset_ball(size_t at)
Definition physics_kinematics.c:61
static void update(bj_real dt)
Definition physics_kinematics.c:103
bj_vec2 initial_position
Definition physics_kinematics.c:54
bj_bitmap * framebuffer
Definition physics_kinematics.c:35
Rendering backend interface.
Header file for system interactions.
Header file for time manipulation utilities.
vector manipulation API
Header file for bj_window type.