LibGDX无限RepeatAction中断及堆叠游戏实现技术咨询
Hey there! Let’s break down how to fix your tower stacking game—first stopping that endless left-right block movement, then adding the satisfying drop when players hit SPACE. Since you’re using libGDX’s Action API (those SequenceAction and RepeatAction calls give it away), here’s a straightforward approach:
First, you need to keep a reference to your infiniteLoop action somewhere accessible (like a class-level variable) so you can target it later to stop the movement. Then, you’ll listen for the SPACE key press to trigger the stop.
Step 1: Store the Loop Reference
Move the infiniteLoop variable to your class scope so it’s not trapped inside a single method:
private RepeatAction infiniteLoop; private Actor block; // Your moving block actor
Step 2: Set Up the Movement (As Before)
Keep your original setup code, but assign the loop to the class variable:
// Initialize the side-to-side sequence SequenceAction overallSequence = new SequenceAction(); overallSequence.addAction(Actions.moveTo(0, block.getY(), 0.5f)); overallSequence.addAction(Actions.moveTo(800 - block.getWidth(), block.getY(), 0.5f)); // Create and start the infinite loop infiniteLoop = new RepeatAction(); infiniteLoop.setCount(RepeatAction.FOREVER); infiniteLoop.setAction(overallSequence); block.addAction(infiniteLoop);
Step 3: Stop the Loop on SPACE Press
In your render() method (or via an InputProcessor), check for the SPACE key and remove the loop action:
if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) { // Stop the endless side-to-side movement block.removeAction(infiniteLoop); // Trigger the block drop (we'll build this next) triggerBlockDrop(); }
Use isKeyJustPressed instead of isKeyPressed to avoid triggering the drop multiple times if the player holds SPACE.
To make the block fall, you’ll need to track your tower’s current height, calculate where the block should land, and add a falling action. After the drop finishes, you’ll update the tower and restart the cycle with a new block.
Step 1: Track Tower Height
Add a class variable to keep track of how tall your tower is:
private float currentTowerHeight = 0; // Starts at 0 (empty tower)
Step 2: Build the Drop Action
Create a method to handle the fall and post-drop logic:
private void triggerBlockDrop() { // Calculate where the block should land: its bottom aligns with the tower's top float targetY = currentTowerHeight; float fallDuration = 0.3f; // Adjust for faster/slower falls // Create a sequence for the drop + post-drop cleanup SequenceAction dropSequence = new SequenceAction(); // Add smooth falling movement dropSequence.addAction(Actions.moveTo(block.getX(), targetY, fallDuration)); // Run logic after the drop finishes dropSequence.addAction(Actions.run(() -> { // Update the tower height with the block's height currentTowerHeight += block.getHeight(); // Optional: Add alignment checks here (e.g., if block is off-center, game over) // Spawn a new block and restart the side-to-side loop spawnNewBlock(); })); // Start the drop block.addAction(dropSequence); }
Step 3: Reset for the Next Block
Create a method to spawn a new block (or reset the existing one) and restart the movement loop:
private void spawnNewBlock() { // Reset the block to the top-left of the screen (adjust as needed) block.setPosition(0, Gdx.graphics.getHeight() - block.getHeight()); // Recreate the infinite side-to-side sequence SequenceAction overallSequence = new SequenceAction(); overallSequence.addAction(Actions.moveTo(0, block.getY(), 0.5f)); overallSequence.addAction(Actions.moveTo(800 - block.getWidth(), block.getY(), 0.5f)); infiniteLoop = new RepeatAction(); infiniteLoop.setCount(RepeatAction.FOREVER); infiniteLoop.setAction(overallSequence); // Restart the movement block.addAction(infiniteLoop); }
Bonus: Realistic Falling
If you want gravity-like acceleration instead of a fixed-duration fall, replace the moveTo action with an acceleration action:
dropSequence.addAction(Actions.accelerateTo(0, -600, 1000)); // Adjust values for desired gravity
内容的提问来源于stack exchange,提问作者mateusz3721

