karl2d_box2d.odin 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package karl2d_box2d_example
  2. import b2 "vendor:box2d"
  3. import k2 "../.."
  4. import "core:math"
  5. import "core:log"
  6. world_id: b2.WorldId
  7. time_acc: f32
  8. circle_body_id: b2.BodyId
  9. bodies: [dynamic]b2.BodyId
  10. GROUND :: k2.Rect {
  11. 0, 600,
  12. 1280, 120,
  13. }
  14. main :: proc() {
  15. context.logger = log.create_console_logger()
  16. init()
  17. run := true
  18. for run {
  19. run = step()
  20. }
  21. shutdown()
  22. }
  23. init :: proc() {
  24. k2.init(1280, 720, "Karl2D + Box2D example")
  25. b2.SetLengthUnitsPerMeter(40)
  26. world_def := b2.DefaultWorldDef()
  27. world_def.gravity = b2.Vec2{0, -900}
  28. world_id = b2.CreateWorld(world_def)
  29. ground_body_def := b2.DefaultBodyDef()
  30. ground_body_def.position = b2.Vec2{GROUND.x, -GROUND.y-GROUND.h}
  31. ground_body_id := b2.CreateBody(world_id, ground_body_def)
  32. ground_box := b2.MakeBox(GROUND.w, GROUND.h)
  33. ground_shape_def := b2.DefaultShapeDef()
  34. _ = b2.CreatePolygonShape(ground_body_id, ground_shape_def, ground_box)
  35. px: f32 = 400
  36. py: f32 = -400
  37. num_per_row := 10
  38. num_in_row := 0
  39. for _ in 0..<50 {
  40. b := create_box(world_id, {px, py})
  41. append(&bodies, b)
  42. num_in_row += 1
  43. if num_in_row == num_per_row {
  44. py += 30
  45. px = 200
  46. num_per_row -= 1
  47. num_in_row = 0
  48. }
  49. px += 30
  50. }
  51. body_def := b2.DefaultBodyDef()
  52. body_def.type = .dynamicBody
  53. body_def.position = b2.Vec2{0, 4}
  54. circle_body_id = b2.CreateBody(world_id, body_def)
  55. shape_def := b2.DefaultShapeDef()
  56. shape_def.density = 1000
  57. shape_def.material.friction = 0.3
  58. circle: b2.Circle
  59. circle.radius = 40
  60. _ = b2.CreateCircleShape(circle_body_id, shape_def, circle)
  61. }
  62. create_box :: proc(world_id: b2.WorldId, pos: b2.Vec2) -> b2.BodyId{
  63. body_def := b2.DefaultBodyDef()
  64. body_def.type = .dynamicBody
  65. body_def.position = pos
  66. body_id := b2.CreateBody(world_id, body_def)
  67. shape_def := b2.DefaultShapeDef()
  68. shape_def.density = 1
  69. shape_def.material.friction = 0.3
  70. box := b2.MakeBox(20, 20)
  71. box_def := b2.DefaultShapeDef()
  72. _ = b2.CreatePolygonShape(body_id, box_def, box)
  73. return body_id
  74. }
  75. step :: proc() -> bool {
  76. k2.new_frame()
  77. dt := k2.get_frame_time()
  78. time_acc += dt
  79. k2.process_events()
  80. k2.clear(k2.GRAY)
  81. k2.draw_rect(GROUND, k2.GREEN)
  82. pos := k2.get_mouse_position()
  83. b2.Body_SetTransform(circle_body_id, {pos.x, -pos.y}, {})
  84. SUB_STEPS :: 4
  85. TIME_STEP :: 1.0 / 60
  86. for time_acc >= TIME_STEP {
  87. b2.World_Step(world_id, TIME_STEP, SUB_STEPS)
  88. time_acc -= TIME_STEP
  89. }
  90. for b in bodies {
  91. position := b2.Body_GetPosition(b)
  92. r := b2.Body_GetRotation(b)
  93. a := math.atan2(r.s, r.c)
  94. // Y position is flipped because raylib has Y down and box2d has Y up.
  95. k2.draw_rect_ex({position.x, -position.y, 40, 40}, {20, 20}, a*(180/3.14), k2.RL_YELLOW)
  96. }
  97. k2.draw_circle(pos, 40, k2.RL_MAGENTA)
  98. k2.present()
  99. free_all(context.temp_allocator)
  100. return !k2.shutdown_wanted()
  101. }
  102. shutdown :: proc() {
  103. b2.DestroyWorld(world_id)
  104. k2.shutdown()
  105. }