Przeglądaj źródła

JS mouse events and bunnymark that works in browser

Karl Zylinski 2 miesięcy temu
rodzic
commit
eaf7a6338d

+ 2 - 1
.gitignore

@@ -5,4 +5,5 @@ raylib/
 *.exe
 *.rdi
 !/.sublime/karl2d.sublime-project
-examples/*/web
+examples/*/web
+examples/raylib_ports/*/web

+ 6 - 1
.sublime/karl2d.sublime-project

@@ -17,7 +17,7 @@
 					"working_dir": "$project_path/../examples/minimal"
 				},
 				{
-					"name": "web example",
+					"name": "minimal (web)",
 					"shell_cmd": "odin run build_web_example -- minimal",
 					"working_dir": "$project_path/../examples"
 				},
@@ -81,6 +81,11 @@
 					"shell_cmd": "odin run . -vet -strict-style -no-bounds-check -keep-executable",
 					"working_dir": "$project_path/../examples/raylib_ports/bunnymark"
 				},
+				{
+					"name": "bunnymark (web)",
+					"shell_cmd": "odin run build_web_example -- raylib_ports/bunnymark",
+					"working_dir": "$project_path/../examples"
+				},
 				{
 					"name": "gamepad",
 					"shell_cmd": "odin run . -vet -strict-style -keep-executable",

+ 4 - 2
examples/build_web_example/build_web_example.odin

@@ -30,9 +30,11 @@ main :: proc() {
 
 	web_build_dir := filepath.join({web_dir, "build"})
 
+	os.make_directory(web_build_dir, 0o644)
+
 	os.write_entire_file(
 		filepath.join(
-			{web_dir, fmt.tprintf("%v_web_entry.odin", dir)},
+			{web_dir, fmt.tprintf("%v_web_entry.odin", filepath.stem(dir))},
 		),
 		WEB_ENTRY_TEMPLATE,
 	)
@@ -61,7 +63,7 @@ main :: proc() {
 			web_dir,
 			fmt.tprintf("-out:%v", wasm_out_path),
 			"-target:js_wasm32",
-			"-debug",
+			"-o:speed",
 			"-vet",
 			"-strict-style",
 		},

+ 73 - 57
examples/raylib_ports/bunnymark/bunnymark.odin

@@ -18,83 +18,99 @@ Bunny :: struct {
 	color: k2.Color,
 }
 
-main :: proc() {
-	context.logger = log.create_console_logger()
+bunnies: [dynamic]Bunny
+tex_bunny: k2.Texture
 
+init :: proc() {
 	SCREEN_WIDTH :: 800
 	SCREEN_HEIGHT :: 450
 
 	k2.init(SCREEN_WIDTH, SCREEN_HEIGHT, "bunnymark (raylib port)", window_creation_flags = { .Resizable })
+	tex_bunny = k2.load_texture_from_bytes(#load("wabbit_alpha.png"))
+}
 
-	tex_bunny := k2.load_texture_from_file("wabbit_alpha.png")
+step :: proc(dt: f32) -> bool {
+	if k2.mouse_button_is_held(.Left) {
+		for _ in 0..<100 {
+			append(&bunnies, Bunny {
+				position = k2.get_mouse_position(),
+				speed = {
+					rand.float32_range(-250, 250)/60,
+					rand.float32_range(-250, 250)/60,
+				},
+				rot_speed = rand.float32_range(-5, 5),
+				color = {
+					u8(rand.int_max(190) + 50),
+					u8(rand.int_max(160) + 80),
+					u8(rand.int_max(140) + 100),
+					255,
+				},
+			})
+		}
+	}
 
-	bunnies: [dynamic]Bunny
-	prev_time := time.now()
+	for &b in bunnies {
+		b.position += b.speed
+		b.rot += b.rot_speed
 
-	for !k2.shutdown_wanted() {
-		cur_time := time.now()
-		dt := f32(time.duration_seconds(time.diff(prev_time, cur_time)))
-		prev_time = cur_time
+		if b.position.x > f32(k2.get_screen_width()) || b.position.x < 0 {
+			b.speed.x *= -1
+			b.rot_speed = rand.float32_range(-5, 5)
+		}
 
-		if k2.mouse_button_is_held(.Left) {
-			for _ in 0..<100 {
-				append(&bunnies, Bunny {
-					position = k2.get_mouse_position(),
-					speed = {
-						rand.float32_range(-250, 250)/60,
-						rand.float32_range(-250, 250)/60,
-					},
-					rot_speed = rand.float32_range(-5, 5),
-					color = {
-						u8(rand.int_max(190) + 50),
-						u8(rand.int_max(160) + 80),
-						u8(rand.int_max(140) + 100),
-						255,
-					},
-				})
-			}
+		if b.position.y > f32(k2.get_screen_height()) || b.position.y < 0 {
+			b.speed.y *= -1
+			b.rot_speed = rand.float32_range(-5, 5)
 		}
+	}
 
-		for &b in bunnies {
-			b.position += b.speed
-			b.rot += b.rot_speed
+	k2.process_events()
+	k2.clear(k2.RL_WHITE)
 
-			if b.position.x > f32(k2.get_screen_width()) || b.position.x < 0 {
-				b.speed.x *= -1
-				b.rot_speed = rand.float32_range(-5, 5)
-			}
+	src := k2.Rect {
+		0, 0,
+		f32(tex_bunny.width), f32(tex_bunny.height),
+	}
 
-			if b.position.y > f32(k2.get_screen_height()) || b.position.y < 0 {
-				b.speed.y *= -1
-				b.rot_speed = rand.float32_range(-5, 5)
-			}
-		}
+	for &b in bunnies {
+		dest := src
+		dest.x = b.position.x 
+		dest.y = b.position.y
+		k2.draw_texture_ex(tex_bunny, src, dest, {dest.w/2, dest.h/2}, b.rot, b.color)
+	}
+	
+	if k2.key_went_down(.B) {
+		fmt.println(len(bunnies))
+		fmt.println(1/dt)
+	}
 
-		k2.process_events()
-		k2.clear(k2.RL_WHITE)
+	k2.draw_text(fmt.tprintf("num bunnies: %v -- fps: %v", len(bunnies), 1/dt), {10, 20}, 40, k2.BLACK)
 
-		src := k2.Rect {
-			0, 0,
-			f32(tex_bunny.width), f32(tex_bunny.height),
-		}
+	k2.present()
 
-		for &b in bunnies {
-			dest := src
-			dest.x = b.position.x 
-			dest.y = b.position.y
-			k2.draw_texture_ex(tex_bunny, src, dest, {dest.w/2, dest.h/2}, b.rot, b.color)
-		}
-		
-		if k2.key_went_down(.B) {
-			fmt.println(len(bunnies))
-			fmt.println(1/dt)
-		}
+	free_all(context.temp_allocator)
 
-		k2.present()
-	}
+	return true
+}
 
+shutdown :: proc() {
 	delete(bunnies)
 	k2.destroy_texture(tex_bunny)
 
 	k2.shutdown()
+}
+
+main :: proc() {
+	context.logger = log.create_console_logger()
+	init()
+	prev_time := time.now()
+
+	for !k2.shutdown_wanted() {
+		cur_time := time.now()
+		dt := f32(time.duration_seconds(time.diff(prev_time, cur_time)))
+		prev_time = cur_time
+		step(dt)
+	}
+
+	shutdown()
 }

+ 1 - 1
examples/snake/snake.odin

@@ -65,7 +65,7 @@ main :: proc() {
 	context.logger = log.create_console_logger()
 
 	when ODIN_DEBUG {
-		track: mem.Tracking_Allocator
+		track: mem.Tracking_Allocatorx	
 		mem.tracking_allocator_init(&track, context.allocator)
 		context.allocator = mem.tracking_allocator(&track)
 

+ 44 - 1
window_js.odin

@@ -47,17 +47,60 @@ js_init :: proc(
 
 	// The browser window probably has some other size than what was sent in.
 	if .Resizable in flags {
-		js.add_window_event_listener(.Resize, nil, js_window_event_resize, true)
+		add_global_event_listener(.Resize, js_window_event_resize)
 		update_canvas_size(s.canvas_id)
 	} else {
 		js_set_size(window_width, window_height)
 	}
+
+	add_event_listener(.Mouse_Move, js_window_event_mouse_move)
+	add_event_listener(.Mouse_Down, js_window_event_mouse_down)
+	add_event_listener(.Mouse_Up, js_window_event_mouse_up)
+}
+
+// These events fire even when the tab isn't in focus
+add_global_event_listener :: proc(evt: js.Event_Kind, callback: proc(e: js.Event)) {
+	js.add_window_event_listener(
+		evt, 
+		nil, 
+		callback,
+		true,
+	)
+}
+
+add_event_listener :: proc(evt: js.Event_Kind, callback: proc(e: js.Event)) {
+	js.add_event_listener(
+		s.canvas_id, 
+		evt, 
+		nil, 
+		callback,
+		true,
+	)
 }
 
 js_window_event_resize :: proc(e: js.Event) {
 	update_canvas_size(s.canvas_id)
 }
 
+js_window_event_mouse_move :: proc(e: js.Event) {
+	dpi := js.device_pixel_ratio()
+	append(&s.events, Window_Event_Mouse_Move {
+		position = {f32(e.mouse.client.x) * f32(dpi), f32(e.mouse.client.y) * f32(dpi)},
+	})
+}
+
+js_window_event_mouse_down :: proc(e: js.Event) {
+	append(&s.events, Window_Event_Mouse_Button_Went_Down {
+		button = .Left,
+	})
+}
+
+js_window_event_mouse_up :: proc(e: js.Event) {
+	append(&s.events, Window_Event_Mouse_Button_Went_Up {
+		button = .Left,
+	})
+}
+
 update_canvas_size :: proc(canvas_id: HTML_Canvas_ID) {
 	rect := js.get_bounding_client_rect(canvas_id)
 	dpi := js.device_pixel_ratio()