Skip to content

Instantly share code, notes, and snippets.

@timetocode
Last active February 9, 2017 04:50
Show Gist options
  • Save timetocode/93f81390ea2dbad2d27e to your computer and use it in GitHub Desktop.
Save timetocode/93f81390ea2dbad2d27e to your computer and use it in GitHub Desktop.
An example of extending a prototypical game Entity to have different functionality (via adding functions to the prototype) in its server environment than on the game client.
/* ClientSide usage test, via browserify */
var Entity = require('./Entity')
require('./EntityClientSide')(Entity)
// the client receives data about a new entity:
var ent = Entity.newFromJson({ name: 'newbie', x: 12, y: -6 })
console.log(ent.name, ent.x, ent.y) // outputs "newbie 12 -6"
// an existing entity receives an update from the server:
ent.updateFromJson({ name: 'newbie the renamed', x: 2, y: 2 })
console.log(ent.name, ent.x, ent.y) // outputs "newbie the renamed 2 2"
// a simple game entity having a name and positional data
function Entity(name) {
this.name = name
this.x = 0
this.y = 0
this.speed = 5
}
module.exports = Entity
// adds render, newFromJson, and updateFromJson to entity
module.exports = function(Entity) {
// draws an Entity
Entity.prototype.render = function(drawDelta, context) {
console.log('drawing', this.name)
// actual drawing code would go here
}
// creates an Entity from json data
Entity.newFromJson = function(entityJson) {
var entity = new Entity(entityJson.name)
entity.x = entityJson.x
entity.y = entityJson.y
return entity
}
// updates an entity from json data
Entity.prototype.updateFromJson = function(entityJson) {
this.name = entityJson.name
this.x = entityJson.x
this.y = entityJson.y
}
}
// adds an update(delta) to entity, which runs its ai logic
module.exports = function(Entity) {
// updates an entity from json data
Entity.prototype.update = function(delta) {
console.log(this.name, 'updating')
this.ai.update(delta)
}
}
// AI for an entity that patrols from right to left
// the actual behavior is irrelevant, I just wanted to have a complex behavior for the serverside example
function PatrolState(entity, distance) {
this.entity = entity
this.distance = distance
this.x0 = entity.x
this.y0 = entity.y
this.movingRight = true
}
PatrolState.prototype.update = function(delta) {
if (this.movingRight) {
// travel to the right
this.entity.x += delta * this.entity.speed
// until distance reached
if (this.entity.x > this.x0 + this.distance) {
// then turn around
this.movingRight = false
}
} else {
// travel to the left
this.entity.x += delta * this.entity.speed * -1
// until distance reached (negative)
if (this.entity.x < this.x0 - this.distance) {
// then turn around
this.movingRight = true
}
}
}
module.exports = PatrolState
/* ServerSide usage example */
var PatrolState = require('./PatrolState')
var Entity = require('./Entity')
require('./EntityServerSide')(Entity)
// create an entity and give it the patroller AI
var sEnt = new Entity('Jimmy')
sEnt.ai = new PatrolState(sEnt, 5)
// run a game loop @ 20 FPS, updating our entity Jimmy
var tickLengthMs = 1000 / 20
var previousTick = Date.now()
var main = function () {
var now = Date.now()
if (previousTick + tickLengthMs <= now) {
var delta = (now - previousTick) / 1000
previousTick = now
sEnt.update(delta)
console.log(sEnt.x)
}
setImmediate(main)
}
main() // output: counts from ~ -5 to 5 as Jimmy patrols back and forth
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment