Welcome to Devium Blog! If you're a game development enthusiast or someone looking to learn how to create a fun and interactive slingshot game, you're in the right place. In this tutorial, we will guide you step by step in creating a Slingshot Game to shoot fruit, using HTML5, CSS, and JavaScript.

This tutorial is aimed at beginners, so if you’re not familiar with HTML5 canvas elements and basic web development, don't worry. You can check out our previous tutorials here for an introduction to those concepts.

In this first part, we’ll start by creating the Splash Screen, setting up the basic game layout, and adding the level selection feature. Let's dive right into it!

Game Layout Overview

Before we dive into the code, let’s take a look at the layout of our slingshot game. The design is simple yet functional, with a few essential screens and elements that will make the game engaging for users. Below is a breakdown of the layout we’ll create for the Froot Wars game:

  1. Game Canvas: This is the main area where all game activities take place. We'll use an HTML5 <canvas> to display the gameplay, such as shooting fruit and targeting objects.

  2. Game Screens: There are several screens in the game, including:

    • Start Screen: This is where players begin, with buttons to start the game and access settings.
    • Level Selection Screen: Displays level options when the player is ready to choose the next stage.
    • Loading Screen: A brief screen shown while the game is loading.
    • End Screen: Appears when a level is completed, offering options to replay or move on to the next level.
  3. Game Controls: These controls will allow the player to toggle music, restart levels, and track their score.

HTML Layout

The first part of building the layout is creating the HTML structure. This defines the placement of elements like the game canvas, score display, and various screens that appear during gameplay.

Here’s the basic structure for the HTML layout:

Game HTML Code
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=uft-8">
        <title>Froot Wars</title>
        <script src="js/game.js" type="text/javascript"></script>
        <link rel="stylesheet" href="styles.css" type="text/css" media="screen">
    </head>
    <body>
        <div id="wrapper">
            <div id="gameContainer">
                <canvas id="gameCanvas" width="640" height="480" class="gamelayer">
                </canvas>

                <div id="scorescreen" class="gamelayer">
                    <img id="toggleMusic" src="22.png" alt="Toggle Music">
                    <img scr="36.png" alt="Restart Level">
                    <span id="score">Score: 0</span>
                </div>

                <div id="gamestartscreen" class="gamelayer">
                    <img src="images/icons/play.png" alt="Play Game" onclick="game.showLevelScreen()"><br>
                    <img src="images/icons/settings.png" alt="Settings">
                </div>

                <div id="levelselectscreen" class="gamelayer">
                </div>

                <div id="loadingscreen" class="gamelayer">
                    <div id="loadingmessage"></div>
                </div>

                <div id="endingscreen" class="gamelayer">
                    <div>
                        <p id="endingmessage">The Level is Over Message</p>
                        <p id="playcurrentlevel" class="endingoption">
                            <img src="22.png" alt="Replay">
                            Replay current level
                        </p>

                        <p id="playnextlevel" class="endingoption">
                            <img src="36.png" alt="Next">
                            Play Next Level
                        </p>

                        <p id="returntolevelscreen" class="endingoption">
                            <img src="36.png" alt="Next">
                            Return to level screens
                        </p>
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

CSS Layout and Styling

Now that we have our HTML structure, let’s move on to the CSS styling. The goal here is to make the game visually appealing while ensuring that the screens and elements are positioned correctly.

CSS Breakdown

  1. Body Styling: This centers the entire game on the screen and gives it a dark background suitable for a game setting.

  2. Wrapper and Game Container: The wrapper element holds everything, while the game container sets the size and adds a repeating splash screen background.

  3. Game Screens: All game layers are absolutely positioned, and only the active layer is displayed at any given time.

  4. Debugging Styles: These styles are added to help during development, ensuring that images load correctly and that the buttons are clickable.

Here’s the CSS code:

Game CSS
body {
    background: #000900;
    user-select: none;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

#wrapper {
    position: relative;  /* Changed from absolute to relative */
    width: 640px;       /* Match game container width */
    height: 480px;      /* Match game container height */
}

#gameContainer {
    width: 640px;
    height: 480px;
    background: url("images/splashscreen.png") repeat;
    position: relative;
    overflow: hidden;
}

.gamelayer {
    width: 100%;
    height: 100%;
    position: absolute;
    display: none;
    top: 0;
    left: 0;
}

#gamestartscreen {
    padding-top: 250px;
    text-align: center;
}

#gamestartscreen img {
    margin: 10px;
    cursor: pointer;
    width: 100px;    /* Define a specific width */
    height: auto;    /* Maintain aspect ratio */
}

/* Debug styles to help see if images are loading */
#gamestartscreen img[alt="Play Game"],
#gamestartscreen img[alt="Settings"] {
    border: 1px solid red;  /* This will show the image bounds even if they don't load */
    min-height: 50px;      /* Ensures a minimum height if image fails to load */
    display: inline-block; /* Ensures the element takes space even if empty */
}

#levelselectscreen {
    padding-top: 150px;
    padding-left: 50px;
}

#levelselectscreen input {
    margin: 20px;
    cursor: pointer;
    background: url("images/icons/level.png");
    color: yellow;
    font-size: 20px;
    width: 64px;
    height: 64px;
    border: 0;
    outline: 0;
}


JavaScript Game Logic: Creating the game.js

Now that we have the layout and styling in place, it's time to make the game interactive using JavaScript.

We'll be building the core logic of the game, including screen management, loading levels, and handling events. Here's how we approach this:

  1. Game Initialization: In the game.init method, we set up the canvas and context, then initialize the levels and display the start screen.

  2. Screen Management: We created functions to hide and show different game screens (start screen, level selection screen, etc.), based on the player’s actions.

  3. Level Data: In the levels.data array, we define the level structure (foreground, background, and entities). This will allow us to create levels dynamically.

Here’s the JavaScript code:

Game Code
var game = {
    init: function() {
        game.canvas = document.getElementById("gameCanvas");
        game.context = game.canvas.getContext("2d");
        
        // Set canvas size
        game.canvas.width = 800;
        game.canvas.height = 400;
        
        levels.init();
        
        game.hideScreens();
        game.showScreen("gamestartscreen");
    },
    
    hideScreens: function() {
        var screens = document.getElementsByClassName("gamelayer");
        for(let i = screens.length - 1; i >= 0; i--) {
            screens[i].style.display = "none";
        }
    },
    
    hideScreen: function(id) {
        var screen = document.getElementById(id);
        if(screen) {
            screen.style.display = "none";
        }
    },
    
    showScreen: function(id) {
        var screen = document.getElementById(id);
        if(screen) {
            screen.style.display = "block";
        }
    },
    
    showLevelScreen: function(){
        game.hideScreens();
        game.showScreen("levelselectscreen");
    }
};

var levels = {
    data: [{
        foreground: "desert-foreground",
        background: "clouds-background",
        entities: []
    },{
        foreground: "desert-foreground",
        background: "clouds-background",
        entities: []
    }],
    
    init: function(){
        var levelSelectionScreen = document.getElementById("levelselectscreen");
        
        var buttonClickHandler = function(){
            game.hideScreen("levelselectscreen");
            levels.load(this.value - 1);
        };
        
        for(let i = 0; i < levels.data.length; i++){
            var button = document.createElement("input");
            
            button.type = "button";
            button.value = (i + 1);
            button.style.margin = "10px";
            button.style.padding = "10px 20px";
            button.style.fontSize = "16px";
            button.style.cursor = "pointer";
            
            button.addEventListener("click", buttonClickHandler);
            levelSelectionScreen.appendChild(button);
        }
    },
    
    load: function(number){
        console.log("Loading level:", number);
        // Add your level loading logic here
    }
};

window.addEventListener("load", function() {
    game.init();
    
    // Debug image loading
    var images = document.getElementsByTagName('img');
    for(var i = 0; i < images.length; i++) {
        images[i].addEventListener('error', function(e) {
            console.error('Error loading image:', e.target.src);
        });
        
        images[i].addEventListener('load', function(e) {
            console.log('Successfully loaded image:', e.target.src);
        });
    }
});


If you are having issues with this code you can check out the game repo here ,SlingShot repo.

Conclusion

That’s it for Part 1 of creating our slingshot game! In this section, we’ve laid out the basic structure and functionality for the splash screen, level selection, and game canvas. We’ve also provided you with all the necessary files to get started.

In Part 2, we’ll dive deeper into adding interactive gameplay features, such as launching the slingshot, shooting fruit, and handling game physics. Stay tuned, and don’t forget to subscribe to our newsletter for updates on upcoming tutorials!

Happy coding, and see you in the next part of this journey!