Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[module] Raylib misses mouse clicks #4749

Closed
4 tasks done
timo-scaleio opened this issue Feb 2, 2025 · 5 comments
Closed
4 tasks done

[module] Raylib misses mouse clicks #4749

timo-scaleio opened this issue Feb 2, 2025 · 5 comments

Comments

@timo-scaleio
Copy link


Please, before submitting a new issue verify and check:

  • I tested it on latest raylib version from master branch
  • I checked there is no similar issue already reported
  • I checked the documentation on the wiki
  • My code has no errors or misuse of raylib

Issue description

While working on a game idea I noticed that mouse clicks don't get registered properly. I wrote a much simplified version of the game loop in Go and in C and observed the same problem.

Basically when you click "swiftly" the code below doesn't always print when the mouse button is pressed. When you hold the button for a bit it does print every time.

Furthermore if you set the frame-rate to 0 (no wait) then it works all the time even with swift presses. I haven't tested if there was actual "rendering load" if it would still work all the time... but in my dumbed down, no-render version it does.

We had a chat with @JeffM2501 in Discord here https://discord.com/channels/426912293134270465/1335478227551912016

The Go library I used packages Raylib-5.5 and I installed Raylib-5.5 through Brew as well for the C version.

Environment

  • Chip: Apple M2 Max
  • MacOS: 14.6.1 (23G93)

Code Example

Go Version:


package main

import (
	"fmt"
	rl "github.com/gen2brain/raylib-go/raylib"
)

const (
	windowTitle         = "Test"
	defaultScreenWidth  = 1024
	defaultScreenHeight = 720
)

var (
	screenWidth  int32 = defaultScreenWidth
	screenHeight int32 = defaultScreenHeight
)

func watchWindowResize() {
	screenWidth = int32(rl.GetScreenWidth())
	screenHeight = int32(rl.GetScreenHeight())
}

func watchUserInput() {
	if rl.IsMouseButtonPressed(rl.MouseButtonLeft) {
		fmt.Printf("left mouse button pressed\n")
	}

	if rl.IsMouseButtonDown(rl.MouseButtonLeft) {
		fmt.Printf("left mouse button down\n")
	}

	if rl.IsMouseButtonUp(rl.MouseButtonLeft) {
		fmt.Printf("left mouse button up\n")
	}

	if rl.IsMouseButtonReleased(rl.MouseButtonLeft) {
		fmt.Printf("left mouse button released\n")
	}
}

func main() {
	rl.SetConfigFlags(rl.FlagWindowResizable)
	rl.InitWindow(screenWidth, screenHeight, windowTitle)
	rl.SetTargetFPS(60)

	camera := rl.Camera3D{
		Position:   rl.NewVector3(0.0, 0.0, 0.0),
		Target:     rl.NewVector3(0.0, 0.0, 0.0),
		Up:         rl.NewVector3(0.0, 1.0, 0.0),
		Fovy:       45.0,
		Projection: rl.CameraPerspective,
	}

	for !rl.WindowShouldClose() {
		watchWindowResize()
		watchUserInput()

		rl.BeginDrawing()
		rl.ClearBackground(rl.RayWhite)

		rl.BeginMode3D(camera)

		rl.EndMode3D()

		rl.DrawFPS(10, 10)

		rl.EndDrawing()
	}

	rl.CloseWindow()
}


C Version


#include "raylib.h"
#include <stdio.h>

int main(void) {
    const int screenWidth = 1024;
    const int screenHeight = 720;
    InitWindow(screenWidth, screenHeight, "Test");
    SetTargetFPS(60);

    while (!WindowShouldClose()) {

        if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
            printf("Left mouse button pressed\n");

        if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
            printf("Left mouse button released\n");

        BeginDrawing();

        ClearBackground(RAYWHITE);

        DrawFPS(10, 10);

        EndDrawing();
    }

    CloseWindow();

    return 0;
}


@timo-scaleio timo-scaleio changed the title [module] Raylib missed mouse clicks [module] Raylib misses mouse clicks Feb 2, 2025
@JeffM2501
Copy link
Contributor

The core issue seems to stem from the polling nature of raylib's input handling in the game loop.
The simplest solution would be add an event queue function for mouse buttons like we have for keys.
GetMouseButtonPressed, just like we have GetKeyPressed. This could provide the list of mouse up and down events that happened during a frame for the users that need that info instead of just the current state.

@veins1
Copy link
Contributor

veins1 commented Feb 2, 2025

It seems like it's the same issue as #4591 but with mouse buttons. The solution is the same and as Jeff said

an event queue function for mouse buttons like we have for keys.

is also needed for those who want exact events.

@raysan5
Copy link
Owner

raysan5 commented Feb 2, 2025

This potential issue could be addressed polling the inputs manually in a second thread. The provided custom_frame_control example could be used as a reference.

Note that hardly any user has reported having problems with current mouse input system in +11 years and redesigning the mouse input system to address a very specific sounds as overengineering to me and implies more complexity and more maintenance cost.

@raysan5 raysan5 closed this as completed Feb 2, 2025
@timo-scaleio
Copy link
Author

timo-scaleio commented Feb 2, 2025 via email

@timo-scaleio
Copy link
Author

timo-scaleio commented Feb 2, 2025

Hi,

I implemented the solutiuon above but the mouse events are still missed. This doesn't seem to address the same problem I reported.

package main

import (
	"fmt"
	rl "github.com/gen2brain/raylib-go/raylib"
)

const (
	windowTitle         = "Test"
	defaultScreenWidth  = 1280
	defaultScreenHeight = 1024
)

func watchUserInput() {
	if rl.IsMouseButtonPressed(rl.MouseButtonLeft) {
		fmt.Printf("left mouse button pressed\n")
	}

	if rl.IsMouseButtonDown(rl.MouseButtonLeft) {
		fmt.Printf("left mouse button down\n")
	}

	if rl.IsMouseButtonUp(rl.MouseButtonLeft) {
		fmt.Printf("left mouse button up\n")
	}

	if rl.IsMouseButtonReleased(rl.MouseButtonLeft) {
		fmt.Printf("left mouse button released\n")
	}
}

func main() {
	ScreenWidth:=  int32(defaultScreenWidth)
	ScreenHeight:= int32(defaultScreenHeight)

	rl.SetConfigFlags(rl.FlagWindowResizable | rl.FlagBorderlessWindowedMode | rl.FlagWindowUndecorated)
	rl.InitWindow(ScreenWidth, ScreenHeight, windowTitle)
	rl.SetTargetFPS(144)

	var previousTime = time.Now()
	var currentTime = time.Now()

	var updateDrawTime time.Duration = 0.0
	var waitTime float64 = 0.0

	var deltaTime time.Duration = 0
	var timeCounter float64 = 0
	var position rl.Vector3 = rl.Vector3{X: 0, Y: 0, Z: 0}
	var pause bool = false
	var targetFPS int = 60

	Camera:= rl.Camera3D{
		Position:   rl.NewVector3(0, 0, 0),
		Target:     rl.NewVector3(0, 0, 0),
		Up:         rl.NewVector3(0.0, 0, 1.0),
		Fovy:       60.0,
		Projection: rl.CameraPerspective,
	}
	
	for !rl.WindowShouldClose() {
		rl.PollInputEvents()

		watchUserInput()

		if !pause {
			position = rl.Vector3{
				X: position.X + float32(10*deltaTime),
				Y: position.Y + float32(10*deltaTime),
				Z: position.Z + float32(10*deltaTime),
			}
			if position.X >= float32(rl.GetScreenWidth()) {
				position = rl.Vector3{X: 0, Y: 0, Z: 0}
			}
			timeCounter += deltaTime.Seconds()
		}

		rl.BeginDrawing()
		rl.ClearBackground(rl.Black)

		rl.BeginMode3D(Camera)

		rl.EndMode3D()

		rl.DrawFPS(10, 10)

		rl.EndDrawing()

		rl.SwapScreenBuffer()

		currentTime = time.Now()
		updateDrawTime = currentTime.Sub(previousTime)

		if targetFPS > 0 {
			waitTime = float64(1)/float64(targetFPS) - updateDrawTime.Seconds()
			if waitTime > 0.0 {
				rl.WaitTime(waitTime)
				currentTime = time.Now()
				deltaTime = currentTime.Sub(previousTime)
			}
		} else {
			deltaTime = updateDrawTime
		}

		previousTime = currentTime
	}

	rl.CloseWindow()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants