Background

Welcome back! Or welcome for the first time! If you do happen to be stopping by for the first time you may want to read the first two posts in this little series.

Of course if you want to stay here you are most welcome. So, what are we doing?

Creating prototypes that can form together into something resembling a game.


Lets Get Shaking

Looking back on our last post I noted at the end that it’d be nice to add a screen shake effect. Something say like this one:

sdl2-test02

As it turns out it is quite easy to do.


Camera

We are going to use the camera position and alter it to achieve a shaking effect. The camera itself is an sdl.Rect() that is the size of our output resolution. It doesn’t need to be an sdl.Rect(), but this removes the need to declare a struct.

We calculate the coordinate points of the rectangle relative to the player. Centering it around the “player character”. Unless it is near the edge of the “map”, then the edge is set to the background edge. A chunk of the background is then copied to the renderer using those coordinates. The player “sprite” is then copied over next. Since we are using the hardware render so we call renderer.Present() to “flip” the back buffer to the screen.

Let’s see what our current camera looks like.

  camera := sdl.Rect{X: 0, Y: 0, W: wWidth, H: wHeight}

  ...snip...

  camera.X = int32((d.posX + d.width/2) - wWidth/2)
  camera.Y = int32((d.posY + d.height/2) - wHeight/2)

  if camera.X < 0 {
    camera.X = 0
  }
  if camera.Y < 0 {
    camera.Y = 0
  }
  if camera.X > bgWidth-camera.W {
    camera.X = bgWidth - camera.W
  }
  if camera.Y > bgHeight-camera.H {
    camera.Y = bgHeight - camera.H
  }

  renderer.Copy(bg, &sdl.Rect{
    X: camera.X,
    Y: camera.Y,
    W: wWidth,
    H: wHeight,
  },
    &sdl.Rect{
      X: 0,
      Y: 0,
      W: wWidth,
      H: wHeight,
    })

Not very exciting is it.


Implementation

To keep this post short I’m not going to repeat all the code. I need to figure out how I’m going to put it up on GitHub. Do I want to use a single repo for all the code or split it up into sections? I should get that taken care of.

We start outside our main game loop and do a bit of setup, with some initial values. Then after our camera bounding code, we check if shaking is true. If it is we use the very inelegant shake * rand.Float64() * maxShake to get our camera offset. This might lead to the following values:

camerax 184, cameray 228
targetx 3.421793651571817, targety 1.0282214265561018

Adding 184+3 (we cast to int32 which drops the decimals) gives us 187 for the X. Likewise, we add 228+1 and get 229. This gives a jitter to the image since the value we’re adding will change every frame. We don’t have any negative offsets when done this way though. This isn’t the perfect screen shake but at this stage it will do. We can look into smoothing it a bit down the road.

  shaking := true
  targetx := 0.0
  targety := 0.0
  shake := 0.8
  maxShake := 5

  ...snip...

  if camera.Y > bgHeight-camera.H {
    camera.Y = bgHeight - camera.H
  }

  if shaking {
    targetx = shake * rand.Float64() * maxShake
    targety = shake * rand.Float64() * maxShake
  }

  renderer.Copy(bg, &sdl.Rect{
    X: int32(targetx) + camera.X,
    Y: int32(targety) + camera.Y,
    W: wWidth,
    H: wHeight,
  },

  ...snip...

The render.Copy() call now uses the original camera value and the shake offset. We don’t want to actually mutate the camera values since we need them once the shaking stops. It’s not visible here but the current code allows us to enable and disable shaking by pressing the space bar. In that bit of code I’m making sure to reset targetx and targety to 0.0.


Wrapping Up

A short month calls for a short post. We didn’t really set out to do to much this month but we accomplished a few things anyway. Besides this post, I finished my makefile! For now at least. I can build for Windows, macOS, and Linux and release to itch.io pretty with no trouble. In theory I can also compile to Android (and maybe iOS).

I may switch gears a little and try to accomplish generating a “map” which will eventually be used as our base for a level. This is going to be cellular automata based. I also may try to get an implementation diamond-square algorithm completed. At the very least I’m hoping to present something on screen for the cellular automata. Where we go after that I’m not quite sure yet.

Anyway until next time!


Give It A Try

I’ve added the prototype over on itch.io. It can be download for Windows, macOS, and Linux. Please give them a try and let me know if you have any issues.


Enjoy this post?
How about buying me a coffee?