You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LWJGL开发问题:生成Tile后ArrayList为空+鼠标点击添加Quad失效

LWJGL Troubleshooting: Tile List Issues, Left-Click Quad Addition, and Mouse Click/Long Press Differentiation

Hey there, let's work through your LWJGL problems one by one—these are all common hurdles, so I’ve got practical fixes and explanations for each:

1. Tile ArrayList Appears Empty After Generation

First up, if you’re sure the Tile objects are being created successfully and you’re reading the list after generation, the most likely culprit is variable shadowing or an incorrect reference.

Common Cause:

You might be initializing a local ArrayList<Tile> inside your generation method instead of using the class-level member variable. For example:

// Class-level member (intended list)
private ArrayList<Tile> tiles;

public void generateTiles() {
    // Oops—this creates a new local list instead of using the member variable
    ArrayList<Tile> tiles = new ArrayList<>();
    tiles.add(new Tile(x, y, texture));
}

In this case, the member variable tiles is never actually populated—you’re just adding Tiles to a temporary list that gets discarded when the method finishes.

Fix:

  • Ensure you’re initializing and modifying the same ArrayList instance across your code. Correct the generation method to use the member variable:
    public void generateTiles() {
        tiles = new ArrayList<>(); // Initialize the member variable
        tiles.add(new Tile(x, y, texture));
        // Verify with a print statement to confirm population
        System.out.println("Generated " + tiles.size() + " tiles");
    }
    
  • Double-check that you’re not reinitializing the list elsewhere in your code (e.g., in a render loop) before reading it.

2. Left-Click Quad Addition Not Working (But Other Additions Are)

If your drawQuads list works for other Quad additions but fails on left-click, the issue is almost certainly in your mouse input handling logic or coordinate conversion.

Possible Causes & Fixes:

  1. Incorrect Mouse Button Check:
    Make sure you’re using the correct GLFW constant for left-click. In LWJGL, the left mouse button is GLFW_MOUSE_BUTTON_LEFT. A common mistake is using the wrong integer value (e.g., 1 instead of the constant).

    glfwSetMouseButtonCallback(window, (window, button, action, mods) -> {
        // Correct check for left-click press
        if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
            // Add your Quad here
            drawQuads.add(new Quad(mouseX, mouseY, 20, 20));
            // Confirm the list is being updated
            System.out.println("Quad added! List size: " + drawQuads.size());
        }
    });
    
  2. Unconverted Screen Coordinates:
    GLFW returns mouse positions in screen space (top-left origin, pixel values). If your drawQuads uses world/orthographic coordinates, you need to convert the screen position to match your rendering space. For example, with an orthographic projection:

    // Get raw screen coordinates
    double screenX = glfwGetCursorPosX(window);
    double screenY = glfwGetCursorPosY(window);
    
    // Convert to orthographic world coordinates (adjust values to match your projection)
    float worldX = (float)(screenX / windowWidth * orthoWidth - orthoWidth / 2);
    // Flip Y-axis since screen Y starts at top, but ortho Y often starts at bottom
    float worldY = (float)((windowHeight - screenY) / windowHeight * orthoHeight - orthoHeight / 2);
    
    drawQuads.add(new Quad(worldX, worldY, 20, 20));
    
  3. Invisible Quad:
    If the Quad is being added but not rendering, check if its color matches the background, or if its size/position is set to 0 (making it invisible).

3. Differentiating Single Clicks vs. Long Presses

To separate single clicks and long presses, you’ll need to track the duration of the mouse press and trigger actions based on that. Here’s a robust implementation:

Step-by-Step Implementation:

  1. Add these class-level variables to track state:

    private long pressStartTime;
    private boolean isLongPressTriggered = false;
    private boolean isLeftMousePressed = false;
    // Adjust these thresholds to your needs (in milliseconds)
    private static final long LONG_PRESS_THRESHOLD = 250; // Time needed to count as long press
    private static final long LONG_PRESS_REPEAT_INTERVAL = 100; // Repeat interval for long press actions
    private long lastLongPressActionTime = 0;
    
  2. Update your mouse button callback to set initial state:

    glfwSetMouseButtonCallback(window, (window, button, action, mods) -> {
        if (button == GLFW_MOUSE_BUTTON_LEFT) {
            if (action == GLFW_PRESS) {
                isLeftMousePressed = true;
                pressStartTime = System.currentTimeMillis();
                isLongPressTriggered = false;
                lastLongPressActionTime = pressStartTime;
            } else if (action == GLFW_RELEASE) {
                isLeftMousePressed = false;
                long pressDuration = System.currentTimeMillis() - pressStartTime;
                // Trigger single click only if long press wasn't activated
                if (pressDuration < LONG_PRESS_THRESHOLD && !isLongPressTriggered) {
                    performSingleClickAction();
                }
            }
        }
    });
    
  3. Add logic to your main render loop to handle long presses:

    while (!glfwWindowShouldClose(window)) {
        // ... Your existing render/update logic ...
    
        if (isLeftMousePressed) {
            long currentTime = System.currentTimeMillis();
            if (!isLongPressTriggered) {
                // Check if we've crossed the long press threshold
                if (currentTime - pressStartTime >= LONG_PRESS_THRESHOLD) {
                    isLongPressTriggered = true;
                    performLongPressStartAction();
                    lastLongPressActionTime = currentTime;
                }
            } else {
                // Repeat long press action at the specified interval
                if (currentTime - lastLongPressActionTime >= LONG_PRESS_REPEAT_INTERVAL) {
                    performLongPressRepeatAction();
                    lastLongPressActionTime = currentTime;
                }
            }
        }
    
        // ... Swap buffers, poll events, etc. ...
    }
    
  4. Replace the placeholder methods with your actual logic:

    private void performSingleClickAction() {
        // Code for single click (e.g., place a tile)
        System.out.println("Single click detected!");
    }
    
    private void performLongPressStartAction() {
        // Code for initial long press trigger (e.g., start deleting tiles)
        System.out.println("Long press started!");
    }
    
    private void performLongPressRepeatAction() {
        // Code for repeated long press action (e.g., delete tiles continuously)
        System.out.println("Long press repeating...");
    }
    

This setup ensures single clicks only fire if the press is short, and long presses trigger both an initial action and repeated actions if held.


内容的提问来源于stack exchange,提问作者Frost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:02:08