From d1d00f46450c10ea388b2bff84974dd29cf3efb0 Mon Sep 17 00:00:00 2001 From: Benjamin San Souci Date: Sat, 2 Dec 2017 13:17:48 -0800 Subject: [PATCH] Initial commit --- .gitignore | 3 + README.md | 31 ++++ assets/font/font.fnt | 194 ++++++++++++++++++++++ assets/font/font.png | Bin 0 -> 10628 bytes assets/spritesheet.png | Bin 0 -> 12536 bytes bsconfig.json | 16 ++ index.html | 9 ++ package.json | 17 ++ require_polyfill.js | 129 +++++++++++++++ src/IndexHot.re | 1 + src/index.re | 357 +++++++++++++++++++++++++++++++++++++++++ 11 files changed, 757 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100755 assets/font/font.fnt create mode 100755 assets/font/font.png create mode 100644 assets/spritesheet.png create mode 100644 bsconfig.json create mode 100644 index.html create mode 100644 package.json create mode 100644 require_polyfill.js create mode 100644 src/IndexHot.re create mode 100644 src/index.re diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..60ecc82 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +lib +node_modules +.merlin diff --git a/README.md b/README.md new file mode 100644 index 0000000..c1b1c29 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +Reprocessing example project +--- + +This is a starter example project. Just clone to get started! + +## How to +``` +git clone https://github.com/bsansouci/reprocessing-example.git +``` + +### Install +_warning_: this doesn't work with npm5 yet. Use npm4 or use yarn. To downgrade to npm4 you can `npm install -g npm@latest-4` +``` +yarn +``` + +### Build +``` +npm run build +``` + +### Start +``` +npm start +``` + +To build to JS run `npm run build:web` and then run a static server, like `python -m SimpleHTTPServer` and go to `localhost:8000`. If you're using safari you can simply open the `index.html` and tick `Develop > Disable Cross-Origin Restrictions`. + +To build to native run `npm run build:native` and run `npm run start:native` + +The build system used is [bsb-native](https://github.com/bsansouci/bsb-native). diff --git a/assets/font/font.fnt b/assets/font/font.fnt new file mode 100755 index 0000000..90c08a3 --- /dev/null +++ b/assets/font/font.fnt @@ -0,0 +1,194 @@ +info face=font size=32 bold=0 italic=0 charset= unicode= stretchH=100 smooth=1 aa=1 padding=3,3,3,3 spacing=0,0 outline=0 +common lineHeight=36 base=25 scaleW=256 scaleH=256 pages=1 packed=0 +page id=0 file="font.png" +chars count=91 +char id=97 x=3 y=3 width=16 height=18 xoffset=1 yoffset=8 xadvance=18 page=0 chnl=15 +char id=98 x=3 y=24 width=15 height=24 xoffset=2 yoffset=2 xadvance=18 page=0 chnl=15 +char id=99 x=3 y=51 width=15 height=18 xoffset=1 yoffset=8 xadvance=16 page=0 chnl=15 +char id=100 x=3 y=72 width=15 height=24 xoffset=1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=101 x=3 y=99 width=16 height=18 xoffset=1 yoffset=8 xadvance=18 page=0 chnl=15 +char id=102 x=21 y=24 width=10 height=24 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=103 x=21 y=51 width=15 height=24 xoffset=1 yoffset=8 xadvance=18 page=0 chnl=15 +char id=104 x=34 y=3 width=14 height=23 xoffset=2 yoffset=2 xadvance=18 page=0 chnl=15 +char id=105 x=3 y=120 width=3 height=23 xoffset=2 yoffset=2 xadvance=7 page=0 chnl=15 +char id=106 x=3 y=146 width=7 height=30 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=15 +char id=107 x=9 y=120 width=14 height=23 xoffset=2 yoffset=2 xadvance=16 page=0 chnl=15 +char id=108 x=22 y=78 width=3 height=23 xoffset=2 yoffset=2 xadvance=7 page=0 chnl=15 +char id=109 x=34 y=29 width=23 height=17 xoffset=2 yoffset=8 xadvance=27 page=0 chnl=15 +char id=110 x=51 y=3 width=14 height=17 xoffset=2 yoffset=8 xadvance=18 page=0 chnl=15 +char id=111 x=3 y=179 width=16 height=18 xoffset=1 yoffset=8 xadvance=18 page=0 chnl=15 +char id=112 x=13 y=146 width=15 height=24 xoffset=2 yoffset=8 xadvance=18 page=0 chnl=15 +char id=113 x=26 y=104 width=15 height=24 xoffset=1 yoffset=8 xadvance=18 page=0 chnl=15 +char id=114 x=22 y=3 width=9 height=17 xoffset=2 yoffset=8 xadvance=11 page=0 chnl=15 +char id=115 x=28 y=78 width=14 height=18 xoffset=1 yoffset=8 xadvance=16 page=0 chnl=15 +char id=116 x=39 y=49 width=8 height=23 xoffset=1 yoffset=3 xadvance=9 page=0 chnl=15 +char id=117 x=3 y=200 width=14 height=17 xoffset=2 yoffset=8 xadvance=18 page=0 chnl=15 +char id=118 x=3 y=220 width=16 height=17 xoffset=0 yoffset=8 xadvance=16 page=0 chnl=15 +char id=119 x=20 y=200 width=23 height=17 xoffset=0 yoffset=8 xadvance=23 page=0 chnl=15 +char id=120 x=22 y=173 width=16 height=17 xoffset=0 yoffset=8 xadvance=16 page=0 chnl=15 +char id=121 x=22 y=220 width=16 height=24 xoffset=1 yoffset=8 xadvance=16 page=0 chnl=15 +char id=122 x=41 y=220 width=15 height=17 xoffset=1 yoffset=8 xadvance=16 page=0 chnl=15 +char id=65 x=31 y=131 width=22 height=23 xoffset=0 yoffset=2 xadvance=21 page=0 chnl=15 +char id=66 x=44 y=99 width=18 height=23 xoffset=2 yoffset=2 xadvance=21 page=0 chnl=15 +char id=67 x=41 y=157 width=21 height=24 xoffset=2 yoffset=2 xadvance=23 page=0 chnl=15 +char id=68 x=56 y=125 width=19 height=23 xoffset=2 yoffset=2 xadvance=23 page=0 chnl=15 +char id=69 x=46 y=184 width=17 height=23 xoffset=3 yoffset=2 xadvance=21 page=0 chnl=15 +char id=70 x=65 y=151 width=16 height=23 xoffset=3 yoffset=2 xadvance=20 page=0 chnl=15 +char id=71 x=59 y=210 width=22 height=24 xoffset=2 yoffset=2 xadvance=25 page=0 chnl=15 +char id=72 x=66 y=177 width=18 height=23 xoffset=3 yoffset=2 xadvance=23 page=0 chnl=15 +char id=73 x=50 y=49 width=3 height=23 xoffset=3 yoffset=2 xadvance=9 page=0 chnl=15 +char id=74 x=56 y=49 width=13 height=24 xoffset=1 yoffset=2 xadvance=16 page=0 chnl=15 +char id=75 x=60 y=23 width=19 height=23 xoffset=2 yoffset=2 xadvance=21 page=0 chnl=15 +char id=76 x=65 y=76 width=15 height=23 xoffset=2 yoffset=2 xadvance=18 page=0 chnl=15 +char id=77 x=72 y=49 width=22 height=23 xoffset=2 yoffset=2 xadvance=27 page=0 chnl=15 +char id=78 x=82 y=3 width=18 height=23 xoffset=2 yoffset=2 xadvance=23 page=0 chnl=15 +char id=79 x=78 y=102 width=22 height=24 xoffset=2 yoffset=2 xadvance=25 page=0 chnl=15 +char id=80 x=83 y=75 width=18 height=23 xoffset=2 yoffset=2 xadvance=21 page=0 chnl=15 +char id=81 x=97 y=29 width=23 height=25 xoffset=1 yoffset=2 xadvance=25 page=0 chnl=15 +char id=82 x=103 y=3 width=20 height=23 xoffset=3 yoffset=2 xadvance=23 page=0 chnl=15 +char id=83 x=84 y=129 width=19 height=24 xoffset=1 yoffset=2 xadvance=21 page=0 chnl=15 +char id=84 x=103 y=101 width=19 height=23 xoffset=1 yoffset=2 xadvance=20 page=0 chnl=15 +char id=85 x=104 y=57 width=18 height=24 xoffset=3 yoffset=2 xadvance=23 page=0 chnl=15 +char id=86 x=123 y=29 width=21 height=23 xoffset=0 yoffset=2 xadvance=21 page=0 chnl=15 +char id=87 x=126 y=3 width=30 height=23 xoffset=0 yoffset=2 xadvance=30 page=0 chnl=15 +char id=88 x=84 y=203 width=21 height=23 xoffset=0 yoffset=2 xadvance=21 page=0 chnl=15 +char id=89 x=84 y=229 width=21 height=23 xoffset=0 yoffset=2 xadvance=21 page=0 chnl=15 +char id=90 x=87 y=156 width=18 height=23 xoffset=1 yoffset=2 xadvance=20 page=0 chnl=15 +char id=48 x=106 y=127 width=15 height=24 xoffset=1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=49 x=108 y=154 width=9 height=23 xoffset=3 yoffset=2 xadvance=18 page=0 chnl=15 +char id=50 x=108 y=180 width=16 height=23 xoffset=1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=51 x=108 y=206 width=15 height=24 xoffset=1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=52 x=120 y=154 width=16 height=23 xoffset=0 yoffset=2 xadvance=18 page=0 chnl=15 +char id=53 x=124 y=127 width=16 height=23 xoffset=1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=54 x=126 y=206 width=15 height=24 xoffset=1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=55 x=127 y=180 width=15 height=23 xoffset=2 yoffset=2 xadvance=18 page=0 chnl=15 +char id=56 x=139 y=153 width=15 height=24 xoffset=1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=57 x=144 y=206 width=15 height=24 xoffset=1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=33 x=145 y=180 width=4 height=23 xoffset=3 yoffset=2 xadvance=9 page=0 chnl=15 +char id=8470 x=152 y=180 width=31 height=23 xoffset=3 yoffset=2 xadvance=34 page=0 chnl=15 +char id=59 x=45 y=75 width=4 height=21 xoffset=3 yoffset=8 xadvance=9 page=0 chnl=15 +char id=37 x=162 y=206 width=25 height=24 xoffset=2 yoffset=2 xadvance=28 page=0 chnl=15 +char id=58 x=68 y=3 width=4 height=17 xoffset=3 yoffset=8 xadvance=9 page=0 chnl=15 +char id=63 x=125 y=55 width=15 height=24 xoffset=1 yoffset=2 xadvance=18 page=0 chnl=15 +char id=42 x=82 y=29 width=11 height=10 xoffset=1 yoffset=2 xadvance=12 page=0 chnl=15 +char id=40 x=125 y=82 width=8 height=30 xoffset=2 yoffset=2 xadvance=11 page=0 chnl=15 +char id=41 x=136 y=82 width=8 height=30 xoffset=2 yoffset=2 xadvance=11 page=0 chnl=15 +char id=95 x=22 y=193 width=19 height=2 xoffset=0 yoffset=29 xadvance=18 page=0 chnl=15 +char id=43 x=59 y=237 width=15 height=15 xoffset=2 yoffset=6 xadvance=19 page=0 chnl=15 +char id=45 x=44 y=125 width=9 height=3 xoffset=1 yoffset=15 xadvance=11 page=0 chnl=15 +char id=61 x=41 y=240 width=15 height=10 xoffset=2 yoffset=9 xadvance=19 page=0 chnl=15 +char id=46 x=82 y=42 width=4 height=4 xoffset=3 yoffset=22 xadvance=9 page=0 chnl=15 +char id=44 x=97 y=57 width=4 height=8 xoffset=3 yoffset=22 xadvance=9 page=0 chnl=15 +char id=47 x=143 y=55 width=9 height=24 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=124 x=143 y=115 width=3 height=30 xoffset=3 yoffset=2 xadvance=8 page=0 chnl=15 +char id=92 x=147 y=82 width=9 height=24 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=15 +char id=34 x=125 y=115 width=9 height=8 xoffset=1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=39 x=77 y=237 width=4 height=8 xoffset=1 yoffset=2 xadvance=6 page=0 chnl=15 +char id=64 x=149 y=109 width=30 height=30 xoffset=2 yoffset=2 xadvance=32 page=0 chnl=15 +char id=35 x=157 y=142 width=17 height=24 xoffset=0 yoffset=2 xadvance=18 page=0 chnl=15 +char id=36 x=177 y=142 width=16 height=29 xoffset=1 yoffset=0 xadvance=18 page=0 chnl=15 +char id=94 x=3 y=240 width=14 height=13 xoffset=1 yoffset=2 xadvance=15 page=0 chnl=15 +char id=38 x=186 y=174 width=20 height=24 xoffset=1 yoffset=2 xadvance=21 page=0 chnl=15 +char id=123 x=155 y=29 width=9 height=30 xoffset=1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=125 x=159 y=62 width=9 height=30 xoffset=1 yoffset=2 xadvance=11 page=0 chnl=15 +char id=91 x=190 y=201 width=7 height=30 xoffset=2 yoffset=2 xadvance=9 page=0 chnl=15 +char id=93 x=200 y=201 width=7 height=30 xoffset=1 yoffset=2 xadvance=9 page=0 chnl=15 +char id=32 x=0 y=0 width=0 height=0 xoffset=1 yoffset=2 xadvance=9 page=0 chnl=15 +kernings count=97 +kerning first=32 second=65 amount=-2 +kerning first=32 second=84 amount=-1 +kerning first=32 second=89 amount=-1 +kerning first=49 second=49 amount=-2 +kerning first=65 second=32 amount=-2 +kerning first=65 second=84 amount=-2 +kerning first=65 second=86 amount=-2 +kerning first=65 second=87 amount=-1 +kerning first=65 second=89 amount=-2 +kerning first=65 second=118 amount=-1 +kerning first=65 second=119 amount=-1 +kerning first=65 second=121 amount=-1 +kerning first=70 second=44 amount=-4 +kerning first=70 second=46 amount=-4 +kerning first=70 second=65 amount=-2 +kerning first=76 second=32 amount=-1 +kerning first=76 second=84 amount=-2 +kerning first=76 second=86 amount=-2 +kerning first=76 second=87 amount=-2 +kerning first=76 second=89 amount=-2 +kerning first=76 second=121 amount=-1 +kerning first=80 second=32 amount=-1 +kerning first=80 second=44 amount=-4 +kerning first=80 second=46 amount=-4 +kerning first=80 second=65 amount=-2 +kerning first=82 second=84 amount=-1 +kerning first=82 second=86 amount=-1 +kerning first=82 second=87 amount=-1 +kerning first=82 second=89 amount=-1 +kerning first=84 second=32 amount=-1 +kerning first=84 second=44 amount=-4 +kerning first=84 second=45 amount=-2 +kerning first=84 second=46 amount=-4 +kerning first=84 second=58 amount=-4 +kerning first=84 second=59 amount=-4 +kerning first=84 second=65 amount=-2 +kerning first=84 second=79 amount=-1 +kerning first=84 second=97 amount=-4 +kerning first=84 second=99 amount=-4 +kerning first=84 second=101 amount=-4 +kerning first=84 second=105 amount=-1 +kerning first=84 second=111 amount=-4 +kerning first=84 second=114 amount=-1 +kerning first=84 second=115 amount=-4 +kerning first=84 second=117 amount=-1 +kerning first=84 second=119 amount=-2 +kerning first=84 second=121 amount=-2 +kerning first=86 second=44 amount=-3 +kerning first=86 second=45 amount=-2 +kerning first=86 second=46 amount=-3 +kerning first=86 second=58 amount=-1 +kerning first=86 second=59 amount=-1 +kerning first=86 second=65 amount=-2 +kerning first=86 second=97 amount=-2 +kerning first=86 second=101 amount=-2 +kerning first=86 second=105 amount=-1 +kerning first=86 second=111 amount=-2 +kerning first=86 second=114 amount=-1 +kerning first=86 second=117 amount=-1 +kerning first=86 second=121 amount=-1 +kerning first=87 second=44 amount=-2 +kerning first=87 second=45 amount=-1 +kerning first=87 second=46 amount=-2 +kerning first=87 second=58 amount=-1 +kerning first=87 second=59 amount=-1 +kerning first=87 second=65 amount=-1 +kerning first=87 second=97 amount=-1 +kerning first=87 second=101 amount=-1 +kerning first=87 second=105 amount=0 +kerning first=87 second=111 amount=-1 +kerning first=87 second=114 amount=-1 +kerning first=87 second=117 amount=-1 +kerning first=87 second=121 amount=0 +kerning first=89 second=32 amount=-1 +kerning first=89 second=44 amount=-4 +kerning first=89 second=45 amount=-3 +kerning first=89 second=46 amount=-4 +kerning first=89 second=58 amount=-2 +kerning first=89 second=59 amount=-2 +kerning first=89 second=65 amount=-2 +kerning first=89 second=97 amount=-2 +kerning first=89 second=101 amount=-3 +kerning first=89 second=105 amount=-1 +kerning first=89 second=111 amount=-3 +kerning first=89 second=112 amount=-2 +kerning first=89 second=113 amount=-3 +kerning first=89 second=117 amount=-2 +kerning first=89 second=118 amount=-2 +kerning first=102 second=102 amount=-1 +kerning first=114 second=44 amount=-2 +kerning first=114 second=46 amount=-2 +kerning first=118 second=44 amount=-2 +kerning first=118 second=46 amount=-2 +kerning first=119 second=44 amount=-2 +kerning first=119 second=46 amount=-2 +kerning first=121 second=44 amount=-2 +kerning first=121 second=46 amount=-2 \ No newline at end of file diff --git a/assets/font/font.png b/assets/font/font.png new file mode 100755 index 0000000000000000000000000000000000000000..8b7758ca7b973adf018ac1072248ed96df4a4cfd GIT binary patch literal 10628 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 D)xVoj literal 0 HcmV?d00001 diff --git a/bsconfig.json b/bsconfig.json new file mode 100644 index 0000000..01602e3 --- /dev/null +++ b/bsconfig.json @@ -0,0 +1,16 @@ +{ + "name": "reprocessing-example", + "sources": "src", + "bs-dependencies": ["reprocessing"], + "entries": [{ + "backend": "bytecode", + "main-module": "IndexHot" + },{ + "backend": "native", + "main-module": "Index" + },{ + "backend": "js", + "main-module": "Index" + }], + "refmt": 3, +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..115730d --- /dev/null +++ b/index.html @@ -0,0 +1,9 @@ + + + + Reprocessing Example + + + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..4fc60e1 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "reprocessing-example", + "scripts": { + "start": "./lib/bs/bytecode/index.byte", + "start:native": "./lib/bs/native/index.native", + "build": "bsb -make-world", + "build:web": "bsb -make-world -backend js", + "build:native": "bsb -make-world -backend native", + "clean": "bsb -clean-world" + }, + "dependencies": { + "reprocessing": "schmavery/reprocessing" + }, + "devDependencies": { + "bs-platform": "bsansouci/bsb-native" + } +} diff --git a/require_polyfill.js b/require_polyfill.js new file mode 100644 index 0000000..519d0cd --- /dev/null +++ b/require_polyfill.js @@ -0,0 +1,129 @@ +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +}; + +function pathNormalize(path) { + var isAbsolute = path.charAt(0) === '/'; + var trailingSlash = path.substr(-1) === '/'; + + // Normalize the path + path = normalizeArray(path.split('/').filter(function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +var globalEval = eval; +var currentScript = document.currentScript; +var projectRoot = currentScript.dataset['project-root'] || currentScript.dataset['projectRoot']; +if (projectRoot == null) { + throw new Error('The attribute `data-project-root` isn\'t found in the script tag. You need to provide the root (in which node_modules reside).') +} +var nodeModulesDir = projectRoot + '/node_modules/'; + +var modulesCache = {}; +var packageJsonMainCache = {}; + +var ensureEndsWithJs = function(path) { + if (path.endsWith('.js')) { + return path; + } else { + return path + '.js'; + } +}; +function loadScript(scriptPath) { + var request = new XMLHttpRequest(); + + request.open("GET", scriptPath, false); // sync + request.send(); + var dirSeparatorIndex = scriptPath.lastIndexOf('/'); + var dir = dirSeparatorIndex === -1 ? '.' : scriptPath.slice(0, dirSeparatorIndex); + + var moduleText = ` +(function(module, exports, modulesCache, packageJsonMainCache, nodeModulesDir) { + function require(path) { + var __dirname = "${dir}/"; + var resolvedPath; + if (path.startsWith('.')) { + // require('./foo/bar') + resolvedPath = ensureEndsWithJs(__dirname + path); + } else if (path.indexOf('/') === -1) { + // require('react') + var packageJson = pathNormalize(nodeModulesDir + path + '/package.json'); + if (packageJsonMainCache[packageJson] == null) { + var jsonRequest = new XMLHttpRequest(); + jsonRequest.open("GET", packageJson, false); + jsonRequest.send(); + var main; + if (jsonRequest.responseText != null) { + main = JSON.parse(jsonRequest.responseText).main; + }; + if (main == null) { + main = 'index.js'; + } else if (!main.endsWith('.js')) { + main = main + '.js'; + } + packageJsonMainCache[packageJson] = nodeModulesDir + path + '/' + main; + } + resolvedPath = packageJsonMainCache[packageJson]; + } else { + // require('react/bar') + resolvedPath = ensureEndsWithJs(nodeModulesDir + path); + }; + resolvedPath = pathNormalize(resolvedPath); + if (modulesCache[resolvedPath] != null) { + return modulesCache[resolvedPath]; + }; + var result = loadScript(resolvedPath); + modulesCache[resolvedPath] = result; + return result; + }; + var process = {env: {}, argv: []}; + var global = {}; + + +// -------Begin Require Polyfilled Module Loaded From Disk------------------------------ +// file: ${scriptPath} +// root: ${projectRoot} +// ---------------------------------------------------------------------- +${request.responseText} +// -------End Polyfill Loaded From Disk------------------------------ +// file: ${scriptPath} +// root: ${projectRoot} +// ---------------------------------------------------------------------- +return module.exports})\n//@ sourceURL=${scriptPath}`; + var module = {exports: {}}; + return globalEval(moduleText)(module, module.exports, modulesCache, packageJsonMainCache, nodeModulesDir); +}; + +loadScript(currentScript.dataset.main) diff --git a/src/IndexHot.re b/src/IndexHot.re new file mode 100644 index 0000000..e2e15e3 --- /dev/null +++ b/src/IndexHot.re @@ -0,0 +1 @@ +Reprocessing.hotreload("src/index.re"); diff --git a/src/index.re b/src/index.re new file mode 100644 index 0000000..5259a86 --- /dev/null +++ b/src/index.re @@ -0,0 +1,357 @@ +open Reprocessing; + +let playerSpeed = 4.; + +let bulletSpeed = 6.; + +type vec2T = { + x: float, + y: float +}; + +type bulletT = { + pos: vec2T, + direction: vec2T, + time: float, + moveBullet: bulletT => vec2T +}; + +type achievementStateT = + | Locked + | Unlocked; + +type gunT = { + amunition: int, + color: colorT, + keyToggle: Reprocessing_Common.KeySet.elt, + fire: (stateT, Reprocessing_Common.KeySet.elt) => stateT +} +and achievementT = { + gun: gunT, + state: achievementStateT, + condition: (stateT, glEnvT) => bool +} +and stateT = { + pos: vec2T, + guns: list(gunT), + equippedGun: int, + playerBullets: list(bulletT), + achievements: list(achievementT), + mainFont: fontT +}; + +let add = (v1, v2) => {x: v1.x +. v2.x, y: v1.y +. v2.y}; + +let defaultGun = { + amunition: 10, + color: Utils.color(155, 155, 0, 255), + keyToggle: Num_1, + fire: (state, direction) => { + let dir = + switch direction { + | Up => {x: 0., y: -. bulletSpeed} + | Down => {x: 0., y: bulletSpeed} + | Left => {x: -. bulletSpeed, y: 0.} + | Right => {x: bulletSpeed, y: 0.} + | _ => assert false + }; + let moveBullet = (bullet: bulletT) => add(bullet.pos, bullet.direction); + { + ...state, + guns: + List.mapi( + (i, gun) => + if (i === state.equippedGun) { + {...gun, amunition: max(gun.amunition - 1, 0)} + } else { + gun + }, + state.guns + ), + playerBullets: + List.nth(state.guns, state.equippedGun).amunition > 0 ? + [ + {pos: {x: state.pos.x, y: state.pos.y}, direction: dir, moveBullet, time: 0.}, + ...state.playerBullets + ] : + state.playerBullets + } + } +}; + +let gunWithSpread = { + amunition: 10, + color: Utils.color(0, 255, 0, 255), + keyToggle: Num_2, + fire: (state, direction) => { + let otherSpeed = 2.; + let dir1 = + switch direction { + | Up => {x: -. otherSpeed, y: -. bulletSpeed} + | Down => {x: otherSpeed, y: bulletSpeed} + | Left => {x: -. bulletSpeed, y: otherSpeed} + | Right => {x: bulletSpeed, y: -. otherSpeed} + | _ => assert false + }; + let dir2 = + switch direction { + | Up => {x: 0., y: -. bulletSpeed} + | Down => {x: 0., y: bulletSpeed} + | Left => {x: -. bulletSpeed, y: 0.} + | Right => {x: bulletSpeed, y: 0.} + | _ => assert false + }; + let dir3 = + switch direction { + | Up => {x: otherSpeed, y: -. bulletSpeed} + | Down => {x: -. otherSpeed, y: bulletSpeed} + | Left => {x: -. bulletSpeed, y: -. otherSpeed} + | Right => {x: bulletSpeed, y: otherSpeed} + | _ => assert false + }; + let moveBullet = (bullet: bulletT) => add(bullet.pos, bullet.direction); + { + ...state, + guns: + List.mapi( + (i, gun) => + if (i === state.equippedGun) { + {...gun, amunition: max(gun.amunition - 1, 0)} + } else { + gun + }, + state.guns + ), + playerBullets: + List.nth(state.guns, state.equippedGun).amunition > 0 ? + [ + {pos: {x: state.pos.x, y: state.pos.y}, direction: dir1, moveBullet, time: 0.}, + {pos: {x: state.pos.x, y: state.pos.y}, direction: dir2, moveBullet, time: 0.}, + {pos: {x: state.pos.x, y: state.pos.y}, direction: dir3, moveBullet, time: 0.}, + ...state.playerBullets + ] : + state.playerBullets + } + } +}; + +let gunWithSine = { + amunition: 10, + color: Utils.color(0, 155, 155, 255), + keyToggle: Num_3, + fire: (state, direction) => { + let otherSpeed = 2.; + let dir1 = + switch direction { + | Up => {x: -. otherSpeed, y: -. bulletSpeed} + | Down => {x: otherSpeed, y: bulletSpeed} + | Left => {x: -. bulletSpeed, y: otherSpeed} + | Right => {x: bulletSpeed, y: -. otherSpeed} + | _ => assert false + }; + let dir2 = + switch direction { + | Up => {x: 0., y: -. bulletSpeed} + | Down => {x: 0., y: bulletSpeed} + | Left => {x: -. bulletSpeed, y: 0.} + | Right => {x: bulletSpeed, y: 0.} + | _ => assert false + }; + let dir3 = + switch direction { + | Up => {x: otherSpeed, y: -. bulletSpeed} + | Down => {x: -. otherSpeed, y: bulletSpeed} + | Left => {x: -. bulletSpeed, y: -. otherSpeed} + | Right => {x: bulletSpeed, y: otherSpeed} + | _ => assert false + }; + let moveBullet = (bullet: bulletT) => { + let pos = add(bullet.pos, bullet.direction); + let perpendicular = {x: -. bullet.direction.y, y: bullet.direction.x}; + /*let perpendicular = bullet.direction;*/ + let perpendicularSize = + sqrt(perpendicular.x *. perpendicular.x +. perpendicular.y *. perpendicular.y); + let perpendicular = { + x: perpendicular.x /. perpendicularSize, + y: perpendicular.y /. perpendicularSize + }; + let norm = cos(bullet.time /. 5.); + let offset = {x: perpendicular.x *. norm *. 3., y: perpendicular.y *. norm *. 3.}; + add(pos, offset) + }; + { + ...state, + guns: + List.mapi( + (i, gun) => + if (i === state.equippedGun) { + {...gun, amunition: max(gun.amunition - 1, 0)} + } else { + gun + }, + state.guns + ), + playerBullets: + List.nth(state.guns, state.equippedGun).amunition > 0 ? + [ + {pos: {x: state.pos.x, y: state.pos.y}, direction: dir1, moveBullet, time: 0.}, + {pos: {x: state.pos.x, y: state.pos.y}, direction: dir2, moveBullet, time: 0.}, + {pos: {x: state.pos.x, y: state.pos.y}, direction: dir3, moveBullet, time: 0.}, + ...state.playerBullets + ] : + state.playerBullets + } + } +}; + +let gunWithTrail = { + amunition: 10, + color: Utils.color(0, 100, 100, 255), + keyToggle: Num_4, + fire: (state, direction) => { + let dir2 = + switch direction { + | Up => {x: 0., y: -. bulletSpeed} + | Down => {x: 0., y: bulletSpeed} + | Left => {x: -. bulletSpeed, y: 0.} + | Right => {x: bulletSpeed, y: 0.} + | _ => assert false + }; + let moveBullet = (bullet: bulletT) => add(bullet.pos, bullet.direction); + { + ...state, + guns: + List.mapi( + (i, gun) => + if (i === state.equippedGun) { + {...gun, amunition: max(gun.amunition - 1, 0)} + } else { + gun + }, + state.guns + ), + playerBullets: + List.nth(state.guns, state.equippedGun).amunition > 0 ? + [ + {pos: {x: state.pos.x, y: state.pos.y}, direction: dir2, moveBullet, time: 0.}, + { + pos: add(add({x: state.pos.x, y: state.pos.y}, dir2), dir2), + direction: dir2, + moveBullet, + time: 0. + }, + { + pos: add(add(add(add({x: state.pos.x, y: state.pos.y}, dir2), dir2), dir2), dir2), + direction: dir2, + moveBullet, + time: 0. + }, + ...state.playerBullets + ] : + state.playerBullets + } + } +}; + +let achievement1 = { + gun: gunWithSpread, + state: Locked, + condition: (state, env) => Env.keyPressed(B, env) +}; + +let drawKey = (x, y, gun, state, env) => { + let body = + switch gun.keyToggle { + | Num_1 => "1" + | Num_2 => "2" + | Num_3 => "3" + | Num_4 => "4" + | Num_5 => "5" + | Num_6 => "6" + | _ => assert false + }; + Draw.text(state.mainFont, body, (int_of_float(x), int_of_float(y) + 10), env) +}; + +let setup = (env) => { + Env.size(~width=1280, ~height=720, env); + { + pos: {x: 50., y: 50.}, + equippedGun: 0, + guns: [defaultGun], + playerBullets: [], + achievements: [achievement1], + mainFont: Draw.loadFont(~filename="assets/font/font.fnt", ~isPixel=true, env) + } +}; + +let draw = (state, env) => { + Draw.background(Utils.color(~r=199, ~g=217, ~b=229, ~a=255), env); + Draw.fill(Utils.color(~r=41, ~g=166, ~b=244, ~a=255), env); + Draw.rectMode(Corner, env); + let state = { + ...state, + playerBullets: + List.map( + (bullet) => {...bullet, pos: bullet.moveBullet(bullet), time: bullet.time +. 1.}, + state.playerBullets + ) + }; + let state = + Env.key(A, env) ? {...state, pos: {x: state.pos.x -. playerSpeed, y: state.pos.y}} : state; + let state = + Env.key(D, env) ? {...state, pos: {x: state.pos.x +. playerSpeed, y: state.pos.y}} : state; + let state = + Env.key(W, env) ? {...state, pos: {x: state.pos.x, y: state.pos.y -. playerSpeed}} : state; + let state = + Env.key(S, env) ? {...state, pos: {x: state.pos.x, y: state.pos.y +. playerSpeed}} : state; + let rec foldOverGuns = (state, guns, i) => + switch guns { + | [] => state + | [gun] => Env.keyPressed(gun.keyToggle, env) ? {...state, equippedGun: i} : state + | [gun, ...guns] => + foldOverGuns( + Env.keyPressed(gun.keyToggle, env) ? {...state, equippedGun: i} : state, + guns, + i + 1 + ) + }; + let state = foldOverGuns(state, state.guns, 0); + let curGun = List.nth(state.guns, state.equippedGun); + let state = Env.keyPressed(Up, env) ? curGun.fire(state, Up) : state; + let state = Env.keyPressed(Down, env) ? curGun.fire(state, Down) : state; + let state = Env.keyPressed(Left, env) ? curGun.fire(state, Left) : state; + let state = Env.keyPressed(Right, env) ? curGun.fire(state, Right) : state; + Draw.rectf(~pos=(state.pos.x, state.pos.y), ~width=30., ~height=30., env); + List.iter( + ({pos, direction: _}) => { + Draw.fill(Utils.color(~r=41, ~g=166, ~b=244, ~a=255), env); + Draw.rectf(~pos=(pos.x, pos.y), ~width=5., ~height=5., env) + }, + state.playerBullets + ); + ignore @@ + List.fold_left( + ((x, y, i), gun) => { + Draw.fill(gun.color, env); + Draw.rectf(~pos=(x +. 25., y +. 5.), ~width=40., ~height=40., env); + if (i === state.equippedGun) { + Draw.fill(Utils.color(255, 0, 0, 255), env); + Draw.rectf(~pos=(x +. 35., y +. 15.), ~width=20., ~height=20., env) + }; + Draw.text( + state.mainFont, + string_of_int(gun.amunition), + (int_of_float(x) + 70, int_of_float(y) + 10), + env + ); + drawKey(x, y, gun, state, env); + (x, y +. 50., i + 1) + }, + (10., 20., 0), + state.guns + ); + state +}; + +run(~setup, ~draw, ());