96 lines
2.7 KiB
Text
96 lines
2.7 KiB
Text
# 3D Physics Game with Raylib and ODE - Improved with Collision Detection
|
|
# A bouncing cube demo that actually collides with the ground
|
|
|
|
fn main() -> int do
|
|
# Initialize raylib
|
|
init_window(800, 600, "3D Physics Game - Improved")
|
|
defer close_window()
|
|
set_target_fps(60)
|
|
|
|
# Initialize ODE
|
|
ode_init()
|
|
defer ode_close()
|
|
|
|
# Create physics world
|
|
let world = ode_world_create()
|
|
defer ode_world_destroy(world)
|
|
let null_space = 0 as *()
|
|
let space = ode_simple_space_create(null_space) # null parent
|
|
defer ode_space_destroy(space)
|
|
|
|
# Set gravity
|
|
ode_world_set_gravity(world, 0.0, -9.81, 0.0)
|
|
|
|
# Create contact joint group
|
|
let contactgroup = ode_joint_group_create(0)
|
|
defer ode_joint_group_destroy(contactgroup)
|
|
|
|
# Create a cube body
|
|
let body = ode_body_create(world)
|
|
defer ode_body_destroy(body)
|
|
|
|
# Set cube mass (density 1.0, size 1x1x1)
|
|
ode_body_set_box_mass(body, 1.0, 1.0, 1.0, 1.0)
|
|
|
|
# Set initial position (5 units up)
|
|
ode_body_set_position(body, 0.0, 5.0, 0.0)
|
|
|
|
# Create geometry for the cube
|
|
let geom = ode_create_box_geom(space, 1.0, 1.0, 1.0)
|
|
defer ode_geom_destroy(geom)
|
|
|
|
# Attach geometry to body
|
|
ode_geom_set_body(geom, body)
|
|
|
|
# Create ground plane (y = 0)
|
|
let ground_geom = ode_create_plane_geom(space, 0.0, 1.0, 0.0, 0.0)
|
|
defer ode_geom_destroy(ground_geom)
|
|
|
|
# Camera position variables
|
|
let mut camera_pos_x = 0.0
|
|
let mut camera_pos_y = 2.0
|
|
let mut camera_pos_z = 10.0
|
|
|
|
# Cube position variables
|
|
let mut cube_x = 0.0
|
|
let mut cube_y = 0.0
|
|
let mut cube_z = 0.0
|
|
|
|
# Main game loop
|
|
let mut frame_count = 0
|
|
while window_should_close() == false do
|
|
# IMPORTANT: Collision detection must happen BEFORE world step
|
|
ode_space_collide(world, space, contactgroup)
|
|
|
|
# Step physics simulation
|
|
ode_world_step(world, 1.0 / 60.0)
|
|
|
|
# Empty contact group after step to avoid accumulation
|
|
ode_joint_group_empty(contactgroup)
|
|
|
|
# Get cube position
|
|
ode_body_get_position(body, &cube_x, &cube_y, &cube_z)
|
|
|
|
# Drawing
|
|
begin_drawing()
|
|
clear_background(135, 206, 235, 255) # Sky blue
|
|
|
|
begin_mode3d(camera_pos_x, camera_pos_y, camera_pos_z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 45.0, 0)
|
|
|
|
# Draw ground plane
|
|
draw_cube(0.0, -1.0, 0.0, 20.0, 0.1, 20.0, 34, 139, 34, 255) # Green ground
|
|
|
|
# Draw the physics cube
|
|
draw_cube(cube_x, cube_y, cube_z, 1.0, 1.0, 1.0, 255, 0, 0, 255) # Red cube
|
|
|
|
# Draw wireframe for better visibility
|
|
draw_cube_wires(cube_x, cube_y, cube_z, 1.0, 1.0, 1.0, 0, 0, 0, 255)
|
|
|
|
end_mode3d()
|
|
end_drawing()
|
|
|
|
frame_count = frame_count + 1
|
|
end
|
|
|
|
0
|
|
end
|