Jaylib - 4, The Bouncing Square

John Gabriele

2020-12-30

(Previous article: Jaylib - 3, Basics)

Here we’ll make a program that displays a square bouncing around inside the borders of the window. It’s a useful next step because:

Start with the skeleton code from the previous article.

We’re still not going to mess with the camera here — just leave it default, as before.

Since we want to have a square bouncing around, we’ll need to keep track of it. So we create a little data structure for it:

# Start the player (the square) in the middle of the screen,
# with some known initial velocity.
(def pl @{:x (/ screen-width 2)
          :y (/ screen-height 2)
          :vx 2
          :vy 4})

where :vx and :vy are velocity components (vx and vy).

Change our drawing function to draw the square wherever it currently is. Also draw some interesting text on the screen:

(defn draw-game
  []
  (jl/draw-fps 10 10)
  (jl/draw-text (string "x: " (pl :x))
                10 30 16 :blue)
  (jl/draw-text (string "y: " (pl :y))
                10 50 16 :green)
  (jl/draw-text (string "v_x: " (pl :vx))
                10 70 16 :blue)
  (jl/draw-text (string "v_y: " (pl :vy))
                10 90 16 :green)
  # Draw the player.
  (jl/draw-rectangle (pl :x) (pl :y) 20 20 :red))

And finally, we need to update pl in case it hits a wall:

(defn update-game
  []
  # First, move the square further whichever
  # way it's already going.
  (+= (pl :x) (pl :vx))
  (+= (pl :y) (pl :vy))
  # If it has hit a wall, reverse its
  # direction away from that wall.
  (cond
    (> (pl :x) screen-width)
    (do (put pl :x screen-width)
        (put pl :vx (- (pl :vx))))
    (< (pl :x) 0)
    (do (put pl :x 0)
        (put pl :vx (- (pl :vx))))
    (> (pl :y) screen-height)
    (do (put pl :y screen-height)
        (put pl :vy (- (pl :vy))))
    (< (pl :y) 0)
    (do (put pl :y 0)
        (put pl :vy (- (pl :vy))))))

main and init-game stay the same as before (unless you want to update the window title in init-game).

Your game should work and look like this:

One note on that code: You’ll notice (+= (pl :x) (pl :vx)). Janet supplies that handy += operator, and allows us to assign to (pl :x), saving us from having to verbosely write out (put pl :x (+ (pl :x) (pl :vx))).

Exercise for the reader: Notice that the square bounces nicely off the top and left walls, but goes too far into the right and bottom walls. Change the code to not let it dip so far into those right and bottom walls.

(Next up: todo)


Notice any errors, glaring omissions, or just clumsy wording? Please email me at approximately <jgabriele©fastmail·fm>. Thank you!