git @ Cat's Eye Technologies Cosmos-Boulders / master src / collision.js
master

Tree @master (Download .tar.gz)

collision.js @masterraw · history · blame

// SPDX-FileCopyrightText: In 2019, Chris Pressey, the original author of this work, placed it into the public domain.
// SPDX-License-Identifier: Unlicense
// For more information, please refer to <https://unlicense.org/>


import { concoctJaft as concoct } from '../contrib/jaft-0.2/jaftConcoctor.js';
import { get, newList, push, reduce } from './immutable.js';
import { abs, makeAction } from './utils.js';
import { updatePlayer } from './player.js';
import { updateBoulder } from './boulder.js';
import { updateMissile } from './missile.js';


/* --[ Collision ]-------------------------------------------------------- */


const isCollidingMissileBoulder = concoct({get, abs}, `(missile, boulder) =>
    abs(get(missile, "x") - get(boulder, "x")) < 10 &&
    abs(get(missile, "y") - get(boulder, "y")) < 10`);


const isCollidingPlayerBoulder = concoct({get, abs}, `(player, boulder) =>
    abs(get(player, "x")     - get(boulder, "x")) < 10 &&
    abs(get(player, "y") + 5 - get(boulder, "y")) < 10`);


const missileCollisionReducer = concoct({
    push, makeAction, updatePlayer, updateMissile, updateBoulder,
    isCollidingMissileBoulder
}, `(accum, missile) =>
    const [player, missiles, boulder] = accum;
    isCollidingMissileBoulder(missile, boulder) ?
        [
            updatePlayer(player, makeAction("SCORE_POINTS")),
            push(missiles, updateMissile(missile, makeAction("EXPLODE"))),
            updateBoulder(boulder, makeAction("EXPLODE"))
        ] :
        [player, push(missiles, missile), boulder]
`);


const boulderCollisionReducer = concoct({
    get, push, reduce, newList, makeAction, updatePlayer, updateBoulder,
    isCollidingPlayerBoulder, missileCollisionReducer
}, `(accum, boulder) =>
    const [player, missiles, boulders] = accum;
    get(boulder, "mode") === "GONE" ? accum : (
	    get(boulder, "mode") === "MOVING" ? (
            get(player, "mode") === "PLAYING" && isCollidingPlayerBoulder(player, boulder) ? (
                [
                    updatePlayer(player, makeAction("EXPLODE")),
                    missiles,
                    push(boulders, updateBoulder(boulder, makeAction("EXPLODE")))
                ]
            ) : (
                const [player2, missiles2, boulder2] = reduce(
                    missiles, missileCollisionReducer, [player, newList(), boulder]
                );
                [player2, missiles2, push(boulders, boulder2)]
            )
        ) : [player, missiles, push(boulders, boulder)]
    )`);


const detectCollisions = concoct({
    reduce, newList, boulderCollisionReducer
}, `(player, missiles, boulders) =>
    reduce(
        boulders, boulderCollisionReducer, [player, missiles, newList()]
    )`);


export { detectCollisions };