Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Realistic Physics in a Simple C/C++ Game Using EasyX: Ball Animation with Gravity and Bounce Effects

Tech May 9 3

8. Enhancing Fall and Collision Behavior

The current ball movement uses constant velocity, lacking realistic deceleration during bounces. Introducing basic physics calculations improves the visual fidelity. While professional open-source physics angines like Box2D and PhysX offer advanced simulation capabilities, this section implements simplified physics manually.

1) Improved Display Function

A refined display function includes boundary checks to prevent the ball from moving outside screen limits. Multiple directional bounds can be added as needed.

void render_ball_animation(ball_object_t* ball)
{
    // Clamp position within screen bounds
    if (ball->state->y > SCREEN_HEIGHT - ball->state->radius)
        ball->state->y = SCREEN_HEIGHT - ball->state->radius;
    else if (ball->state->y < ball->state->radius)
        ball->state->y = ball->state->radius;
    else if (ball->state->x > SCREEN_WIDTH - ball->state->radius)
        ball->state->x = SCREEN_WIDTH - ball->state->radius;
    else if (ball->state->x < ball->state->radius)
        ball->state->x = ball->state->radius;

    cleardevice();
    fillcircle((int)ball->state->x, (int)ball->state->y, (int)ball->state->radius);
    Sleep(50);
}
2) Implementing Free-Fall Motion

Replace uniform downward motion with acceleration-based fall. Since mass is not modeled, a constant vertical acceleration simulates gravity.

Physics update logic:

  • Velocity increases by acceleration per frame
  • Position updates based on current velocity
ball->state->velocity_y += ball->state->gravity_accel;
ball->state->y += ball->state->velocity_y * 1; // 1 represents time delta (frame)
3) Adding Damped Bounce Effect

When the ball hits the bottom or top edge, apply energy loss via velocity scaling.

ball->state->velocity_y = -0.95f * ball->state->velocity_y;
4) Complete Falling and Bouncing Sequence

Combine physics update and collision response. Constants are now encapsulated within the animation structure for better maintainability.

void simulate_falling_ball(ball_object_t* ball)
{
    const float ENERGY_LOSS_FACTOR = 0.95f;
    
    ball->state->velocity_y += ball->state->gravity_accel;
    ball->state->y += ball->state->velocity_y;
    
    if (ball->state->y >= SCREEN_HEIGHT - ball->state->radius)
    {
        ball->state->velocity_y = -ENERGY_LOSS_FACTOR * ball->state->velocity_y;
    }
    
    render_ball_animation(ball);
}

9. Creating Parabolic Trajectory Animation

Now implement a more complex animation: parabolic motion.

1) Directional Velocity Components

Instead of using angles and trigonometry, define independent x and y velocity components directly in the state structure.

float velocity_x; // Horizontal speed
float velocity_y; // Vertical speed
2) Parabolic Motion Logic

The ball moves under simulated gravity and rebounds off walls with energy loss:

  • Update position based on current velocities
  • Apply gravity to vertical velocity
  • Reverse direcsion and dampen speed upon wall collision
ball->state->x += ball->state->velocity_x;
ball->state->y += ball->state->velocity_y;
ball->state->velocity_y += GRAVITY; // Simulate gravitational pull

// Handle collisions
if (ball->state->x >= SCREEN_WIDTH - ball->state->radius || ball->state->x <= ball->state->radius)
    ball->state->velocity_x = -K * ball->state->velocity_x;
if (ball->state->y >= SCREEN_HEIGHT - ball->state->radius || ball->state->y <= ball->state->radius)
    ball->state->velocity_y = -K * ball->state->velocity_y;
3) Full Parabolic Animation Functon
void simulate_parabolic_motion(ball_object_t* ball)
{
    const float GRAVITY = 0.8f;
    const float K = 0.95f;
    
    ball->state->x += ball->state->velocity_x;
    ball->state->y += ball->state->velocity_y;
    ball->state->velocity_y += GRAVITY;
    
    // Wall collision detection and response
    if (ball->state->x >= SCREEN_WIDTH - ball->state->radius || ball->state->x <= ball->state->radius)
        ball->state->velocity_x = -K * ball->state->velocity_x;
    if (ball->state->y >= SCREEN_HEIGHT - ball->state->radius || ball->state->y <= ball->state->radius)
        ball->state->velocity_y = -K * ball->state->velocity_y;
    
    render_ball_animation(ball);
}
4) Main Loop Integration

Initialize initial velocity and run animation loop:

ball->state->velocity_x = 10.0f;
ball->state->velocity_y = 0.0f;

while (true)
{
    simulate_parabolic_motion(&ball);
    // simulate_falling_ball(&ball); // Alternative: use simple fall
}

This completes the core graphical behavior of the animated ball. Future improvements include refactoring the object structure to support multiple shapes, replacing Sleep() with a non-blocking timer system, and introducing callback function pointers for event handling. A finalized version will be made available later.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.