DEV Community

Cover image for JavaScript Catch the Fish Game
Petrina Ropra
Petrina Ropra

Posted on • Edited on

JavaScript Catch the Fish Game

Intro: A small game inspired by a chapter of the Foundation Game Design with HTML5 and JavaScript Book by Rex van der Spuy. I've commented on each line so it's basically for complete beginners.

Game Demo:https://youtube.com/shorts/hYimZgPLHcA?feature=share

Note: You can use this code to create your version of games. I drew the pictures of the fish, hook, dynamite and background myself on Microsoft Paint.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="catch_fish.css">
  <title></title>
</head>
<body>
    <div id="game">
    <h1>Catch the Fish</h1>
    <div id="stage">
    <div id="background"></div>
    <div class="box" id="fish"></div>
    <div class="box" id="dynamite"></div>
    <div id="hook"></div>
    <div id="explosion"></div>
    </div>
    <br>
    <br>
    <p id="output">Enter the X and Y position (0–300), then click fire.</p>
    <input id="inputX" type="text" placeholder="X...">
    <input id="inputY" type="text" placeholder="Y...">
    <button>Catch!</button>
    </div>
    <script src="catch_fish.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode
*
{
    font-family: sans-serif;
    text-align: center;
}

p{
    font-weight: bold;
    font-size: 22px;
    margin: 0px, auto;
}

input, button{
    font-size: 18px;
}

#game
{
    margin: 0px auto;
    width: 600px;
    height: 630px;
    padding: 15px;
    border: black;
    background: lightblue;
    box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
    border-radius: 10px;
}


#stage
{
    width: 400px;
    height: 400px;
    margin: 0px auto;
    position: relative;
    border-color: blue;
    text-align: center;
}

.box{
    position: absolute;
    height: 100px;
    width: 100px;
    margin: 5px;
}

#background
{
    width: 520px;
    height: 430px;
    left: -55px;
    position: absolute;
    background-image: url('C:/Users/petix/OneDrive/Desktop//my_javascript_games/catch_fish/background.png');
}


#dynamite
{
    width: 60px;
    height: 60px;
    background-image: url('C:/Users/petix/OneDrive/Desktop/my_javascript_games/catch_fish/dynamite.png');
}

#hook
{
    width: 40px;
    height: 40px;
    top: 380px;
    left: 160px;
    position: absolute;
    background-image: url('C:/Users/petix/OneDrive/Desktop/my_javascript_games/catch_fish/hook.png');
}

#fish
{
    width: 80px;
    height: 50px;
    top: 70px;
    left: 100px;
    background-image: url('C:/Users/petix/OneDrive/Desktop//my_javascript_games/catch_fish/fish.png');
}

#explosion
{
    display: block;
    width: 60px;
    height: 60px;
    background-image: url('C:/Users/petix/OneDrive/Desktop/my_javascript_games/catch_fish/explosion.png');
}
Enter fullscreen mode Exit fullscreen mode
//Game variables
//the position of the fish on the horizontal axis 
var fishX = Math.floor(Math.random() * 350);
//the position of the fish on the vertical axis 
var fishY = Math.floor(Math.random() * 100);
//the players input for the horizontal axis
var guessX = 0;
//the players input for the vertical axis
var guessY = 0;
//the amount of chances the player has
var shotsRemaining = 3;
//the amount of chances the player used
var shotsMade = 0;
//message to tell the player the game state
var gameState = "";
//whether the game is won or not
var gameWon = false;
//whether the hook is destroyed or not
var hookDestroyed = false;
//the spa
var tolerance = 10;


//The game objects the html
//access the div ids on  
var hook = document.querySelector("#hook");
var explosion = document.querySelector("#explosion");
var fish = document.querySelector("#fish");
var dynamite = document.querySelector("#dynamite");

//The input and output fields
var inputX = document.querySelector("#inputX");
var inputY = document.querySelector("#inputY");
var output = document.querySelector("#output");

//The button
var button = document.querySelector("button");
button.style.cursor = "pointer";
button.addEventListener("click", clickHandler, false);

//Add 50 to fishY and dynamiteY to stop them 
//from going out the background
fishY = fishY + 50;

//Position the fish when the game starts
fish.style.left = fishX + "px";
fish.style.top = fishY + "px";

//Position the dynamite when the game starts
//the offsets are there to stop the fish div
//and the dynamite div from overlapping each other
var dynamiteX = fish.offsetLeft + fishX;
var dynamiteY = (fish.offsetTop + fish.offsetHeight + 30);

//this if-else statement is to stop the dynamite from
//going out of the background when the game starts
if(dynamiteX > 400){
    console.log("higher than 400");
    dynamiteX = dynamiteX - 350;
    dynamite.style.left = dynamiteX + 'px';
    dynamite.style.top = dynamiteY + 'px';
}else{
    dynamite.style.left = dynamiteX + 'px';
    dynamite.style.top = dynamiteY + 'px';
}

//this to print on the console
//this is optional 
x = dynamite.style.left;
y = dynamite.style.top;
console.log(x);
console.log(y);
console.log(fishX);
console.log(fishY);


//repositions the dynamite and fish
//whenever the button is clicked
function render(){
    //Position the fish
    fish.style.left = fishX + "px";
    fish.style.top = fishY + "px";

    //Position the hook
    hook.style.left = guessX + "px";
    hook.style.top = guessY + "px";

    if(gameWon){
        //remove the fish and hook
        fish.style.display = "none";
        hook.style.display = "none";

    }
}

//the button function to call the 
//validateInput()
function clickHandler(){
    validateInput();
}

//this functions checks the input of the 
//player
function validateInput(){
    //changes the string input into numbers
    guessX = parseInt(inputX.value);
    guessY = parseInt(inputY.value);

    //if input is not a number then display bottom message
    if(isNaN(guessX) || isNaN(guessY)){
        output.innerHTML = "Please enter a number.";
    }
    //if both inputs are more than 400 then display message
    else if(guessX > 400 || guessY > 400){
        output.innerHTML = "Please enter a number less than 400";
    }
    //if the Y input is less than 50 then display message
    else if(guessY < 50){
        output.innerHTML = "For Y, enter a number more than 50";
    }
    //if all above are not the case then call playGame() functionqqq
    else{
        playGame()
    }
}

function playGame(){
    //decrease the value of shotRemaining by 1
    shotsRemaining = shotsRemaining - 1;
    //increase the value of shotsMade by 1
    shotsMade = shotsMade + 1;
    //the variable gameState gets this message
    gameState = " Shots: " + shotsMade + ", Remaining: " + shotsRemaining;
    //the variable guessX gets the players inputX value turned to integer
    guessX = parseInt(inputX.value);
    //the variable guessY gets the players inputX value turned to integer
    guessY = parseInt(inputY.value);
    //Find out whether the player's x and y guesses are inside
    //The fish's area

    //this if statement checks if the player's guess is within the fish div
    //horizontal range
    if(guessX >= (fishX - tolerance) && guessX <= (fishX + 20 + tolerance))
    {
        //Yes, it's within the X range, so now let's
        //check the Y range

        //this if statement checks if the player's guess is within the fish div
        //vertical range
        if(guessY >= (fishY - tolerance) && guessY <= fishY + 20 + tolerance)
        {
            //It's in both the X and Y range, so it's a hit!
            gameWon = true;
            endGame();
        }
    //this if statement checks if the player's guess is within the dynamite div
    //horizontal range
    } else if(guessX >= (dynamiteX - tolerance) && guessX <= (dynamiteX + 20 + tolerance))
    {
        //Yes, it's within the X range, so now let's
        //check the Y range

        //this if statement checks if the player's guess is within the fish div
        //vertical range
        if(guessY >= (dynamiteY -  tolerance) && guessY <= (dynamiteY + 20 + tolerance))
        {
            //It's in both the X and Y range, so it's a hit!
            hookDestroyed = true;

            //remove the dynamite from the game
            dynamite.style.display = 'none';

            //display the explosion in the dynamite position
            explosion.style.display = "block";
            explosion.style.position = "absolute";
            explosion.style.left = dynamiteX + "px";
            explosion.style.top = dynamiteY + "px";
            endGame();

        }
    }
    //if the hook is out of the dynamite and the hook
    //range
    else{
        output.innerHTML = "Miss!" + gameState;

        //set a timer
        setTimeout(() => {
            //the hook moves back to its original position
            //after 300 miliseconds
            hook.style.top = 380 + "px";
            hook.style.left = 160 + "px";
        }, 300);

        //if the value of shotsRemaining is zero
        if (shotsRemaining < 1)
        {
            //then call endGame() function
            endGame();
        }   
    }
    //Update the alien's position if the
    //game hasn't yet been won
    if(!gameWon)
    {
        //Update the fish's X position
        fishX = Math.floor(Math.random() * 300);
        fishY = Math.floor(Math.random() * 300);

        fishY += 50;
        }

    //Render the new game state
    render();
    //console.log("X: " + alienX);
    //console.log("Y: " + alienY);
}   

//this function checks whether the game is won
function endGame(){
    //if the game is won
    if(gameWon){
        //if the value of shotsMade is less than 2
        //display this message
        if(shotsMade < 2){
            output.innerHTML = "Hooray! You caught the fish!" + "<br>"
             + "It only took you " + shotsMade + " shot.";
        }
        //this is for aesthetic purposes. It's not necessary
        else{
            output.innerHTML = "Hooray! You caught the fish!" + "<br>"
                     + "It only took you " + shotsMade + " tries.";
        }
    } 
    //if the hook is destroyed by the dynamite
    //display this message
    else if(hookDestroyed){
        output.innerHTML = "Boom!! You hit a dynamite!" + "<br>"
                        + "Your hook is destroyed. :("
    }
    //if the game is lost and the hook is not destroyed
    //display this message
    else{
        output.innerHTML = "You lost!" + "<br>"
        + "The fish got away!";
        }

    //Disable the button
    button.removeEventListener("click", clickHandler, false);
    button.disabled = true;

    //Disable the enter key 
    //window.removeEventListener("keydown", keydownHandler, false);

    //Disable the input fields
    inputY.disabled = true;
    inputX.disabled = true;

    //hide hook and fish
    hook.style.display = "none";
    fish.style.display = "none";
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)