Mouse-Controlled Movement – Click to Select & Move in LibGdx

In my sixteenth video of the “Building a Game Development Framework” series, I focus on adding background image handling and implementing mouse-controlled movements for game objects.

I introduce a formalized approach to handling game backgrounds via a new Background interface and a FixedBackground implementation.

  • Separation from Collisions: Backgrounds are treated as purely visual elements. They are rendered behind all other objects (such as game pieces), and the system does not test for physical collisions with them.
  • Tiling and Stretching: The FixedBackground can either “stretch” to fill the entire screen or “tile” an image (repeat it) if the original asset is smaller than the display area. I demonstrate this by using a checkerboard pattern.
  • Viewport Syncing: The background logic includes a screenOrigin setting to keep the background fixed relative to the player’s view, even if the game camera moves.

I have updated the core feature with a specialized movement class that lets users move actors with the mouse. In this video, I show how to “pick up” a chip and move it.

  • Selection Logic: The system uses a contains(x, y) check to determine if the user’s mouse click is physically over the actor’s bounding box.
  • Two Interaction Modes:
    • Hold-to-Drag: The actor moves only while the mouse button is held down.
    • Click-to-Toggle: Clicking once “attaches” the actor to the cursor, and clicking a second time “drops” it.
  • Offset Handling: To prevent the actor from “snapping” its top-left corner to the cursor, the movement class calculates the exact offset of where the user clicked relative to the sprite’s center. This ensures the drag feels smooth and natural.

I show how the drag movement interacts with the framework’s existing collision system:

  • Physics Reversion: If you drag a game piece into another object, the framework detects the collision and “reverts” the movement, effectively blocking the drag.
  • The “Overlap” Bug: In early testing, dragging one piece over another would cause the system to accidentally “swap” control to the second piece. I fix this by strictly tracking the “Active” state of the specific actor being dragged, ensuring input isn’t stolen by overlapping sprites.

To support this functionality, I have updated several base classes:

  • SpriteUpdate & BoundingBox: Added the contains(x, y) method to allow actors to sense when they are being hovered or clicked.
  • SimpleScreen: The rendering loop was slightly reorganized to ensure backgrounds are drawn first, followed by actors and UI elements, preventing game objects from being hidden behind the board.

By the end of the video, I demonstrate a functional board game setup where red and black checker pieces can be naturally dragged and dropped onto a tiled game board while obeying physical boundaries.

The Gdx2DGameFramework can be found here on github.

Building a shoot’em up game with the framework

In my fifteenth video of the “Building a Game Development Framework” series, I demonstrate the Framework by creating a Shoot’em-up game. I implement a sophisticated Visual Effects API, introduce Enemy Projectiles, and streamlines the framework’s actor management.

I updated the “Color Effect” system into a more generic Effects API.

  • Stacked Effects: Instead of a single color slot, every animation and motion now maintains a list of effects. This allows a sprite to simultaneously flash red (when damaged) and become transparent (when dying).
  • Translucency Effect: A new effect class is added that controls the “Alpha” of a sprite over time. This is used to make obstacles fade away once they are destroyed.
  • Global Resets: A reset() method is added to actors, motions, and animations to ensure that all active effects are cleared when an actor is pulled back into the Object Pool for reuse.

To reduce repetitive boilerplate code, I created the ForgedActor class and an updated ActorFactory:

  • Automatic Registration: Previously, developers had to manually call factory.actorRemoved(this) in their code. Now, by extending ForgedActor, the actor automatically notifies its factory when it is “removed” from the game play, significantly simplifying the logic in the Laser and Obstacle classes.

The enemy ship is upgraded with offensive capabilities:

  • Bullet Factory: Similar to the player’s lasers, enemy bullets use an ActorFactory with pooling (starting with a queue of 20 bullets).
  • Burst Fire Logic: The enemy ship uses a timer in its updateChild method. Every 2 seconds, it enters a “firing state” where it launches a burst of 10 bullets, spaced 0.2 seconds apart.
  • Weapons Positioning: The code calculates the ship’s width and fires two bullets simultaneously from different positions on the ship’s hull.

New sound effects are integrated to distinguish between player and enemy interactions:

  • Varying Hit Sounds: Distinct .wav files are added for the player’s ship taking damage versus the enemy’s ship being hit.
  • Explosion Timing: The obstacle’s “hit” sound now triggers as soon as the collision is detected, coinciding with its red color flash and fade-out effect.

I demonstrate the new features in action, showing:

  • Projectile Interactions: Logic is added so that enemy bullets don’t collide with the enemy’s own falling obstacles or lasers.
  • Difficulty Adjustments: The enemy spawning time is reduced from 100 seconds to 5 seconds to get the action started sooner.
  • Visual Polish: Obstacles now smoothly fade out into transparency when hit, rather than instantly vanishing.

By the end of this video, the framework supports a full combat loop where both the player and AI exchange fire, receive visual and auditory damage feedback, and utilize an efficient memory-management system for high volumes of objects.

The Gdx2DGameFramework can be found here on github.

Enhancing a Simple Game with the Framework

In my fourteenth video of the “Building a Game Development Framework” series, I continue developing the Shoot ‘Em Up game, introducing more complex enemy behaviors, advanced movement scripting, and visual color effects.

To improve the game feel, I add an immediate audio-visual feedback when an obstacle is destroyed:

  • Explosion Sound: A new sound effect is triggered the moment an obstacle is “hit.”
  • State Management: The hit() method sets the obstacle’s state to “destroyed,” plays the sound, and swaps its visual representation to a red box while it executes its scripted “easing out” death animation, where it slows down and disappears.

I create a new organizational class, the Enemy Manager, to oversee the spawning of both obstacles and the enemy ship.

  • Dynamic Spawning: The manager waits 10 seconds before spawning the first enemy ship from the top of the screen.
  • Randomized Patrols: To make the enemy ship more unpredictable, I build a Random Destination Action. This action uses “Suppliers” (a Java functional interface) to generate new random (X, Y) targets every time the ship reaches its previous goal.
  • Infinite Loops: By chaining the random movement with a GoToAction from the ScriptMovement, the enemy ship permanently patrols the top of the screen, weaving between random left and right positions.

I introduce a sophisticated Color Effect System to visually indicate damage without needing new sprite art:

  • Color Cycling: The ColorCycleEffect gradually transitions an actor’s color from its base color (e.g., Blue) to a “hit” color (Red) and back again over a set duration.
  • Linear Interpolation (Lerp): The system calculates the percentage of time elapsed and adjusts the RGB values incrementally. This creates a smooth “flash” effect rather than a jarring color swap.
  • Framework Integration: The BaseAnimation and Motion classes were updated to support these effects, ensuring that any actor—whether a single-frame sprite or a multi-directional animation—can utilize the Effects. The Effects can be translucency to color changes.

A BaseShip abstract class is created to centralize the logic for both the player and the enemy:

  • Hit Protection: A “hit” flag ensures that if a ship is hit multiple times rapidly, the color flash effect doesn’t constantly restart; it must finish its cycle before flashing again.
  • Max Hits (HP): Each ship now has a MaxHits variable. The player is given 10 HP, while the enemy ship has 5 HP. When HP reaches zero, the Actor is removed from the screen.

I refined the collision checks to ensure that game objects only interact with what they are supposed to:

  • Laser Logic: Lasers now check if they’ve hit an EnemyShip. If so, they trigger the ship’s hit() method and remove themselves.
  • Obstacle Logic: Obstacles check if they’ve collided with the player’s ship to deal damage, but they ignore the enemy ship so that the enemies don’t accidentally destroy their own falling obstacles or get destroyed by them.

By the end of this session, the game has a sophisticated AI enemy that patrols the screen, takes damage with a visual flash, and eventually dies after a set number of hits.

The Gdx2DGameFramework can be found here on github.

GameMaps and Layers

In the seventeenth video of the “Building a Game Development Framework” series, I implement a sophisticated Layering System and a new architectural concept called Game Maps. These updates provide 3D-like depth in a 2D game, enabling objects to be rendered on top of one another and moved across different visual planes.

I go from managing sprites directly in the Screen class to using a GameMap.

  • Centralized Logic: SimpleScreen is moved into the BaseScreen, and the logic for storing and updating sprites is delegated to the GameMap.
  • Custom Iterators: To handle complex updates (like removing an object from one layer and adding it to another in the same frame), the creator implements a custom Iterator. This prevents “Concurrent Modification Exceptions” when the game tries to update the list of objects while it is still drawing them.

Entities now possess a layer property (an integer), allowing the framework to sort them from back to front.

  • Rendering Order: The GameMap renders objects starting from layer 0 upward. Objects in higher layers are naturally drawn on top of those in lower layers.
  • Collision by Layer: To optimize performance and enable complex interactions, collision detection is updated to only check objects that are currently in the same layer.

Building on the previous “Mouse Drag” system, I add the ability to physically “lift” an object to a higher layer when it is grabbed.

  • Vertical Transitions: When a user clicks a chip (like in Checkers), the movement class automatically increments its layer. This visually pulls the piece “up” toward the camera.
  • Reversion on Collision: If a user tries to “drop” a piece into a lower layer where another object already exists, the framework detects the collision, reverses the layer change, and prevents the drop.

With multiple layers and overlapping sprites, a major technical hurdle is ensuring that a single click doesn’t trigger multiple objects simultaneously.

  • The Lock System: The creator introduces an InputLocks object. When an actor is grabbed, it “locks” the mouse input to itself. Even if the user drags that actor over another one, the second actor ignores all input because it doesn’t hold the lock.
  • Two-Step Clearing: Unlocking is handled as a two-step process to ensure that a “release” click doesn’t accidentally trigger a different object on the frame immediately following the drop.

I show these features using red and black checker chips on a board:

  • Stacking: Pieces can now be moved over one another without colliding if they are at different heights (layers).
  • Layer Toggling: When a piece is clicked, it visually pops to the top layer. When released, it settles back down into the base layer.
  • Drop Logic: You can successfully drag a piece over another, but you cannot “drop” it unless the square underneath is empty.

By the end of this video, the framework supports complex 2D depth, allowing for board games, top-down RPGs with multi-level environments, or UI systems with overlapping windows.

The Gdx2DGameFramework can be found here on github.

Building a Simple Game with the Framework

I my thirteenth video of the “Building a Game Development Framework” series, I change things up by using the framework to build a functional Shoot ‘Em Up (Shmup) style game. This project shows how to use the framework in a game development scenario. It focuses on using the framework’s features, such as input handling, movement scripting, and collision detection.

First I update the framework to the latest versions.

  • LibGDX 1.12.1: I updated the framework to the latest version of LibGDX.
  • LWJGL3 Transition: With newer LibGDX versions, the backend transitions from LWJGL2 to LWJGL3. This requires updating the DesktopLauncher configuration to use Lwjgl3ApplicationConfiguration, which changes how window titles, icons, and dimensions are set.

Implementing the Game

I build the player character using the Actor class:

  • Movement Constraints: First, I override the update method to prevent the ship from moving off-screen. The Movement checks the X-coordinate and “clamps” it so the ship stops just before hitting the window edges.
  • Audio Integration: A laser sound effect (created in ChipTone) is triggered whenever the player presses the Space key.

To handle many objects on screen (like hundreds of lasers or falling obstacles), I create the Actor Factory class with Object Pooling:

  • The Problem: Creating a new “Laser” object every time the player fires is memory-intensive and can cause lag.
  • The Solution (Pooling): The factory maintains a Queue of pre-created actors. When a laser is needed, it’s pulled from the queue and “reset.” When it leaves the screen, it’s added back to the queue for reuse instead of being deleted.

The game needs a way to spawn enemies or obstacles over time. I made these updates to accomplish that:

  • Updatable Interface: A new interface is added for logic that needs to run every frame but doesn’t have a visual sprite (like a “spawner” or “game manager”).
  • Randomized Spawning: The ObstacleFactory implements Updatable. Every 1 second, it picks a random X-coordinate and spawns a falling block at the top of the screen.

The collision logic between lasers and obstacles utilizes the movement scripts built in the previous video:

  • Hit Logic: When a laser hits an obstacle, it doesn’t just disappear. The obstacle’s movement script transitions to an Easing Action, causing it to slow down and changing its color to red (simulating being “destroyed”) before eventually being removed and returned to the pool.
  • Collision Filtering: To prevent “ghost” collisions, the obstacle’s contains method is overridden to return false once it has been destroyed, allowing other lasers to pass through it while it’s in its death animation.

By the end of the video, the user has a playable demo where they can move a ship, fire lasers, and destroy falling obstacles with smooth transitions and efficient memory management.

The Gdx2DGameFramework can be found here on github.

Scripting Movement

In my twelfth video of the “Building a Game Development Framework” series, I introduce a Scripted Movement System. This allows developers to define a sequence of automated actions for Non-Player Characters (NPCs) or cinematic events without writing manual update logic for every frame.

Before diving into scripting, I made a few essential adjustments to the core framework:

  • Window Resizing: Desktop window sizes are now correctly handled via LibGDX configurations and the resize method, ensuring the game’s internal coordinate system matches the actual window dimensions.
  • Safe Sprite Removal: To avoid “Concurrent Modification Exceptions” (crashes when deleting a sprite while the game is still drawing or updating it), the framework now uses a “To Be Added” list and a removed flag. Sprites are only physically added or removed from the main list between render cycles.
  • Clean Interfaces: Redundant methods were removed from the Movement interface, delegating all positional updates to the SpriteUpdate class.

The scripting system is built around two main components:

  • ScriptMovement: The “brain” that holds a list of actions and executes them one by one. Once an action reports it is “done,” the script automatically transitions to the next one in the list.
  • ScriptAction: The base class for specific behaviors (waiting, moving, turning). It includes logic for Gradual Direction Changes, allowing actors to make smooth arcs rather than “snapping” to a new heading.

I detail several specialized actions that can be chained together:

  • Wait Action: Pauses the actor for a set duration. You can also specify a direction for the actor to face while waiting.
  • Time Movement Action: Moves the actor in a specific direction at a set speed for a fixed amount of time.
  • Change Speed Action: Gradually accelerates or decelerates the actor over time.
  • Destination Action: Moves the actor to a specific (X, Y) coordinate. It uses the Pythagorean theorem to calculate the distance and ensures the actor stops exactly on the target.
  • Easing Action: Provides advanced acceleration/deceleration curves (Linear, Quadratic, Cubic, etc.). This allows for “juicy” movement where an actor starts slow and “eases in” to a high speed.
  • Go-To Action: A logic-based action that jumps to a previous step in the script, allowing for infinite loops or repeating patterns.

I then demonstrate how to combine these actions to create a complex patrol path:

  1. Ease In: The character starts from a standstill and slowly speeds up.
  2. Move to Destination: The character hits a series of four (X, Y) coordinates to walk in a square.
  3. Go-To: After the fourth corner, a GoToAction sends the script back to the second step, creating a permanent walking loop.

This scripting system significantly reduces the complexity of AI behavior, allowing developers to “choreograph” NPCs using a simple list of commands.

The Gdx2DGameFramework can be found here on github.

Handling Collisions in Video Games

In my eleventh video of the “Building a Game Development Framework” series, I implement Collision Detection and update the Screen Management system. This update allows game objects to interact with each other physically and simplifies how developers add entities to their game world.

I make the foundation of the collision system the BoundingBox class.

  • AABB (Axis-Aligned Bounding Box): The framework uses simple rectangle-to-rectangle intersection checks. It verifies if the X or Y edges of one sprite fall within the span of another.
  • Insets and Offsets: A major improvement I made is adding Insets. Often, a sprite’s image (for example, 64×64 pixels) is much larger than the actual character (e.g., a person is thin, but the image is a square). With Insets this allows you to shrink the physical “hitbox” independently of the visual image so collisions will feel more realistic.

I setup the framework to categorizes collisions based on whether an object is an “Actor” or “Decor”. Since Decors do not move, they don’t check if they collide with another sprite. Actors, which move, do check if they collide with another sprite.

  • Impact Flag: Not all objects need to check for collisions. The doesImpact() method allows the system to skip checks for static background objects (Decor) that don’t move, saving processing power.
  • Reversion Logic: When a collision is detected, the framework “reverts” the character’s movement. In the basic implementation, it simply moves the character back to their previous non-colliding position.
  • Sliding Physics: In more advanced movement (like in 4-key or mouse movement), the framework checks horizontal and vertical collisions separately. If you walk diagonally into a wall, the X-movement might be blocked, but the system allows the Y-movement to continue, creating a “sliding” effect against the wall.

I also introduce the SimpleScreen, which automates the rendering loop:

  • The Sprite List: Instead of manually updating every character, the screen maintains a list of all Sprites.
  • Automated Loop: The renderChild method automatically iterates through the list, calls update(), performs detectCollision(), and then calls draw() for every entity.
  • Separation of Concerns: New abstract methods addActor() and addDecor() provide a clean way for developers to populate their game world during the show() phase.

To make the world feel more alive, I introduce a Random Sound class:

  • Footstep Variance: Instead of a single repetitive sound, this class holds a list of similar sounds (e.g., four different footstep recordings). Every time an animation triggers a sound, it randomly picks one from the list to create a more natural, less “robotic” audio experience.

I conclude with a demonstration of an Actor (the player) navigating around our “Soda Machine” Decor objects. I show how the player is physically blocked by the machines and how the “sliding” logic feels smoother than a hard stop.

This set of features transforms the framework from a simple animation player into a functional game engine where objects have physical presence and sound.

The Gdx2DGameFramework can be found here on github.

Sound and Music with LibGDX

In my tenth video of the “Building a Game Development Framework” series, I focus on integrating audio capabilities into the LibGDX framework. I cover the distinction between sound effects and music, how to manage their lifecycles, and how to trigger them within an animation system.

The LibGDX framework distinguishes between two types of audio objects based on how they are handled in memory:

  • Sound: Intended for short clips (typically < 10 seconds), such as explosions or footsteps. These are completely loaded into RAM.
  • Music: Intended for longer tracks, like background music or ambient loops. These are streamed from the storage device to save memory.

I demonstrate the primary methods for controlling both types of audio:

  • Playback: Simple .play(), .pause(), .resume(), and .stop() methods. Note that Music does not have a dedicated “resume” method; calling play() on a paused track automatically resumes it from where it left off.
  • Volume & Pitch: Volume is set as a float from 0.0 to 1.0. Pitch (available only for Sound) speeds up or slows down the audio to change its tone—useful for varied sound effects like different-pitched “hellos”.
  • Panning: Moves audio between the left and right speakers (values from -1.0 to 1.0). This only works on mono audio files.
  • Positioning: Specifically for Music, you can jump to a specific second in a track using setDevicePosition().

Because audio objects consume system resources, they must be “disposed” when no longer needed.

  • Automatic Disposal: I have updated the BaseScreen with maps for both Sound and Music objects. When a screen is closed, the framework automatically iterates through these maps and disposes of every audio file to prevent memory leaks.

Then I update my framework to have “Sound-Aware” animations. By adding a Sound field to the BaseAnimation class, animations can now trigger audio automatically:

  • Static/Block Animations: Play a sound once when they first appear on the screen.
  • Loop Animations: Play a sound at the start of every loop cycle (e.g., a footstep sound every time a walk cycle reaches the first frame).
  • Bounce Animations: Trigger sounds at both the beginning and the “apex” (last frame) of the animation, making it ideal for things like bouncing balls or swinging pendulums.
  • Random Animations: Use a counter to ensure a sound plays every time the animation completes a full set of frames, even though the frames themselves are randomized.

I then recommend two browser-based tools for generating 8-bit/16-bit sound effects for game development:

  • SFXR: A classic generator for “retro” sounds.
  • ChipTone: A more modern, user-friendly version of SFXR for creating explosions, jumps, and other game effects.

The Gdx2DGameFramework can be found here on github.

Improved Sprite System For Games

In my ninth video for the “Building a Game Development Framework” series, I focus on establishing a professional-grade Sprite System. I enhance the framework, moving from loose animation and movement logic into a structured architecture by introducing two primary classes: Decor and Actor.

To better manage a game world, the framework now separates objects based on their behavior:

  • Decor: Represents static elements that do not move or have complex logic, such as a rock or a building. These are lightweight and optimized for objects that just need to be drawn.
  • Actor: Represents dynamic, “living” entities that can move, animate, and react to logic (e.g., players, enemies, or NPCs).

The “Sprite” in this framework acts as the parent container. It ties together the separate components built in previous videos into a single, cohesive unit:

  • Movement: Handles the math of where the object is going (Keyboard, Mouse, or AI).
  • Motion: Manages which animation set to use based on the heading (4-way, 8-way, etc.).
  • Animation: Handles the actual frame-by-frame rendering.

In this video, I demonstrate how to build the Actor class to automate the character’s update loop.

  • Automated Updates: Instead of manually calling movement.update() and motion.update() in your screen’s render method, you now simply call actor.update(). The Actor class internally handles data (delta time) delegation between its movement and motion components.
  • Flexibility: Because the Actor uses the Movement and Motion interfaces, you can swap a player’s controls from “Keyboard” to “Mouse” just by changing one line of code during initialization, without changing how the character is drawn or updated.

I then integrate this with the LibGdx library by updating the Screen class logic, making the game screen significantly less cluttered. Instead of managing individual floats for X and Y or multiple animation timers, the screen simply holds a list of Sprite objects and iterates through them to call update() and draw().

By separating Decor from Actors, you optimize performance (static objects don’t need movement logic) and create a system where complex game entities are built like “Legos.” This modularity makes it easy to add features like pathfinding or new animation types later in development without breaking existing characters.

Note: Since this is part of a series, this video serves as the “bridge” that turns the experimental code from earlier videos into a structured framework ready for actual game projects.

Movement using a mouse

In my eighth installment of the “Building a Game Development Framework” series, I expand on the movement system to include mouse-based interaction and introduce visual translucency for sprites.

I have created a new Movement class that allows characters to move toward a target destination clicked by the user.

  • Goal-Oriented Logic: The class tracks a goalX and goalY. When the user clicks, the system calculates the direction from the Sprite’s current position to the click point and moves the character at a set speed.
  • Overshoot Prevention: To prevent the Sprite from going past the target, the code includes logic to check whether the next move would exceed the goal. If so, it simply sets the character’s position to the exact goal coordinates.
  • Continuous Tracking: If the mouse button is held down, the character will continuously follow the cursor.

To make the movement classes more flexible, the framework now uses a SpriteUpdate interface. This acts as a bridge (using a visitor pattern) that allows the movement logic to “get” and “set” the X and Y coordinates of any object, whether it’s a player character or an NPC, without the movement class needing to know the specific details of that object.

A significant challenge in 2D games is clicking on the screen when the camera has moved or is moving.

  • The Problem: Standard input gives “screen coordinates,” but if your camera has scrolled to the right (or any direction from center), a click at screen position (100, 100) is actually a different coordinate on the game’s screen (game world).
  • The Solution: The ScreenInput class is updated to take the camera’s position into account when returning the location of the mouse click on the world map. It offsets the raw mouse input by the camera’s current X and Y coordinates, ensuring that clicking on a world object always works regardless of where the viewport is positioned.

Additionally, I added a “translucency” property (often called Alpha, or sometimes transparency) to the animation and motion interfaces.

  • Value Range: A float from 0.0 (fully invisible) to 1.0 (fully opaque).
  • Inheritance: Setting the translucency on a Motion object automatically applies it to all underlying animations (4-way, 8-way, etc.).
  • Visual Trick for “Behind Walls”: I demonstrate a clever rendering trick for characters walking behind objects (or through objects). Instead of making the character translucent, you render the character in front of an opaque image and behind another layer, then the front layer is rendered semi-transparent. This creates a professional-looking “X-ray” effect where the character appears to be obscured but still visible.

I also point out a subtle LibGDX “gotcha”: the built-in color constants (like Color.WHITE) are actually mutable objects. If you change the alpha of Color.WHITE for one sprite, it would change it for every other sprite using that constant. To fix this, the framework now creates a new color object every time a color or translucency is set, ensuring visual isolation between sprites