5
\$\begingroup\$

This is a game for children 3years+ to learn Hand-Eye Coordination with Mouse Movement.
Goal is to catch all dinosaurs in the jungle, get the egg reward and then repeat the game.

I tried to add sounds but unfortunately chrome rules say if the user doesn't interact with the page (aka click, etc.) no sound play is allowed so I wasn't able to do a hover sound for collecting a dino.

Same goes for background music. Getting a button which was first hidden to press for restart the game also didn't work so I did an delayed 8 seconds reload.
Maybe I do it in PHP?

For best experience press F11 for Browser Full Screen :D
With Pics https://github.com/CodeLegend27/Hand-Eye-Coordination-Child-3y-plus
Pure Code https://codepen.io/CodeLegend27/pen/RwRRGNa

Kind regards

HTML

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Child Game</title>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <meta name='viewport' content='width=device-width, initial-scale=1'>
    <link rel='stylesheet' type='text/css' media='screen' href='dist/main.css'>
    <script src='main.js'></script>
</head>
<body style="overflow: hidden;">
     <div id="egg" style="display: none;">
</div>
<div id="egg" style="display: none;">
</div>
<img id="gg" src="img/net-3850048_960_720.png" style="position:absolute; width: 50px; overflow: hidden;">
<script>
     $(document).mousemove(function(e){
    $("#gg").css({left:e.pageX, top:e.pageY});
});
</script>


     <div class="main">
         
<div class="row">
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"><p>&#128512;</p></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
</div>
<div class="row">
     <div class="square"></div>
     <div class="square"></div>
     <div class="square"></div>
     <div class="square"></div>
     <div class="square"></div>
     <div class="square"></div>
     <div class="square"></div>
     <div class="square"></div>
     <div class="square"></div>
     <div class="square"></div>
     </div>
     <div class="row">
          <div class="square"></div>
          <div class="square"></div>
          <div class="square"></div>
          <div class="square"></div>
          <div class="square"></div>
          
          <div class="square"></div>
          <div class="square"></div>
          <div class="square"></div>
          <div class="square"></div>
          <div class="square"></div>
          </div>
          <div class="row">
               <div class="square"></div>
               <div class="square"></div>
               <div class="square"></div>
               <div class="square"></div>
               <div class="square"></div>
               <div class="square"></div>
               <div class="square"></div>
               <div class="square"></div>
               <div class="square"></div>
               <div class="square"></div>
               </div>
               <div class="row">
                    <div class="square"></div>
                    <div class="square"></div>
                    <div class="square"></div>
                    <div class="square"></div>
                    <div class="square"></div>
                    <div class="square"></div>
                    <div class="square"></div>
                    <div class="square"></div>
                    <div class="square"></div>
                    <div class="square"></div>
                    </div>
     </div>

</body>
</html>

CSS

.main {
  height: 100vh;
  width: 100%;
}

.row {
  display: flex;
}

.square {
  display: flex;
  width: 10vw;
  height: 20vh;
  align-items: center;
  justify-content: center;
}
p {
  font-size: 15em;
  height: 100%;
  cursor: pointer;
  width: 100%;
  display: none;
}

body {
  cursor: url("../img/net-3850048_960_720.png"), auto;
  height: 100vh;
  /*  background: rgb(18, 4, 250);
   background: linear-gradient(180deg, rgba(18, 4, 250, 1) 0%, rgba(0, 212, 255, 1) 100%); */
  background-image: url("../img/jungle-4003374_1920.jpg");
  background-size: cover;
}

* {
  margin: 0;
  padding: 0;
}

#egg {
  position: absolute;
  bottom: 30px;
  display: inline-block;
  width: 126px;
  height: 60px;
  padding-top: 120px;
  text-align: center;
  text-shadow: 1px 1px rgba(250, 249, 246, 0.9);
  color: rgba(168, 168, 168, 0.8);
  font-weight: 900;
  border-radius: 63px 63px 63px 63px/108px 108px 72px 72px;
  background: radial-gradient(75% 100% at 63px 15px, #f7f7f2 0%, #eaeae3 30%, #b1ac9d 100%);
  box-shadow: 0px 3px 18px -4px rgba(40, 40, 40, 0.9);
  margin: 20px;
  margin-right: 45px;
  transition: all 0.2s linear 0;
  -webkit-transition: 0.2s;
  -webkit-transition-timing-function: linear;
  -webkit-animation: anime_egg_move 3s infinite;
  -webkit-animation-timing-function: linear;
  -webkit-animation-direction: alternate;
}

@-webkit-keyframes anime_egg_move {
  to {
    -webkit-transform: rotate(360deg);
    margin-left: 700px;
  }
}

JS

// 
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
    alert("Please Play on Desktop PC")
   }

   // IMG ARRAY

var images = ['dino8.png', 'dino1.png', 'dino2.png','dino3.png', 'dino4.png', 'dino5.png', 'dino6.png', 'dino7.png']; 

$( document ).ready(function() {
  
// POPULATE SITE WITH IMAGES -- Randomly, Random size
$('.square').each(function() {
    var randNumb =  Math.floor(Math.random() * 71) + 30;
    var rand = Math.floor(Math.random() * images.length);
    $(this).append('<img class="dino" src="img/' + images[rand] + '"/ width="'+ randNumb +'%" height="'+randNumb+'%">');
   });

   // COUNT TILL GAME FINISH, Show Egg and smiley, RELOAD PAGE
let x = 0;


$('.dino').hover(function(){
   
    $(this).remove();
        x++
    if (x == 50){
        $("#egg").css("display", "block");
        $("p").css("display", "block");

        setTimeout(location.reload.bind(location), 8000);
    }
    console.log(x);
});



}); 
\$\endgroup\$
2
  • \$\begingroup\$ thanks for input i thought github and codepen is enough, my first time here. i did added the code \$\endgroup\$ – john_doe_221 Oct 18 '20 at 18:14
  • 2
    \$\begingroup\$ btw, you can use github pages instead of codepen to deploy the page :) \$\endgroup\$ – hjpotter92 Oct 18 '20 at 18:18
4
\$\begingroup\$

Indentation Much of the indentation in the HTML, CSS, and JS is inconsistent, which makes the code moderately harder to read than would be ideal. Consider using an IDE which automatically formats code properly so things can be made readable without having to mess with it manually.

Duplicate IDs are invalid HTML You have two elements with div id="egg", which isn't permitted in HTML. The $("#egg") will only select the first one, because jQuery is only expecting one such element to exist in the document. Maybe just completely remove the second one?

gg? You have img id="gg". It's not entirely clear what this refers to just from reading the markup. I initially thought it might be a reference to "good game" and would appear after the game is over, but it's not, it's an image that follows the mouse. Maybe call it mouseImage instead, or something like that?

Or, you could set the whole cursor to the image via CSS, which might be even better, allowing you to remove that element entirely:

cursor:url(/img/net-3850048_960_720.png), auto;

Smiley face? You render the smiley by putting it inside a square:

<div class="square"><p>&#128512;</p></div>

and by hiding the <p> until the game is over. This is very confusing; I'd expect the squares to contain only the dino pictures. Something completely unrelated should be in a separate element, outside of the <div class="row">s. It's not at all clear what the purpose of the HTML entity is either - consider using an <img> instead so it can be understood at a glance.

<img src="smiley.png">
$('img[src="smiley.png"]').css('display', 'block');

Inline CSS You have a number of inline styles, like

<body style="overflow: hidden;">
     <div id="egg" style="display: none;">
</div>

Best to separate concerns; better to put them all in one place, in the CSS file, so that you can then do

<body>
    <div id="egg">
    </div>

in the HTML.

Refuse to run on mobile Since hover events are required for the app to work, rather than just alerting that the app should be run on a desktop, consider not running the app at all if mobile is detected. For example, you could do something like:

if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
    $('.error').text("Please Play on Desktop PC");
} else {
    main();
}

where main runs the main script.

As shown above, better to display messages to the user in the HTML rather than alert, which blocks the browser and is quite user-unfriendly.

Readyness Rather than wrapping everything in:

$( document ).ready(function() {

Consider using the more standard form nowadays of

$(function() {

Or, even better, remove it entirely, and use the HTML to ensure the JS only runs once the DOM is populated: either give your script the defer attribute (best option IMO), or move your script to right above the bottom of the <body>. Then there's no need for $( document ).ready(function() {, or to wait for DOMContentLoaded, or anything like that.

Images array Rather than hard-coding:

var images = ['dino8.png', 'dino1.png', 'dino2.png','dino3.png', 'dino4.png', 'dino5.png', 'dino6.png', 'dino7.png'];

Consider simply choosing a random number from 1 to 8 instead, and interpolating that into the middle of dino#.png (see below).

randNumb and rand? What's the difference? It's not obvious at a glance what the difference is or what those variables mean without continuing below. Give them better names that indicate what they're used for:

const totalImages = 8;
$('.square').each(function() {
  const widthAndHeight = Math.floor(Math.random() * 71) + 30;
  const src = `img/dino${1 + Math.floor(Math.random() * totalImages)}.png`;
  $(this).append(`<img class="dino" src="${src}" width="${widthAndHeight}%" height="${widthAndHeight}%"`);
});

You could also use .attr instead of directly concatenating HTML strings - concatenating HTML strings can result in odd display issues, unexpected elements appearing in the DOM, and arbitrary code execution when the input isn't trustworthy. While the input happens to be trustworthy here, it'd probably a good habit to get into to avoid concatenating when possible:

const src = `img/dino${1 + Math.floor(Math.random() * totalImages)}.png`;
$('<img />')
  .appendTo(this)
  .attr({
    src,
    width: widthAndHeight + '%',
    height: widthAndHeight + '%',
  });

That's not only better practice, it's also easier to read.

Note the use of ES2015 syntax - you can count on the vast majority of users to be using browsers that support ES2015. Very few people are still using IE11, and those that are (old business enterprise networks, mostly) are less likely to have overlap with teaching children. If you want IE11 support, the most maintainable solution IMO is to write in (clean, readable, concise) modern syntax and then automatically transpile down to ES5 for production.

End condition Rather than doing if (x == 50){ to check if all dinos have been removed, consider checking whether the .dino selector string returns any elements instead - this'll let you avoid hard-coding the number, and will let you remove the x variable entirely:

if (!$('.dino').length) {
  // show egg
}

No need for hover Since you aren't attaching a mouseleave event, the hover handler isn't so appropriate - you only want to listen for mouseenter events:

$('.dino').on('mouseenter', function() {
  // ...
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.