odin-blend2d

Odin bindings to Blend2D
Log | Files | Refs | README | LICENSE

main.odin (2743B)


      1 // Odin + Box2D + Raylib example with stacking boxes and a shape attached to the cursor that can smack the shapes.
      2 // Made (mostly) during this stream: https://www.youtube.com/watch?v=LYW7jdwEnaI
      3 
      4 // I have updated this to use the `vendor:box2d` bindings instead of the ones I used on the stream.
      5 
      6 package game
      7 
      8 import b2 "../box2d"
      9 import rl "vendor:raylib"
     10 import "core:math"
     11 
     12 create_box :: proc(world_id: b2.WorldId, pos: b2.Vec2) -> b2.BodyId{
     13 	body_def := b2.DefaultBodyDef()
     14 	body_def.type = .dynamicBody
     15 	body_def.position = pos
     16 	body_id := b2.CreateBody(world_id, body_def)
     17 
     18 	shape_def := b2.DefaultShapeDef()
     19 	shape_def.density = 1
     20 	shape_def.friction = 0.3
     21 
     22 	box := b2.MakeBox(20, 20)
     23 	box_def := b2.DefaultShapeDef()
     24 	_ = b2.CreatePolygonShape(body_id, box_def, box)
     25 
     26 	return body_id
     27 }
     28 
     29 main :: proc() {
     30 	rl.InitWindow(1280, 720, "Box2D + Raylib example")
     31 
     32 	world_def := b2.DefaultWorldDef()
     33 	world_def.gravity = b2.Vec2{0, -1}
     34 	world_id := b2.CreateWorld(world_def)
     35 	defer b2.DestroyWorld(world_id)
     36 
     37 	ground := rl.Rectangle {
     38 		0, 600,
     39 		1280, 120,
     40 	}
     41 
     42 	ground_body_def := b2.DefaultBodyDef()
     43 	ground_body_def.position = b2.Vec2{ground.x, -ground.y-ground.height}
     44 	ground_body_id := b2.CreateBody(world_id, ground_body_def)
     45 
     46 	ground_box := b2.MakeBox(ground.width, ground.height)
     47 	ground_shape_def := b2.DefaultShapeDef()
     48 	_ = b2.CreatePolygonShape(ground_body_id, ground_shape_def, ground_box)
     49 
     50 	bodies: [dynamic]b2.BodyId
     51 
     52 	px: f32 = 400
     53 	py: f32 = -400
     54 
     55 	num_per_row := 10
     56 	num_in_row := 0
     57 
     58 	for _ in 0..<50 {
     59 		b := create_box(world_id, {px, py})
     60 		append(&bodies, b)
     61 		num_in_row += 1
     62 
     63 		if num_in_row == num_per_row {
     64 			py += 30
     65 			px = 200
     66 			num_per_row -= 1
     67 			num_in_row = 0
     68 		}
     69 
     70 		px += 30
     71 	}
     72 
     73 	body_def := b2.DefaultBodyDef()
     74 	body_def.type = .dynamicBody
     75 	body_def.position = b2.Vec2{0, 4}
     76 	body_id := b2.CreateBody(world_id, body_def)
     77 
     78 	shape_def := b2.DefaultShapeDef()
     79 	shape_def.density = 1000
     80 	shape_def.friction = 0.3
     81 
     82 	circle: b2.Circle
     83 	circle.radius = 40
     84 	_ = b2.CreateCircleShape(body_id, shape_def, circle)
     85 
     86 	time_step: f32 = 1.0 / 60
     87 	sub_steps: i32 = 4
     88 
     89 	for !rl.WindowShouldClose() {
     90 		rl.BeginDrawing()
     91 		rl.ClearBackground(rl.BLACK)
     92 
     93 		rl.DrawRectangleRec(ground, rl.RED)
     94 		mouse_pos := rl.GetMousePosition()
     95 
     96 		b2.Body_SetTransform(body_id, {mouse_pos.x, -mouse_pos.y}, {})
     97 		b2.World_Step(world_id, time_step, sub_steps)
     98 
     99 		for b in bodies {
    100 			position := b2.Body_GetPosition(b)
    101 			r := b2.Body_GetRotation(b)
    102 			a := math.atan2(r.s, r._c)
    103 			// Y position is flipped because raylib has Y down and box2d has Y up.
    104 			rl.DrawRectanglePro({position.x, -position.y, 40, 40}, {20, 20}, a*(180/3.14), rl.YELLOW)
    105 		}
    106 
    107 		rl.DrawCircleV(mouse_pos, 40, rl.MAGENTA)
    108 		rl.EndDrawing()	
    109 	}
    110 
    111 	rl.CloseWindow()
    112 }