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
|
||||
-- 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
|
||||
|
||||
local Node = {
|
||||
_nodesById = setmetatable({}, {__mode="k"})
|
||||
}
|
||||
local nodesById = nil
|
||||
local root = nil
|
||||
|
||||
function Node:new()
|
||||
local node = { callbacks = {}, children = setmetatable({}, {__mode="k"}) }
|
||||
return setmetatable( node, { __index = Node } )
|
||||
local function newNode()
|
||||
return { callbacks = {}, children = setmetatable({}, {__mode="k"}) }
|
||||
end
|
||||
|
||||
function Node:findById(id)
|
||||
return self._nodesById[id]
|
||||
local function initialize()
|
||||
root = newNode()
|
||||
nodesById = setmetatable({}, {__mode="k"})
|
||||
end
|
||||
|
||||
function Node:findOrCreateChild(key)
|
||||
self.children[key] = self.children[key] or Node:new()
|
||||
local function findNodeById(id)
|
||||
return nodesById[id]
|
||||
end
|
||||
|
||||
local function findOrCreateChildNode(self, key)
|
||||
self.children[key] = self.children[key] or newNode()
|
||||
return self.children[key]
|
||||
end
|
||||
|
||||
function Node:findOrCreateDescendant(keys)
|
||||
local function findOrCreateDescendantNode(self, keys)
|
||||
local node = self
|
||||
for i=1, #keys do
|
||||
node = node:findOrCreateChild(keys[i])
|
||||
node = findOrCreateChildNode(node, keys[i])
|
||||
end
|
||||
return node
|
||||
end
|
||||
|
||||
function Node:invokeCallbacks(params)
|
||||
local function invokeNodeCallbacks(self, params)
|
||||
local counter = 0
|
||||
for _,callback in pairs(self.callbacks) do
|
||||
callback(unpack(params))
|
||||
@ -48,94 +51,87 @@ function Node:invokeCallbacks(params)
|
||||
return counter
|
||||
end
|
||||
|
||||
function Node:invokeAllCallbacksInSubTree(params)
|
||||
local counter = self:invokeCallbacks(params)
|
||||
local function invokeAllNodeCallbacksInSubTree(self, params)
|
||||
local counter = invokeNodeCallbacks(self, params)
|
||||
for _,child in pairs(self.children) do
|
||||
counter = counter + child:invokeAllCallbacksInSubTree(params)
|
||||
counter = counter + invokeAllNodeCallbacksInSubTree(child, params)
|
||||
end
|
||||
return counter
|
||||
end
|
||||
|
||||
function Node:invokeCallbacksFromPath(path)
|
||||
local function invokeNodeCallbacksFromPath(self, path)
|
||||
local node = self
|
||||
local params = copy(path)
|
||||
local counter = node:invokeCallbacks(params)
|
||||
local counter = invokeNodeCallbacks(node, params)
|
||||
|
||||
for i=1, #path do
|
||||
node = node.children[path[i]]
|
||||
if not node then break end
|
||||
table.remove(params, 1)
|
||||
counter = counter + node:invokeCallbacks(params)
|
||||
counter = counter + invokeNodeCallbacks(node, params)
|
||||
end
|
||||
|
||||
return counter
|
||||
end
|
||||
|
||||
function Node:addCallback(callback)
|
||||
local function addCallbackToNode(self, callback)
|
||||
local id = {}
|
||||
self.callbacks[id] = callback
|
||||
Node._nodesById[id] = self
|
||||
nodesById[id] = self
|
||||
return id
|
||||
end
|
||||
|
||||
function Node:removeCallback(id)
|
||||
local function removeCallbackFromNode(self, id)
|
||||
self.callbacks[id] = nil
|
||||
Node._nodesById[id] = nil
|
||||
nodesById[id] = nil
|
||||
end
|
||||
|
||||
|
||||
------ beholder table
|
||||
|
||||
local beholder = {}
|
||||
|
||||
|
||||
-- beholder private functions
|
||||
|
||||
local function falseIfZero(n)
|
||||
return n > 0 and n
|
||||
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)
|
||||
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)
|
||||
return params, callback
|
||||
end
|
||||
|
||||
local function initialize(self)
|
||||
self._root = Node:new()
|
||||
end
|
||||
|
||||
------ Public interface
|
||||
|
||||
local beholder = {}
|
||||
|
||||
function beholder:observe(...)
|
||||
checkSelf(self, 'observe')
|
||||
function beholder.observe(...)
|
||||
local event, callback = extractEventAndCallbackFromParams({...})
|
||||
return self._root:findOrCreateDescendant(event):addCallback(callback)
|
||||
local node = findOrCreateDescendantNode(root, event)
|
||||
return addCallbackToNode(node, callback)
|
||||
end
|
||||
|
||||
function beholder:stopObserving(id)
|
||||
checkSelf(self, 'stopObserving')
|
||||
local node = Node:findById(id)
|
||||
function beholder.stopObserving(id)
|
||||
local node = findNodeById(id)
|
||||
if not node then return false end
|
||||
node:removeCallback(id)
|
||||
removeCallbackFromNode(node, id)
|
||||
return true
|
||||
end
|
||||
|
||||
function beholder:trigger(...)
|
||||
checkSelf(self, 'trigger')
|
||||
return falseIfZero( self._root:invokeCallbacksFromPath({...}) )
|
||||
function beholder.trigger(...)
|
||||
return falseIfZero( invokeNodeCallbacksFromPath(root, {...}) )
|
||||
end
|
||||
|
||||
function beholder:triggerAll(...)
|
||||
checkSelf(self, 'triggerAll')
|
||||
return falseIfZero( self._root:invokeAllCallbacksInSubTree({...}) )
|
||||
function beholder.triggerAll(...)
|
||||
return falseIfZero( invokeAllNodeCallbacksInSubTree(root, {...}) )
|
||||
end
|
||||
|
||||
function beholder:reset()
|
||||
checkSelf(self, 'reset')
|
||||
initialize(self)
|
||||
function beholder.reset()
|
||||
initialize()
|
||||
end
|
||||
|
||||
initialize(beholder)
|
||||
initialize()
|
||||
|
||||
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 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
|
||||
beholder:trigger("COLLISION", a, b)
|
||||
beholder:trigger("COLLISION", b, a)
|
||||
beholder.trigger("COLLISION", a, b)
|
||||
beholder.trigger("COLLISION", b, a)
|
||||
end
|
||||
end
|
||||
|
||||
@ -91,7 +91,7 @@ end
|
||||
|
||||
function gameOver()
|
||||
print("braains")
|
||||
beholder:reset()
|
||||
beholder.reset()
|
||||
love.event.push('q')
|
||||
end
|
||||
|
||||
@ -107,12 +107,12 @@ function createPlayer()
|
||||
}
|
||||
setmetatable(player, {__tostring = function(t) return 'player' end})
|
||||
for dir,_ in pairs(directions) do
|
||||
beholder:observe("KEYPRESSED", dir, function() startMoving(player, dir) end)
|
||||
beholder:observe("KEYRELEASED", dir, function() stopMoving(player, dir) end)
|
||||
beholder.observe("KEYPRESSED", dir, function() startMoving(player, dir) end)
|
||||
beholder.observe("KEYRELEASED", dir, function() stopMoving(player, dir) end)
|
||||
end
|
||||
beholder:observe("KEYPRESSED", " ", activateMine)
|
||||
beholder.observe("KEYPRESSED", " ", activateMine)
|
||||
|
||||
beholder:observe("COLLISION", player, gameOver)
|
||||
beholder.observe("COLLISION", player, gameOver)
|
||||
|
||||
table.insert(entities, player)
|
||||
end
|
||||
@ -141,12 +141,12 @@ function createMine()
|
||||
}
|
||||
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
|
||||
mine.exploded = true
|
||||
mine.color = {50,50,50}
|
||||
zombie.dead = true
|
||||
beholder:trigger("KILLED", zombie)
|
||||
beholder.trigger("KILLED", zombie)
|
||||
end
|
||||
end)
|
||||
|
||||
@ -177,11 +177,11 @@ function love.draw()
|
||||
end
|
||||
|
||||
function love.keypressed(key)
|
||||
beholder:trigger("KEYPRESSED", key)
|
||||
beholder.trigger("KEYPRESSED", key)
|
||||
end
|
||||
|
||||
function love.keyreleased(key)
|
||||
beholder:trigger("KEYRELEASED", key)
|
||||
beholder.trigger("KEYRELEASED", key)
|
||||
end
|
||||
|
||||
function love.load()
|
||||
@ -196,34 +196,34 @@ function love.load()
|
||||
createZombie()
|
||||
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
|
||||
lastPressedKey = "<none yet>"
|
||||
beholder:observe("KEYPRESSED", function(key)
|
||||
beholder.observe("KEYPRESSED", function(key)
|
||||
lastPressedKey = key
|
||||
end)
|
||||
|
||||
-- binds escape to the gameOver function (quit game)
|
||||
beholder:observe("KEYPRESSED", "escape", gameOver)
|
||||
beholder.observe("KEYPRESSED", "escape", gameOver)
|
||||
|
||||
-- handle pause
|
||||
beholder:observe("KEYPRESSED", "pause", function()
|
||||
beholder.observe("KEYPRESSED", "pause", function()
|
||||
all(entities, pause)
|
||||
local id
|
||||
id = beholder:observe("KEYPRESSED", function()
|
||||
id = beholder.observe("KEYPRESSED", function()
|
||||
all(entities, unpause)
|
||||
beholder:stopObserving(id)
|
||||
beholder.stopObserving(id)
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
-- victor is triggered if enough kills are done
|
||||
beholder:observe("KILLED", function()
|
||||
beholder.observe("KILLED", function()
|
||||
killCount = killCount + 1
|
||||
if killCount == zombieCount then
|
||||
print("You win!")
|
||||
beholder:reset()
|
||||
beholder.reset()
|
||||
love.event.push('q')
|
||||
end
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user