Skip to content

A clone of Snake, built with React inside of Ruby on Rails.

Notifications You must be signed in to change notification settings

john-farina/snake-port

Repository files navigation

React JavaScript SASS Ruby Rails


Snake

A web recreation of the classic game Snake
View Live Demo

Table of Contents
  1. About The Project
  2. React
  3. Rails
  4. Design
  5. Usage
  6. Contact

About The Project

This is a web recreation of the classic snake game, but when you get a high score you can save it for the world to see. Using React inside of Rails.

Built With

  • Rails
  • React
  • SCSS

React

State

Snake

The whole state of the project is revolving around the coordinates of snake, which are default 2 arrays inside an array. I sparingly use States in the project only using it for what is needed to update every frame or so.
I am also saving a string with useRef that is saying what direction the snake is facing which helps with moving it around.

Food Coordinates

The food coordinates are saved in a useRef so I don't lose the value of it with all the other React data. And getting the value using .current

Grid

For saving and updating the grid I'm using a useMemo because I want the grid to update every time the Snake updates OR when food coordinates update. So I can properly update the array that coordinates with the graph, inside the use memo I am drawing the grid every time snake or food is updated.

(back to top)

Game Logic

Drawing Grid

Every time snake updates the drawGrid function is getting called, which takes in snake coordinates, and food coordinates. It loops through the set Grid array and puts each one correspondingly. The first set in the snake array is drawn as the snake head, and the last is the tail. The rest of the array is placed as a snake body. And the food coordinates get placed as food.

Moving & Growing Snake in Grid

For moving the snake in the grid I remove the last value in the Snake Array and add another value to the first value. Determining which direction the snake is going the first or second spot in the new coordinates will be adjusted accordingly.
For Growing the snake when a player eats food, I add a value behind the last one, growing the tail out by one. I did it from the tail so it doesn't mess with the players movements.

Snake Collision

For Snake collision I'm using functions inside a useMemo, for snake to wall collision I am seeing if the head position in Snake Array ever is equal to 0 or 1, etc. depending on which wall. And if the direction is the one which it would run into it. This is in a useMemo because I want to run checks every time the snake moves if it ran into something. The Snake to food collision is practically the same as the rest but only seeing if the Snake Head value is equal to the food Coordinates, and if it is then it grows the snake by one

Random Food Spawn

Food is spawned randomly on the grid and will keep trying to spawn if it failed because snake was in that position. Food cannot be spawned on the snake.

(back to top)

Rails

Model

I wanted to save the high scores in a classic arcade way. (3 letter save no login) so all I'm saving in rails is a PlayerScore model which saves the 3 letter string. And the players score which is saved inside a hidden value in forms, so the user cant manipulate it on screen. When submitting I save a fake value over React that shows your score right away without a refresh. When user refreshes/reloads the real score replaces the fake score that was just saved.

Controller

In the controller I am taking all saved high scores and ordering them by value, and sending that back to react so I can then show the user a ranked high score in order.

I also am creating new PlayerScores over params, and saving when the user submits the form.

Gems

The most important gem I'm using in this project is
gem react-rails
This is one out of two React gems, I find this one works better and adds less of a hassle to set it up and use.

(back to top)

Design

Header

for the Title header I wanted to go for an engraved Game Boy type of title, so I added a shadow inside the text making it look more indented with a blinking red light to the right of it

I also added a point counter in the top right to fill up space, and it updates when a User gets more points

Screen

For the screen I added a screen texture over the square div. This works out really well to emulate an older screen texture. And I made the background a shade of green that is also the color of old Game Boy screens and basing the rest of the colors around a darker green scale.
The Food is bright white and glows trying to make it more obvious that it's what the goal of the game is

Animations

Most animations are being run on steps to make it not smooth on purpose with the whole emulation feel I was going for. Text animation growing and shrinking, or colors going back and forth

Buttons

For the buttons I made them bigger so it's easier to click if user isn't using the arrow keys. The colors are based off of how older generation game controllers had this color scheme of buttons, For the clicks I remove the background shadow and scale it down slightly to create the illusion of an actual button going down.

(back to top)

Usage

To play snake click anywhere on the screen to start, or any button. When started you can use the on-screen buttons to move around or the arrow keys on your keyboard.
Eat the squares to grow and try not to run into yourself or any walls.

Contact

John Farina - [email protected]

My Website: johnfarina.co

Project Link: github.com/john-farina/snake-port

(back to top)

About

A clone of Snake, built with React inside of Ruby on Rails.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published