Making a Game in JavaScript - Part 1


It is me, 28 year-old Tom.

I have ceased to gain any enjoyment from video games.

This is a major depressive event in my life, and I'm struggling to cope with it.

While I figure this out, would you like to come along with me while I try to teach myself game development in Phaser 3?

I promise it'll be a hilarious shitshow, since the current version of Phaser is 3.5 and the documentation isn't even online yet. Better yet, I have no experience with game development except for this tile renderer I built and this implementation of the only useful Phaser 3 documentation - "Your First Phaser 3 Game"

Step 1: What to plagiarize?

First things first: pick a suitable first game.

Pong was arguably one of the first "video games" ever created, and features extremely simple gameplay:

  • Two paddles move vertically on the left and right sides of the screen.
  • A ball moves around the screen bouncing off the top and bottom and off the paddles.
  • There's a dashed line down the middle.
  • There's a simple integer score at the top of each player's side - first to 11 wins (failing to return the ball is a point for the opponent).
  • The game makes a noise when the ball: strikes the floor or ceiling, strikes a paddle, or exits the playing field

There are a couple special features that the original developer put into the game:

  • The ball accelerates slightly the longer it's been in the game.
  • The paddles can't quite get to the top of the screen (a hardware bug, in the original!)
  • The paddles are divided into eight sections, where the center two segments return the ball at 90° to the paddle (perpendicular), and each segment moving outward returns the ball at slighly smaller angles.

Some other things I noticed about the original game:

  • Boy, this thing is a lot harder than I remember from when I played with a home TV console kind of like the one pictured below.
    A seventies style pong console, with vertical slider inputs 'docked' to the left and right of the center control console, which has the game configuration buttons and dials.
    The in-game paddles are tiny and the analog control makes lining up a defense difficult. Maybe this was just a function of the arcade / cabinet implementation of the first iteration.

  • When you win, the paddles disappear and the ball bounces around as if there are walls just off-screen on the left and right. The score stays up - mocking the loser.

Step 2: What do I need?

Without question, I'm going to need 4 static assets:

  • A single, white, 1px by 1px graphic.

    I can scale this to any size I want with Phaser's built in image scaling, and all of the game is some combination of a white rectangle on the black background.

    I don't know of any performance problem with doing the scaling in-game, and I also don't know of any way to generate graphics that I can apply physics to in-game without having any static images. I'm almost positive there must be a way, but programmatically generating graphics is well outside the scope of this segment of my learning.

  • A sound effect for the paddle strike, the floor/ceiling strike, and for scoring.

    I've never used Phaser's built-in Audio engine, so this one will be a challenge. I also don't know where I'll get free audio clips, but I'm sure I can figure something out.

Step 3: What do I do?

I'll need three physics bodies: the ball, and the two paddles. The paddles will be controllable by the keyboard (mouse as a future upgrade!), and the ball will just bounce around with standard "arcade" physics. Since Phaser ships arcade physics by default (as well as something called P2 physics, which looks like it can do all the big boy physics engine things), this will be utterly trivial to implement.

Of course, there will need to be a bit of logic around bouncing off the top and bottom but scoring at the left and right. Likewise, implementing the varying angles of bounce off the paddles will require some interesting logic. I think there's a way to determine which parts of the objects collide with each other, and I think it's baked into the default Phaser physics colliders, but I'm not sure. Boy, it'd be nice to have online docs.

Generating a ball always starts at the center line and flies - at a random angle - at the last player who was scored on. This is a great implementation to really just grind the salt into your worst enemy's wounds, since it's really hard to react to the ball given that you have half the time you have during regular play. In the original implementation, you had to have been a masochist to have fun, and some people are really into that kind of thing, I've found out:

As you became better friends, you could put down your beer and hug. You could put your arm around the person. You could play left-handed if you so desired. In fact, there are a lot of people who have come up to me over the years and said, 'I met my wife playing Pong,' and that's kind of a nice thing to have achieved. – Nolan Bushnell, on Pong, quoted from Wikipedia, quoting from Next Generation magazine, 11 April 1995

To start with, the score can just be text rendered onto the screen. Like the original game, text in Phaser doesn't interact with the game physics, so there's nothing extra to do there. As a side note, it might be a fun exercise to make some kind of game where the game text like the score is a part of the game physics.

For the audio, I'll have to figure out how the Phaser Audio API works, but since all I need to do it play a short sound on paddle and floor / ceiling collisions, plus a sound when a score happens, I suspect I'll only need to learn a couple functions, like - just guessing here - loadSound and playSound. We'll see.

I'm off

I'm going to go off and do this and try to ignore the existential dread that maybe interactive entertainment isn't for me - an old - any more, and maybe now I'm one of the mindless consumer-only TV-watching drones that I hate.

I'll post again when I've finished my implementation of Pong with a wrap up of how it went and what I misjudged from the start.
So anyway, cheers! See you next time!