From c495f14ea7b294538828db68f1f56002d21d101d Mon Sep 17 00:00:00 2001 From: Michael Ficarra Date: Fri, 3 Oct 2014 02:06:15 -0700 Subject: [PATCH] initial commit --- .gitignore | 6 +++ LICENSE | 26 ++++++++++ Makefile | 61 +++++++++++++++++++++++ README.md | 18 +++++++ bower.json | 28 +++++++++++ demo.gif | Bin 0 -> 157200 bytes docs/README.md | 72 +++++++++++++++++++++++++++ index.html | 29 +++++++++++ package.json | 33 +++++++++++++ src/Mario.purs | 119 +++++++++++++++++++++++++++++++++++++++++++++ src/Mario/DOM.purs | 54 ++++++++++++++++++++ 11 files changed, 446 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 bower.json create mode 100644 demo.gif create mode 100644 docs/README.md create mode 100644 index.html create mode 100644 package.json create mode 100644 src/Mario.purs create mode 100644 src/Mario/DOM.purs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..81f187b --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.psci_modules +bower_components +built-tests +coverage +lib +node_modules diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..68b62ea --- /dev/null +++ b/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2014, Michael Ficarra. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of the project nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +This software is provided by the copyright holders and contributors "as is" and +any express or implied warranties, including, but not limited to, the implied +warranties of merchantability and fitness for a particular purpose are +disclaimed. In no event shall the copyright holder be liable for any direct, +indirect, incidental, special, exemplary, or consequential damages (including, +but not limited to, procurement of substitute goods or services; loss of use, +data, or profits; or business interruption) however caused and on any theory of +liability, whether in contract, strict liability, or tort (including negligence +or otherwise) arising in any way out of the use of this software, even if +advised of the possibility of such damage. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5c0a130 --- /dev/null +++ b/Makefile @@ -0,0 +1,61 @@ +default: build doc +all: build doc test + +MODULE = Mario + +build: lib/$(MODULE).js +build-tests: $(TESTSOUT) +externs: lib/$(MODULE).externs.purs +deps: node_modules bower_components +doc: docs/README.md + + +BOWER_DEPS = $(shell find bower_components/purescript-*/src -name '*.purs' -type f | sort) +SRC = $(shell find src -name '*.purs' -type f | sort) +TESTS = $([ -d test ] && shell find test -name '*.purs' -type f | sort) +TESTSOUT = $(TESTS:test/%.purs=built-tests/%.js) + +BOWER = node_modules/.bin/bower +ISTANBUL = node_modules/.bin/istanbul +MOCHA = node_modules/.bin/_mocha +MOCHA_OPTS = --inline-diffs --check-leaks -R dot + +lib/$(MODULE).js: bower_components src/$(MODULE).purs + @mkdir -p '$(@D)' + psc --verbose-errors \ + --main $(MODULE) \ + ${BOWER_DEPS} $(SRC) \ + > lib/$(MODULE).js + +.PHONY: default all build externs deps doc clean test build-tests + +lib/$(MODULE).externs.purs: bower_components src/$(MODULE).purs + @mkdir -p '$(@D)' + psc --verbose-errors \ + -m $(MODULE) \ + --codegen $(MODULE) \ + -e lib/$(MODULE).externs.purs \ + ${BOWER_DEPS} $(SRC) \ + > /dev/null + +docs/README.md: lib/$(MODULE).externs.purs + @mkdir -p '$(@D)' + docgen lib/$(MODULE).externs.purs > docs/README.md + +built-tests/%.js: bower_components test/%.purs + @mkdir -p '$(@D)' + psc --verbose-errors -m Tests \ + $(BOWER_DEPS) '$<' \ + >'$@' + +node_modules: + npm install + +bower_components: node_modules + $(BOWER) install + +test: node_modules $(TESTSOUT) lib/$(MODULE).js + [ -d test ] && $(ISTANBUL) cover --root lib $(MOCHA) -- $(MOCHA_OPTS) -- built-tests + +clean: + rm -rf lib built-tests coverage bower_components node_modules diff --git a/README.md b/README.md new file mode 100644 index 0000000..39afeeb --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +purescript-demo-mario +===================== + +Implementation of [Elm's Mario demo](http://elm-lang.org/edit/examples/Intermediate/Mario.elm) in PureScript. + +![](https://raw.githubusercontent.com/michaelficarra/purescript-demo-mario/master/demo.gif) + +## Usage + +```sh +make +``` + +Open `index.html` to interact. + +## Documentation + +See the [auto-generated documentation](./docs). diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..e094f13 --- /dev/null +++ b/bower.json @@ -0,0 +1,28 @@ +{ + "name": "purescript-demo-mario", + "homepage": "https://github.com/michaelficarra/purescript-demo-mario", + "description": "implementation of Elm's Mario demo in PureScript", + "keywords": [ + "purescript", + "demo", + "mario", + "example", + "sample", + "frp", + "elm" + ], + "license": "BSD-3-Clause", + "ignore": [ + "**/.*", + "bower_components", + "node_modules", + "bower.json", + "package.json" + ], + "dependencies": { + "purescript-dom": "*", + "purescript-math": "*", + "purescript-signal": "git@github.com:bodil/purescript-signal.git" + }, + "devDependencies": {} +} diff --git a/demo.gif b/demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..b08bf6cb4e9ac050f3bf67257cc1f8b851b42f89 GIT binary patch literal 157200 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 z Number + + airAccel :: Number + + airFriction :: Number + + applyFriction :: Mario.GameState -> Mario.GameState + + applyGravity :: Mario.GameState -> Mario.GameState + + currentActivity :: Mario.GameState -> Mario.Verb + + friction :: Mario.GameState -> Number + + gravity :: Number + + groundAccel :: Number + + groundFriction :: Number + + groundHeight :: Number + + initialState :: Mario.GameState + + isAirborne :: Mario.GameState -> Boolean + + jump :: Boolean -> Mario.GameState -> Mario.GameState + + jumpKeyCode :: Number + + jumpSpeed :: Number + + leftKeyCode :: Number + + main :: forall t1844. Control.Monad.Eff.Eff t1844 Prelude.Unit + + marioLogic :: Mario.Inputs -> Mario.GameState -> Mario.GameState + + marioSpriteUrl :: Mario.Verb -> Mario.Direction -> String + + maxMoveSpeed :: Number + + mkInputs :: Boolean -> Boolean -> Boolean -> Mario.Inputs + + offsetGround :: Number -> Mario.DOM.Coordinate -> Mario.DOM.Coordinate + + rightKeyCode :: Number + + velocity :: Mario.GameState -> Mario.GameState + + walk :: Boolean -> Boolean -> Mario.GameState -> Mario.GameState + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..d735905 --- /dev/null +++ b/index.html @@ -0,0 +1,29 @@ + + + + + purescript-demo-mario + + + + + mario +

+ + diff --git a/package.json b/package.json new file mode 100644 index 0000000..759fa23 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "purescript-demo-mario", + "version": "0.0.0", + "description": "implementation of Elm's Mario demo in PureScript", + "main": "index.js", + "scripts": { + "test": "make test" + }, + "repository": { + "type": "git", + "url": "https://github.com/michaelficarra/purescript-demo-mario" + }, + "keywords": [ + "purescript", + "demo", + "mario", + "example", + "sample", + "frp", + "elm" + ], + "author": "Michael Ficarra", + "license": "BSD-3-Clause", + "bugs": { + "url": "https://github.com/michaelficarra/purescript-demo-mario/issues" + }, + "homepage": "https://github.com/michaelficarra/purescript-demo-mario", + "devDependencies": { + "bower": "^1.3.12", + "istanbul": "^0.3.2", + "mocha": "^1.21.4" + } +} diff --git a/src/Mario.purs b/src/Mario.purs new file mode 100644 index 0000000..0189652 --- /dev/null +++ b/src/Mario.purs @@ -0,0 +1,119 @@ +module Mario where + +import Math (abs, max, min) +import Signal ((~>), foldp, runSignal, sampleOn) +import Signal.DOM (animationFrame, keyPressed) + +import Mario.DOM + + +initialState :: GameState +initialState = { + x: -40, y: 0, + dx: maxMoveSpeed, dy: jumpSpeed, + dir: Right + } + +data Direction = Left | Right +instance showDirection :: Show Direction where + show Left = "left" + show Right = "right" + +data Verb = Jumping | Walking | Standing +instance showVerb :: Show Verb where + show Jumping = "jump" + show Walking = "walk" + show Standing = "stand" + +type GameState = { x :: Number, y :: Number, dx :: Number, dy :: Number, dir :: Direction } +type Inputs = { right :: Boolean, left :: Boolean, jump :: Boolean } + + +jumpKeyCode = 38 -- up arrow +rightKeyCode = 39 -- right arrow +leftKeyCode = 37 -- left arrow + +groundHeight = 0.08 -- * viewport height + +gravity = 0.3 -- px / frame^2 + +jumpSpeed = 6 -- px / frame +maxMoveSpeed = 4 -- px / frame + +groundAccel = 0.06 -- px / frame^2 +airAccel = 0.04 -- px / frame^2 + +groundFriction = 0.15 -- px / frame^2 +airFriction = 0.02 -- px / frame^2 + + +marioSpriteUrl :: Verb -> Direction -> String +marioSpriteUrl verb dir = "http://elm-lang.org/imgs/mario/" ++ show verb ++ "/" ++ show dir ++ ".gif" + +offsetGround :: Number -> Coordinate -> Coordinate +offsetGround amount pos = pos { y = pos.y + amount - 4 } -- 4 pixels for image offset + +mkInputs :: Boolean -> Boolean -> Boolean -> Inputs +mkInputs l r j = { left: l, right: r, jump: j } + +isAirborne :: GameState -> Boolean +isAirborne s = s.y > 0 + +currentActivity :: GameState -> Verb +currentActivity s | isAirborne s = Jumping +currentActivity s | s.dx /= 0 = Walking +currentActivity s = Standing + +accel :: GameState -> Number +accel s = if isAirborne s then airAccel else groundAccel + +friction :: GameState -> Number +friction s = if isAirborne s then airFriction else groundFriction + + +velocity :: GameState -> GameState +velocity s = s { x = s.x + s.dx, y = s.y + s.dy } + +applyGravity :: GameState -> GameState +applyGravity s = + if s.y <= -s.dy + then s { y = 0, dy = 0 } + else s { y = s.y + s.dy, dy = s.dy - gravity } + +jump :: Boolean -> GameState -> GameState +jump true s | not (isAirborne s) = s { dy = jumpSpeed } +jump _ s = s + +walk :: Boolean -> Boolean -> GameState -> GameState +walk true false s = + let s' = if s.dx > 0 then applyFriction s else s in + s' { dx = max (-maxMoveSpeed) (s'.dx - accel s'), dir = Left } +walk false true s = + let s' = if s.dx < 0 then applyFriction s else s in + s' { dx = min maxMoveSpeed (s'.dx + accel s'), dir = Right } +walk x y s = applyFriction s + +applyFriction :: GameState -> GameState +applyFriction s | s.dx == 0 = s +applyFriction s | abs s.dx <= friction s = s { dx = 0 } +applyFriction s | s.dx > 0 = s { dx = s.dx - friction s } +applyFriction s | s.dx < 0 = s { dx = s.dx + friction s } + +marioLogic :: Inputs -> GameState -> GameState +marioLogic inputs = velocity <<< applyGravity + <<< jump inputs.jump + <<< walk inputs.left inputs.right + + +main = onDOMContentLoaded do + marioElement <- getMario + viewportDimensions <- getViewportDimensions + let groundHeightPx = groundHeight * viewportDimensions.height + jumpKey <- keyPressed jumpKeyCode + rightKey <- keyPressed rightKeyCode + leftKey <- keyPressed leftKeyCode + let inputs = mkInputs <$> leftKey <*> rightKey <*> jumpKey + frames <- animationFrame + runSignal $ foldp marioLogic initialState (sampleOn frames inputs) ~> \gameState -> do + updateSprite marioElement $ marioSpriteUrl (currentActivity gameState) gameState.dir + updatePosition marioElement (offsetGround groundHeightPx {x: gameState.x, y: gameState.y}) diff --git a/src/Mario/DOM.purs b/src/Mario/DOM.purs new file mode 100644 index 0000000..e7018b3 --- /dev/null +++ b/src/Mario/DOM.purs @@ -0,0 +1,54 @@ +module Mario.DOM where + +import Control.Monad.Eff + +import DOM (DOM(..), Node(..)) + +type Dimensions = { width :: Number, height :: Number } +type Coordinate = { x :: Number, y :: Number } + +foreign import getViewportDimensions """ + function getViewportDimensions() { + return { + width: document.documentElement.clientWidth, + height: document.documentElement.clientHeight + }; + } + """ :: forall eff. Eff (dom :: DOM | eff) Dimensions + +foreign import updatePosition """ + function updatePosition(node) { + return function(coord) { + return function() { + node.style.left = coord.x + 'px'; + node.style.bottom = coord.y + 'px'; + }; + }; + } + """ :: Node -> Coordinate -> forall eff. Eff (dom :: DOM | eff) Unit + +foreign import updateSprite """ + function updateSprite(node) { + return function(url) { + return function() { + if (node.src !== url) node.src = url; + }; + }; + } + """ :: Node -> String -> forall eff. Eff (dom :: DOM | eff) Unit + +foreign import onDOMContentLoaded """ + function onDOMContentLoaded(action) { + if (document.readyState === 'interactive') { + action(); + } else { + document.addEventListener('DOMContentLoaded', action); + } + return function() { return {}; }; + } + """ :: forall eff a. Eff (dom :: DOM | eff) a -> Eff (eff) Unit + +foreign import getMario + "function getMario() { return document.getElementById('mario'); }" + :: forall eff. Eff (dom :: DOM | eff) Node +