During college I was initially focusing on an emphasis in web-based game development alongside programming. For that purpose, I created several games in JavaScript.
This game simulates the 2018 FIRST Robotics Competition game. The goal of this game is to pickup yellow cubes and place or throw them on the blue side of one of several seesaws. While there are more cubes on your side of the seesaws, you get +1 points per second. There is an opponent that will attempt to place cubes on their side of the goals. You have 60 seconds to score more points than your opponent.
It can be played in any modern browser here: https://pycee.github.io/Firebears-Power_Up
The source code can be found at github: https://github.com/PyCee/Firebears-Power_Up
Playing The Game On An Arcade Machine
I volunteer as a programming teacher for a high school robotics team. One of the students built a custom arcade cabinet. I modified this game to be playable on this arcade cabinet. It has been brought to several of the team’s events and used as a show-piece, open to the public.
My volunteering with a robotics team is detailed here: https://kimpampusch.tech/?page_id=101

The student built this arcade machine from a Raspberry Pi connected to a monitor, and a USB gamepad setup for the joystick and buttons. Since this game was written in JavaScript, it can run on any machine that has a modern browser. I believe the Pi ran Ice Weasel, a Firefox spinoff.
The arcade controls are functionally the same as any other gamepad. The gamepad instance can be used as shown below.
// We reference the list of gamepads with // navigator.getGamepads() // There should only be one gamepad, // If there are any gamepads plugged in, // We reference the first one var Gamepad_Index = -1; if (navigator.getGamepads().length){ Gamepad_Index = 0; } // With the gamepad index, we can write a function to give // us the valid joystick instance if there is one function get_gamepad () { if (Gamepad_Index == -1){ // If there is no valid gamepad index return null ; } else { return navigator.getGamepads()[Gamepad_Index]; } } // We can also detect joystick connection events as seen below window.addEventListener( "gamepadconnected" , function (event) { // Runs when a new gamepad has been connected Gamepad_Index = event.gamepad.index; console.log( "Connected gamepad: " + get_gamepad().id); }); window.addEventListener( "gamepaddisconnected" , function (event) { // Runs when a gamepad is disconnected if (navigator.getGamepads().length){ Gamepad_Index = 0; } else { Gamepad_Index = -1; } console.log( "Disconnected gamepad" ); }); |
If we know that the horizontal axis on the joystick is axis index 0 and the axis values range from [-1.0, 1.0], then we can calculate the controlled move speed of the robot with:
var joystick_x_index = 0; var joystick_x_input = get_gamepad().axes[joystick_x_index]; var move_speed = joystick_x_input * MAX_ROBOT_MOVE_SPEED; |
Implementing The Launch Mechanic
In designing this game, the mechanic that was most difficult to implement was launching a cube onto the upper seesaw. In addition to forming a parabola, the launched cube would have to collide with the seesaw and any other cubes that were previously launched.

In games, there are dynamic objects and static objects. Dynamic objects move and must handle collisions with other objects. An example of a dynamic object is a playable character that moves and interacts with the surrounding area. A static object does not move and simply exists as a collider, such as a wall or the ground.
The launch mechanic required a modification the physics system to handle collisions between multiple dynamic objects (robots and cubes) so cubes could interact with other cubes. This game was built off of the codebase I used for a previous game demo, Slime, which could only resolve collisions between one dynamic object and static objects, the playable character and the walls.
For collisions between a dynamic object and a static object, the dynamic object is simply moved to the nearest point outside of the static object.

To make this game handle collisions between multiple dynamic colliders I had to implement momentum, based on mass and velocity.
Whenever two dynamic objects collide, several steps happen:
- Figure out which axis the collision is on (to simplify the math)
- The collision is resolved so there is no overlap between objects
- Calculate a new momentum for each object based on that object’s mass
This implementation allows cubes to collide with each other and also results in robots being able to push cubes and other robots around.
