Last active
December 27, 2018 05:18
-
-
Save Larkenx/139b4215089deeff38d2599686be72a1 to your computer and use it in GitHub Desktop.
JavaScript multiple inheritance / mixins for game development (entity component systems inspired) - mixin implementation from http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Entity } from '#/entities/Entity.js' | |
import { itemTypes, equipmentSlots, ammoTypes } from '#/utils/Constants'; | |
import { mix } from '#/utils/Mixins' | |
import { Stackable, Equippable, AmmunitionTyped, Fireable } from './ItemMixins'; | |
export default class Item extends Entity { | |
constructor(options) { | |
super(options) | |
this.category = options.category || itemTypes.MISCELLANEOUS | |
this.description = options.description || [] | |
} | |
} | |
export class Arrow extends mix(Item).with(Stackable, Equippable, AmmunitionTyped) { | |
constructor(configuration) { | |
super({ | |
equipmentSlot: equipmentSlots.AMMO, | |
ammoType: ammoTypes.ARROW, | |
...configuration | |
}) | |
} | |
} | |
export class Bow extends mix(Item).with(Equippable, AmmunitionTyped, Fireable) { | |
constructor(configuration) { | |
super({ | |
equipmentSlot: equipmentSlots.WEAPON, | |
ammoType: ammoTypes.ARROW, | |
...configuration | |
}) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ammoTypes } from "#/utils/Constants"; | |
export const Stackable = superclass => class extends superclass { | |
constructor(configuration) { | |
super(configuration) | |
if (!configuration.equipmentSlot) console.warn(`Defaulting to stackable quantity of 1 for stackable item: ${this}!`) | |
this.quantity = configuration.quantity || 1 | |
} | |
} | |
export const Equippable = superclass => class extends superclass { | |
constructor(configuration) { | |
super(configuration) | |
if (!configuration.equipmentSlot) throw `Unable to create equippable item without equipment slot: ${this}!` | |
this.equipmentSlot = configuration.equipmentSlot | |
} | |
} | |
export const Consumable = superclass => class extends superclass { | |
constructor(configuration) { | |
super(configuration) | |
if (!configuration.use) throw `Unable to create consumable item without "use" function: ${this}!` | |
this.use = configuration.use | |
} | |
} | |
export const Fireable = superclass => class extends superclass { | |
constructor(configuration) { | |
super(configuration) | |
if (!configuration.range) console.warn(`No maximum firable range set for this item: ${this}`) | |
this.cb.range = configuration.range || null | |
this.cb.ranged = true | |
} | |
} | |
export const AmmunitionTyped = superclass => class extends superclass { | |
constructor(configuration) { | |
super(configuration) | |
if (!configuration.ammoType) console.warn(`No ammunition type specified for this item, assuming it can be fired with anything: ${this}`) | |
this.ammoType = configuration.ammoType || ammoTypes.ANY | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const mix = superclass => new MixinBuilder(superclass) | |
class MixinBuilder { | |
constructor(superclass) { | |
this.superclass = superclass | |
} | |
with(...mixins) { | |
return mixins.reduce((c, mixin) => mixin(c), this.superclass) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment