Circle Game#

This is a simple game of timing. You can test your reflexes by stopping the growing circle on right time when it reaches to target size. You’ll lose if you are early or late.

You can see and explore final sketch here

We’ll start by creating our canvas and get render contex as usual. Then we fit the canvas to the window screen with resizeCanvas function and keep it dynamically resized by adding resize listener. With setDefaults function we set starting values for our game. Finally we add mousedown to track players mouse clicks.

canvas = CANVAS("", width=canvas_size, height=canvas_size)
ctx = canvas.getContext("2d")
ctx.font = "30px Verdana"
document.body <= [canvas]

resizeCanvas(canvas)
setDefaults()

# Set mouse click callback
document.addEventListener("mousedown", mousedown)
# Set screen resize callback
window.addEventListener('resize', lambda x : resizeCanvas(canvas))

Next we add loop function as same as in our previous tutorials, we draw our scene on each frame here.

def loop(timestamp = 0):
   draw()
   window.requestAnimationFrame(loop)

loop()

There are two states we need to track to determine if game is over or continues. First we check if player is too late and circle passed the target size. We do this check each frame in the draw function. If it is, we stop the game.

def draw():
   ... # Draw scene

   if player_radius > target_radius + tolerance + 50:
      game_over = True

Second we listen player clicks and check if player is on the tolerance zone. If player clicks on the tolerance zone, then we continue the game by generating new target and making game little bit harder for the next round by increaing speed and decreasing tolerance zone. If player misses the tolerance zone, we stop the game.

def mousedown(e):
   if game_over:
      setDefaults()
   else:
      # Check player circle is close enough to target circle.
      # If not, set game is over.
      if player_radius > target_radius + tolerance + 4 or player_radius < target_radius - tolerance - 4:
         game_over = True
      # If user hit the target circle setup the next round.
      else:
         # Set player radius back to zero.
         player_radius = 0
         # Generate new target with the fresh radius.
         target_radius = gen_target_radius()
         # Change bg color
         bg_color = gen_color()
         # Award player with +1 score.
         score += 1

      # Make game harder on every 2nd score player makes.
      if (score % 2 == 0):
         # Increase growing speed.
         speed += .05
         # Make error space smaller.
         tolerance = tolerance - 1 if tolerance - 1 > 1 else 1
      # Set new high score as player passes current high score.
      if score > hi_score:
         hi_score = score

That’s it! We’ve finished our game and hope you enjoy it. If you want to explore further you can read inline comments and see what other helper functions do in the final sketch.