Skip to content

The Snake game, using ClojureScript and re-frame

License

Notifications You must be signed in to change notification settings

jpalharini/snaklj

Repository files navigation

snaklj

The famous Nokia snake game designed in re-frame.

This is a project for the Fundamentos de Sistemas Digitais subject at IMED, ministered by Prof. Thaisa Leal.

The Game

How it works

The snake runs through a matrix. It is initially placed at a random, but safe* position and moving in any of the four basic directions (up, down, left or right). Its direction can be controlled by the arrow keys of the keyboard.

*the safe position is anywhere within the matrix at a minimum distance of 5 blocks from any edge.

Randomically, "food" will be placed at any position within the matrix. Anytime the snake eats, it grows its size.

Your score is the size of the snake. You lose if you crash into an edge or into the body of the snake.

States

Game

The game can be running, paused or ended; which resets its and the snake's state.

image

Snake

The snake has three possible states, represented in the below diagram. When it eats their food, it grows and goes back to running; and when it crashes, it dies.

image

The Project

Project Overview

Directory structure

  • /: project config files
  • dev/: source files compiled only with the dev profile
  • resources/public/: SPA root directory; dev / prod profile depends on the most recent build
    • index.html: SPA home page
      • Dynamic SPA content rendered in the following div:
        <div id="app"></div>
      • Customizable; add headers, footers, links to other scripts and styles, etc.
    • Generated directories and files
      • Created on build with either the dev or prod profile
      • js/compiled/: compiled CLJS (shadow-cljs)
  • src/snaklj/: SPA source files (ClojureScript, re-frame)
    • config.cljs: defines constants that control the setup of the game
    • core.cljs: contains the SPA entry point, init; and game cycles logic
    • db.cljs: contains event handlers for changes to the app-db
    • events.cljs: registers event handlers for the game's and app's lifecycle
    • subs.cljs: defines subscriptions to access data in app-db
    • views.cljs: draws and styles the HTML elements using hiccup
    • game/
      • controller.cljs: the "brains" of the game. Controls collisions, snake movements and updates the matrix in app-db
      • logic.cljs: helper, pure functions that implement business/game rules
      • setup.cljs: defines functions to setup the game when starting up (or restarting);
  • .github/workflows/: contains the github actions pipelines.

Editor/IDE

Use your preferred editor or IDE that supports Clojure/ClojureScript development. See Clojure tools for some popular options.

Environment Setup

  1. Install JDK 11 or later (Java Development Kit)
  2. Install Node.js (JavaScript runtime environment) which should include NPM or if your Node.js installation does not include NPM also install it.
  3. Clone this repo and open a terminal in the snaklj project root directory

Browser Setup

Browser caching should be disabled when developer tools are open to prevent interference with shadow-cljs hot reloading.

Custom formatters must be enabled in the browser before CLJS DevTools can display ClojureScript data in the console in a more readable way.

Chrome/Chromium

  1. Open DevTools (Linux/Windows: F12 or Ctrl-Shift-I; macOS: ⌘-Option-I)
  2. Open DevTools Settings (Linux/Windows: ? or F1; macOS: ? or Fn+F1)
  3. Select Preferences in the navigation menu on the left, if it is not already selected
  4. Under the Network heading, enable the Disable cache (while DevTools is open) option
  5. Under the Console heading, enable the Enable custom formatters option

Firefox

  1. Open Developer Tools (Linux/Windows: F12 or Ctrl-Shift-I; macOS: ⌘-Option-I)
  2. Open Developer Tools Settings (Linux/macOS/Windows: F1)
  3. Under the Advanced settings heading, enable the Disable HTTP Cache (when toolbox is open) option

Unfortunately, Firefox does not yet support custom formatters in their devtools. For updates, follow the enhancement request in their bug tracker: 1262914 - Add support for Custom Formatters in devtools.

Development

Running the App

Start a temporary local web server, build the app with the dev profile, and serve the app, browser test runner and karma test runner with hot reload:

npm install
npx shadow-cljs watch app

Please be patient; it may take over 20 seconds to see any output, and over 40 seconds to complete.

When [:app] Build completed appears in the output, browse to http://localhost:8280/.

shadow-cljs will automatically push ClojureScript code changes to your browser on save. To prevent a few common issues, see Hot Reload in ClojureScript: Things to avoid.

Opening the app in your browser starts a ClojureScript browser REPL, to which you may now connect.

Connecting to the browser REPL from your editor

See Shadow CLJS User's Guide: Editor Integration. Note that npm run watch runs npx shadow-cljs watch for you, and that this project's running build ids is app, browser-test, karma-test, or the keywords :app, :browser-test, :karma-test in a Clojure context.

Alternatively, search the web for info on connecting to a shadow-cljs ClojureScript browser REPL from your editor and configuration.

For example, in Vim / Neovim with fireplace.vim

  1. Open a .cljs file in the project to activate fireplace.vim
  2. In normal mode, execute the Piggieback command with this project's running build id, :app:
    :Piggieback :app

Connecting to the browser REPL from a terminal

  1. Connect to the shadow-cljs nREPL:

    lein repl :connect localhost:8777

    The REPL prompt, shadow.user=>, indicates that is a Clojure REPL, not ClojureScript.

  2. In the REPL, switch the session to this project's running build id, :app:

    (shadow.cljs.devtools.api/nrepl-select :app)

    The REPL prompt changes to cljs.user=>, indicating that this is now a ClojureScript REPL.

  3. See user.cljs for symbols that are immediately accessible in the REPL without needing to require.

Running shadow-cljs Actions

See a list of shadow-cljs CLI actions:

npx shadow-cljs --help

Please be patient; it may take over 10 seconds to see any output. Also note that some actions shown may not actually be supported, outputting "Unknown action." when run.

Run a shadow-cljs action on this project's build id (without the colon, just app):

npx shadow-cljs <action> app

Debug Logging

The debug? variable in config.cljs defaults to true in dev builds, and false in prod builds.

Use debug? for logging or other tasks that should run only on dev builds:

(ns snaklj.example
  (:require [snaklj.config :as config])

(when config/debug?
  (println "This message will appear in the browser console only on dev builds."))

Production

Build the app with the prod profile:

npm install
npm run release

Please be patient; it may take over 15 seconds to see any output, and over 30 seconds to complete.

The resources/public/js/compiled directory is created, containing the compiled app.js and manifest.edn files.

About

The Snake game, using ClojureScript and re-frame

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published