├── index.js
├── src
├── post.js
├── pre.js
├── definitions.js
├── env_prod.js
├── shaders
│ ├── static.vert
│ └── badcolor.frag
├── player.js
├── canvasRenderer.js
├── index.html
├── tiles.js
├── backgroundEffects.js
├── gameloop.js
├── webglRenderer.js
├── env_dev.js
├── effects.js
├── sounds.js
├── font.js
├── collisionHandler.js
├── items.js
├── levelUpScene.js
├── spriteLoader.js
├── scene.js
├── gameObject.js
├── gameHud.js
├── theScript.js
├── generatedSprites.js
├── gameSetup.js
├── fighterController.js
└── fighter.js
├── scripts
├── wrapjs.sh
├── compileglsfiles.sh
└── concat.sh
├── README.md
├── assets
├── hero17.sprite
├── hero18.sprite
├── hero19.sprite
├── hero20.sprite
├── hero21.sprite
├── hero22.sprite
├── hero08_jump_01.sprite
├── hero05_run_02.sprite
├── hero16_defeated_00.sprite
├── hero14_knocked_down_00.sprite
├── hero11_get_hit_face_00.sprite
├── hero12_get_hit_body_00.sprite
├── hero13_get_hit_legs_00.sprite
├── hero06_speed_punch_00.sprite
├── hero10_dragon_kick_00.sprite
├── hero15_wake_up_00.sprite
├── hero08_jump_00.sprite
├── hero02_punch_01.sprite
├── hero02_punch_02.sprite
├── hero03_kick_01.sprite
├── hero03_kick_02.sprite
├── hero09_air_kick_00.sprite
├── hero08_jump_02.sprite
├── hero04_walk_00.sprite
├── hero01_idle_00.sprite
├── hero07_speed_kick_00.sprite
├── z_explosion_02.sprite
├── z_explosion_01.sprite
├── z_tilemap_00.sprite
├── hero05_run_01.sprite
└── fonts.sprite
├── lib
├── utils.js
├── keyboardController.js
├── audio.js
├── stats.min.js
├── webgl.js
└── jsfxr.js
├── script.temp
├── todo
├── LICENSE.txt
├── .gitignore
├── spriteChangeSide.js
├── sprite.temp
├── package.json
└── spriteConverter.js
/index.js:
--------------------------------------------------------------------------------
1 | console.log('index.js?')
--------------------------------------------------------------------------------
/src/post.js:
--------------------------------------------------------------------------------
1 | // ending wrap code
2 | })();
--------------------------------------------------------------------------------
/src/pre.js:
--------------------------------------------------------------------------------
1 | // start wrapping code
2 | (function() {
3 |
--------------------------------------------------------------------------------
/src/definitions.js:
--------------------------------------------------------------------------------
1 |
2 | var W = 320;
3 | var H = 240;
4 |
5 | var c = document.getElementById('c');
6 | var g = document.getElementById('g');
--------------------------------------------------------------------------------
/src/env_prod.js:
--------------------------------------------------------------------------------
1 | const DEBUG = false; // eslint-disable-line no-unused-vars
2 | var _fps_
3 | var _processing_
4 | var _memory_
5 | var _enemies_
6 |
7 |
--------------------------------------------------------------------------------
/src/shaders/static.vert:
--------------------------------------------------------------------------------
1 | attribute vec2 p;
2 | varying vec2 uv;
3 |
4 | void main() {
5 | gl_Position = vec4(p,.0,1.);
6 | uv = .5 * (p+1.);
7 | }
--------------------------------------------------------------------------------
/src/player.js:
--------------------------------------------------------------------------------
1 | // src/player.js >>>
2 |
3 |
4 | var player = Fighter([8, 120, FIGHTER_STATUS_IDS[0], '#ddfed9']);
5 | var basePlayerStat = {
6 | maxHp: 30,
7 | damage: 0,
8 | defense: 0
9 | };
10 |
--------------------------------------------------------------------------------
/scripts/wrapjs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # original script from @gre
3 | # https://github.com/gre/behind-asteroids/blob/master/scripts/wrapjs.sh
4 | # usage: cat glslfile | ./wrapjs.sh varname
5 |
6 | echo -n "var $1 ='"
7 | perl -p -e 's/\n/\\n/';
8 | echo -ne "';"
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # js13k2018
2 | Without a code name... yet...
3 |
4 |
5 | # npm packages
6 | - https://www.npmjs.com/package/nodemon
7 |
8 | ## installation
9 |
10 | `npm run install`
11 |
12 | ## live-reload server
13 |
14 | `npm run start`
15 |
16 | ## build zip generator
17 |
18 | `npm run build`
--------------------------------------------------------------------------------
/src/canvasRenderer.js:
--------------------------------------------------------------------------------
1 | // src/canvasRenderer.js >>>
2 |
3 | var graphics = c.getContext('2d');
4 |
5 | var animationIndex = 0;
6 | var pixelSize = 2;
7 | var frames = animations[0];
8 |
9 | function draw() {
10 |
11 | drawBackground();
12 | sceneManager.draw();
13 | }
14 |
15 | // ending file
16 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
JS13K 2018 @agar3s
--------------------------------------------------------------------------------
/src/tiles.js:
--------------------------------------------------------------------------------
1 | // src/tiles.js
2 |
3 | function Tile(props) {
4 | var base = Sprite([props[0], props[1], 30]);
5 | base.frame = base.animation[props[2]];
6 | base.color = '#ddfed9';
7 | base.pixelSize = 2;
8 | var extended = {
9 | update: function(){}
10 | }
11 | extendFunction(base, extended);
12 | return extended;
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/assets/hero17.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | _______MM_______
5 | _______MM_______
6 | ______MM________
7 | ______MM_M______
8 | ______MMM_______
9 | ______MM________
10 | _______MM_______
11 | _______M_M______
12 | _______M__M_____
13 | _______M__M_____
14 | ______M__M______
15 | ______M__M______
16 | _____M___M______
17 | Animation:
18 | 0
--------------------------------------------------------------------------------
/assets/hero18.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | _______MM_______
5 | _______MM_______
6 | ______MM________
7 | ______MM_M______
8 | ______MMM_______
9 | ______MM________
10 | _______MM_______
11 | _______M_M______
12 | _______M__M_____
13 | _______M__M_____
14 | ______M__M______
15 | ______M__M______
16 | _____M___M______
17 | Animation:
18 | 0
--------------------------------------------------------------------------------
/assets/hero19.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | _______MM_______
5 | _______MM_______
6 | ______MM________
7 | ______MM_M______
8 | ______MMM_______
9 | ______MM________
10 | _______MM_______
11 | _______M_M______
12 | _______M__M_____
13 | _______M__M_____
14 | ______M__M______
15 | ______M__M______
16 | _____M___M______
17 | Animation:
18 | 0
--------------------------------------------------------------------------------
/assets/hero20.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | _______MM_______
5 | _______MM_______
6 | ______MM________
7 | ______MM_M______
8 | ______MMM_______
9 | ______MM________
10 | _______MM_______
11 | _______M_M______
12 | _______M__M_____
13 | _______M__M_____
14 | ______M__M______
15 | ______M__M______
16 | _____M___M______
17 | Animation:
18 | 0
--------------------------------------------------------------------------------
/assets/hero21.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | _______MM_______
5 | _______MM_______
6 | ______MM________
7 | ______MM_M______
8 | ______MMM_______
9 | ______MM________
10 | _______MM_______
11 | _______M_M______
12 | _______M__M_____
13 | _______M__M_____
14 | ______M__M______
15 | ______M__M______
16 | _____M___M______
17 | Animation:
18 | 0
--------------------------------------------------------------------------------
/assets/hero22.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | _______MM_______
5 | _______MM_______
6 | ______MM________
7 | ______MM_M______
8 | ______MMM_______
9 | ______MM________
10 | _______MM_______
11 | _______M_M______
12 | _______M__M_____
13 | _______M__M_____
14 | ______M__M______
15 | ______M__M______
16 | _____M___M______
17 | Animation:
18 | 0
--------------------------------------------------------------------------------
/assets/hero08_jump_01.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________MM______
3 | ______MMMM______
4 | _____M_MM_______
5 | _____M_MMM______
6 | _____M_MM_______
7 | _______M________
8 | _______MMM______
9 | ________M_M_____
10 | ________M_M_____
11 | ________MM______
12 | _______MM_______
13 | _______M________
14 | _______M________
15 | _______M________
16 | ________________
17 | Animation:
18 | 0
--------------------------------------------------------------------------------
/assets/hero05_run_02.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | ______MM________
6 | ______MM________
7 | ______MMM_M_____
8 | _____M_MMM______
9 | ______MMM_______
10 | ________M_______
11 | ________MM______
12 | ________M_M_____
13 | ________M__M____
14 | ________M__M____
15 | _______M____M___
16 | _______M_____M__
17 | Animation:
18 | 0,0,0
--------------------------------------------------------------------------------
/assets/hero16_defeated_00.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | ________________
6 | ________________
7 | ________________
8 | ________________
9 | ________________
10 | ________________
11 | ________________
12 | ________________
13 | ________________
14 | ________________
15 | __MMMMMM________
16 | MMMMMMMMMMMMMMMM
17 | Animation:
18 | 0
--------------------------------------------------------------------------------
/assets/hero14_knocked_down_00.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | _____M__________
6 | _CC__M__________
7 | _CC__M__________
8 | __CCC___________
9 | __CCCC__________
10 | __M__MMMMM______
11 | __M___MM__M_____
12 | ___M____M_M_____
13 | _______M___M____
14 | _______M___M____
15 | ______M_________
16 | ______M_________
17 | Animation:
18 | 0
--------------------------------------------------------------------------------
/assets/hero11_get_hit_face_00.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | _____MM_________
6 | _____MM_________
7 | _____MMM________
8 | _____MMMM_______
9 | ____M_MM________
10 | ______MM________
11 | ______MMM_______
12 | _______MM_______
13 | _______M_M______
14 | _______M_M______
15 | _______M__M_____
16 | ______M___M_____
17 | Animation:
18 | 0,0,0
--------------------------------------------------------------------------------
/assets/hero12_get_hit_body_00.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | ________________
6 | _________MM_____
7 | ________MMM_____
8 | _______MMM______
9 | _______MM_______
10 | _______MM_______
11 | _______M________
12 | _______MM_______
13 | _______M_M______
14 | ________M_M_____
15 | _______M__M_____
16 | ______M__M______
17 | Animation:
18 | 0,0,0
--------------------------------------------------------------------------------
/assets/hero13_get_hit_legs_00.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | ___________MM___
6 | _________MMMM___
7 | ________MMM_____
8 | _______MMM_M____
9 | _______MM_M_MM__
10 | ______MM________
11 | ___M__MMM_______
12 | ____M_M__M______
13 | _____M___M______
14 | _______MM_______
15 | ______M_________
16 | ________________
17 | Animation:
18 | 0,0,0,0
--------------------------------------------------------------------------------
/assets/hero06_speed_punch_00.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | ________________
6 | __________MM____
7 | _______MM_MM____
8 | ______M__CCCCCCC
9 | ________MMM_____
10 | _______MM_______
11 | ______MM________
12 | _____M__MM______
13 | ___MM_____M_____
14 | __M_____MM______
15 | _M_____M________
16 | M______M________
17 | Animation:
18 | 0,0,0,0,0,0
--------------------------------------------------------------------------------
/assets/hero10_dragon_kick_00.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | ____MM__________
6 | ____MM__________
7 | ___MMM_M________
8 | ___MMMM_________
9 | __M__MM_________
10 | ___M__MMM_______
11 | ______MMMM______
12 | __________MM____
13 | _________MM_C___
14 | _____________CC_
15 | ______________CC
16 | ________________
17 | Animation:
18 | 0,0,0,0,0,0
--------------------------------------------------------------------------------
/assets/hero15_wake_up_00.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | ________________
6 | ________________
7 | ________________
8 | ________________
9 | ________________
10 | ________________
11 | ________________
12 | _______MMMM_____
13 | ______MMMMMMM___
14 | ______MM__MMM___
15 | ___MMMMM__M_____
16 | __M_MMMMM__M____
17 | Animation:
18 | 0,0,0,0,0,0,0,0,0,0,0,0,0
--------------------------------------------------------------------------------
/lib/utils.js:
--------------------------------------------------------------------------------
1 |
2 | var getRandomValue = function(value, offset) {
3 | return Math.random()*(value||1) + (offset||0);
4 | }
5 |
6 | var randomSign = function() {
7 | return getRandomValue()>0.5?1:-1;
8 | }
9 |
10 | var extendFunction = function(parent, child) {
11 | var keys = Object.keys(parent);
12 | for(var i=0; i= flashEffect[0]) {
21 | flashEffect[3] = 0;
22 | currentBackground = '#0c1d05';
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/scripts/compileglsfiles.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # original script from @gre
3 | # https://github.com/gre/behind-asteroids/blob/master/scripts/compileglsfiles.sh
4 |
5 | if [ "$#" -ne 2 ]; then
6 | echo "Invalid arguments. Usage: $0 fromDir toDir" >&2;
7 | exit 1;
8 | fi;
9 | if [ "$1" == "$2" ]; then
10 | echo "fromDir and toDir must be different" >&2;
11 | exit 2;
12 | fi;
13 | if [ ! -d "$1" ]; then
14 | echo "fromDir must be a directory" >&2;
15 | exit 3;
16 | fi;
17 | if [ ! -d "$2" ]; then
18 | echo "toDir must be a directory" >&2;
19 | exit 4;
20 | fi;
21 |
22 | for glsl in $1/*.frag $1/*.vert; do
23 | name=`basename $glsl`;
24 | cat $glsl | glslmin > $2/$name;
25 | done;
26 |
--------------------------------------------------------------------------------
/src/gameloop.js:
--------------------------------------------------------------------------------
1 | // src/gameLoop.js >>>
2 |
3 | var timeEnd = 0;
4 | function loop(time) {
5 | if(DEBUG){
6 | _fps_.begin();
7 | _processing_.begin();
8 | _memory_.begin();
9 | _enemies_.begin();
10 | }
11 | var dt = time - timeEnd;
12 | var refreshRatio = dt/1000;
13 | timeEnd = time;
14 | resetMatrix();
15 | updateBackgroud(refreshRatio);
16 | sceneManager.update(time, refreshRatio);
17 |
18 | draw();
19 | // drawPostProcessing(~~(time));
20 | requestAnimationFrame(loop);
21 |
22 | if(DEBUG){
23 | _fps_.end();
24 | _processing_.end();
25 | _memory_.end();
26 | _enemies_.end();
27 | //enemiesPanel.update(enemies?enemies.length:0, 1000);
28 | }
29 | }
30 |
31 | loop(1);
32 |
--------------------------------------------------------------------------------
/assets/hero08_jump_00.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | ________________
6 | ________MM______
7 | ________MM______
8 | _______MM_______
9 | ______MMM_M_____
10 | ______MMMM______
11 | _______M________
12 | _______MMMM_____
13 | ________M__M____
14 | ________M_M_____
15 | _______M__M_____
16 | ______M___M_____
17 | //new Frame
18 | ________________
19 | ________________
20 | ________MM______
21 | _______MMM______
22 | ______MMM_M_____
23 | ______MMMM______
24 | ______MM________
25 | _______MM_______
26 | _______MMM______
27 | ________M_M_____
28 | ________M_M_____
29 | _______M_M______
30 | ______M__M______
31 | _____M__M_______
32 | ________M_______
33 | ________________
34 | Animation:
35 | 0,1
--------------------------------------------------------------------------------
/assets/hero02_punch_01.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | _______MM_______
5 | _______MM_______
6 | ______MM________
7 | ______MM_M______
8 | ______MMM_______
9 | ______MM________
10 | _______MM_______
11 | _______M_M______
12 | _______M__M_____
13 | _______M__M_____
14 | ______M__M______
15 | ______M__M______
16 | _____M___M______
17 | //new Frame
18 | ________________
19 | ________________
20 | ________________
21 | _______MM_______
22 | ______CCCCCCCC__
23 | _____MMM________
24 | _____MMM________
25 | ______MM________
26 | ______MM________
27 | _______MM_______
28 | _______M_M______
29 | _______M__M_____
30 | _______M__M_____
31 | ______M__M______
32 | ______M__M______
33 | _____M___M______
34 | Animation:
35 | 0,1,1,0
--------------------------------------------------------------------------------
/assets/hero02_punch_02.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | _______MM_______
5 | _______MM_______
6 | ______MM________
7 | ______MM_M______
8 | ______MMM_______
9 | ______MM________
10 | _______MM_______
11 | _______M_M______
12 | _______M__M_____
13 | _______M__M_____
14 | ______M__M______
15 | ______M__M______
16 | _____M___M______
17 | //new Frame
18 | ________________
19 | ________________
20 | ________________
21 | ________________
22 | ________MM______
23 | ________MM______
24 | _______MCC______
25 | ______MMM_CC____
26 | _______MM___CC__
27 | _______MM_______
28 | _______MMM______
29 | ______M___M_____
30 | ______M___M_____
31 | _____M___M______
32 | _____M___M______
33 | ____M____M______
34 | Animation:
35 | 0,1,1,0
--------------------------------------------------------------------------------
/assets/hero03_kick_01.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ____MM__________
5 | ____MM__________
6 | ____MMM_________
7 | ____MMMM________
8 | ____M_MMM_______
9 | ______M_MM______
10 | ______MM__M_____
11 | ______M___M_____
12 | ______M___M_____
13 | ______M_________
14 | ______M_________
15 | _____M__________
16 | _____M__________
17 | //new Frame
18 | ________________
19 | ________________
20 | ________________
21 | ____MM__________
22 | ____MM__________
23 | ____MMM_________
24 | ____MMMM________
25 | ____M_CCCCCCCCC_
26 | ______M_________
27 | ______M_________
28 | ______M_________
29 | ______M_________
30 | ______M_________
31 | ______M_________
32 | _____M__________
33 | _____M__________
34 | Animation:
35 | 0,1,1,1,0,0
--------------------------------------------------------------------------------
/assets/hero03_kick_02.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ____MM__________
5 | ____MM__________
6 | ____MMM_________
7 | ____MMMM________
8 | ___M_MM_________
9 | ______M_MM______
10 | ______MM__M_____
11 | ______M___M_____
12 | ______M___M_____
13 | ______M_________
14 | ______M_________
15 | _____M__________
16 | _____M__________
17 | //new Frame
18 | ________________
19 | ________________
20 | ________________
21 | ____MM________C_
22 | ____MMM______CC_
23 | ____MMMM___CC___
24 | ____MMM__CC_____
25 | ___MM_MMM_______
26 | ______M_________
27 | ______M_________
28 | ______M_________
29 | ______M_________
30 | ______M_________
31 | ______M_________
32 | ______M_________
33 | _____M__________
34 | Animation:
35 | 0,1,1,1,0,0
--------------------------------------------------------------------------------
/assets/hero09_air_kick_00.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________MM______
3 | ______MMMM______
4 | _____M_MM_______
5 | _____M_MMM______
6 | _______MM_______
7 | _______M________
8 | _______MMMM_____
9 | ________M__M____
10 | ________M__M____
11 | ________M__M____
12 | _______M__M_____
13 | ______M_________
14 | ________________
15 | ________________
16 | ________________
17 | //new Frame
18 | ________________
19 | ________MM______
20 | ______MMMM______
21 | _____MMMM_______
22 | _______MMM______
23 | _______MM_______
24 | _______M________
25 | _______MMMMCCCC_
26 | _______MM_______
27 | _____MMMM_______
28 | ________________
29 | ________________
30 | ________________
31 | ________________
32 | ________________
33 | ________________
34 | Animation:
35 | 0,1,1
--------------------------------------------------------------------------------
/src/webglRenderer.js:
--------------------------------------------------------------------------------
1 | // src/webglRenderer.js
2 | var glprops = {preserveDrawingBuffer: true};
3 | var gl = g.getContext('webgl', glprops) || g.getContext('experimental-webgl', glprops);
4 |
5 | // webgl setup
6 | gl.viewport(0, 0, W, H);
7 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
8 |
9 | var buffer = gl.createBuffer();
10 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
11 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
12 | -1.0, -1.0,
13 | 1.0, -1.0,
14 | -1.0, 1.0,
15 | -1.0, 1.0,
16 | 1.0, -1.0,
17 | 1.0, 1.0
18 | ]), gl.STATIC_DRAW);
19 |
20 | var badColorShader = glCreateShader(STATIC_VERT, BADCOLOR_FRAG);
21 | gl.uniform2f(glUniformLocation(badColorShader, 'dim'), W, H);
22 |
23 | var fbo1 = glCreateFBO();
24 | var fbo2 = glCreateFBO();
25 |
26 | var textureGame = glCreateTexture();
27 |
--------------------------------------------------------------------------------
/lib/keyboardController.js:
--------------------------------------------------------------------------------
1 |
2 | var keyMap = 0;
3 | // default keyboard
4 | var inputs = {
5 | UP: 38,
6 | DOWN: 40,
7 | LEFT: 37,
8 | RIGHT: 39,
9 | PUNCH: 83,
10 | KICK: 68,
11 | JUMP: 32,
12 | ENTER: 13,
13 | ESC: 27
14 | };
15 |
16 | var keys = {};
17 | var inputNames = Object.keys(inputs);
18 | for (var i = 0; i < inputNames.length; i++) {
19 | var inputName = inputNames[i];
20 | keys[inputs[inputName]] = (1< js13k
22 | > colisiones
23 | > generar impactos
24 | esta es la clave de este juego.
25 | SoundBox
26 | > get
27 |
28 | > evil glitch
29 | > unreal
30 |
31 | > phaser boilerplate engine
32 |
33 | ahora los sprites pueden tener areas de impacto.
34 | cabeza 1 - 6
35 | tronco 7 - 11
36 | pies? 12 - 16
37 |
38 |
39 | diseño de evil glitch
40 | y hacerlo en unity
41 |
42 | js13k
43 | leer el libro de manufacturing consent
44 |
45 | +- quiero saber si pego arriba, medio o abajo
46 | +- agregar efecto de fondo
47 | +- mostrar una chispita o algo cuando haga hit
48 | +- animar el golpe dependiendo de la ubicacion
49 | +- separate sprite de actor
50 |
51 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Giovanny Beltran
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
63 | # skip dist files
64 | dist
65 | package-lock.json
66 | target*
67 | *.exe
68 | *.ini
69 |
--------------------------------------------------------------------------------
/src/font.js:
--------------------------------------------------------------------------------
1 | // src/font.js
2 |
3 | var fontLetters = 'abcdefghijklmnopqrstuvwxyz0123456789!?# :,.’+()><';
4 | var indexOfFontFrame = 0;
5 |
6 | function parseText(text) {
7 | var indexes = [];
8 | for (var i = 0; i < text.length; i++) {
9 | indexes.push(fontLetters.indexOf(text[i]));
10 | }
11 | return indexes;
12 | }
13 |
14 | function drawFrame(index, size) {
15 | var letterFrame = animations[indexOfFontFrame][index];
16 | for (var i = 0; i < letterFrame.length; i++) {
17 | var coords = letterFrame[i];
18 | graphics.fillRect(coords[0]*size, coords[1]*size, size, size);
19 | }
20 | }
21 |
22 | function Text(props) {
23 | var base = GameObject(props);
24 | var indexes = parseText(props[2]);
25 | return {
26 | x: base.x,
27 | y: base.y,
28 | visible: true,
29 | color: '#ddfed9',
30 | size: 1,
31 | update: base.update,
32 | setText: function(text) {
33 | indexes = parseText(text);
34 | },
35 | draw: function() {
36 | graphics.fillStyle = this.color;
37 | for (var i = 0; i < indexes.length; i++) {
38 | graphics.save();
39 | graphics.translate((~~this.x) + i*7*this.size, (~~this.y));
40 | drawFrame(indexes[i], this.size);
41 | graphics.restore();
42 | }
43 | }
44 | }
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/scripts/concat.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # original script from @gre
3 | # https://github.com/gre/behind-asteroids/blob/master/scripts/concat.sh
4 | echo "// larga vida al #js13k! "
5 | # pre
6 | cat src/pre.js
7 |
8 | if [ "$NODE_ENV" == "production" ]; then
9 | cat src/env_prod.js
10 | else
11 | cat lib/stats.min.js
12 | cat src/env_dev.js
13 | fi;
14 |
15 | # definitions
16 | cat src/definitions.js
17 |
18 | # libs
19 | cat lib/utils.js
20 | cat lib/jsfxr.js
21 | cat lib/audio.js
22 | #cat lib/webgl.js
23 | cat lib/keyboardController.js
24 |
25 | # shaders
26 | #cd dist;
27 | #for glsl in *.frag *.vert; do
28 | # name=`echo $glsl | tr '.' '_' | tr '[:lower:]' '[:upper:]'`
29 | # cat $glsl | ../scripts/wrapjs.sh $name
30 | # echo
31 | #done
32 | #cd ..;
33 |
34 | # game
35 | cat src/generatedSprites.js
36 | cat src/theScript.js
37 | cat src/spriteLoader.js
38 | cat src/gameObject.js
39 | cat src/items.js
40 | cat src/fighter.js
41 | cat src/font.js
42 | cat src/tiles.js
43 | cat src/sounds.js
44 | cat src/collisionHandler.js
45 |
46 | cat src/backgroundEffects.js
47 |
48 | cat src/fighterController.js
49 | cat src/player.js
50 |
51 | cat src/canvasRenderer.js
52 | #cat src/webglRenderer.js
53 | #cat src/effects.js
54 | cat src/scene.js
55 | cat src/gameSetup.js
56 | cat src/gameHud.js
57 | cat src/levelUpScene.js
58 | cat src/gameloop.js
59 | cat src/post.js
60 |
--------------------------------------------------------------------------------
/spriteChangeSide.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var dir = './assets';
3 |
4 | //assuming sprites with 16X16 dimmension
5 | var cols = 16;
6 | var rows = 16;
7 |
8 | function main(){
9 | fs.readdir(dir, function(err, files){
10 | var sprites = [];
11 | if (err) throw err;
12 | files.forEach(function(filename){
13 | if(filename.indexOf('hero14') === -1) return;
14 | var file = fs.readFileSync(dir+'/'+filename, 'utf-8');
15 | var rawSprite = file.replace(/\r\n/g, '\n');
16 | var indexOfAnimation = rawSprite.indexOf('\nAnimation:\n');
17 | var frames = rawSprite.substring(0, indexOfAnimation).split('//new Frame');
18 | var animations = rawSprite.substring(indexOfAnimation+12).split(',');
19 |
20 | var newFile = '';
21 | for (var i = 0; i < frames.length; i++) {
22 | var lines = frames[i].split('\n');
23 | for (var j = 0; j < lines.length; j++) {
24 | lines[j] = lines[j].split('').reverse().join('');
25 | }
26 | frames[i] = lines.join('\n');
27 | }
28 | frames = frames.join('//new Frame');
29 | newFile = frames + `\nAnimation:\n${animations}`;
30 | fs.writeFile('./assets/'+filename, newFile, function(err){
31 | if(err){
32 | console.log('exception saving file', err);
33 | }
34 | console.log(`file ${filename} replaced`)
35 | })
36 | });
37 | });
38 | };
39 |
40 | main();
--------------------------------------------------------------------------------
/src/collisionHandler.js:
--------------------------------------------------------------------------------
1 |
2 | // first two sprites collides when overlaps
3 |
4 | var itemsColliders = {};
5 | var matrixDrawing = {};
6 |
7 | function addHitPixelToCollisionMatrix(x, y, id, target) {
8 | var key = x+'-'+y;
9 | if(!matrixDrawing[key]) matrixDrawing[key] = [];
10 | matrixDrawing[key][0] = [id, target];
11 | }
12 |
13 | function addPixelToCollisionMatrix(x, y, id, type) {
14 | var key = x+'-'+y;
15 | if(!matrixDrawing[key]) return;
16 | matrixDrawing[key].push([id, type]);
17 |
18 | var spriteHitId = matrixDrawing[key][0];
19 | for (var i = 1; i < matrixDrawing[key].length; i++) {
20 | var data = matrixDrawing[key][i];
21 | // if the same sprite is on the hit area continue
22 | if((spriteHitId[1]&data[1]) == 0) continue;
23 | if((spriteHitId[0]==data[0])) continue;
24 | var sprite = itemsColliders[data[0]];
25 | var kicker = itemsColliders[spriteHitId[0]];
26 |
27 | if(kicker.type==='pickable'){
28 | return sprite.pick(kicker);
29 | }
30 | if(!kicker.damage(sprite, y)) return;
31 | if(player.id === sprite.id) {
32 | flash('#60004b');
33 | }
34 | //sprite.colliding = true;
35 | // example
36 | var explosion = Sprite([x-8, y-8, 29, '#fff']);
37 | explosion.pixelSize = 2;
38 | explosion.orientation = 0;
39 | explosion.animationEnds = function(){
40 | mainScene.remove(this);
41 | }
42 | mainScene.add(explosion);
43 | // ends example
44 | }
45 |
46 | }
47 |
48 | function resetMatrix() {
49 | matrixDrawing = {};
50 | }
51 |
--------------------------------------------------------------------------------
/src/items.js:
--------------------------------------------------------------------------------
1 |
2 | function Pickable(props) {
3 | var base = Sprite([props[0], props[1], 30]);
4 | base.frame = base.animation[props[2]];
5 | base.pixelSize = 1;
6 | base.color = '#9bbc0f';
7 | base.type = 'pickable';
8 | base.colliding = false;
9 | base.collisionAnimation = collisionAnimations[30];
10 | base.collisionFrame = base.collisionAnimation[props[2]];
11 | base.targetHit = 3;
12 | var extended = {
13 | updateFrame: function(dt){},
14 | setHitArea: function() {
15 | addHitPixelToCollisionMatrix(this.x, this.y, this.id, this.targetHit);
16 | addHitPixelToCollisionMatrix(this.x+4, this.y+4, this.id, this.targetHit);
17 | addHitPixelToCollisionMatrix(this.x+8, this.y-4, this.id, this.targetHit);
18 | addHitPixelToCollisionMatrix(this.x+12, this.y+4, this.id, this.targetHit);
19 | addHitPixelToCollisionMatrix(this.x+16, this.y-4, this.id, this.targetHit);
20 | },
21 | update: function(dt) {
22 | this.collided = this.colliding;
23 | this.setHitArea();
24 | }
25 | };
26 | extendFunction(base, extended);
27 | return extended;
28 | }
29 |
30 | function Heart(props) {
31 | var base = Pickable([props[0], props[1], 6]);
32 | var extended = {
33 | affectFighter: function(fighter) {
34 | fighter.incrementHp(15);
35 | play(powerup);
36 | }
37 | };
38 | extendFunction(base, extended);
39 | return extended;
40 | }
41 |
42 | function Disquette(props) {
43 | var base = Pickable([props[0], props[1], 7]);
44 | var extended = {
45 | affectFighter: function(fighter) {
46 | //fighter.incrementHp(15);
47 | play(powerup);
48 | mainScene.displayLevelUpScene()
49 | }
50 | };
51 | extendFunction(base, extended);
52 | return extended;
53 | }
54 |
--------------------------------------------------------------------------------
/sprite.temp:
--------------------------------------------------------------------------------
1 |
2 | ________________
3 | _______MM_______
4 | _______MM_______
5 | _______MM_______
6 | _____MMMM__M____
7 | ____M_MMMM_M____
8 | ___M__MMMM_M____
9 | ___M__MMM_M_____
10 | _______M________
11 | ______MMM_______
12 | ______M_MMM_____
13 | ______M____M____
14 | _____M_____M____
15 | _____M____M_____
16 | ____M___________
17 | ____M___________
18 | //new Frame
19 | ________________
20 | _______MM_______
21 | _______MM_______
22 | _______MM_______
23 | ______MMMM______
24 | ______MMMM______
25 | _____M_MM_M_____
26 | _____M_MM_M_____
27 | _____M____M_____
28 | _____M_MM_M_____
29 | ______M__M______
30 | ______M__M______
31 | ________________
32 | ______M__M______
33 | ______M__M______
34 | ______M__M______
35 | //new Frame
36 | ________________
37 | ________________
38 | ________________
39 | ________________
40 | _______MM_______
41 | _______MM_______
42 | ______MMMM______
43 | _____MMMMMM_____
44 | ____M__MM__M____
45 | ___M___MM___M___
46 | _______MM_______
47 | ______M__M______
48 | _____MM__MM_____
49 | ____M______M____
50 | _____MM__MM_____
51 | ______M__M______
52 | //new Frame
53 | ________________
54 | ________________
55 | ________________
56 | ________________
57 | ________MM______
58 | ________MM______
59 | _______MM_______
60 | ______MMM_______
61 | _____M_MM_M_____
62 | ____M__MMM______
63 | _______MM_______
64 | _______M_M______
65 | _______M__M_____
66 | ______M___M_____
67 | _____M____M_____
68 | ____M_____M_____
69 | //new Frame
70 | ________________
71 | ________________
72 | ___MM___________
73 | __MMM___________
74 | _MMM____________
75 | _MMMM___________
76 | __MM_MM_________
77 | __MM____________
78 | __MMMMMMMMMM____
79 | __M_____________
80 | ___MMMM_________
81 | ________________
82 | ________________
83 | ________________
84 | ________________
85 | ________________
86 | Animation:
87 | 0,1,2,3,4
--------------------------------------------------------------------------------
/lib/stats.min.js:
--------------------------------------------------------------------------------
1 | // stats.js - http://github.com/mrdoob/stats.js
2 | var Stats=function(){function h(a){c.appendChild(a.dom);return a}function k(a){for(var d=0;de+1E3&&(r.update(1E3*a/(c-e),100),e=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){g=this.end()},domElement:c,setMode:k}};
4 | Stats.Panel=function(h,k,l){var c=Infinity,g=0,e=Math.round,a=e(window.devicePixelRatio||1),r=80*a,f=48*a,t=3*a,u=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=f;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,f);b.fillStyle=k;b.fillText(h,t,u);b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(f,
5 | v){c=Math.min(c,f);g=Math.max(g,f);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=k;b.fillText(e(f)+" "+h+" ("+e(c)+"-"+e(g)+")",t,u);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,e((1-f/v)*p))}}};"object"===typeof module&&(module.exports=Stats);
6 |
--------------------------------------------------------------------------------
/assets/z_explosion_02.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | ________________
6 | ________________
7 | ________________
8 | ________________
9 | ________________
10 | ________________
11 | ________________
12 | ________________
13 | ________________
14 | ________________
15 | ________________
16 | ________________
17 | //new Frame
18 | ________________
19 | ________________
20 | ________________
21 | ________________
22 | ________________
23 | ________________
24 | _______M________
25 | ____M__M__M_____
26 | _____M___M______
27 | ________________
28 | ______M_M_______
29 | _____M___M______
30 | ________________
31 | ________________
32 | ________________
33 | ________________
34 | //new Frame
35 | ________________
36 | ________________
37 | ________________
38 | ________________
39 | _______M________
40 | _______M________
41 | ___MM______M____
42 | ____M_____M_____
43 | _______M________
44 | ______MMM_______
45 | _______M________
46 | _____M___M______
47 | ____M____M______
48 | __________M_____
49 | ________________
50 | ________________
51 | //new Frame
52 | ________________
53 | ________________
54 | ________________
55 | _______M________
56 | ___M___M________
57 | ___M________M___
58 | ____M______M____
59 | _______M________
60 | ______M_M_______
61 | ___M_M___M_M____
62 | ______M_M_______
63 | _______M________
64 | ____M___________
65 | ___M___M__M_____
66 | _______M___M____
67 | ________________
68 | //new Frame
69 | ________________
70 | ________________
71 | _______M________
72 | __M____M________
73 | ___M_________M__
74 | ____________M___
75 | ________________
76 | ______M_M_______
77 | _____M___M______
78 | _M___________M__
79 | _____M___M______
80 | ______M_M_______
81 | ________________
82 | ___M____________
83 | __M____M___M____
84 | ____________M___
85 | Animation:
86 | 0,1,3,4,0,0,0,0,0,0,0
--------------------------------------------------------------------------------
/src/levelUpScene.js:
--------------------------------------------------------------------------------
1 | // second scene HUD
2 | var levelUpScene = Scene({});
3 | levelUpScene.active = false;
4 |
5 | levelUpScene.create = function() {
6 |
7 | var name = Text([40, 28, 'n30: tank, load a new program: ']);
8 | this.add(name);
9 |
10 | this.options = [];
11 |
12 | this.indexOption = 0;
13 | this.options.push(Text([55, 50, 'hit points: '+basePlayerStat.maxHp+' (+5)']));
14 | this.options.push(Text([55, 65, 'defense: +'+basePlayerStat.defense+' (+0.5)']));
15 | this.options.push(Text([55, 80, 'damage: +'+basePlayerStat.damage+' (+0.5)']));
16 |
17 | for (var i = 0; i < this.options.length; i++) {
18 | this.add(this.options[i]);
19 | }
20 |
21 | this.setOption(0);
22 | };
23 |
24 | levelUpScene.setOption = function(index){
25 | this.options[this.indexOption].color = '#ddfed9';
26 | this.indexOption = index;
27 | if(this.indexOption>=this.options.length){
28 | this.indexOption = 0;
29 | }
30 | if(this.indexOption<0){
31 | this.indexOption = this.options.length - 1;
32 | }
33 | this.options[this.indexOption].color = '#9bbc0f';
34 | }
35 |
36 | levelUpScene.applyStat = function(){
37 | switch(this.indexOption){
38 | case 0: basePlayerStat.maxHp+=5;break;
39 | case 1: basePlayerStat.defense+=0.5;break;
40 | case 2: basePlayerStat.damage+=0.5;break;
41 | }
42 | this.options[0].setText('hit points: '+basePlayerStat.maxHp+' (+5)');
43 | this.options[1].setText('defense: +'+basePlayerStat.defense+' (+0.5)');
44 | this.options[2].setText('damage: +'+basePlayerStat.damage+' (+0.5)');
45 |
46 | player.resetHp();
47 | play(powerup);
48 | }
49 |
50 | levelUpScene.updateData = function(time){
51 | }
52 |
53 | levelUpScene.predraw = function() {
54 | if(!this.active) return;
55 | graphics.fillStyle = 'rgba(0,0,0,0.5)';
56 | graphics.fillRect(0,0,320,240);
57 | }
58 |
59 |
60 | sceneManager.add(levelUpScene);
61 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "js13k2018",
3 | "version": "0.0.1",
4 | "description": "my entry for the #js13k 2018",
5 | "main": "index.js",
6 | "scripts": {
7 | "concat": "./scripts/concat.sh > dist/build.js && cp dist/build.js target/b.js",
8 | "clean": "rm target.zip; rm -rf dist/; rm -rf target/; mkdir -p dist target",
9 | "compileglsl": "./scripts/compileglsfiles.sh src/shaders dist",
10 | "minify": "npx google-closure-compiler --compilation_level=ADVANCED_OPTIMIZATIONS --js=dist/build.js --js_output_file=dist/build.min.js",
11 | "gen": "cp src/index.html target/index.html && cp dist/build.min.js target/b.js",
12 | "zip": "cd target; zip -r ../target.zip .; cd ..; wc -c target.zip",
13 | "nominify": "cp dist/build.js dist/build.min.js",
14 | "build-nominify": "npm run clean && npm run compileglsl && npm run concat && npm run nominify && npm run gen",
15 | "build-nominify-purejs": "npm run clean && npm run concat && npm run nominify && npm run gen",
16 | "build": "export NODE_ENV=production; npm run clean && npm run compileglsl && npm run concat && npm run minify && npm run gen && npm run zip",
17 | "watch": "nodemon -e js,sh --watch src --watch scripts --exec npm run build-nominify;",
18 | "liveserver": "mkdir -p target; cd target; live-server --no-browser",
19 | "start": "npm run watch & npm run liveserver",
20 |
21 | "build-sprites": "node ./spriteConverter.js",
22 |
23 | "concatlite": "./scripts/concat.sh > dist/build.js && cp dist/build.js target/b.js",
24 | "watchlite": "nodemon -e js,sh,html --watch src --watch scripts --exec npm run concatlite",
25 | "lite": "npm run watchlite & npm run liveserver"
26 | },
27 | "repository": {
28 | "type": "git",
29 | "url": "git+https://github.com/agar3s/js13k2018.git"
30 | },
31 | "keywords": [
32 | "js13k"
33 | ],
34 | "author": "agar3s",
35 | "license": "ISC",
36 | "bugs": {
37 | "url": "https://github.com/agar3s/js13k2018/issues"
38 | },
39 | "homepage": "https://github.com/agar3s/js13k2018#readme",
40 | "devDependencies": {
41 | "glslmin": "0.0.0",
42 | "live-server": "^1.2.0",
43 | "nodemon": "^1.18.3"
44 | },
45 | "dependencies": {
46 | "google-closure-compiler": "^20180805.0.0"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/assets/z_explosion_01.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | _____MM___MM____
6 | ____MMMM_MMMM___
7 | _____MMMMMMMM___
8 | _____MMMMMMM____
9 | _____MMMMMMMMM_M
10 | _____MMMMMMM____
11 | _____MMMMMMMM___
12 | ____MMMMMMMMM___
13 | ____MMMMM_MM____
14 | _____MM_________
15 | ________________
16 | ________________
17 | //new Frame
18 | ________________
19 | ________________
20 | ________________
21 | _____MM__MM_____
22 | ____MMMM__MM____
23 | _____MM_________
24 | _________M_MM___
25 | ____MM__MMM_____
26 | ___MMMM_MM______
27 | ___MMMM__M__MM__
28 | _______MMMM_____
29 | _____MM_MM______
30 | ____MMMM________
31 | _____MM__MM_____
32 | ________MMMM____
33 | ________________
34 | //new Frame
35 | ________________
36 | ________________
37 | ___MM___MM______
38 | __M_MM___MM_____
39 | __M_________M___
40 | _____MM_________
41 | ______MM_MM_____
42 | __MM_____MM_____
43 | _MMMM_MM________
44 | _MMMM____M______
45 | __MM__MM________
46 | ______MM_MM_____
47 | __MM_MM__MM_____
48 | ________________
49 | ___MM___MM_M____
50 | __MM____M_______
51 | //new Frame
52 | ________________
53 | __MM____MM______
54 | ___MM___MM______
55 | ________________
56 | ____MM____M_____
57 | ____MM__________
58 | ________M_______
59 | ____MM__________
60 | _MM_MM__________
61 | _MM______M______
62 | _______M________
63 | ________________
64 | _________M______
65 | _______MM__M____
66 | __MM___MM_______
67 | __MM______M_____
68 | //new Frame
69 | ________________
70 | __M_____M_______
71 | ________________
72 | ________________
73 | ____M___________
74 | ________________
75 | ________________
76 | ________________
77 | _M__M___________
78 | ________________
79 | ________________
80 | ________________
81 | ________________
82 | ________________
83 | _______M________
84 | __M_____________
85 | //new Frame
86 | ________________
87 | ________________
88 | ________________
89 | ________________
90 | ________________
91 | ________________
92 | ________________
93 | ________________
94 | ________________
95 | ________________
96 | ________________
97 | ________________
98 | ________________
99 | ________________
100 | ________________
101 | ________________
102 | Animation:
103 | 5,0,1,2,2,3,3,4,4,5
--------------------------------------------------------------------------------
/src/spriteLoader.js:
--------------------------------------------------------------------------------
1 |
2 | var collisionAnimations = [];
3 | var conter = 0;
4 | function animationLoader (animationData) {
5 | var frames = [];
6 | var previousFrame = [];
7 | var frame = [];
8 |
9 | var indexCollider = 0;
10 | for (var i = 0; i < animationData.length; i+=2) {
11 | var dataByte = parseInt(animationData[i]+animationData[i+1], 16);
12 | if (dataByte==2) {
13 | indexCollider = i+2;
14 | break;
15 | }
16 | if (dataByte==1) {
17 | frames.push(JSON.parse(JSON.stringify(frame)));
18 | previousFrame = frame;
19 | } else {
20 | var index = previousFrame.indexOf(dataByte);
21 | if(index==-1){
22 | frame.push(dataByte);
23 | } else {
24 | index = frame.indexOf(dataByte);
25 | frame.splice(index, 1);
26 | }
27 | }
28 | }
29 | frames.push(frame);
30 | // check frames with collisions
31 |
32 | var indexFrame = 0;
33 | previousFrame = [];
34 | frame = [];
35 | var colliderFrames = [];
36 | for (var i = indexCollider; i < animationData.length; i+=2) {
37 | var dataByte = parseInt(animationData[i]+animationData[i+1], 16);
38 | if (dataByte==1) {
39 | colliderFrames.push(JSON.parse(JSON.stringify(frame)));
40 | previousFrame = frame;
41 | } else {
42 | var index = previousFrame.indexOf(dataByte);
43 | if(index==-1){
44 | frame.push(dataByte);
45 | } else {
46 | index = frame.indexOf(dataByte);
47 | frame.splice(index, 1);
48 | }
49 | }
50 | }
51 | colliderFrames.push(frame);
52 |
53 |
54 |
55 | for (var i = 0; i < frames.length; i++) {
56 | for (var j = 0; j < frames[i].length; j++) {
57 | var dataByte = frames[i][j];
58 | var x = dataByte&0x0f;
59 | var y = dataByte>>4;
60 | frames[i][j] = [x, y];
61 | }
62 | }
63 |
64 | for (var i = 0; i < colliderFrames.length; i++) {
65 | for (var j = 0; j < colliderFrames[i].length; j++) {
66 | var dataByte = colliderFrames[i][j];
67 | var x = dataByte&0x0f;
68 | var y = dataByte>>4;
69 | frames[i].push([x, y, 1]);
70 | }
71 | }
72 |
73 | return frames;
74 | }
75 |
76 | for (var i = 0; i < animations.length; i++) {
77 | animations[i] = animationLoader(animations[i]);
78 | collisionAnimations.push([])
79 |
80 | // frames
81 | for (var j = 0; j < animations[i].length; j++) {
82 | // frame
83 | collisionAnimations[i].push([])
84 | for (var k = 0; k < animations[i][j].length; k++) {
85 | var coords = animations[i][j][k];
86 | if(coords[2]==1) collisionAnimations[i][j].push([coords[0], coords[1]])
87 | }
88 | }
89 | }
90 |
91 |
--------------------------------------------------------------------------------
/lib/webgl.js:
--------------------------------------------------------------------------------
1 | /*
2 | * original script from @gre
3 | * https://github.com/gre/behind-asteroids/blob/master/src/lib/webgl.sh
4 | */
5 | function glCreateShader (vert, frag) {
6 | var handle, type = gl.VERTEX_SHADER, src = vert;
7 | handle = gl.createShader(type);
8 | gl.shaderSource(handle, src);
9 | gl.compileShader(handle);
10 | var vertex = handle;
11 | if (DEBUG) {
12 | if (!gl.getShaderParameter(handle, gl.COMPILE_STATUS))
13 | throw gl.getShaderInfoLog(handle);
14 | }
15 |
16 | type = gl.FRAGMENT_SHADER;
17 | src = frag;
18 | handle = gl.createShader(type);
19 | gl.shaderSource(handle, src);
20 | gl.compileShader(handle);
21 | var fragment = handle;
22 |
23 | if (DEBUG) {
24 | if (!gl.getShaderParameter(handle, gl.COMPILE_STATUS))
25 | throw gl.getShaderInfoLog(handle);
26 | }
27 |
28 | var program = gl.createProgram();
29 | gl.attachShader(program, vertex);
30 | gl.attachShader(program, fragment);
31 | gl.linkProgram(program);
32 |
33 | if (DEBUG) {
34 | if (!gl.getProgramParameter(program, gl.LINK_STATUS))
35 | throw gl.getProgramInfoLog(program);
36 | }
37 |
38 | gl.useProgram(program);
39 | var p = gl.getAttribLocation(program, "p");
40 | gl.enableVertexAttribArray(p);
41 | gl.vertexAttribPointer(p, 2, gl.FLOAT, false, 0, 0);
42 | return [program];
43 | }
44 | function glBindShader (shader) {
45 | gl.useProgram(shader[0]);
46 | }
47 | function glUniformLocation(shader, name) {
48 | return shader[name] || (shader[name] = gl.getUniformLocation(shader[0], name));
49 | }
50 | function glCreateTexture () {
51 | var tex = gl.createTexture();
52 | gl.bindTexture(gl.TEXTURE_2D, tex);
53 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
54 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
55 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
56 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
57 | return tex;
58 | }
59 | function glSetTexture (t, value) {
60 | gl.bindTexture(gl.TEXTURE_2D, t);
61 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, value);
62 | }
63 | function glBindTexture (t, unit) {
64 | gl.activeTexture(gl.TEXTURE0 + unit);
65 | gl.bindTexture(gl.TEXTURE_2D, t);
66 | return unit;
67 | }
68 | function glCreateFBO () {
69 | var handle = gl.createFramebuffer();
70 | gl.bindFramebuffer(gl.FRAMEBUFFER, handle);
71 | var color = glCreateTexture();
72 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, W, H, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
73 | gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, color, 0);
74 | return [handle, color];
75 | }
76 | function glBindFBO (fbo) {
77 | gl.bindFramebuffer(gl.FRAMEBUFFER, fbo[0]);
78 | }
79 | function glGetFBOTexture (fbo) {
80 | return fbo[1];
81 | }
82 |
--------------------------------------------------------------------------------
/src/scene.js:
--------------------------------------------------------------------------------
1 | // src/scene.js
2 | // should display different objects in screen, like scenes in phaser
3 |
4 | var sceneManager = {
5 | scenes: [],
6 | add: function(scene) {
7 | scene.create();
8 | this.scenes.push(scene);
9 | },
10 | update: function(time, dt) {
11 | for (var i = 0; i < this.scenes.length; i++) {
12 | this.scenes[i].update(time, dt);
13 | }
14 | },
15 | draw: function() {
16 | for (var i = 0; i < this.scenes.length; i++) {
17 | this.scenes[i].predraw();
18 | this.scenes[i].draw();
19 | }
20 | }
21 | };
22 |
23 | function Scene (props) {
24 | var t = {
25 | x: 0,
26 | dx: 0,
27 | active: true,
28 | children: [],
29 | following: undefined,
30 | limit: [],
31 | maxWidth: 320,
32 | create: function(){},
33 | add: function(gameObject) {
34 | t.children.push(gameObject);
35 | if(gameObject.type==='character'||gameObject.type==='pickable'){
36 | itemsColliders[gameObject.id] = gameObject;
37 | }
38 | },
39 | remove: function(gameObject) {
40 | var index = t.children.indexOf(gameObject);
41 | if(index!=-1){
42 | t.children.splice(index, 1);
43 | }
44 | },
45 | updateData: function(time, dt){},
46 | update: function(time, dt) {
47 | if(!t.active) return;
48 | for (var i = 0; i < t.children.length; i++) {
49 | var gameObject = t.children[i]
50 | if(gameObject.x + 24 > -this.x && gameObject.x < -this.x + 320){
51 | gameObject.update(dt);
52 | }
53 | }
54 | t.updateData(time, dt);
55 |
56 | if (this.moving) {
57 | this.moving = this.x>-this.targetX && this.x-320>-this.limit[1];
58 | if (this.moving) this.x -= 1;
59 | }else if(this.following) {
60 | this.x = -(this.following.x-150);
61 | this.x = ~~this.x;
62 | if(this.x>-this.limit[0]) {
63 | this.x = -this.limit[0];
64 | }else if(this.x<-this.limit[1]+320){
65 | this.x = -this.limit[1]+320;
66 | }
67 | }
68 | },
69 | predraw: function(){},
70 | draw: function() {
71 | if(!t.active) return;
72 | graphics.save();
73 | graphics.translate(this.x, 0);
74 |
75 | for (var i = 0; i < t.children.length; i++) {
76 | var gameObject = t.children[i]
77 | if(gameObject.x + 24 > -this.x && gameObject.x < -this.x + 310 && gameObject.visible){
78 | gameObject.draw();
79 | }
80 | }
81 |
82 | graphics.restore();
83 | },
84 | moveToLimit: function(minLimit, maxLimit){
85 | this.moving = true;
86 | this.targetX = player.x-150;
87 | if (this.targetX>
2 |
3 | function GameObject(props) {
4 | return {
5 | x: props[0],
6 | y: props[1],
7 | visible: true,
8 | update: function(dt) {},
9 | draw: function() {}
10 | }
11 | }
12 |
13 | function Sprite(props) {
14 | var base = GameObject(props);
15 |
16 | var extended = {
17 | dx: base.x,
18 | dy: base.y,
19 | id: (~~(Math.random()*10000000)).toString(16),
20 | frame: [],
21 | type: 'sprite',
22 | animation: animations[props[2]],
23 | color: props[3],
24 | animIndex: 0,
25 | pixelSize: 4,
26 | orientation: 1, // right
27 | animationEnds: function() {},
28 | updateFrame: function (dt) {
29 | this.animIndex += dt*22;
30 | if (this.animIndex >= this.animation.length) {
31 | this.animIndex = 0;
32 | this.animationEnds();
33 | }
34 | this.frame = this.animation[~~(this.animIndex)];
35 | },
36 | updateData: function(dt) {},
37 | update: function(dt) {
38 | this.updateData(dt);
39 | this.updateFrame(dt);
40 | },
41 | drawFrame: function() {
42 | for (var i = 0; i < this.frame.length; i++) {
43 | var coords = this.frame[i];
44 | graphics.fillStyle = this.color
45 | if(this.orientation == 1){
46 | graphics.fillRect(coords[0]*this.pixelSize, coords[1]*this.pixelSize, this.pixelSize, this.pixelSize);
47 | }else{
48 | graphics.fillRect(14*this.pixelSize - coords[0]*this.pixelSize, coords[1]*this.pixelSize, this.pixelSize, this.pixelSize);
49 | }
50 | }
51 | },
52 | draw: function() {
53 | graphics.save();
54 | graphics.translate(this.x, this.y);
55 | graphics.fillStyle = this.color;
56 | this.drawFrame();
57 | graphics.restore();
58 | },
59 | setAnimation: function(animationIndex) {
60 | this.animation = animations[animationIndex]
61 | }
62 | }
63 | extendFunction(base, extended);
64 | return extended;
65 | }
66 |
67 |
68 | function Character(props) {
69 | var base = Sprite(props);
70 | var extended = {
71 | type: 'character',
72 | colliding: false,
73 | hitPoints: 30,
74 | collisionAnimation: collisionAnimations[props[2]],
75 | collisionFrame: [],
76 | targetHit: 2,
77 | typeHit: 1,
78 | update: function(dt) {
79 | this.collided = this.colliding;
80 | this.updateData(dt);
81 | this.updateFrame(dt);
82 | this.collisionFrame = this.collisionAnimation[~~(this.animIndex)];
83 | this.setHitArea();
84 | },
85 | setHitArea: function() {
86 | for (var i = 0; i < this.collisionFrame.length; i++) {
87 | var coords = this.collisionFrame[i];
88 | if(this.orientation == 1){
89 | addHitPixelToCollisionMatrix(this.x + coords[0]*this.pixelSize, this.y +coords[1]*this.pixelSize, this.id, this.targetHit);
90 | }else{
91 | addHitPixelToCollisionMatrix(this.x + 14*this.pixelSize - coords[0]*this.pixelSize, this.y +coords[1]*this.pixelSize, this.id, this.targetHit);
92 | }
93 | }
94 | }
95 | }
96 | extendFunction(base, extended)
97 | return extended
98 | }
99 |
--------------------------------------------------------------------------------
/src/gameHud.js:
--------------------------------------------------------------------------------
1 | // second scene HUD
2 | var hudScene = Scene({});
3 | var enemyPunched;
4 | var enemyId = Text([250, 28, '']);
5 |
6 | hudScene.create = function() {
7 | var heroBar = GameObject([20,20]);
8 | heroBar.barLength = 80;
9 | heroBar.draw = function() {
10 | graphics.fillStyle = '#DFEFE2';
11 | var length = 80*(player.hitPoints/30);
12 | if(length<0) return;
13 | graphics.fillRect(this.x, this.y, ~~length, 5);
14 | }
15 | heroBar.direction = 1;
16 | heroBar.update = function(dt) {}
17 | this.add(heroBar);
18 |
19 | var enemyBar = GameObject([300,20]);
20 | enemyBar.barLength = 80;
21 | enemyBar.draw = function() {
22 | if (enemyPunched){
23 | graphics.fillStyle = enemyPunched.color;
24 | var length = ~~(80*(enemyPunched.hitPoints/30));
25 | if(length<0) return;
26 | var start = this.x - length
27 | graphics.fillRect(start, this.y, length, 5);
28 | }
29 | }
30 | enemyBar.direction = 1;
31 | enemyBar.update = function(dt) {}
32 |
33 | this.add(heroBar);
34 | var name = Text([20, 28, 'mr anderson']);
35 | name.size = 1;
36 | this.add(name);
37 | this.add(enemyBar);
38 | this.add(enemyId);
39 |
40 | var progressBar = GameObject([20, 234]);
41 | progressBar.length = 280;
42 | progressBar.draw = function() {
43 | graphics.fillStyle = '#306230';
44 | graphics.fillRect(this.x, this.y, this.length, 3);
45 | graphics.fillStyle = '#9bbc0f';
46 | var position = ~~(this.length*((player.x+12)/(mainScene.maxWidth-24)));
47 | graphics.fillRect(this.x + position, this.y, 3, 3);
48 | }
49 | this.add(progressBar);
50 |
51 | this.goMessage = Text([200, 60, 'go!']);
52 | this.goMessage.size = 2;
53 | this.goMessage.time = 0;
54 | this.goMessage.color = '#9bbc0f';
55 | this.goMessage.visible = false;
56 | this.goMessage.update = function(dt) {
57 | if(!this.active) return;
58 | this.time += dt;
59 | var value = this.time%0.8;
60 | this.visible = value<0.6;
61 |
62 | if(this.time > 4) {
63 | this.visible = false;
64 | this.time = 0;
65 | this.active = false;
66 | }
67 | }
68 |
69 | this.add(this.goMessage);
70 |
71 | this.clock = Text([150, 1, '00:00'])
72 | this.clock.time = 0;
73 | this.clock.setTime = function(time){
74 | this.time = time;
75 | var cents = this.time%100;
76 | if(cents<10) cents = '0'+cents;
77 | var seconds = ~~(this.time/100);
78 | if(seconds<10) seconds = '0'+seconds;
79 | this.setText(seconds+':'+cents);
80 | }
81 | this.add(this.clock);
82 |
83 | this.dialogue = Text([10, 70, '']);
84 | this.dialogue.size = 1;
85 | this.dialogue.time = 0;
86 | this.dialogue.visible = false;
87 | this.dialogue.pipeline = [];
88 | this.dialogue.index = -1;
89 | this.dialogue.color = '#9bbc0f';
90 | this.dialogue.setIndex = function(index){
91 | this.index = index;
92 | if(this.index>=this.pipeline.length) {
93 | this.active = false;
94 | this.visible = false;
95 | return;
96 | }
97 | var dialogue = this.pipeline[this.index];
98 | this.setText(dialogue[0]);
99 | this.time = dialogue[1];
100 | this.active = true;
101 | this.visible = true;
102 |
103 | };
104 | this.dialogue.update = function(dt) {
105 | if(!this.active) return;
106 | this.time -= dt;
107 | if(this.time<0) {
108 | this.setIndex(this.index + 1);
109 | }
110 | }
111 | this.add(this.dialogue);
112 | };
113 |
114 | hudScene.updateData = function(time){
115 | var time = ~~(time/10);
116 | if(this.clock.time != time){
117 | this.clock.setTime(time);
118 | }
119 | }
120 |
121 | hudScene.setDialoguePipeline = function(dialogue){
122 | this.dialogue.pipeline = dialogue;
123 | if(this.dialogue.pipeline.length>0){
124 | this.dialogue.setIndex(0);
125 | }
126 | }
127 |
128 |
129 | sceneManager.add(hudScene);
130 |
131 |
--------------------------------------------------------------------------------
/src/theScript.js:
--------------------------------------------------------------------------------
1 |
2 | var matrixScript = [
3 | // 0
4 | [['tank: operator', 2],
5 | ['',0.6],
6 | ['neo: tank, i need an exit', 2],
7 | ['',0.6],
8 | ['neo: now!',2],
9 | ['',1],
10 | ['operator: .', 0.4],
11 | ['operator: ..', 0.4],
12 | ['operator: ...', 1],
13 | ['operator: got one ready', 2],
14 | ['', 0.6],
15 | ['operator: subway station, state and balboa.', 2]
16 | ],
17 | // 1
18 | [['...', 0.2],
19 | ['agent smith: mr. anderson', 2],
20 | ['',0.6],
21 | ['agent smith: we meet again', 2],
22 | ['',2],
23 | ['trinity: run, neo. run! what is he doing?', 3],
24 | ['',0.6],
25 | ['morpheus: he’s beginning to believe.', 2]
26 | ],
27 | // 2
28 | [['agent smith: i’m going to enjoy...', 1.5],
29 | ['agent smith: watching you die,', 1.5],
30 | ['agent smith: mr. anderson.', 1.5],
31 | ['',0.6],
32 | ['neo: my name is..', 1.2],
33 | ['',0.6],
34 | ['neo: n', 0.4],
35 | ['neo: ne', 0.4],
36 | ['neo: neo', 0.4],
37 | ['neo: neo!', 0.2],
38 | ['neo: neo!!', 0.2],
39 | ['neo: neo!!!', 0.2],
40 | ['neo: neo!!!!', 1]
41 | ],
42 | // 3
43 | [['neo: mr. wizard...', 2],
44 | ['neo: get me the hell out of here.', 3],
45 | ['',0.6],
46 | ['tank: got a patch on an old exit...', 2],
47 | ['tank: wabash and lake.', 2]
48 | ],
49 | // 4
50 | [['',0.6],
51 | ['.',0.6],
52 | ['..',0.6],
53 | ['...',1],
54 | ['',1],
55 | ['neo: oh shit...', 1.5],
56 | ['neo: help.', 1.5],
57 | ['neo: need a little help.', 1.5]
58 | ],
59 | //5
60 | [['',0.6],
61 | ['agent smith: i’m going to be honest', 3],
62 | ['agent smith: i hate this place,', 3],
63 | ['',0.6],
64 | ['agent smith: this zoo', 2],
65 | ['agent smith: this prison', 2],
66 | ['agent smith: this reality', 2],
67 | ['agent smith: whatever you want to call it', 3],
68 | ['agent smith: i can’t stand it any longer.', 3],
69 | ['',1],
70 | ['agent smith: it’s the smell', 3],
71 | ['agent smith: if there is such a thing', 3],
72 | ['agent smith: i feel.', 0.6],
73 | ['agent smith: i feel..', 0.6],
74 | ['agent smith: i feel...', 1.8],
75 | ['agent smith: saturated by it', 2],
76 | ['',0.6],
77 | ['agent smith: i can taste your stink', 2],
78 | ['agent smith: and every time i do', 2],
79 | ['agent smith: i feel i have somehow been...', 3],
80 | ['agent smith: infected by it', 2],
81 | ['agent smith: it’s repulsive', 2],
82 | ['agent smith: ', 2],
83 | ['agent smith: i must get out of here', 2]
84 | ],
85 | //6
86 | [['...',0.6],
87 | ['i know you’re out there.', 2],
88 | ['i can feel you now.',2],
89 | ['i know that you’re afraid.', 2],
90 | ['you’re afraid of us.', 2],
91 | ['you’re afraid of change.', 2],
92 | ['',0.6],
93 | ['i don’t know the future.', 2],
94 | ['i didn’t come here to tell you ', 2],
95 | ['how this is going to end.', 2],
96 | ['i came here to tell you how ', 2],
97 | ['it’s going to begin.', 2],
98 | ['',0.6],
99 | ['i’m going to hang up this phone', 2],
100 | ['and then i’m going to show these', 2],
101 | ['people what you don’t want', 2],
102 | ['them to see.', 2],
103 | ['',0.6],
104 | ['i’m going to show them a world without you,', 2],
105 | ['a world without rules and controls,', 2],
106 | ['without borders or boundaries,', 2],
107 | ['a world where anything is possible.', 2],
108 | ['where we go from there is a choice', 2],
109 | ['i leave to you', 2],
110 | ['',0.6],
111 | ['thanks for playing', 3],
112 | ['m', 0.05],
113 | ['ma', 0.05],
114 | ['mad', 0.05],
115 | ['made', 0.05],
116 | ['made ', 0.05],
117 | ['made w', 0.05],
118 | ['made wi', 0.05],
119 | ['made wit', 0.05],
120 | ['made with', 0.05],
121 | ['made with ', 0.05],
122 | ['made with l', 0.05],
123 | ['made with lo', 0.05],
124 | ['made with lov', 0.05],
125 | ['made with love', 0.05],
126 | ['made with love ', 0.05],
127 | ['made with love b', 0.05],
128 | ['made with love by', 0.05],
129 | ['made with love by ', 0.05],
130 | ['made with love by a', 0.05],
131 | ['made with love by ag', 0.05],
132 | ['made with love by aga', 0.05],
133 | ['made with love by agar', 0.05],
134 | ['made with love by agar3', 0.05],
135 | ['made with love by agar3s', 60]
136 |
137 | ]
138 | ];
139 |
--------------------------------------------------------------------------------
/spriteConverter.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var dir = './assets';
3 |
4 | //assuming sprites with 16X16 dimmension
5 | var cols = 16;
6 | var rows = 16;
7 |
8 | function main(cb){
9 | fs.readdir(dir, function(err, files){
10 | var sprites = [];
11 | if (err) throw err;
12 | files.forEach(function(filename){
13 | if(filename.indexOf('.sprite') === -1) return;
14 | var file = fs.readFileSync(dir+'/'+filename, 'utf-8');
15 | var res = processFile(filename, file);
16 | sprites.push(res);
17 | });
18 |
19 | var result = joinSprites(sprites);
20 | return cb(result);
21 | });
22 | };
23 |
24 | function copyArray(array){
25 | var newArray = [];
26 | for (var i = 0; i < array.length; i++) {
27 | newArray.push(array[i]);
28 | };
29 | return newArray;
30 | }
31 |
32 | function isEmptyLayer(sprite){
33 | var sum = 0;
34 | for (var i = 0; i < sprite.frames.length; i++) {
35 | sum+=sprite.frames[i].length;
36 | };
37 | return !sprite.key && !sum;
38 | }
39 |
40 | function processFile(name, rawSprite){
41 | rawSprite = rawSprite.replace(/\r\n/g, '\n');
42 | var indexOfAnimation = rawSprite.indexOf('\nAnimation:\n');
43 | var frames = rawSprite.substring(0, indexOfAnimation).split('//new Frame');
44 | var animations = rawSprite.substring(indexOfAnimation+12).split(',');
45 |
46 | return processSprite(name, copyArray(frames), animations);
47 | };
48 |
49 | function saveSprite(name, byteArray){
50 | fs.writeFile('./assets/'+name, byteArray.join(''), function (err){
51 | if(err){
52 | console.log('exception:', err);
53 | return;
54 | }
55 | console.log('file created');
56 | });
57 |
58 | }
59 |
60 | function processSprite(name, frames, animations){
61 | for (var i = 0; i < frames.length; i++) {
62 | frames[i] = encodeFrame(frames[i]);
63 | };
64 | console.log('processing ', name)
65 | var animres = buildDiffArray(frames, animations);
66 |
67 | var fullAnimation = [];
68 | animres.main.forEach(function(data){
69 | fullAnimation = fullAnimation.concat([...data]).concat(['01']);
70 | });
71 | fullAnimation.splice(fullAnimation.length-1, 1);
72 | fullAnimation = fullAnimation.concat(['02'])
73 | animres.collision.forEach(function(data){
74 | fullAnimation = fullAnimation.concat([...data]).concat(['01']);
75 | });
76 | fullAnimation.splice(fullAnimation.length-1, 1);
77 |
78 | return {
79 | name: name.replace('.sprite', ''),
80 | frames: fullAnimation
81 | };
82 | }
83 |
84 | function encodeFrame(frame){
85 | var mainFrameByteArray = [];
86 | var collisionFrameByteArray = [];
87 | var encoded = '';
88 | var data = frame.replace(/\n/g, '');
89 | for (var i = 0; i < data.length; i++) {
90 | var character = data[i];
91 | if(character==='M' || character==='C'){
92 | var x = (i%cols);
93 | var y = ~~(i/rows);
94 | //encode the value as an hexadecimal code
95 | // yx
96 | var code = ((y<<4)+x).toString(16);
97 | if(code.length==1) code = `0${code}`
98 |
99 | if(character==='M') {
100 | mainFrameByteArray.push(code);
101 | }else {
102 | collisionFrameByteArray.push(code);
103 | }
104 | }
105 | if(character==='/'){
106 | break;
107 | }
108 | };
109 |
110 |
111 | return {
112 | main: mainFrameByteArray,
113 | collision: collisionFrameByteArray
114 | }
115 |
116 | };
117 |
118 | function buildDiffArray(encodedFrames, animations){
119 | var diffMainArray = [];
120 | var diffCollisionArray = [];
121 | var arrangedMainFrames = [];
122 | var arrangedCollisionFrames = [];
123 | for (var i = 0; i < animations.length; i++) {
124 | arrangedMainFrames.push(encodedFrames[animations[i]].main);
125 | arrangedCollisionFrames.push(encodedFrames[animations[i]].collision);
126 | };
127 | // starting frame
128 | diffMainArray.push(arrangedMainFrames[0]);
129 | diffCollisionArray.push(arrangedCollisionFrames[0]);
130 | for (var j = 1; j < arrangedMainFrames.length; j++) {
131 | var diffMainElement = [];
132 | var diffCollisionElement = [];
133 | for (var k = arrangedMainFrames[j].length - 1; k >= 0; k--) {
134 | if(arrangedMainFrames[j-1].indexOf(arrangedMainFrames[j][k])==-1){
135 | diffMainElement.push(arrangedMainFrames[j][k]);
136 | }
137 | };
138 | for (var k = arrangedMainFrames[j-1].length - 1; k >= 0; k--) {
139 | if(arrangedMainFrames[j].indexOf(arrangedMainFrames[j-1][k])==-1){
140 | diffMainElement.push(arrangedMainFrames[j-1][k]);
141 | }
142 | };
143 | // check collider frames
144 | for (var k = arrangedCollisionFrames[j].length - 1; k >= 0; k--) {
145 | if(arrangedCollisionFrames[j-1].indexOf(arrangedCollisionFrames[j][k])==-1){
146 | diffCollisionElement.push(arrangedCollisionFrames[j][k]);
147 | }
148 | };
149 | for (var k = arrangedCollisionFrames[j-1].length - 1; k >= 0; k--) {
150 | if(arrangedCollisionFrames[j].indexOf(arrangedCollisionFrames[j-1][k])==-1){
151 | diffCollisionElement.push(arrangedCollisionFrames[j-1][k]);
152 | }
153 | };
154 |
155 | diffMainArray.push(diffMainElement);
156 | diffCollisionArray.push(diffCollisionElement);
157 | };
158 | return {
159 | main: diffMainArray,
160 | collision: diffCollisionArray
161 | };
162 | };
163 |
164 |
165 | function joinSprites (sprites) {
166 | var keyFrames = {};
167 | var frames = [''];
168 | var animations = {};
169 |
170 | var code = '// src/generatedSprites.js \n// sprites generated with npm run build-sprites\n';
171 | var lastCode = [];
172 | for (var i = 0; i < sprites.length; i++) {
173 | var sprite = sprites[i];
174 | var indexAnimation = i;
175 | if(indexAnimation<10) indexAnimation = '0'+i
176 | var spriteName = `anim${indexAnimation}_${sprite.name}`
177 | code += `\nvar ${spriteName} = '${sprite.frames.join('')}';`
178 | lastCode.push(spriteName);
179 | };
180 | code+=`\nvar animations = [${lastCode}];\n`;
181 |
182 | return code;
183 | }
184 |
185 |
186 | main(function(script){
187 | fs.writeFile('./src/generatedSprites.js', script, function(err){
188 | if(err){
189 | console.log('exception:', err);
190 | return;
191 | }
192 | console.log('file created');
193 | });
194 | });
--------------------------------------------------------------------------------
/src/generatedSprites.js:
--------------------------------------------------------------------------------
1 | // src/generatedSprites.js
2 | // sprites generated with npm run build-sprites
3 |
4 | var anim00_fonts = '565758596566696a7576797a8586898a95969798999aa5a6a9aab5b6b9ba01b8b7888755ba98978a01b59a998988877a795501b59a998a897a795501ba88875aaaa99a998a897a796a6901bab9b8b701bab9b8b7aaa99a998a896a69b5875a5501b5877a795a55b8b7585701b8b7a8a79897787768675857bab5aaa9a6a59a9996958a8986857a7976756a6966655a5501a5b9b801bab9b5aaa9a699969586857976756a6966655a55b7a8a797776867585701b8b7aaa99998888779786a695a5901aa9a988a887a786a6968675a5957b9b8b701b9a999897977987868675701b8b75857bab588775a5501b5989755b9b8b7aaa99a01cac9b9b8b7aaa99ab598975501bab5989755cac9b8b79a01b8b79a8887bab5989796958a857a795501a8a79897787768675a55b9b6aaa9a6a59a99898676756a69666501b9b6aaa9a6a59a9996958a8986857a7976756a696665a8a79897888778776867585701a8a7b9b6aaa501bab9b6b5aaa5988878b899897969590199978779776959b7a8a79a958a86857a7501b8b7a8a789867a75bab9b6b5aaa9a6a59996787701bab9b6b5a6a596785857a8a79889867a7675666501a9a79a99958a8986857a76756866bab9b6b5a5978887786a5a59565501bab9b6b5a898978887787767a9a69a9996958a8986857a7976756901a6a596897a796a69655956a8a77877686701aaa99a99867877685a55bab59897967a796a666501a8989796958579767566b7b6aaa6a587775a565501b7b6aaa6a58a77655655a8989796958886856968019695888786856a698a7978775501a8a7989779785a55b9b6aaa9a6a59a999695898685767501b9b6aaa9a6a59a99969589867a777675a8a797785a55018a9896957701b59678776867b9b8b7b6aaa9a6a59a998a89887a79756a66655601b79789887a796a666556b59686787776686701b9b6aaa9a8a7a6a599968678777675b79788876a655958575601b9b6aaa9a8a7a6a5999689867a7978777675696601a6a596956665565501c4b56665565501c4b501847566655655a6a5969501a7978988878685776784756665565501b8b7a69676665857a79789888785776701a999897969a696867666019a8b8a888786857ab8b7585701a79796777667a99a997a796902010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101';
5 | var anim01_hero01_idle_00 = '2728373846475657596667687677879798a7a9b7b9c7c9d6d9e6e9f5f9010101010101786948685928270101caba86c9b946010101010101c9b946caba860102010101010101010101010101010101';
6 | var anim02_hero02_punch_01 = '37384748565766676976777886879798a7a9b7bac7cad6d9e6e9f5f901655578694847010178694847655502014d4c4b4a4948474601014d4c4b4a49484746';
7 | var anim03_hero02_punch_02 = '37384748565766676976777886879798a7a9b7bac7cad6d9e6e9f5f901f4e5d5c6b6a888595849f5e6d6c7b786696657564738370101f5e6d6c7b78669665756473837f4e5d5c6b6a88859584902018d8c7b7a696801018d8c7b7a6968';
8 | var anim04_hero03_kick_01 = '34354445545556646566677476777886888996979aa6aab6bac6d6e5f501baaa9a978988787776010101baaa9a9789887877760102017e7d7c7b7a797877760101017e7d7c7b7a7978777601';
9 | var anim05_hero03_kick_02 = '343544455455566465666773757686888996979aa6aab6bac6d6e5f501e67877745746e5baaa9a9789887567010101e5baaa9a9789887567e678777457460102016a695c5b4e4d3e0101016a695c5b4e4d3e01';
10 | var anim06_hero04_walk_00 = '27283738464756575a666768697677879798a7a9b7bac7cad6dae6eaf5fb010101fae9d97858483929fbeada766656463727010101f6e7d7f5e6d60101f5e6d6f6e7d701010201010101010101010101';
11 | var anim07_hero05_run_01 = '4a4b58595a5b6768696a78797a7b8889989aa7abb6bac5c9d4e4f30101fdfcecdcccbb96957c57f3e4d4c9c5bab678680101f9e9d9c9baaaa9a8a6998b68fdfcecdcccbbab9a96957c7b67570101f5f4e5e4d6d5c7c6b8b7f9e9d9c9baaaa7a68b0101f2e3d4c5bab9b6aba79a57f5f4e5e4d6d5c7c6b8b7a9a80101feeeddccbb9695f2e3d4c5bab9b69968570101f9e9d9c9bab7aaa9a8a6a59968feeeddccbbaba79a96950101f2e3d4c5b6a79a7b7667f9e9d9c9baaaa6a5680102010101010101010101010101010101';
12 | var anim08_hero05_run_02 = '464756576667686a7577787986878898a8a9b8bac8cbd8dbe7ecf7fd0101020101';
13 | var anim09_hero06_speed_punch_00 = '5a5b67686a6b7688898a9798a6a7b5b8b9c3c4cad2d8d9e1e7f0f7010101010102797a7b7c7d7e7f0101010101';
14 | var anim10_hero07_speed_kick_00 = '6a6b797a7b898a999aa8a9b5b6b8bac7cbdbecfd0101f6ede6d7cac9c8b9b7a7a6a596958577767574686564585655544645fdcbc7bab6b5a99a998a897b7a796b6a0101f3f2e7e5e4e2d9d4d3c7c4c3c2b5b3b2edecdbcac8b9b7a8a7a6a59695857776757468656458565554464501010101010101010201010101fffefdfcfbfaf9f8f7ebda0101010101010101';
15 | var anim11_hero08_jump_00 = '5859686977788687888a96979899a7b7b8b9bac8cbd8dae7eaf6fa01e8d5c9c6aaa89a89676657564a4847463938372928faf6eae7dacbc8bab8a79997968a8669680201';
16 | var anim12_hero08_jump_01 = '1819262728293537384547484955575867777879888a989aa8a9b7b8c7d7e702';
17 | var anim13_hero08_jump_02 = '2728363738464756575866677686878889979aa8aab8bac7cad6e6f60101faf4eae7e5dad8cbc8b9b7a79998968a7877696859f6d6cac7aaa89a897667665756474638373628270101cabbaaa9a8897a7667574948cbbab9b79998968a6901020101010101';
18 | var anim14_hero09_air_kick_00 = '181926272829353738454748495758677778797a888b989ba8abb7bac6019796958736c6bab7aba89b8b450102017e7d7c7b01';
19 | var anim15_hero10_dragon_kick_00 = '44455455636465677374757682858693969798a6a7a8a9babbc9ca010101010102ccdddeeeef0101010101';
20 | var anim16_hero11_get_hit_face_00 = '45465556656667757677788486879697a6a7a8b7b8c7c9d7d9e7eaf6fa0101020101';
21 | var anim17_hero12_get_hit_body_00 = '595a68696a77787987889798a7b7b8c7c9d8dae7eaf6f90101020101';
22 | var anim18_hero13_get_hit_legs_00 = '4b4c595a5b5c68696a7778797b87888a8c8d9697a3a6a7a8b4b6b9c5c9d7d8e601010102010101';
23 | var anim19_hero14_knocked_down_00 = '455565929596979899a2a6a7aab3b8bac7cbd7dbe6f6025152616272737482838485';
24 | var anim20_hero15_wake_up_00 = 'b7b8b9bac6c7c8c9cacbccd6d7dadbdce3e4e5e6e7eaf2f4f5f6f7f8fb01010101010101010101010102010101010101010101010101';
25 | var anim21_hero16_defeated_00 = 'e2e3e4e5e6e7f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff02';
26 | var anim22_hero17 = '37384748565766676976777886879798a7a9b7bac7cad6d9e6e9f5f902';
27 | var anim23_hero18 = '37384748565766676976777886879798a7a9b7bac7cad6d9e6e9f5f902';
28 | var anim24_hero19 = '37384748565766676976777886879798a7a9b7bac7cad6d9e6e9f5f902';
29 | var anim25_hero20 = '37384748565766676976777886879798a7a9b7bac7cad6d9e6e9f5f902';
30 | var anim26_hero21 = '37384748565766676976777886879798a7a9b7bac7cad6d9e6e9f5f902';
31 | var anim27_hero22 = '37384748565766676976777886879798a7a9b7bac7cad6d9e6e9f5f902';
32 | var anim28_z_explosion_01 = '01d6d5cbcac8c7c6c5c4bcbbbab9b8b7b6b5b4acabaaa9a8a7a6a59b9a99989796958f8d8c8b8a89888786857b7a79787776756c6b6a69686766655c5b5a59575655544b4a464501ebeae9e8dad99d9c949384837447443a393635cbcac8bcbbbab7b4acaba6a59b9a98978f8d8c8b8a877b77766a686766655c5b5a59575401f8f3f2e4e3cac9c3c2bab7a6a3a2929187828173726a67664c42343229282423eadad9d6d5c7c4b8b5aaa9a89d9c96958988857875746c6b4b4a47464544360101fae7e2dbd8d785757468544a454419181312f8ebe9e4cac6c5c3c2bab9b7b6a6a3a294938786837a7973726a696766564c423a393534320101faf3e8e3e2dbd8d7c9a7999291858275746855544a452928242319130101f2e7848144181202010101010101010101';
33 | var anim29_z_explosion_02 = '01b9b5a8a689857a77746701ebe7dad7d3c4b79b99959388866b645c53474337b9b589857a746701fce2b8b6a9a59d91898578764d3227dad7c4b7a8a69b9995938886776b64534701fcebe7e2d3b8b6a9a59d91898578765c4d433732270101010101010201010101010101010101';
34 | var anim30_z_tilemap_00 = '12131415161718191a1b1c1d2122232425262728292a2b2c2d2e3132333435363738393a3b3c3d3e4142444d4e5152535455565758595a5b5d5e6162636465666768696a6b6d6e7172737475767778797a7b7d7e8182838485868788898a8b8d8e9192939495969798999a9b9c9d9ea1a2a4a5a6a7a8a9aaabadaeb1b2b5b6b7b8b9babbbcbdbec2c3c4c5c6c7c8c9cacbcccdd1d2d3d4d5d6d7d8d9dadbdcdddee2e4e6e8eaeced01ac4abc998979787701bcb399897877b5aca49301eeebe9e7e5e3e1dfd0cfc0bfb0afa09f908f807f706f605f504f4c43403f302f201e11ddd2cdc2bbbab9b8b7b6abaaa9a89c9b9a9998978b8a8988878685837b7a7877767574736867666564635b57565554534a443e3d32312d2201ddd2cecdc2c19c9b9a999897938c8b8a8988878685837c7b7a797877767574735c5b57565554534b4a4948474645443e3d32312d22eeedecebeae9e8e7e6e5e4e3e2e1bfbebdbcb3b2b1b0afaeada7a6a5a2a1a06f6e6d6b6a696261601e1d1c1b1a19181716151413121101fbfaf9f7f6f5ebeae9e7e6e51b1a19171615dcd8d4ccc8c49c98948c88847c78745c58544c48443c38342c282401ccc8c4bdbcb9b8b7b6b5b3adabaaa9a8a7a6a5a4a39c98948c88847c786d6c6b6a6966656463625c544838fbfaf9f7f6f5ebe9e7e6e5dfdedddad9d3d2d1d0cfcecdcbcac3c2c1c09f9e91908f8d81807f7d7a71705f5e5d595756535251504f4e4d49474645434241403f3e3d3b3a3935333231302f2e2d2b2a29232221201b1a1917161501fefdfbfaf9f8f7f6f5f3f2edebe9e8e7e6e5e3deddd3d2cdcbcac3beb2aea28d7d746e68675e5d5958575653524d474645433e3d3b3533322e2d2b2823221e1d1b181716151312dbd7d6d5ccc4bcb9b8b7b6b5abaaa9a8a7a6a5a4927b79787776756c645c544a4802010101010101bab49e7a745301cec2924e4842bab47a7453';
35 | var animations = [anim00_fonts,anim01_hero01_idle_00,anim02_hero02_punch_01,anim03_hero02_punch_02,anim04_hero03_kick_01,anim05_hero03_kick_02,anim06_hero04_walk_00,anim07_hero05_run_01,anim08_hero05_run_02,anim09_hero06_speed_punch_00,anim10_hero07_speed_kick_00,anim11_hero08_jump_00,anim12_hero08_jump_01,anim13_hero08_jump_02,anim14_hero09_air_kick_00,anim15_hero10_dragon_kick_00,anim16_hero11_get_hit_face_00,anim17_hero12_get_hit_body_00,anim18_hero13_get_hit_legs_00,anim19_hero14_knocked_down_00,anim20_hero15_wake_up_00,anim21_hero16_defeated_00,anim22_hero17,anim23_hero18,anim24_hero19,anim25_hero20,anim26_hero21,anim27_hero22,anim28_z_explosion_01,anim29_z_explosion_02,anim30_z_tilemap_00];
36 |
--------------------------------------------------------------------------------
/src/gameSetup.js:
--------------------------------------------------------------------------------
1 |
2 | var mainScene = Scene({});
3 | var playerController = PlayerController([player]);
4 |
5 | var aIControllers = [];
6 |
7 | var enemyConfigurations = [
8 | [0, '#346856', 10],
9 | [1, '#306230', 10],
10 | [2, '#768448', 20], // 69ccef
11 | [3, '#7e8416', 20], // 1ae0b8
12 | [4, '#8fcc3e', 30], // 8fcc3e
13 | [5, '#7bc67b', 30], // fe1111
14 | [6, '#F6FF97', 40], // fe1111
15 | [7, '#9bbc0f', 50] // fe1111
16 | ];
17 |
18 | mainScene.create = function(){
19 |
20 | this.loadIntro();
21 |
22 | this.enemyCounter = 0;
23 | this.add(player);
24 | this.following = player;
25 | this.enemiesToSummon = [];
26 | this.lastCheckPoint = 0;
27 |
28 | var map = [0];
29 | for (var i = 1; i < 150; i++) {
30 | var tile = 4;
31 | if(i%15==0){
32 | map[i-1] = 3;
33 | map[i-10] = 0;
34 | };
35 | map.push(tile);
36 | }
37 | map[5] = 1;
38 | map[20] = 1;
39 | map[35] = 1;
40 | map[50] = 1;
41 |
42 | for (var i = 0; i < map.length; i++) {
43 | this.add(Tile([i*16*2, 118+16*4, map[i]]));
44 | }
45 |
46 | mainScene.maxWidth = map.length*32;
47 |
48 | this.sections = [
49 | // 0
50 | [32*15,[],[], matrixScript[0]],
51 | [32*15,[[32*10, 0]],[[0,0],[0,0],[1]]],
52 | // 1
53 | [32*30,[],[]],
54 | [32*30,[[32*25, 1], [32*27, 1]],[[1],[1,1],[],[2]]],
55 |
56 | // 2
57 | [32*45,[],[]],
58 | [32*45,[[32*40, 4]],[],matrixScript[1]],
59 | // 3
60 | [32*60,[],[],[['operator: i cant believe it!', 2]]],
61 | [32*60,[[32*58, 2]],[[1,1],[0,0],[1,1],[],[3]]],
62 | // 4
63 | [32*75,[],[]],
64 | [32*75,[[32*69,0],[32*71,0],[32*73, 3]],[[0,1],[0,0],[1,0]]],
65 | // 5
66 | [32*90,[],[]],
67 | [32*90,[[32*85, 5]],[], matrixScript[2]],
68 | // 6
69 | [32*105,[],[], matrixScript[3]],
70 | [32*105,[],[[0,0],[1,1],[0,0,0],[1,1,1],[],[],[0,0,1,1],[1,0,0,1],[],[],[],[2]]],
71 | // 7
72 | [32*120,[],[], [['trinity: hurry, neo!', 2]]],
73 | [32*120,[],[[5, 6]], matrixScript[4]],
74 | // 8
75 | [32*135,[],[]],
76 | [32*135,[[32*130, 7]], [], matrixScript[5]],
77 | // 9
78 | [32*150,[],[]],
79 | [32*150,[],[], matrixScript[6]]
80 | ];
81 | mainScene.limit = [0, 320];
82 | //this.loadSection(0);
83 |
84 | this.add(new Heart([32*19,120+12*4, 6]));
85 | this.add(new Heart([32*34,120+12*4, 6]));
86 | this.add(new Disquette([32*49,120+12*4, 6]));
87 | this.add(new Heart([32*64,120+12*4, 6]));
88 | this.add(new Heart([32*79,120+12*4, 6]));
89 | this.add(new Disquette([32*94,120+12*4, 6]));
90 | this.add(new Heart([32*109,120+12*4, 6]));
91 | this.add(new Heart([32*124,120+12*4, 6]));
92 |
93 | this.loadCheckPoint(0*2);
94 | this.loadCheckPoint(0*2);
95 | };
96 |
97 | mainScene.loadIntro = function(){
98 | var title = Text([140, 35, 'the matr13k']);
99 | title.color = '#306230';
100 | title.size = 2;
101 | this.add(title);
102 | var title2 = Text([140, 35, ' 13k']);
103 | title2.color = '#9bbc0f';
104 | title2.size = 2;
105 | this.add(title2);
106 |
107 | var madeby = Text([170, 55, 'made by agar3s']);
108 | madeby.color = '#9bbc0f';
109 | madeby.size = 1;
110 | this.add(madeby);
111 |
112 | var controlsA = Text([160, 100, 'arrow keys to move']);
113 | controlsA.color = '#306230';
114 | controlsA.size = 1;
115 | this.add(controlsA);
116 | var controlsB = Text([160, 112, '(s key) to punch']);
117 | controlsB.color = '#306230';
118 | controlsB.size = 1;
119 | this.add(controlsB);
120 | var controlsC = Text([160, 124, '(d key) to kick']);
121 | controlsC.color = '#306230';
122 | controlsC.size = 1;
123 | this.add(controlsC);
124 | var controlsD = Text([160, 136, '(space key) to jump']);
125 | controlsD.color = '#306230';
126 | controlsD.size = 1;
127 | this.add(controlsD);
128 |
129 | var controlsE = Text([320, 100, '(> > s) special punch']);
130 | controlsE.color = '#306230';
131 | controlsE.size = 1;
132 | this.add(controlsE);
133 |
134 | var controlsF = Text([320, 112, '(> > d) special kick']);
135 | controlsF.color = '#306230';
136 | controlsF.size = 1;
137 | this.add(controlsF);
138 |
139 | var controlsG = Text([480, 220, 'your progress is down here']);
140 | controlsG.color = '#306230';
141 | controlsG.size = 1;
142 | this.add(controlsG);
143 | var controlsH = Text([480, 220, ' here']);
144 | controlsH.color = '#9bbc0f';
145 | controlsH.size = 1;
146 | this.add(controlsH);
147 |
148 | /*
149 | var colorA = Text([50, 100, '00000']);
150 | colorA.color = '#306230';
151 | this.add(colorA);
152 | var colorB = Text([50, 110, '00000']);
153 | colorB.color = '#346856';
154 | this.add(colorB);
155 | var colorC = Text([50, 120, '00000']);
156 | colorC.color = '#768448';
157 | this.add(colorC);
158 | var colorD = Text([50, 130, '00000']);
159 | colorD.color = '#7e8416';
160 | this.add(colorD);
161 | var colorE = Text([50, 140, '00000']);
162 | colorE.color = '#8fcc3e';
163 | this.add(colorE);
164 | var colorF = Text([50, 150, '00000']);
165 | colorF.color = '#7bc67b';
166 | this.add(colorF);
167 | var colorG = Text([50, 160, '00000']);
168 | colorG.color = '#F6FF97';
169 | this.add(colorG);
170 | var colorH = Text([50, 170, '00000']);
171 | colorH.color = '#9bbc0f';
172 | this.add(colorH);*/
173 | //colorB.color = '#306230';
174 |
175 | }
176 |
177 | mainScene.loadCheckPoint = function(point) {
178 | var distance = this.sections[point][0];
179 | this.enemyCounter = 0;
180 | player.dx = distance-32*15;
181 | player.x = player.dx;
182 | this.x = -player.x;
183 | mainScene.limit = [0, distance-32*5];
184 | this.loadSection(point);
185 | }
186 |
187 | mainScene.gameOver = function(player){
188 | //this.remove(player);
189 | player.hitPoints = basePlayerStat.maxHp;
190 | playerController.fighter = player;
191 | this.enemiesToSummon = [];
192 | for (var i = aIControllers.length - 1; i >= 0; i--) {
193 | this.remove(aIControllers[i].fighter);
194 | aIControllers.splice(i, 1);
195 | }
196 | // remove aIcontrollers with enemies
197 | this.loadCheckPoint(this.lastCheckPoint);
198 | }
199 |
200 |
201 | mainScene.updateData = function(time, dt) {
202 | playerController.update(time, dt);
203 | for (var i = 0; i < aIControllers.length; i++) {
204 | aIControllers[i].update(time, dt);
205 | }
206 |
207 | if(!this.moving && -this.x >= this.limit[1]-320-8*16 && this.enemyCounter==0 && this.enemiesToSummon.length==0) {
208 | mainScene.loadSection(this.currentSectionIndex+1);
209 | }
210 |
211 | this.nextSummon -= dt;
212 | if(this.enemiesToSummon.length>0 && this.nextSummon<0) {
213 | var enemyprops = this.enemiesToSummon.splice(0, 1)[0];
214 | var enemy = mainScene.loadEnemy([enemyprops[0], enemyprops[1]]);
215 | enemy.setAnimation(11);
216 | enemy.speed = enemyprops[2];
217 | enemy.y = 0;
218 | enemy.speedY= -250;
219 | enemy.dy = 0;
220 | enemy.locked = true;
221 | this.nextSummon = 0.5;
222 | }
223 | };
224 |
225 | mainScene.loadSection = function(index) {
226 | if(index>=this.sections.length) {
227 | return;
228 | }
229 |
230 | this.currentSectionIndex = index;
231 | var section = JSON.parse(JSON.stringify(this.sections[this.currentSectionIndex]));
232 | mainScene.moveToLimit(this.limit[1]-320, section[0]);
233 | for (var i = 0; i < section[1].length; i++) {
234 | this.loadEnemy(section[1][i]);
235 | }
236 | this.enemyPool = section[2].reverse();
237 | if(i==0) {
238 | this.summonEnemies(-(this.limit[1]-320), 2);
239 | }
240 | if (section[3]) {
241 | setTimeout(function(){
242 | hudScene.setDialoguePipeline(section[3]);
243 | }, 1500)
244 | }
245 | this.lastCheckPoint = (~~(index/2))*2;
246 | };
247 |
248 | mainScene.loadEnemy = function(props) {
249 | var enemyConfig = enemyConfigurations[props[1]];
250 | var enemy = Fighter([props[0], 120, FIGHTER_STATUS_IDS[0], enemyConfig[1]]);
251 | this.add(enemy);
252 | enemy.hitPoints = enemyConfig[2];
253 | aIControllers.push(AIController([enemy, enemyConfig[0]]));
254 | this.enemyCounter += 1;
255 | return enemy;
256 | };
257 |
258 | mainScene.removeEnemy = function(enemy) {
259 | this.enemyCounter -= 1;
260 | for (var i = 0; i < aIControllers.length; i++) {
261 | if(aIControllers[i].fighter.id == enemy.id){
262 | aIControllers.splice(i, 1);
263 | break;
264 | }
265 | }
266 | this.remove(enemy);
267 | mainScene.summonEnemies(this.x, 0);
268 | if (this.enemyCounter==0&&this.enemiesToSummon.length==0) {
269 | hudScene.goMessage.active = true;
270 | }
271 | };
272 |
273 | mainScene.summonEnemies = function(xOffset, delay) {
274 | if(!this.enemyPool.length) return;
275 | var enemiesToSummon = this.enemyPool.pop();
276 | for (var i = 0; i < enemiesToSummon.length; i++) {
277 | var enemyType = enemiesToSummon[i];
278 | var x = -xOffset + (i%2==0?0:32*8);
279 |
280 | this.nextSummon = 0.5 + delay;
281 |
282 | this.enemiesToSummon.push([x, enemyType, i%2==0?250:-250]);
283 | }
284 | };
285 |
286 | mainScene.displayLevelUpScene = function() {
287 | levelUpScene.active = true;
288 | hudScene.active = false;
289 | player.locked = true
290 | }
291 |
292 | sceneManager.add(mainScene);
293 |
294 |
295 |
--------------------------------------------------------------------------------
/src/fighterController.js:
--------------------------------------------------------------------------------
1 |
2 | function CharacterController(props) {
3 | return {
4 | fighter: props[0],
5 | update: function(dt) {}
6 | }
7 | }
8 |
9 | function PlayerController(props) {
10 | var base = CharacterController(props);
11 | base.fighter.human = true;
12 | base.fighter.hitPoints = basePlayerStat.maxHp;
13 | base.fighter.targetHit = 1;
14 | base.fighter.typeHit = 2;
15 | base.fighter.orientation = 1;
16 | base.lastTime = {
17 | left: 0,
18 | right: 0
19 | };
20 | base.previousStateKey = {
21 | left: false,
22 | right: false
23 | };
24 |
25 | var controller = {
26 | update: function(time, dt) {
27 | if(levelUpScene.active) return this.controlInterface(time, dt);
28 | if(mainScene.moving){
29 | this.fighter.speed = 0;
30 | return;
31 | }
32 | var fighter = this.fighter;
33 | if(fighter.locked) return;
34 | fighter.speed = 0;
35 | var hitLock = false;
36 | // punch
37 | if(keyMap&keys[inputs.PUNCH]) {
38 | fighter.punch();
39 | hitLock = fighter.y == 120;
40 | }
41 |
42 | // kick
43 | if(keyMap&keys[inputs.KICK]) {
44 | fighter.kick();
45 | hitLock = fighter.y == 120;
46 | }
47 |
48 | // move to the left
49 | if(!hitLock) {
50 | if(keyMap&keys[inputs.LEFT]) {
51 |
52 | if(!this.previousStateKey.left) {
53 | if(fighter.orientation==0 && time-this.lastTime.left<300){
54 | fighter.run();
55 | }else if(fighter.orientation==1 && time-this.lastTime.left<1000){
56 | fighter.turnSide();
57 | }
58 | }
59 |
60 | if (this.simpleTurnMode&&fighter.orientation==1) {
61 | fighter.turnSide();
62 | }
63 |
64 | fighter.move(0);
65 |
66 | this.lastTime.left = time;
67 | this.previousStateKey.left = true;
68 | this.previousStateKey.right = true;
69 | } else {
70 | this.previousStateKey.left = false;
71 | }
72 |
73 | // move to the right
74 | if(keyMap&keys[inputs.RIGHT]) {
75 | if(!this.previousStateKey.right) {
76 | if(fighter.orientation==1 && time-this.lastTime.right<300){
77 | fighter.run();
78 | } else if(fighter.orientation==0 && time-this.lastTime.right<1000){
79 | fighter.turnSide();
80 | }
81 | }
82 | if(this.simpleTurnMode && fighter.orientation==0){
83 | fighter.turnSide();
84 | }
85 |
86 | fighter.move(1);
87 |
88 | this.lastTime.right = time;
89 | this.previousStateKey.right = true;
90 | this.previousStateKey.left = true;
91 | } else {
92 | this.previousStateKey.right = false;
93 | }
94 | }
95 |
96 | // I don't know
97 | if(keyMap&keys[inputs.ENTER]) {
98 | fighter.orientation ^= 1;
99 | }
100 |
101 | // jump
102 | if(keyMap&keys[inputs.JUMP]) {
103 | fighter.jump();
104 | }
105 | },
106 | controlInterface: function(time, dt) {
107 | if(keyMap&keys[inputs.RIGHT]) {
108 | if(!this.previousStateKey.right){
109 | this.previousStateKey.right = true;
110 | levelUpScene.setOption(levelUpScene.indexOption+1);
111 | }
112 | } else {
113 | this.previousStateKey.right = false;
114 | }
115 |
116 | if(keyMap&keys[inputs.LEFT]) {
117 | if(!this.previousStateKey.left){
118 | this.previousStateKey.left = true;
119 | levelUpScene.setOption(levelUpScene.indexOption-1);
120 | }
121 | } else {
122 | this.previousStateKey.left = false;
123 | }
124 |
125 | if((keyMap&keys[inputs.PUNCH]) || (keyMap&keys[inputs.KICK])) {
126 | levelUpScene.applyStat();
127 | levelUpScene.active = false;
128 | hudScene.active = true;
129 | player.locked = false;
130 | }
131 | }
132 | }
133 | extendFunction(base, controller)
134 | return controller
135 | }
136 |
137 | function AIController(props) {
138 | var base = CharacterController(props);
139 | var actions = [
140 | base.fighter.move,
141 | base.fighter.run,
142 | base.fighter.jump,
143 | base.fighter.turnSide,
144 | base.fighter.punch,
145 | base.fighter.kick
146 | ];
147 |
148 |
149 | function getDistanceToPlayer(fighter){
150 | return Math.abs(fighter.x - player.x);
151 | }
152 | function getOrientationToPlayer(fighter) {
153 | return fighter.x - player.x < 0 ? 1: 0;
154 | }
155 | function closeDistance(fighter) {
156 | var distance = getDistanceToPlayer(fighter);
157 | if(distance>24 && distance<300) {
158 | var orientation = getOrientationToPlayer(fighter);
159 | if(fighter.orientation!=orientation){
160 | fighter.turnSide()
161 | }
162 | fighter.move(orientation);
163 | }
164 | return distance>=24;
165 | }
166 | function punch(fighter) {
167 | fighter.punch();
168 | return true;
169 | }
170 |
171 | function kick(fighter) {
172 | fighter.kick();
173 | return true;
174 | }
175 |
176 | function runToSpecial(fighter) {
177 | var distance = getDistanceToPlayer(fighter);
178 | if(distance>270) return false;
179 | if(!fighter.running)fighter.run();
180 | fighter.running = true;
181 | fighter.move();
182 | return distance>60;
183 | }
184 |
185 | function runToSpecialAlert(fighter) {
186 | var distance = getDistanceToPlayer(fighter);
187 | if(distance>270) return false;
188 | if(!fighter.running)fighter.run();
189 | fighter.running = true;
190 | fighter.move();
191 | if(distance < 70 && player.velocity>100) {
192 | fighter.jump();
193 | return false;
194 | }
195 | return distance>60;
196 | }
197 |
198 | function runToClose(fighter) {
199 | var distance = getDistanceToPlayer(fighter);
200 | if(distance>270) return false;
201 | if(!fighter.running)fighter.run();
202 | fighter.running = true;
203 | fighter.move();
204 | return distance>24;
205 | }
206 |
207 | function runToCloseAlert(fighter) {
208 | var distance = getDistanceToPlayer(fighter);
209 | if(distance>270) return false;
210 | if(!fighter.running)fighter.run();
211 | fighter.running = true;
212 | fighter.move();
213 |
214 | if(distance < 70 && player.velocity>100) {
215 | fighter.jump();
216 | return false;
217 | }
218 |
219 | return distance>24;
220 | }
221 |
222 | function resetRun(fighter) {
223 | fighter.running = false;
224 | return false;
225 | }
226 |
227 | function takeDistance(fighter){
228 | var distance = getDistanceToPlayer(fighter);
229 | if(distance>10 && distance<120) {
230 | var orientation = getOrientationToPlayer(fighter);
231 | fighter.move(orientation^1);
232 | }
233 | return true;
234 | }
235 | function wait(){return true;}
236 |
237 | function alert(fighter) {
238 | var distance = getDistanceToPlayer(fighter);
239 | var orientation = getOrientationToPlayer(fighter);
240 | if(fighter.orientation!=orientation){
241 | fighter.turnSide();
242 | }
243 | if(distance < 60 && player.velocity>100) {
244 | fighter.jump();
245 | return false;
246 | }else if(distance<40){
247 | fighter.kick();
248 | }
249 | return true;
250 | }
251 |
252 | var basicPuncher = [[closeDistance, 1.5], [wait, 0.1], [punch, 0.5], [wait, 0.1], [takeDistance, 1]];
253 | var basicKicker = [[closeDistance, 1.4], [wait, 0.1], [kick, 1], [wait, 0.2], [takeDistance, 0.5]];
254 | var fasterPuncher = [[closeDistance, 0.2], [punch, 0.1], [kick, 0.1], [wait, 0.3], [closeDistance, 0.1], [runToSpecial, 1], [punch, 0.3], [wait, 1], [closeDistance, 0.1], [punch, 0.5], [takeDistance, 0.8], [resetRun, 0.1], [wait, 0.5]];
255 | var fasterKicker = [[closeDistance, 0.2], [kick, 0.3], [wait, 0.4], [closeDistance, 0.2], [runToSpecial, 0.6], [closeDistance, 0.1],[kick, 0.3], [wait, 0.6], [closeDistance, 0.1],[kick, 0.5], [takeDistance, 1], [resetRun, 0.1], [wait, 0.6]];
256 | var jumper = [[alert, 1.5], [punch, 0.3], [closeDistance, 0.2],[wait, 0.2], [punch, 0.3],[takeDistance, 0.4], [wait, 0.3], [closeDistance, 0.5]];
257 | var aggressive = [[alert, 1.7], [closeDistance, 0.2], [alert, 0.5], [runToClose, 1], [wait, 0.1], [closeDistance, 0.1], [punch, 1], [closeDistance, 0.1],[kick,1], [closeDistance, 0.1], [takeDistance, 0.5], [resetRun, 0.1], [closeDistance, 0.1], [punch, 1]];
258 |
259 | var aggressiveA = [[closeDistance, 0.1], [alert, 0.6], [runToCloseAlert, 0.6], [closeDistance, 0.1], [alert, 0.6], [resetRun, 0.1], [runToSpecialAlert, 0.6], [punch, 0.6], [takeDistance, 0.5],[closeDistance, 0.1], [kick, 0.8], [resetRun, 0.1]];
260 |
261 | var aggressiveS = [[closeDistance, 0.1], [runToSpecialAlert, 0.6], [closeDistance, 0.1], [kick, 1], [resetRun, 0.1], [closeDistance, 0.1], [runToSpecialAlert, 1], [closeDistance, 0.1], [punch, 1], [resetRun, 0.1]];
262 |
263 | var heuristics = [basicPuncher, basicKicker, fasterPuncher, fasterKicker, jumper, aggressive, aggressiveA, aggressiveS];
264 |
265 | var controller = {
266 | id: (Math.random()).toString(16),
267 | time: 0,
268 | indexAction: 100,
269 | nextActionTime: 0,
270 | currentAction: [],
271 | actionPipeline: heuristics[props[1] || 0],
272 | programNextAction: function(){
273 | this.indexAction++;
274 | if(this.indexAction >= this.actionPipeline.length) {
275 | this.indexAction = 0;
276 | }
277 | this.currentAction = this.actionPipeline[this.indexAction];
278 | this.nextActionTime = this.currentAction[1];
279 | this.time = 0;
280 | },
281 | update: function(time, dt) {
282 | if(mainScene.moving){
283 | this.fighter.speed = 0;
284 | return;
285 | }
286 | if(this.fighter.locked) return;
287 | this.fighter.speed = 0;
288 | this.time += dt;
289 | if(this.time > this.nextActionTime) {
290 | this.programNextAction();
291 | }
292 | var result = this.currentAction[0](this.fighter, dt);
293 | if(!result) this.programNextAction();
294 | }
295 | }
296 | extendFunction(base, controller)
297 | return controller
298 | }
299 |
--------------------------------------------------------------------------------
/src/fighter.js:
--------------------------------------------------------------------------------
1 | // 0: left, 1: right
2 | const CHARACTER_SIDES = [-1, 1];
3 | const PUNCHS = [1, 2];
4 | const KICKS = [3, 4];
5 |
6 | const FIGHTER_STATUS_IDS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27];
7 |
8 | const FIGHTER_STATUS = [
9 | {anim: FIGHTER_STATUS_IDS[0], loop: 1}, // idle
10 | {anim: FIGHTER_STATUS_IDS[1], loop: 0, end: 0}, // punch 01 - ground
11 | {anim: FIGHTER_STATUS_IDS[2], loop: 0, end: 0}, // punch 02 - ground
12 | {anim: FIGHTER_STATUS_IDS[3], loop: 0, end: 0}, // kick 01 - ground
13 | {anim: FIGHTER_STATUS_IDS[4], loop: 0, end: 0}, // kick 02 - ground
14 | {anim: FIGHTER_STATUS_IDS[5], loop: 1}, // walk - ground
15 | {anim: FIGHTER_STATUS_IDS[6], loop: 1}, // run 01 - anim18
16 | {anim: FIGHTER_STATUS_IDS[7], loop: 0, end: 0}, // run 02 - anim19
17 | {anim: FIGHTER_STATUS_IDS[8], loop: 0, end: 0}, // punch running
18 | {anim: FIGHTER_STATUS_IDS[9], loop: 0, end: 0}, // kick running
19 | {anim: FIGHTER_STATUS_IDS[10], loop: 0, end: 11}, // jump start - anim 22
20 | {anim: FIGHTER_STATUS_IDS[11], loop: 1}, // jump idle - anim 23
21 | {anim: FIGHTER_STATUS_IDS[12], loop: 0, end: 0}, // jump land - anim 24
22 | {anim: FIGHTER_STATUS_IDS[13], loop: 0, end: 11}, // jump kick
23 | {anim: FIGHTER_STATUS_IDS[14], loop: 1}, // jump-running kick
24 | {anim: FIGHTER_STATUS_IDS[15], loop: 0, end: 0}, // get hit face
25 | {anim: FIGHTER_STATUS_IDS[16], loop: 0, end: 0}, // get hit body
26 | {anim: FIGHTER_STATUS_IDS[17], loop: 0, end: 20}, // get hit legs
27 | {anim: FIGHTER_STATUS_IDS[18], loop: 1}, // knocked down
28 | {anim: FIGHTER_STATUS_IDS[19], loop: 0, end: 0}, // wake up
29 | {anim: FIGHTER_STATUS_IDS[20], loop: 0, end: 19}, // defeated
30 | {anim: FIGHTER_STATUS_IDS[21], loop: 1}, // reserved 1 - anim33
31 | {anim: FIGHTER_STATUS_IDS[22], loop: 1}, // reserved 2 - anim34
32 | {anim: FIGHTER_STATUS_IDS[23], loop: 1}, // reserved 3 - anim35
33 | {anim: FIGHTER_STATUS_IDS[24], loop: 1}, // reserved 4 - anim36
34 | {anim: FIGHTER_STATUS_IDS[25], loop: 1}, // reserved 5 - anim37
35 | {anim: FIGHTER_STATUS_IDS[26], loop: 1} // reserved 6 - anim38
36 | ];
37 |
38 | const VELOCITIES = [60, 160];
39 | const DAMAGE_VALUES = [
40 | 1, // 0 basic punch
41 | 1.5, // 1 basic kick
42 | 4.1, // 2 running punch
43 | 1, // 3 running kick
44 | 2, // 4 jump kick
45 | 5 // 5 dragon kick
46 | ];
47 |
48 | function Fighter(props) {
49 | var base = Character(props);
50 | var extended = {
51 | speed: 0,
52 | nextPunch: 0,
53 | nextKick: 0,
54 | status: FIGHTER_STATUS[0],
55 | statusIndex: 0,
56 | locked: false,
57 | freezeTime: 0,
58 | brakeSpeed: 0,
59 | baseSpeed: 0,
60 | previousSpeed: 0,
61 | speedY: 0,
62 | damageToApply: 0,
63 | onDamageTime: 0,
64 | continousComboDamage: 0,
65 | nextFlash: 0,
66 | orientation: 1,
67 | removeMeNextTime: false,
68 | drawFrame: function() {
69 | if(this.hitPoints<0){
70 | var countdown = ~~(this.freezeTime*100);
71 | if(countdown=120) {
130 | this.y = 120;
131 | this.speedY = 0;
132 | if(this.statusIndex!=18){
133 | if(this.velocity> VELOCITIES[0]){
134 | this.setAnimation(6);
135 | } else {
136 | this.setAnimation(12);
137 | }
138 | }else {
139 | this.brakeSpeed = 0;
140 | this.baseSpeed = 0;
141 | this.speed = 0;
142 | this.typeHit = this.typeHit ^ 3;
143 | this.targetHit = this.targetHit ^ 3;
144 | this.setAnimation(20, true, 1);
145 | }
146 | }
147 | }
148 |
149 | if (this.speed) {
150 | this.dx += this.speed*dt;
151 | var minLimit = mainScene.limit[0] - 10;
152 | var maxLimit = mainScene.limit[1] - 40;
153 | if(this.dx < minLimit){
154 | this.dx = minLimit;
155 | }else if(this.dx > maxLimit){
156 | this.dx = maxLimit;
157 | }
158 | this.x = ~~(this.dx/this.pixelSize)*this.pixelSize;
159 | } else {
160 | if (this.statusIndex==5) {
161 | this.setAnimation(0);
162 | } else if(this.statusIndex ===6) {
163 | this.setAnimation(7);
164 | }
165 | this.velocity = 0;
166 | }
167 | },
168 | jump: function() {
169 | if(this.locked) return;
170 | if(this.y != 120) return
171 | this.setAnimation(10);
172 | this.speedY -= 650;
173 | this.y -= this.pixelSize;
174 | play(jumpSound);
175 | },
176 | hit: function(animationIndex, damageValueIndex){
177 | if(this.locked) return true;
178 | var soundIndex = ~~(Math.random()*3);
179 | // running? super kick
180 | if(this.velocity === VELOCITIES[1]) {
181 | this.baseSpeed = CHARACTER_SIDES[this.orientation]*VELOCITIES[1]*0.8;
182 | this.brakeSpeed = -this.baseSpeed*0.1;
183 | if(this.y!=120) {
184 | this.setAnimation(14, true);
185 | this.damageToApply = DAMAGE_VALUES[5];
186 | } else {
187 | this.setAnimation(animationIndex, true);
188 | this.damageToApply = DAMAGE_VALUES[damageValueIndex];
189 | }
190 | play(punchSounds[soundIndex]);
191 | return true;
192 | }
193 | // jump kick
194 | if (this.y!=120) {
195 | this.setAnimation(13, true);
196 | play(punchSounds[soundIndex]);
197 | this.damageToApply = DAMAGE_VALUES[4];
198 | return true;
199 | }
200 |
201 | return false;
202 | },
203 | kick: function() {
204 | if(this.hit(9, 2)) return;
205 |
206 | // idle kick
207 | if(this.statusIndex === 3 || this.statusIndex === 4) return;
208 | if(this.statusIndex !== 0 && this.statusIndex !== 5) return;
209 |
210 | this.setAnimation(KICKS[this.nextKick]);
211 | this.nextKick++;
212 | this.speed = 0;
213 | this.damageToApply = DAMAGE_VALUES[1];
214 | if(this.nextKick === KICKS.length) this.nextKick = 0
215 | play(punchSounds[~~(Math.random()*3)]);
216 | },
217 | punch: function() {
218 | if(this.hit(8, 2)) return;
219 |
220 | // idle punch
221 | if(this.statusIndex === 1 || this.statusIndex === 2) return;
222 | if(this.statusIndex !== 0 && this.statusIndex !== 5) return;
223 |
224 | this.setAnimation(PUNCHS[this.nextPunch]);
225 | this.nextPunch++;
226 | this.speed = 0;
227 | this.damageToApply = DAMAGE_VALUES[0];
228 | play(punchSounds[~~(Math.random()*3)]);
229 | if(this.nextPunch === PUNCHS.length) this.nextPunch = 0
230 | },
231 | move: function(side) {
232 | if(this.locked) return;
233 | if((this.statusIndex !==5&&this.statusIndex !=6&&this.statusIndex!=7)&&this.y==120) {
234 | this.setAnimation(5);
235 | }
236 | this.velocity = this.velocity!=0?this.velocity:VELOCITIES[0];
237 | if(side==undefined){
238 | side = this.orientation;
239 | }else if(side!=this.orientation) {
240 | this.velocity = VELOCITIES[0];
241 | if(this.statusIndex !==5)this.setAnimation(5);
242 | }
243 | this.speed = CHARACTER_SIDES[side]*this.velocity;
244 | },
245 | run: function() {
246 | this.setAnimation(6);
247 | this.velocity = VELOCITIES[1];
248 | },
249 | turnSide: function() {
250 | this.orientation ^= 1;
251 | },
252 | setAnimation: function(statusIndex, lock, freezeTime) {
253 | this.statusIndex = statusIndex
254 | this.status = FIGHTER_STATUS[statusIndex];
255 | this.animation = animations[this.status.anim];
256 | this.collisionAnimation = collisionAnimations[this.status.anim];
257 | this.animIndex = 0;
258 | if (lock) {
259 | this.freezeTime = freezeTime || this.animation.length/20;
260 | this.locked = true;
261 | }
262 | },
263 | animationEnds: function() {
264 | if(this.status.loop || this.locked) return;
265 | this.colliding = false;
266 | this.setAnimation(this.status.end)
267 | },
268 | setDamage: function(damage, y, kickerOrientation) {
269 | if(this.colliding) return false;
270 | if(this.locked) return false;
271 | if(this.statusIndex===18) return false;
272 | this.colliding = true;
273 | if(this.human){
274 | damage -= basePlayerStat.defense;
275 | if(damage<=0) return;
276 | }
277 |
278 | var impactOnY = (y - this.y)/this.pixelSize;
279 | var nextStatus = 0;
280 | var factor = 1;
281 | var throwHit = false;
282 | var throwHeight = 0;
283 | var throwDistance = 1;
284 |
285 | if(impactOnY <= 6){
286 | // impact on face
287 | nextStatus = 15;
288 | factor = 2;
289 | }else if(impactOnY <= 11) {
290 | nextStatus = 16;
291 | // impact on body
292 | factor = 1;
293 | }else {
294 | nextStatus = 17;
295 | // impact on legs
296 | factor = 0.6;
297 | throwHit = true;
298 | throwHeight = 100;
299 | throwDistance = 0.5;
300 | }
301 |
302 | play(hitSound[~~(Math.random()*3)]);
303 | // check damage on combo
304 | if(+new Date() - this.onDamageTime < 350) {
305 | // connect combo
306 | this.continousComboDamage++;
307 | factor += this.continousComboDamage*0.1;
308 | if(this.continousComboDamage>3 && factor*damage>2){
309 | throwHit = true;
310 | throwHeight = 200;
311 | }
312 | }else {
313 | this.continousComboDamage = 0;
314 | }
315 | if(factor*damage>4) {
316 | throwHeight = 100;
317 | throwHit = true;
318 | throwDistance = 2;
319 | }
320 | this.onDamageTime = + new Date();
321 |
322 | // calculate damage
323 | this.hitPoints -= factor*damage;
324 |
325 | if(this.hitPoints<0) {
326 | throwHit = true;
327 | throwHeight = 300;
328 | }
329 | if(this.y!=120){
330 | throwHeight = -200;
331 | }
332 |
333 | if (throwHit) {
334 | nextStatus = 18;
335 | this.baseSpeed = -CHARACTER_SIDES[kickerOrientation]*VELOCITIES[1]*throwDistance;
336 | this.brakeSpeed = -this.baseSpeed*2;
337 | this.speedY -= 200 + throwHeight;
338 | this.y -= this.pixelSize;
339 | this.setAnimation(nextStatus, true, 1);
340 | this.typeHit = this.typeHit ^ 3;
341 | this.targetHit = this.targetHit ^ 3;
342 | } else {
343 | this.speed = 0;
344 | this.setAnimation(nextStatus, true);
345 | }
346 |
347 | if(!this.human) {
348 | enemyId.setText(this.id);
349 | enemyId.color = this.color;
350 | enemyPunched = this;
351 | }
352 | return true;
353 | },
354 | damage: function(target, y) {
355 | var orientation = this.x > target.x ? 1: 0;
356 | var damage = this.damageToApply;
357 | if(this.human){
358 | damage += basePlayerStat.damage;
359 | }
360 | return target.setDamage(damage || 2, y, orientation);
361 | },
362 | pick: function(pickable) {
363 | pickable.affectFighter(this);
364 | mainScene.remove(pickable);
365 | },
366 | incrementHp: function(hp) {
367 | this.hitPoints += hp;
368 | if(this.human && this.hitPoints>basePlayerStat.maxHp){
369 | this.hitPoints = basePlayerStat.maxHp;
370 | }
371 | },
372 | resetHp: function(){
373 | if(this.human){
374 | this.hitPoints = basePlayerStat.maxHp;
375 | }
376 | }
377 | };
378 | extendFunction(base, extended)
379 | return extended
380 | }
--------------------------------------------------------------------------------
/assets/fonts.sprite:
--------------------------------------------------------------------------------
1 | ________________
2 | ________________
3 | ________________
4 | ________________
5 | ________________
6 | ______MMMM______
7 | _____MM__MM_____
8 | _____MM__MM_____
9 | _____MM__MM_____
10 | _____MMMMMM_____
11 | _____MM__MM_____
12 | _____MM__MM_____
13 | ________________
14 | ________________
15 | ________________
16 | ________________
17 | //new Frame
18 | ________________
19 | ________________
20 | ________________
21 | ________________
22 | ________________
23 | _____MMMMM______
24 | _____MM__MM_____
25 | _____MM__MM_____
26 | _____MMMMM______
27 | _____MM__MM_____
28 | _____MM__MM_____
29 | _____MMMMM______
30 | ________________
31 | ________________
32 | ________________
33 | ________________
34 | //new Frame
35 | ________________
36 | ________________
37 | ________________
38 | ________________
39 | ________________
40 | ______MMMM______
41 | _____MM__MM_____
42 | _____MM_________
43 | _____MM_________
44 | _____MM_________
45 | _____MM__MM_____
46 | ______MMMM______
47 | ________________
48 | ________________
49 | ________________
50 | ________________
51 | //new Frame
52 | ________________
53 | ________________
54 | ________________
55 | ________________
56 | ________________
57 | _____MMMMM______
58 | _____MM__MM_____
59 | _____MM__MM_____
60 | _____MM__MM_____
61 | _____MM__MM_____
62 | _____MM__MM_____
63 | _____MMMMM______
64 | ________________
65 | ________________
66 | ________________
67 | ________________
68 | //new Frame
69 | ________________
70 | ________________
71 | ________________
72 | ________________
73 | ________________
74 | _____MMMMMM_____
75 | _____MM_________
76 | _____MM_________
77 | _____MMMM_______
78 | _____MM_________
79 | _____MM_________
80 | _____MMMMMM_____
81 | ________________
82 | ________________
83 | ________________
84 | ________________
85 | //new Frame
86 | ________________
87 | ________________
88 | ________________
89 | ________________
90 | ________________
91 | _____MMMMMM_____
92 | _____MM_________
93 | _____MM_________
94 | _____MMMM_______
95 | _____MM_________
96 | _____MM_________
97 | _____MM_________
98 | ________________
99 | ________________
100 | ________________
101 | ________________
102 | //new Frame
103 | ________________
104 | ________________
105 | ________________
106 | ________________
107 | ________________
108 | ______MMMM______
109 | _____MM__MM_____
110 | _____MM_________
111 | _____MM_MMM_____
112 | _____MM__MM_____
113 | _____MM__MM_____
114 | ______MMMMM_____
115 | ________________
116 | ________________
117 | ________________
118 | ________________
119 | //new Frame
120 | ________________
121 | ________________
122 | ________________
123 | ________________
124 | ________________
125 | _____MM__MM_____
126 | _____MM__MM_____
127 | _____MM__MM_____
128 | _____MMMMMM_____
129 | _____MM__MM_____
130 | _____MM__MM_____
131 | _____MM__MM_____
132 | ________________
133 | ________________
134 | ________________
135 | ________________
136 | //new Frame
137 | ________________
138 | ________________
139 | ________________
140 | ________________
141 | ________________
142 | ______MMMM______
143 | _______MM_______
144 | _______MM_______
145 | _______MM_______
146 | _______MM_______
147 | _______MM_______
148 | ______MMMM______
149 | ________________
150 | ________________
151 | ________________
152 | ________________
153 | //new Frame
154 | ________________
155 | ________________
156 | ________________
157 | ________________
158 | ________________
159 | ______MMMM______
160 | _______MM_______
161 | _______MM_______
162 | _______MM_______
163 | _______MM_______
164 | _____M_MM_______
165 | ______MM________
166 | ________________
167 | ________________
168 | ________________
169 | ________________
170 | //new Frame
171 | ________________
172 | ________________
173 | ________________
174 | ________________
175 | ________________
176 | _____MM__MM_____
177 | _____MM__MM_____
178 | _____MM_MM______
179 | _____MMMM_______
180 | _____MM_MM______
181 | _____MM__MM_____
182 | _____MM__MM_____
183 | ________________
184 | ________________
185 | ________________
186 | ________________
187 | //new Frame
188 | ________________
189 | ________________
190 | ________________
191 | ________________
192 | ________________
193 | _____MM_________
194 | _____MM_________
195 | _____MM_________
196 | _____MM_________
197 | _____MM_________
198 | _____MM_________
199 | _____MMMMMM_____
200 | ________________
201 | ________________
202 | ________________
203 | ________________
204 | //new Frame
205 | ________________
206 | ________________
207 | ________________
208 | ________________
209 | ________________
210 | _____MMM_MM_____
211 | _____MMMMMM_____
212 | _____MM_M_M_____
213 | _____MM_M_M_____
214 | _____MM_M_M_____
215 | _____MM___M_____
216 | _____MM___M_____
217 | ________________
218 | ________________
219 | ________________
220 | ________________
221 | //new Frame
222 | ________________
223 | ________________
224 | ________________
225 | ________________
226 | ________________
227 | _____MM__MM_____
228 | _____MM__MM_____
229 | _____MMM_MM_____
230 | _____MM_MMM_____
231 | _____MM__MM_____
232 | _____MM__MM_____
233 | _____MM__MM_____
234 | ________________
235 | ________________
236 | ________________
237 | ________________
238 | //new Frame
239 | ________________
240 | ________________
241 | ________________
242 | ________________
243 | ________________
244 | ______MMMM______
245 | _____MM__MM_____
246 | _____MM__MM_____
247 | _____MM__MM_____
248 | _____MM__MM_____
249 | _____MM__MM_____
250 | ______MMMM______
251 | ________________
252 | ________________
253 | ________________
254 | ________________
255 | //new Frame
256 | ________________
257 | ________________
258 | ________________
259 | ________________
260 | ________________
261 | _____MMMMM______
262 | _____MM__MM_____
263 | _____MM__MM_____
264 | _____MM__MM_____
265 | _____MMMMM______
266 | _____MM_________
267 | _____MM_________
268 | ________________
269 | ________________
270 | ________________
271 | ________________
272 | //new Frame
273 | ________________
274 | ________________
275 | ________________
276 | ________________
277 | ________________
278 | ______MMMM______
279 | _____MM__MM_____
280 | _____MM__MM_____
281 | _____MM__MM_____
282 | _____MM__MM_____
283 | _____MM__MM_____
284 | ______MMMM______
285 | _________MM_____
286 | ________________
287 | ________________
288 | ________________
289 | //new Frame
290 | ________________
291 | ________________
292 | ________________
293 | ________________
294 | ________________
295 | _____MMMMM______
296 | _____MM__MM_____
297 | _____MM__MM_____
298 | _____MM__MM_____
299 | _____MMMMM______
300 | _____MM__MM_____
301 | _____MM__MM_____
302 | ________________
303 | ________________
304 | ________________
305 | ________________
306 | //new Frame
307 | ________________
308 | ________________
309 | ________________
310 | ________________
311 | ________________
312 | ______MMMM______
313 | _____MM__MM_____
314 | _____MM_________
315 | ______MMMM______
316 | _________MM_____
317 | _____MM__MM_____
318 | ______MMMM______
319 | ________________
320 | ________________
321 | ________________
322 | ________________
323 | //new Frame
324 | ________________
325 | ________________
326 | ________________
327 | ________________
328 | ________________
329 | _____MMMMMM_____
330 | _______MM_______
331 | _______MM_______
332 | _______MM_______
333 | _______MM_______
334 | _______MM_______
335 | _______MM_______
336 | ________________
337 | ________________
338 | ________________
339 | ________________
340 | //new Frame
341 | ________________
342 | ________________
343 | ________________
344 | ________________
345 | ________________
346 | _____MM__MM_____
347 | _____MM__MM_____
348 | _____MM__MM_____
349 | _____MM__MM_____
350 | _____MM__MM_____
351 | _____MM__MM_____
352 | ______MMMM______
353 | ________________
354 | ________________
355 | ________________
356 | ________________
357 | //new Frame
358 | ________________
359 | ________________
360 | ________________
361 | ________________
362 | ________________
363 | _____MM__MM_____
364 | _____MM__MM_____
365 | _____MM__MM_____
366 | _____MM__MM_____
367 | _____MM__MM_____
368 | ______MMMM______
369 | _______MM_______
370 | ________________
371 | ________________
372 | ________________
373 | ________________
374 | //new Frame
375 | ________________
376 | ________________
377 | ________________
378 | ________________
379 | ________________
380 | _____MM___M_____
381 | _____MM___M_____
382 | _____MM_M_M_____
383 | _____MM_M_M_____
384 | _____MM_M_M_____
385 | _____MMMMMM_____
386 | _____MMM_MM_____
387 | ________________
388 | ________________
389 | ________________
390 | ________________
391 | //new Frame
392 | ________________
393 | ________________
394 | ________________
395 | ________________
396 | ________________
397 | _____MM__MM_____
398 | _____MM__MM_____
399 | ______MMMM______
400 | _______MM_______
401 | ______MMMM______
402 | _____MM__MM_____
403 | _____MM__MM_____
404 | ________________
405 | ________________
406 | ________________
407 | ________________
408 | //new Frame
409 | ________________
410 | ________________
411 | ________________
412 | ________________
413 | ________________
414 | _____MM__MM_____
415 | _____MM__MM_____
416 | _____MM__MM_____
417 | ______MMMM______
418 | _______MM_______
419 | _______MM_______
420 | _______MM_______
421 | ________________
422 | ________________
423 | ________________
424 | ________________
425 | //new Frame
426 | ________________
427 | ________________
428 | ________________
429 | ________________
430 | ________________
431 | _____MMMMMM_____
432 | _________MM_____
433 | ________MM______
434 | _______MM_______
435 | ______MM________
436 | _____MM_________
437 | _____MMMMMM_____
438 | ________________
439 | ________________
440 | ________________
441 | ________________
442 | //new Frame
443 | ________________
444 | ________________
445 | ________________
446 | ________________
447 | ________________
448 | _______MM_______
449 | ______M_MM______
450 | _____MM__MM_____
451 | _____MM__MM_____
452 | _____MM__MM_____
453 | ______MM_M______
454 | _______MM_______
455 | ________________
456 | ________________
457 | ________________
458 | ________________
459 | //new Frame
460 | ________________
461 | ________________
462 | ________________
463 | ________________
464 | ________________
465 | _______MM_______
466 | ______MMM_______
467 | _______MM_______
468 | _______MM_______
469 | _______MM_______
470 | _______MM_______
471 | _____MMMMMM_____
472 | ________________
473 | ________________
474 | ________________
475 | ________________
476 | //new Frame
477 | ________________
478 | ________________
479 | ________________
480 | ________________
481 | ________________
482 | ______MMMM______
483 | _____MM__MM_____
484 | _________MM_____
485 | _______MMM______
486 | ______MMM_______
487 | _____MM_________
488 | _____MMMMMM_____
489 | ________________
490 | ________________
491 | ________________
492 | ________________
493 | //new Frame
494 | ________________
495 | ________________
496 | ________________
497 | ________________
498 | ________________
499 | _____MMMMMM_____
500 | ________MM______
501 | _______MM_______
502 | ______MMMM______
503 | _________MM_____
504 | _____MM__MM_____
505 | ______MMMM______
506 | ________________
507 | ________________
508 | ________________
509 | ________________
510 | //new Frame
511 | ________________
512 | ________________
513 | ________________
514 | ________________
515 | ________________
516 | _______MMM______
517 | ______M_MM______
518 | _____MM_MM______
519 | _____MM_MM______
520 | _____MMMMMM_____
521 | ________MM______
522 | ________MM______
523 | ________________
524 | ________________
525 | ________________
526 | ________________
527 | //new Frame
528 | ________________
529 | ________________
530 | ________________
531 | ________________
532 | ________________
533 | _____MMMMM______
534 | _____MM_________
535 | _____MMMMM______
536 | _________MM_____
537 | _________MM_____
538 | _____MM__MM_____
539 | ______MMMM______
540 | ________________
541 | ________________
542 | ________________
543 | ________________
544 | //new Frame
545 | ________________
546 | ________________
547 | ________________
548 | ________________
549 | ________________
550 | ______MMMM______
551 | _____MM__MM_____
552 | _____MM_________
553 | _____MMMMM______
554 | _____MM__MM_____
555 | _____MM__MM_____
556 | ______MMMM______
557 | ________________
558 | ________________
559 | ________________
560 | ________________
561 | //new Frame
562 | ________________
563 | ________________
564 | ________________
565 | ________________
566 | ________________
567 | _____MMMMMM_____
568 | _____MM__MM_____
569 | ________MM______
570 | _______MM_______
571 | _______MM_______
572 | _______MM_______
573 | _______MM_______
574 | ________________
575 | ________________
576 | ________________
577 | ________________
578 | //new Frame
579 | ________________
580 | ________________
581 | ________________
582 | ________________
583 | ________________
584 | ______MMMM______
585 | _____MM__MM_____
586 | _____MMM_MM_____
587 | ______MMMM______
588 | _____MM_MMM_____
589 | _____MM__MM_____
590 | ______MMMM______
591 | ________________
592 | ________________
593 | ________________
594 | ________________
595 | //new Frame
596 | ________________
597 | ________________
598 | ________________
599 | ________________
600 | ________________
601 | ______MMMM______
602 | _____MM__MM_____
603 | _____MM__MM_____
604 | ______MMMMM_____
605 | _________MM_____
606 | _____MM__MM_____
607 | ______MMMM______
608 | ________________
609 | ________________
610 | ________________
611 | ________________
612 | //new Frame
613 | ________________
614 | ________________
615 | ________________
616 | ________________
617 | ________________
618 | _______MMM______
619 | _______MMM______
620 | ______MMM_______
621 | ______MM________
622 | ______M_________
623 | ________________
624 | _____M__________
625 | ________________
626 | ________________
627 | ________________
628 | ________________
629 | //new Frame
630 | ________________
631 | ________________
632 | ________________
633 | ________________
634 | ________________
635 | ______MMMM______
636 | _____MM__MM_____
637 | _________MM_____
638 | _______MMM______
639 | _______M________
640 | ________________
641 | _______M________
642 | ________________
643 | ________________
644 | ________________
645 | ________________
646 | //new Frame
647 | ________________
648 | ________________
649 | ________________
650 | ________________
651 | ________________
652 | ________________
653 | ______M__M______
654 | _____MMMMMM_____
655 | ______M__M______
656 | ______M__M______
657 | _____MMMMMM_____
658 | ______M__M______
659 | ________________
660 | ________________
661 | ________________
662 | ________________
663 | //new Frame
664 | ________________
665 | ________________
666 | ________________
667 | ________________
668 | ________________
669 | ________________
670 | ________________
671 | ________________
672 | ________________
673 | ________________
674 | ________________
675 | ________________
676 | ________________
677 | ________________
678 | ________________
679 | ________________
680 | //new Frame
681 | ________________
682 | ________________
683 | ________________
684 | ________________
685 | ________________
686 | _____MM_________
687 | _____MM_________
688 | ________________
689 | ________________
690 | _____MM_________
691 | _____MM_________
692 | ________________
693 | ________________
694 | ________________
695 | ________________
696 | ________________
697 | //new Frame
698 | ________________
699 | ________________
700 | ________________
701 | ________________
702 | ________________
703 | ________________
704 | ________________
705 | ________________
706 | ________________
707 | _____MM_________
708 | _____MM_________
709 | _____M__________
710 | ____M___________
711 | ________________
712 | ________________
713 | ________________
714 | //new Frame
715 | ________________
716 | ________________
717 | ________________
718 | ________________
719 | ________________
720 | ________________
721 | ________________
722 | ________________
723 | ________________
724 | _____MM_________
725 | _____MM_________
726 | ________________
727 | ________________
728 | ________________
729 | ________________
730 | ________________
731 | //new Frame
732 | ________________
733 | ________________
734 | ________________
735 | ________________
736 | ________________
737 | _____MM_________
738 | _____MM_________
739 | _____M__________
740 | ____M___________
741 | ________________
742 | ________________
743 | ________________
744 | ________________
745 | ________________
746 | ________________
747 | ________________
748 |
749 | //new Frame
750 | ________________
751 | ________________
752 | ________________
753 | ________________
754 | ________________
755 | ________________
756 | _______M________
757 | _______M________
758 | _____MMMMM______
759 | _______M________
760 | _______M________
761 | ________________
762 | ________________
763 | ________________
764 | ________________
765 | ________________
766 | //new Frame
767 | ________________
768 | ________________
769 | ________________
770 | ________________
771 | ________________
772 | _______MM_______
773 | ______M_________
774 | ______M_________
775 | ______M_________
776 | ______M_________
777 | ______M_________
778 | _______MM_______
779 | ________________
780 | ________________
781 | ________________
782 | ________________
783 | //new Frame
784 | ________________
785 | ________________
786 | ________________
787 | ________________
788 | ________________
789 | _______MM_______
790 | _________M______
791 | _________M______
792 | _________M______
793 | _________M______
794 | _________M______
795 | _______MM_______
796 | ________________
797 | ________________
798 | ________________
799 | ________________
800 | //new Frame
801 | ________________
802 | ________________
803 | ________________
804 | ________________
805 | ________________
806 | ________________
807 | _________M______
808 | _________MM_____
809 | _____MMMMMMM____
810 | _________MM_____
811 | _________M______
812 | ________________
813 | ________________
814 | ________________
815 | ________________
816 | ________________
817 | //new Frame
818 | ________________
819 | ________________
820 | ________________
821 | ________________
822 | ________________
823 | ________________
824 | _______M________
825 | ______MM________
826 | _____MMMMMMM____
827 | ______MM________
828 | _______M________
829 | ________________
830 | ________________
831 | ________________
832 | ________________
833 | ________________
834 | Animation:
835 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48
--------------------------------------------------------------------------------
/lib/jsfxr.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SfxrParams
3 | *
4 | * Copyright 2010 Thomas Vian
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | *
18 | * @author Thomas Vian
19 | */
20 |
21 | /* eslint-disable */
22 |
23 | /** @constructor */
24 | function SfxrParams() {
25 | //--------------------------------------------------------------------------
26 | //
27 | // Settings String Methods
28 | //
29 | //--------------------------------------------------------------------------
30 |
31 | /**
32 | * Parses a settings array into the parameters
33 | * @param array Array of the settings values, where elements 0 - 23 are
34 | * a: waveType
35 | * b: attackTime
36 | * c: sustainTime
37 | * d: sustainPunch
38 | * e: decayTime
39 | * f: startFrequency
40 | * g: minFrequency
41 | * h: slide
42 | * i: deltaSlide
43 | * j: vibratoDepth
44 | * k: vibratoSpeed
45 | * l: changeAmount
46 | * m: changeSpeed
47 | * n: squareDuty
48 | * o: dutySweep
49 | * p: repeatSpeed
50 | * q: phaserOffset
51 | * r: phaserSweep
52 | * s: lpFilterCutoff
53 | * t: lpFilterCutoffSweep
54 | * u: lpFilterResonance
55 | * v: hpFilterCutoff
56 | * w: hpFilterCutoffSweep
57 | * x: masterVolume
58 | * @return If the string successfully parsed
59 | */
60 | this.ss = function(values)
61 | {
62 | for ( var i = 0; i < 24; i++ )
63 | {
64 | this[String.fromCharCode( 97 + i )] = values[i] || 0;
65 | }
66 |
67 | // I moved this here from the r(true) function
68 | if (this['c'] < .01) {
69 | this['c'] = .01;
70 | }
71 |
72 | var totalTime = this['b'] + this['c'] + this['e'];
73 | if (totalTime < .18) {
74 | var multiplier = .18 / totalTime;
75 | this['b'] *= multiplier;
76 | this['c'] *= multiplier;
77 | this['e'] *= multiplier;
78 | }
79 | }
80 | }
81 |
82 | /**
83 | * SfxrSynth
84 | *
85 | * Copyright 2010 Thomas Vian
86 | *
87 | * Licensed under the Apache License, Version 2.0 (the "License");
88 | * you may not use this file except in compliance with the License.
89 | * You may obtain a copy of the License at
90 | *
91 | * http://www.apache.org/licenses/LICENSE-2.0
92 | *
93 | * Unless required by applicable law or agreed to in writing, software
94 | * distributed under the License is distributed on an "AS IS" BASIS,
95 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
96 | * See the License for the specific language governing permissions and
97 | * limitations under the License.
98 | *
99 | * @author Thomas Vian
100 | */
101 | /** @constructor */
102 | function SfxrSynth() {
103 | // All variables are kept alive through function closures
104 |
105 | //--------------------------------------------------------------------------
106 | //
107 | // Sound Parameters
108 | //
109 | //--------------------------------------------------------------------------
110 |
111 | this._p = new SfxrParams(); // Params instance
112 |
113 | //--------------------------------------------------------------------------
114 | //
115 | // Synth Variables
116 | //
117 | //--------------------------------------------------------------------------
118 |
119 | var _envelopeLength0, // Length of the attack stage
120 | _envelopeLength1, // Length of the sustain stage
121 | _envelopeLength2, // Length of the decay stage
122 |
123 | _period, // Period of the wave
124 | _maxPeriod, // Maximum period before sound stops (from minFrequency)
125 |
126 | _slide, // Note slide
127 | _deltaSlide, // Change in slide
128 |
129 | _changeAmount, // Amount to change the note by
130 | _changeTime, // Counter for the note change
131 | _changeLimit, // Once the time reaches this limit, the note changes
132 |
133 | _squareDuty, // Offset of center switching point in the square wave
134 | _dutySweep; // Amount to change the duty by
135 |
136 | //--------------------------------------------------------------------------
137 | //
138 | // Synth Methods
139 | //
140 | //--------------------------------------------------------------------------
141 |
142 | /**
143 | * rs the runing variables from the params
144 | * Used once at the start (total r) and for the repeat effect (partial r)
145 | */
146 | this.r = function() {
147 | // Shorter reference
148 | var p = this._p;
149 |
150 | _period = 100 / (p['f'] * p['f'] + .001);
151 | _maxPeriod = 100 / (p['g'] * p['g'] + .001);
152 |
153 | _slide = 1 - p['h'] * p['h'] * p['h'] * .01;
154 | _deltaSlide = -p['i'] * p['i'] * p['i'] * .000001;
155 |
156 | if (!p['a']) {
157 | _squareDuty = .5 - p['n'] / 2;
158 | _dutySweep = -p['o'] * .00005;
159 | }
160 |
161 | _changeAmount = 1 + p['l'] * p['l'] * (p['l'] > 0 ? -.9 : 10);
162 | _changeTime = 0;
163 | _changeLimit = p['m'] == 1 ? 0 : (1 - p['m']) * (1 - p['m']) * 20000 + 32;
164 | }
165 |
166 | // I split the r() function into two functions for better readability
167 | this.tr = function() {
168 | this.r();
169 |
170 | // Shorter reference
171 | var p = this._p;
172 |
173 | // Calculating the length is all that remained here, everything else moved somewhere
174 | _envelopeLength0 = p['b'] * p['b'] * 100000;
175 | _envelopeLength1 = p['c'] * p['c'] * 100000;
176 | _envelopeLength2 = p['e'] * p['e'] * 100000 + 12;
177 | // Full length of the volume envelop (and therefore sound)
178 | // Make sure the length can be divided by 3 so we will not need the padding "==" after base64 encode
179 | return ((_envelopeLength0 + _envelopeLength1 + _envelopeLength2) / 3 | 0) * 3;
180 | }
181 |
182 | /**
183 | * Writes the wave to the supplied buffer ByteArray
184 | * @param buffer A ByteArray to write the wave to
185 | * @return If the wave is finished
186 | */
187 | this.sw = function(buffer, length) {
188 | // Shorter reference
189 | var p = this._p;
190 |
191 | // If the filters are active
192 | var _filters = p['s'] != 1 || p['v'],
193 | // Cutoff multiplier which adjusts the amount the wave position can move
194 | _hpFilterCutoff = p['v'] * p['v'] * .1,
195 | // Speed of the high-pass cutoff multiplier
196 | _hpFilterDeltaCutoff = 1 + p['w'] * .0003,
197 | // Cutoff multiplier which adjusts the amount the wave position can move
198 | _lpFilterCutoff = p['s'] * p['s'] * p['s'] * .1,
199 | // Speed of the low-pass cutoff multiplier
200 | _lpFilterDeltaCutoff = 1 + p['t'] * .0001,
201 | // If the low pass filter is active
202 | _lpFilterOn = p['s'] != 1,
203 | // masterVolume * masterVolume (for quick calculations)
204 | _masterVolume = p['x'] * p['x'],
205 | // Minimum frequency before stopping
206 | _minFreqency = p['g'],
207 | // If the phaser is active
208 | _phaser = p['q'] || p['r'],
209 | // Change in phase offset
210 | _phaserDeltaOffset = p['r'] * p['r'] * p['r'] * .2,
211 | // Phase offset for phaser effect
212 | _phaserOffset = p['q'] * p['q'] * (p['q'] < 0 ? -1020 : 1020),
213 | // Once the time reaches this limit, some of the iables are r
214 | _repeatLimit = p['p'] ? ((1 - p['p']) * (1 - p['p']) * 20000 | 0) + 32 : 0,
215 | // The punch factor (louder at begining of sustain)
216 | _sustainPunch = p['d'],
217 | // Amount to change the period of the wave by at the peak of the vibrato wave
218 | _vibratoAmplitude = p['j'] / 2,
219 | // Speed at which the vibrato phase moves
220 | _vibratoSpeed = p['k'] * p['k'] * .01,
221 | // The type of wave to generate
222 | _waveType = p['a'];
223 |
224 | var _envelopeLength = _envelopeLength0, // Length of the current envelope stage
225 | _envelopeOverLength0 = 1 / _envelopeLength0, // (for quick calculations)
226 | _envelopeOverLength1 = 1 / _envelopeLength1, // (for quick calculations)
227 | _envelopeOverLength2 = 1 / _envelopeLength2; // (for quick calculations)
228 |
229 | // Damping muliplier which restricts how fast the wave position can move
230 | var _lpFilterDamping = 5 / (1 + p['u'] * p['u'] * 20) * (.01 + _lpFilterCutoff);
231 | if (_lpFilterDamping > .8) {
232 | _lpFilterDamping = .8;
233 | }
234 | _lpFilterDamping = 1 - _lpFilterDamping;
235 |
236 | var _finished = false, // If the sound has finished
237 | _envelopeStage = 0, // Current stage of the envelope (attack, sustain, decay, end)
238 | _envelopeTime = 0, // Current time through current enelope stage
239 | _envelopeVolume = 0, // Current volume of the envelope
240 | _hpFilterPos = 0, // Adjusted wave position after high-pass filter
241 | _lpFilterDeltaPos = 0, // Change in low-pass wave position, as allowed by the cutoff and damping
242 | _lpFilterOldPos, // Previous low-pass wave position
243 | _lpFilterPos = 0, // Adjusted wave position after low-pass filter
244 | _periodTemp, // Period modified by vibrato
245 | _phase = 0, // Phase through the wave
246 | _phaserInt, // Integer phaser offset, for bit maths
247 | _phaserPos = 0, // Position through the phaser buffer
248 | _pos, // Phase expresed as a Number from 0-1, used for fast sin approx
249 | _repeatTime = 0, // Counter for the repeats
250 | _sample, // Sub-sample calculated 8 times per actual sample, averaged out to get the super sample
251 | _superSample, // Actual sample writen to the wave
252 | _vibratoPhase = 0; // Phase through the vibrato sine wave
253 |
254 | // Buffer of wave values used to create the out of phase second wave
255 | var _phaserBuffer = new Array(1024),
256 | // Buffer of random values used to generate noise
257 | _noiseBuffer = new Array(32);
258 | for (var i = _phaserBuffer.length; i--; ) {
259 | _phaserBuffer[i] = 0;
260 | }
261 | for (var i = _noiseBuffer.length; i--; ) {
262 | _noiseBuffer[i] = getRandomValue(2,-1);
263 | }
264 |
265 | for (var i = 0; i < length; i++) {
266 | if (_finished) {
267 | return i;
268 | }
269 |
270 | // Repeats every _repeatLimit times, partially rting the sound parameters
271 | if (_repeatLimit) {
272 | if (++_repeatTime >= _repeatLimit) {
273 | _repeatTime = 0;
274 | this.r();
275 | }
276 | }
277 |
278 | // If _changeLimit is reached, shifts the pitch
279 | if (_changeLimit) {
280 | if (++_changeTime >= _changeLimit) {
281 | _changeLimit = 0;
282 | _period *= _changeAmount;
283 | }
284 | }
285 |
286 | // Acccelerate and apply slide
287 | _slide += _deltaSlide;
288 | _period *= _slide;
289 |
290 | // Checks for frequency getting too low, and stops the sound if a minFrequency was set
291 | if (_period > _maxPeriod) {
292 | _period = _maxPeriod;
293 | if (_minFreqency > 0) {
294 | _finished = true;
295 | }
296 | }
297 |
298 | _periodTemp = _period;
299 |
300 | // Applies the vibrato effect
301 | if (_vibratoAmplitude > 0) {
302 | _vibratoPhase += _vibratoSpeed;
303 | _periodTemp *= 1 + Math.sin(_vibratoPhase) * _vibratoAmplitude;
304 | }
305 |
306 | _periodTemp |= 0;
307 | if (_periodTemp < 8) {
308 | _periodTemp = 8;
309 | }
310 |
311 | // Sweeps the square duty
312 | if (!_waveType) {
313 | _squareDuty += _dutySweep;
314 | if (_squareDuty < 0) {
315 | _squareDuty = 0;
316 | } else if (_squareDuty > .5) {
317 | _squareDuty = .5;
318 | }
319 | }
320 |
321 | // Moves through the different stages of the volume envelope
322 | if (++_envelopeTime > _envelopeLength) {
323 | _envelopeTime = 0;
324 |
325 | switch (++_envelopeStage) {
326 | case 1:
327 | _envelopeLength = _envelopeLength1;
328 | break;
329 | case 2:
330 | _envelopeLength = _envelopeLength2;
331 | }
332 | }
333 |
334 | // Sets the volume based on the position in the envelope
335 | switch (_envelopeStage) {
336 | case 0:
337 | _envelopeVolume = _envelopeTime * _envelopeOverLength0;
338 | break;
339 | case 1:
340 | _envelopeVolume = 1 + (1 - _envelopeTime * _envelopeOverLength1) * 2 * _sustainPunch;
341 | break;
342 | case 2:
343 | _envelopeVolume = 1 - _envelopeTime * _envelopeOverLength2;
344 | break;
345 | case 3:
346 | _envelopeVolume = 0;
347 | _finished = true;
348 | }
349 |
350 | // Moves the phaser offset
351 | if (_phaser) {
352 | _phaserOffset += _phaserDeltaOffset;
353 | _phaserInt = _phaserOffset | 0;
354 | if (_phaserInt < 0) {
355 | _phaserInt = -_phaserInt;
356 | } else if (_phaserInt > 1023) {
357 | _phaserInt = 1023;
358 | }
359 | }
360 |
361 | // Moves the high-pass filter cutoff
362 | if (_filters && _hpFilterDeltaCutoff) {
363 | _hpFilterCutoff *= _hpFilterDeltaCutoff;
364 | if (_hpFilterCutoff < .00001) {
365 | _hpFilterCutoff = .00001;
366 | } else if (_hpFilterCutoff > .1) {
367 | _hpFilterCutoff = .1;
368 | }
369 | }
370 |
371 | _superSample = 0;
372 | for (var j = 8; j--; ) {
373 | // Cycles through the period
374 | _phase++;
375 | if (_phase >= _periodTemp) {
376 | _phase %= _periodTemp;
377 |
378 | // Generates new random noise for this period
379 | if (_waveType == 3) {
380 | for (var n = _noiseBuffer.length; n--; ) {
381 | _noiseBuffer[n] = getRandomValue(2,-1);
382 | }
383 | }
384 | }
385 |
386 | // Gets the sample from the oscillator
387 | switch (_waveType) {
388 | case 0: // Square wave
389 | _sample = ((_phase / _periodTemp) < _squareDuty) ? .5 : -.5;
390 | break;
391 | case 1: // Saw wave
392 | _sample = 1 - _phase / _periodTemp * 2;
393 | break;
394 | case 2: // Sine wave (fast and accurate approx)
395 | _pos = _phase / _periodTemp;
396 | _pos = (_pos > .5 ? _pos - 1 : _pos) * 6.28318531;
397 | _sample = 1.27323954 * _pos + .405284735 * _pos * _pos * (_pos < 0 ? 1 : -1);
398 | _sample = .225 * ((_sample < 0 ? -1 : 1) * _sample * _sample - _sample) + _sample;
399 | break;
400 | case 3: // Noise
401 | _sample = _noiseBuffer[Math.abs(_phase * 32 / _periodTemp | 0)];
402 | }
403 |
404 | // Applies the low and high pass filters
405 | if (_filters) {
406 | _lpFilterOldPos = _lpFilterPos;
407 | _lpFilterCutoff *= _lpFilterDeltaCutoff;
408 | if (_lpFilterCutoff < 0) {
409 | _lpFilterCutoff = 0;
410 | } else if (_lpFilterCutoff > .1) {
411 | _lpFilterCutoff = .1;
412 | }
413 |
414 | if (_lpFilterOn) {
415 | _lpFilterDeltaPos += (_sample - _lpFilterPos) * _lpFilterCutoff;
416 | _lpFilterDeltaPos *= _lpFilterDamping;
417 | } else {
418 | _lpFilterPos = _sample;
419 | _lpFilterDeltaPos = 0;
420 | }
421 |
422 | _lpFilterPos += _lpFilterDeltaPos;
423 |
424 | _hpFilterPos += _lpFilterPos - _lpFilterOldPos;
425 | _hpFilterPos *= 1 - _hpFilterCutoff;
426 | _sample = _hpFilterPos;
427 | }
428 |
429 | // Applies the phaser effect
430 | if (_phaser) {
431 | _phaserBuffer[_phaserPos % 1024] = _sample;
432 | _sample += _phaserBuffer[(_phaserPos - _phaserInt + 1024) % 1024];
433 | _phaserPos++;
434 | }
435 |
436 | _superSample += _sample;
437 | }
438 |
439 | // Averages out the super samples and applies volumes
440 | _superSample *= .125 * _envelopeVolume * _masterVolume;
441 |
442 | // Clipping if too loud
443 | buffer[i] = _superSample >= 1 ? 32767 : _superSample <= -1 ? -32768 : _superSample * 32767 | 0;
444 | }
445 |
446 | return length;
447 | }
448 | }
449 |
450 | // Adapted from http://codebase.es/riffwave/
451 | var synth = new SfxrSynth();
452 | // Export for the Closure Compiler
453 | function jsfxr (settings, audioCtx, cb) {
454 | // Initialize SfxrParams
455 | synth._p.ss(settings);
456 | // Synthesize Wave
457 | var envelopeFullLength = synth.tr();
458 | var data = new Uint8Array(((envelopeFullLength + 1) / 2 | 0) * 4 + 44);
459 |
460 | var used = synth.sw(new Uint16Array(data.buffer, 44), envelopeFullLength) * 2;
461 |
462 | var dv = new Uint32Array(data.buffer, 0, 44);
463 | // Initialize header
464 | dv[0] = 0x46464952; // "RIFF"
465 | dv[1] = used + 36; // put total size here
466 | dv[2] = 0x45564157; // "WAVE"
467 | dv[3] = 0x20746D66; // "fmt "
468 | dv[4] = 0x00000010; // size of the following
469 | dv[5] = 0x00010001; // Mono: 1 channel, PCM format
470 | dv[6] = 0x0000AC44; // 44,100 samples per second
471 | dv[7] = 0x00015888; // byte rate: two bytes per sample
472 | dv[8] = 0x00100002; // 16 bits per sample, aligned on every two bytes
473 | dv[9] = 0x61746164; // "data"
474 | dv[10] = used; // put number of samples here
475 |
476 | // Base64 encoding written by me, @maettig
477 | used += 44;
478 | var i = 0,
479 | base64Characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
480 | output = 'data:audio/wav;base64,';
481 | for (; i < used; i += 3)
482 | {
483 | var a = data[i] << 16 | data[i + 1] << 8 | data[i + 2];
484 | output += base64Characters[a >> 18] + base64Characters[a >> 12 & 63] + base64Characters[a >> 6 & 63] + base64Characters[a & 63];
485 | }
486 |
487 | audioCtx && audioCtx.decodeAudioData(data.buffer, cb);
488 |
489 | return output;
490 | }
491 |
--------------------------------------------------------------------------------