mirror of
https://github.com/kikito/beholder.lua.git
synced 2024-12-16 00:34:21 +00:00
updated demo to beholder 2.0.0
This commit is contained in:
parent
333b25c40c
commit
7095da9ed1
Binary file not shown.
98
beholder.lua
98
beholder.lua
@ -1,4 +1,4 @@
|
|||||||
-- beholder.lua - v1.0.1 (2011-11)
|
-- beholder.lua - v2.0.0 (2011-11)
|
||||||
|
|
||||||
-- Copyright (c) 2011 Enrique García Cota
|
-- Copyright (c) 2011 Enrique García Cota
|
||||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
-- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
@ -13,33 +13,36 @@ end
|
|||||||
|
|
||||||
-- private Node class
|
-- private Node class
|
||||||
|
|
||||||
local Node = {
|
local nodesById = nil
|
||||||
_nodesById = setmetatable({}, {__mode="k"})
|
local root = nil
|
||||||
}
|
|
||||||
|
|
||||||
function Node:new()
|
local function newNode()
|
||||||
local node = { callbacks = {}, children = setmetatable({}, {__mode="k"}) }
|
return { callbacks = {}, children = setmetatable({}, {__mode="k"}) }
|
||||||
return setmetatable( node, { __index = Node } )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Node:findById(id)
|
local function initialize()
|
||||||
return self._nodesById[id]
|
root = newNode()
|
||||||
|
nodesById = setmetatable({}, {__mode="k"})
|
||||||
end
|
end
|
||||||
|
|
||||||
function Node:findOrCreateChild(key)
|
local function findNodeById(id)
|
||||||
self.children[key] = self.children[key] or Node:new()
|
return nodesById[id]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function findOrCreateChildNode(self, key)
|
||||||
|
self.children[key] = self.children[key] or newNode()
|
||||||
return self.children[key]
|
return self.children[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
function Node:findOrCreateDescendant(keys)
|
local function findOrCreateDescendantNode(self, keys)
|
||||||
local node = self
|
local node = self
|
||||||
for i=1, #keys do
|
for i=1, #keys do
|
||||||
node = node:findOrCreateChild(keys[i])
|
node = findOrCreateChildNode(node, keys[i])
|
||||||
end
|
end
|
||||||
return node
|
return node
|
||||||
end
|
end
|
||||||
|
|
||||||
function Node:invokeCallbacks(params)
|
local function invokeNodeCallbacks(self, params)
|
||||||
local counter = 0
|
local counter = 0
|
||||||
for _,callback in pairs(self.callbacks) do
|
for _,callback in pairs(self.callbacks) do
|
||||||
callback(unpack(params))
|
callback(unpack(params))
|
||||||
@ -48,94 +51,87 @@ function Node:invokeCallbacks(params)
|
|||||||
return counter
|
return counter
|
||||||
end
|
end
|
||||||
|
|
||||||
function Node:invokeAllCallbacksInSubTree(params)
|
local function invokeAllNodeCallbacksInSubTree(self, params)
|
||||||
local counter = self:invokeCallbacks(params)
|
local counter = invokeNodeCallbacks(self, params)
|
||||||
for _,child in pairs(self.children) do
|
for _,child in pairs(self.children) do
|
||||||
counter = counter + child:invokeAllCallbacksInSubTree(params)
|
counter = counter + invokeAllNodeCallbacksInSubTree(child, params)
|
||||||
end
|
end
|
||||||
return counter
|
return counter
|
||||||
end
|
end
|
||||||
|
|
||||||
function Node:invokeCallbacksFromPath(path)
|
local function invokeNodeCallbacksFromPath(self, path)
|
||||||
local node = self
|
local node = self
|
||||||
local params = copy(path)
|
local params = copy(path)
|
||||||
local counter = node:invokeCallbacks(params)
|
local counter = invokeNodeCallbacks(node, params)
|
||||||
|
|
||||||
for i=1, #path do
|
for i=1, #path do
|
||||||
node = node.children[path[i]]
|
node = node.children[path[i]]
|
||||||
if not node then break end
|
if not node then break end
|
||||||
table.remove(params, 1)
|
table.remove(params, 1)
|
||||||
counter = counter + node:invokeCallbacks(params)
|
counter = counter + invokeNodeCallbacks(node, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
return counter
|
return counter
|
||||||
end
|
end
|
||||||
|
|
||||||
function Node:addCallback(callback)
|
local function addCallbackToNode(self, callback)
|
||||||
local id = {}
|
local id = {}
|
||||||
self.callbacks[id] = callback
|
self.callbacks[id] = callback
|
||||||
Node._nodesById[id] = self
|
nodesById[id] = self
|
||||||
return id
|
return id
|
||||||
end
|
end
|
||||||
|
|
||||||
function Node:removeCallback(id)
|
local function removeCallbackFromNode(self, id)
|
||||||
self.callbacks[id] = nil
|
self.callbacks[id] = nil
|
||||||
Node._nodesById[id] = nil
|
nodesById[id] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
------ beholder table
|
||||||
|
|
||||||
|
local beholder = {}
|
||||||
|
|
||||||
|
|
||||||
-- beholder private functions
|
-- beholder private functions
|
||||||
|
|
||||||
local function falseIfZero(n)
|
local function falseIfZero(n)
|
||||||
return n > 0 and n
|
return n > 0 and n
|
||||||
end
|
end
|
||||||
|
|
||||||
local function checkSelf(self, methodName)
|
|
||||||
assert(type(self)=="table" and self._root, "Use beholder:" .. methodName .. " instead of beholder." .. methodName)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function extractEventAndCallbackFromParams(params)
|
local function extractEventAndCallbackFromParams(params)
|
||||||
assert(#params > 0, "beholder:observe requires at least one parameter - the callback. You usually want to use two, i.e.: beholder:observe('EVENT', callback)")
|
assert(#params > 0, "beholder.observe requires at least one parameter - the callback. You usually want to use two, i.e.: beholder.observe('EVENT', callback)")
|
||||||
local callback = table.remove(params, #params)
|
local callback = table.remove(params, #params)
|
||||||
return params, callback
|
return params, callback
|
||||||
end
|
end
|
||||||
|
|
||||||
local function initialize(self)
|
|
||||||
self._root = Node:new()
|
|
||||||
end
|
|
||||||
|
|
||||||
------ Public interface
|
------ Public interface
|
||||||
|
|
||||||
local beholder = {}
|
function beholder.observe(...)
|
||||||
|
|
||||||
function beholder:observe(...)
|
|
||||||
checkSelf(self, 'observe')
|
|
||||||
local event, callback = extractEventAndCallbackFromParams({...})
|
local event, callback = extractEventAndCallbackFromParams({...})
|
||||||
return self._root:findOrCreateDescendant(event):addCallback(callback)
|
local node = findOrCreateDescendantNode(root, event)
|
||||||
|
return addCallbackToNode(node, callback)
|
||||||
end
|
end
|
||||||
|
|
||||||
function beholder:stopObserving(id)
|
function beholder.stopObserving(id)
|
||||||
checkSelf(self, 'stopObserving')
|
local node = findNodeById(id)
|
||||||
local node = Node:findById(id)
|
|
||||||
if not node then return false end
|
if not node then return false end
|
||||||
node:removeCallback(id)
|
removeCallbackFromNode(node, id)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function beholder:trigger(...)
|
function beholder.trigger(...)
|
||||||
checkSelf(self, 'trigger')
|
return falseIfZero( invokeNodeCallbacksFromPath(root, {...}) )
|
||||||
return falseIfZero( self._root:invokeCallbacksFromPath({...}) )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function beholder:triggerAll(...)
|
function beholder.triggerAll(...)
|
||||||
checkSelf(self, 'triggerAll')
|
return falseIfZero( invokeAllNodeCallbacksInSubTree(root, {...}) )
|
||||||
return falseIfZero( self._root:invokeAllCallbacksInSubTree({...}) )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function beholder:reset()
|
function beholder.reset()
|
||||||
checkSelf(self, 'reset')
|
initialize()
|
||||||
initialize(self)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
initialize(beholder)
|
initialize()
|
||||||
|
|
||||||
return beholder
|
return beholder
|
||||||
|
38
main.lua
38
main.lua
@ -44,8 +44,8 @@ function checkCollision(a,b)
|
|||||||
local ax1, ay1, ax2, ay2 = a.x, a.y, a.x+16, a.y+16
|
local ax1, ay1, ax2, ay2 = a.x, a.y, a.x+16, a.y+16
|
||||||
local bx1, by1, bx2, by2 = b.x, b.y, b.x+16, b.y+16
|
local bx1, by1, bx2, by2 = b.x, b.y, b.x+16, b.y+16
|
||||||
if ax1 < bx2 and ax2 > bx1 and ay1 < by2 and ay2 > by1 then
|
if ax1 < bx2 and ax2 > bx1 and ay1 < by2 and ay2 > by1 then
|
||||||
beholder:trigger("COLLISION", a, b)
|
beholder.trigger("COLLISION", a, b)
|
||||||
beholder:trigger("COLLISION", b, a)
|
beholder.trigger("COLLISION", b, a)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ end
|
|||||||
|
|
||||||
function gameOver()
|
function gameOver()
|
||||||
print("braains")
|
print("braains")
|
||||||
beholder:reset()
|
beholder.reset()
|
||||||
love.event.push('q')
|
love.event.push('q')
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -107,12 +107,12 @@ function createPlayer()
|
|||||||
}
|
}
|
||||||
setmetatable(player, {__tostring = function(t) return 'player' end})
|
setmetatable(player, {__tostring = function(t) return 'player' end})
|
||||||
for dir,_ in pairs(directions) do
|
for dir,_ in pairs(directions) do
|
||||||
beholder:observe("KEYPRESSED", dir, function() startMoving(player, dir) end)
|
beholder.observe("KEYPRESSED", dir, function() startMoving(player, dir) end)
|
||||||
beholder:observe("KEYRELEASED", dir, function() stopMoving(player, dir) end)
|
beholder.observe("KEYRELEASED", dir, function() stopMoving(player, dir) end)
|
||||||
end
|
end
|
||||||
beholder:observe("KEYPRESSED", " ", activateMine)
|
beholder.observe("KEYPRESSED", " ", activateMine)
|
||||||
|
|
||||||
beholder:observe("COLLISION", player, gameOver)
|
beholder.observe("COLLISION", player, gameOver)
|
||||||
|
|
||||||
table.insert(entities, player)
|
table.insert(entities, player)
|
||||||
end
|
end
|
||||||
@ -141,12 +141,12 @@ function createMine()
|
|||||||
}
|
}
|
||||||
setmetatable(mine, {__tostring = function(t) return 'mine' end})
|
setmetatable(mine, {__tostring = function(t) return 'mine' end})
|
||||||
|
|
||||||
beholder:observe("COLLISION", mine, function(zombie)
|
beholder.observe("COLLISION", mine, function(zombie)
|
||||||
if not mine.exploded then
|
if not mine.exploded then
|
||||||
mine.exploded = true
|
mine.exploded = true
|
||||||
mine.color = {50,50,50}
|
mine.color = {50,50,50}
|
||||||
zombie.dead = true
|
zombie.dead = true
|
||||||
beholder:trigger("KILLED", zombie)
|
beholder.trigger("KILLED", zombie)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -177,11 +177,11 @@ function love.draw()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function love.keypressed(key)
|
function love.keypressed(key)
|
||||||
beholder:trigger("KEYPRESSED", key)
|
beholder.trigger("KEYPRESSED", key)
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.keyreleased(key)
|
function love.keyreleased(key)
|
||||||
beholder:trigger("KEYRELEASED", key)
|
beholder.trigger("KEYRELEASED", key)
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.load()
|
function love.load()
|
||||||
@ -196,34 +196,34 @@ function love.load()
|
|||||||
createZombie()
|
createZombie()
|
||||||
end
|
end
|
||||||
|
|
||||||
beholder:observe(print) -- print every event on the terminal
|
beholder.observe(print) -- print every event on the terminal
|
||||||
|
|
||||||
-- prints the last pressed key on the screen
|
-- prints the last pressed key on the screen
|
||||||
lastPressedKey = "<none yet>"
|
lastPressedKey = "<none yet>"
|
||||||
beholder:observe("KEYPRESSED", function(key)
|
beholder.observe("KEYPRESSED", function(key)
|
||||||
lastPressedKey = key
|
lastPressedKey = key
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- binds escape to the gameOver function (quit game)
|
-- binds escape to the gameOver function (quit game)
|
||||||
beholder:observe("KEYPRESSED", "escape", gameOver)
|
beholder.observe("KEYPRESSED", "escape", gameOver)
|
||||||
|
|
||||||
-- handle pause
|
-- handle pause
|
||||||
beholder:observe("KEYPRESSED", "pause", function()
|
beholder.observe("KEYPRESSED", "pause", function()
|
||||||
all(entities, pause)
|
all(entities, pause)
|
||||||
local id
|
local id
|
||||||
id = beholder:observe("KEYPRESSED", function()
|
id = beholder.observe("KEYPRESSED", function()
|
||||||
all(entities, unpause)
|
all(entities, unpause)
|
||||||
beholder:stopObserving(id)
|
beholder.stopObserving(id)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
-- victor is triggered if enough kills are done
|
-- victor is triggered if enough kills are done
|
||||||
beholder:observe("KILLED", function()
|
beholder.observe("KILLED", function()
|
||||||
killCount = killCount + 1
|
killCount = killCount + 1
|
||||||
if killCount == zombieCount then
|
if killCount == zombieCount then
|
||||||
print("You win!")
|
print("You win!")
|
||||||
beholder:reset()
|
beholder.reset()
|
||||||
love.event.push('q')
|
love.event.push('q')
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user