How I Built a 2D Game in Java with Custom Sprites and Tile-Based Collision Detection
by Wassim MESFIOUI

Developing a 2D game from scratch is a journey filled with creativity, challenges, and a lot of learning. In this blog, I’ll walk you through how I built my own 2D game in Java, focusing on creating custom sprites, managing tile-based maps, and implementing collision detection. From tools to techniques, I'll share the methods and resources that helped me bring this game to life.
Creating the Map Using Tiled
The journey began with designing the game map. I used Tiled, a powerful map editor, to create the base of my game world. Tiled allowed me to break down the game world into manageable tiles, each assigned a number corresponding to its image and properties. This approach made it easier to manage large maps and ensure that each tile behaved as expected, especially in terms of collisions and visual consistency.
Once the map was designed, I exported it as a sprite sheet. This sheet essentially contained all the tiles I needed, packed neatly into a single image. But to use these tiles effectively in my game, I needed to cut them into individual images.
Cutting the Sprite Sheet
For slicing the sprite sheet into individual tiles, I turned to ezgif’s sprite cutter. This online tool made the process simple and efficient. By uploading the sprite sheet, I could specify the dimensions of each tile, and ezgif would handle the rest, outputting a series of images that I could then use in my game.
Implementing Tile-Based Collision Detection
With the tiles ready, the next step was to implement them into my game using Java. Here’s where things got a bit technical. The core idea was to create a system where the player doesn’t actually move through the world—instead, the map itself moves around the player. This approach simplifies collision detection and ensures that the game performs well even as the player navigates large maps.
Managing Tile Images and Collisions
In Java, I used a custom TileManager class to handle the loading and rendering of tiles. This class is responsible for managing which tiles are currently on the screen, based on the player’s position, and for detecting collisions.
The key to collision detection in my game lies in the properties of each tile. Each tile in the game is assigned a specific ID, and some of these IDs correspond to tiles that block the player’s movement. For example, walls, trees, or other obstacles have IDs that the game recognizes as impassable. Here’s a simplified version of how this works:
if(tilePos<=1074){
tileMenos = tilePos -1;
tile[tilePos] = new Tile();
tile[tilePos].image = ImageIO.read(getClass().getResourceAsStream("/tiles/mainboard/"+tileMenos+".png"));
tile[tilePos].collision = true;
if(tilePos >= 36 && tilePos<= 215){
tile[tilePos].collision = false;
}
}
This snippet shows how each tile is loaded with its image and collision properties. If a tile is meant to block the player, its collision property is set to true. Otherwise, it remains false, allowing the player to move through it.
Creating Custom Sprites
No game is complete without characters, and in my game, these are represented by custom sprites. For creating and editing these sprites, I used LibreSprite, a free and open-source sprite editor. This tool allowed me to design characters that fit the unique aesthetic of my game.
Creating custom sprites took time, especially since I was learning the ropes as I went. I spent hours refining the look and feel of each character, ensuring they matched the overall style of the game world. LibreSprite’s intuitive interface and robust feature set made this process enjoyable and rewarding.
Character Design with Ascension Game Dev Resources
To bring even more life to the game, I used 2D character templates from Ascension Game Dev. These templates provided a great starting point, giving me a base to build upon. From there, I customized each character using LibreSprite, tweaking animations, colors, and other details to suit the game's narrative and style.
Learning from the Best
Developing this game was a significant learning experience, and I couldn’t have done it without the vast amount of knowledge available online. YouTube was an invaluable resource. Channels like RyiSnow, Java 2D Platformer Tutorial, and ForeignGuyMike provided tutorials that guided me through the more complex aspects of game development. From handling game physics to optimizing performance, these creators offered insights that were crucial to the success of my project.
Coding the Game Logic in Java
Once the visual elements were in place, it was time to bring everything together with code. Writing the game logic in Java involved managing the game loop, handling user input, and ensuring smooth animations. The key challenge was making sure the game ran efficiently, even as it processed large amounts of data related to the map and sprites.
For instance, in the TileManager class, I implemented the logic to move the map based on the player’s position:
double screenX = worldX - gp.player.worldX + gp.player.screenX;
double screenY = worldY - gp.player.worldY + gp.player.screenY;
This code calculates the position of each tile relative to the player, ensuring that the right tiles are displayed on the screen. It also accounts for the edges of the map, preventing the camera from moving beyond the game world.
Testing and Iteration
Game development is an iterative process. After coding the basic mechanics, I spent countless hours testing the game, identifying bugs, and refining the gameplay. Whether it was tweaking the collision detection or adjusting the speed of animations, each small change brought the game closer to my vision.
One of the most satisfying aspects of this project was seeing the game evolve from a simple concept into a fully playable experience. Testing involved not just playing the game myself but also sharing it with friends and receiving feedback. This input was invaluable in identifying areas for improvement and ensuring the game was enjoyable for others.
Challenges and Overcoming Them
The journey wasn’t without its challenges. Learning how to manage large sprite sheets, implement efficient collision detection, and optimize game performance were all significant hurdles. But each challenge was an opportunity to learn and improve my skills. I found that the key to overcoming these obstacles was persistence and a willingness to seek out resources and ask for help when needed.
Conclusion
Building a 2D game in Java from scratch was a rewarding experience that taught me a lot about game development, from coding to design. By using tools like Tiled, ezgif, LibreSprite, and resources from Ascension Game Dev, I was able to create a game that reflects my vision and provides an engaging experience for players. The journey was long and filled with learning, but the end result made it all worthwhile.
If you're interested in creating your own 2D game, I highly recommend diving in and experimenting with these tools and techniques. With determination and the right resources, you'll be surprised at what you can accomplish.
FAQs
How do you manage tile-based collision detection in a 2D game?
In tile-based games, each tile is assigned properties such as collision status. The game checks these properties to determine whether a player can pass through a tile or if it's an obstacle.
What tools can I use to create custom sprites for my game?
LibreSprite is an excellent tool for creating and editing custom sprites. It's free, open-source, and provides a wide range of features to bring your characters to life.
Why does the map move instead of the player in some 2D games?
Moving the map instead of the player can simplify collision detection and improve game performance, especially in large, complex worlds.
What is Tiled, and how does it help in game development?
Tiled is a map editor that allows developers to create and manage tile-based maps easily. It exports maps as sprite sheets, which can be used in various game engines.
How do you optimize a 2D game for performance?
Optimizing a 2D game involves managing resources efficiently, such as loading only visible tiles and reducing the complexity of collision detection. Testing and iteration are also crucial for identifying and fixing performance bottlenecks.
Where can I learn more about 2D game development in Java?
YouTube channels like RyiSnow, Java 2D Platformer Tutorial, and ForeignGuyMike offer great tutorials on 2D game development in Java, covering everything from basic mechanics to advanced techniques.