Writing A Word Memory Game In Elm - Part 1: Setting Up an Elm Application With Parcel
Mickey
Posted on March 20, 2019
This is part 1 of the series "Writing A Word Memory Game In Elm", find:
- Part 1: Setting Up an Elm Application With Parcel
- Part 2: Modeling And Building a Basic Word Memory Game
- Part 3: Rethinking the Model
- Part 4: Spicing Things Up With Randomness
- Part 5 - More Randomness And More Game
Preface
One of the most effective ways to learn is by doing. I was looking for a project to improve my Elm skills and a friend gave me an excellent idea -- to write a word memory game.
Note: this series of posts reflects my personal learning experience, any constructive feedback is welcome.
The Memory Game
There is a sentence which the player can read. Several words are then taken out and the player must reconstruct the sentence from memory.
For example, the sentence is:
If you want something done right, you have to do it yourself.
And with several words removed:
If --- want something ---- right, you ---- to do it yourself."
The game is pretty simple, but there are many ways it can be be extended:
- The missing words can be presented to the user in-place (as a dropdown), or near the sentence as a list
- Each time the player guesses the correct word, they can be informed straight away or find out the result only when all the words are used
- At the beginning of the game the sentence is visible to the player for several seconds only
- Etc
Starting the Project
To make the development cycle easier I chose to use Parcel bundler, which supports Elm out of the box since v1.10.0
and HMR
since v1.11.0
.
Let's create a project folder, for example word-memory-game
, cd
into it and initialise the NPM project:
$ npm init -y
The -y
option will accept all defaults and create package.json
file.
Let's install the Parcel bundler locally (it can also be installed globally):
$ npm i -D parcel-bundler
Following Parcel's Getting Started let's add index.html
:
<!doctype html>
<html>
<body>
<script src="./index.js"></script>
</body>
</html>
and index.js
:
console.log('Words Memory Game started');
Also let's add the following lines to the scripts
section of package.json
:
"scripts": {
"dev": "parcel index.html",
"build": "parcel build index.html"
}
In order to start the development server let's run:
$ npm run dev
and navigate to http://localhost:1234
In order to host our Elm application in a page let's add
<div id="app"></div>
to index.html
:
<!-- index.html -->
<!doctype html>
<html>
<body>
<div id="app"></div>
<script src="./index.js"></script>
</body>
</html>
Let's create src
folder and add Main.elm
to it:
module Main exposing (main)
import Html
main =
Html.text "Words Memory Game"
and change index.js
to:
import { Elm } from "./src/Main.elm";
Elm.Main.init({
node: document.getElementById("app")
});
After we save all the files, Parcel will automatically initialise an Elm project (including creating elm.json
file), install needed dependencies and reload. We can also reload the page manually to clear all the previous errors from the console.
Now let's make our Elm skeleton a real Elm application by adding Msg
, Model
, view
and update
, as well as updating main
:
module Main exposing (main)
import Browser
import Html exposing (Html)
type alias Model =
{ sentence : String
}
initialModel : Model
initialModel =
{ sentence = "The pen is mightier than the sword" }
type Msg
= NoOp
update : Msg -> Model -> Model
update msg model =
case msg of
NoOp ->
model
view : Model -> Html msg
view model =
Html.text model.sentence
main : Program () Model Msg
main =
Browser.sandbox
{ init = initialModel
, update = update
, view = view
}
Great! We have our basic "Hello, World!".
I personally like my applications to look nice, so let's add the popular Bulma CSS framework in our index.html
(or we can install it locally and import it) and a meta
tag that Bulma recommends:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Words Memory Game</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css"
/>
</head>
<body>
<div id="app" class="section"></div>
<script src="./index.js"></script>
</body>
</html>
Now in Main.elm
let's update our view
function to show a title and a sentence in a nice box:
view : Model -> Html msg
view model =
main_ [ class "section" ]
[ div [ class "container" ]
[ viewTitle
, div [ class "box" ]
[ p
[ class "has-text-centered" ]
[ text model.sentence ]
]
]
]
viewTitle : Html msg
viewTitle =
h1 [ class "title has-text-centered" ]
[ text "Words Memory Game" ]
Don't forget to import Html
and Html.Attributes
functions:
import Html exposing (Html, div, h1, main_, p, text)
import Html.Attributes exposing (class)
Now our application looks nicer:
Another touch that I want to add to our game is the ability to show pretty icons. Therefore let's add a link to Font Awesome web font in our index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Words Memory Game</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css"
/>
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.7.1/css/regular.css"
integrity="sha384-IG162Tfx2WTn//TRUi9ahZHsz47lNKzYOp0b6Vv8qltVlPkub2yj9TVwzNck6GEF"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.7.1/css/fontawesome.css"
integrity="sha384-4aon80D8rXCGx9ayDt85LbyUHeMWd3UiBaWliBlJ53yzm9hqN21A+o1pqoyK04h+"
crossorigin="anonymous"
/>
</head>
<body>
<div id="app" class="section"></div>
<script src="./index.js"></script>
</body>
</html>
Now we are all set up for the next steps, read about them in the upcoming posts.
The current progress is saved in the repo under a Tag v0.0
: https://github.com/mickeyvip/words-memory-game/tree/v0.0.
Posted on March 20, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 28, 2024