Don't get me wrong, I'm all for sticking to standards. I was just clarifying that you can use it (wasn't that what was meant by "It probably won't work"?).Robin wrote:The subtle difference between "you shouldn't use it" and "you can't use it".BlackBulletIV wrote:Funny thing is, it actually does work.slime wrote:It probably won't work.
Share your Utils
- BlackBulletIV
- Inner party member
- Posts: 1261
- Joined: Wed Dec 29, 2010 8:19 pm
- Location: Queensland, Australia
- Contact:
Re: Share your Utils
Thanks for the help guys!
Re: Share your Utils
To revive this, here's my "sound manager" that overloads love.audio.play to create sources if a file(name) instead of a source is given as argument and manages references to the sources so you don't have to worry about them anymore when playing sound effects.
Example:
I also use automatic image caching (which could also be done with kikitos memoize.lua):
Use it like this:
Last but not least, here's a case statement for Lua:
Example usage:
Example:
Code: Select all
function love.load()
bgm = love.audio.play("background-music.ogg", "stream", true) -- stream and loop background music and get a handle to the source
end
function love.update(dt)
love.audio.update()
end
function love.keypressed(key)
if key == 's' then
love.audio.stop(bgm)
elseif key == 'p' then
love.audio.play(bgm)
else
love.audio.play("explosion.ogg") -- play explosion sound once
end
end
I also use automatic image caching (which could also be done with kikitos memoize.lua):
Code: Select all
IMG = setmetatable({}, {__index = function(self, key)
local res = love.graphics.newImage("img/" .. key)
rawset(self, key, res)
return res
end})
Code: Select all
function love.draw()
love.graphics.draw(IMG['hamster.png'], 400,300)
end
Last but not least, here's a case statement for Lua:
Code: Select all
function case(x)
return function (of)
local what = of[x] or of.default
if type(what) == "function" then
return what()
end
return what
end
end
Code: Select all
self.animation_offset = case(self.anim.position) {
[2] = vector(0,-1),
[3] = vector(1,-1),
[4] = vector(1,0),
default = vector(0,0),
}
local x = case (position) {
left = 0, -- same as ['left'] = 0
center = (love.graphics.getWidth() - self.width) / 2,
right = love.graphics.getWidth() - self.width,
default = 100
}
-- function evaluation
case (key) {
up = function() player.move(0,-1) end,
down = function() player.move(0,1) end,
left = function() player.move(-1,0) end,
right = function() player.move(1,0) end,
}
- BlackBulletIV
- Inner party member
- Posts: 1261
- Joined: Wed Dec 29, 2010 8:19 pm
- Location: Queensland, Australia
- Contact:
Re: Share your Utils
Now that is some cool stuff you've got there vrld! I might use some of those.
Re: Share your Utils
There's some really awesome stuff in here.
I've made a simple event class that's been really helpful to me.
Example:
I've made a simple event class that's been really helpful to me.
Code: Select all
---------------------------------------------------------------------------------------------------
-- Event.lua
---------------------------------------------------------------------------------------------------
-- A structure that stores callback functions and calls them when triggered
---------------------------------------------------------------------------------------------------
-- Setup
local Event = {}
local next = next
local weakkey= { __mode="k" }
-- Registers a callback function for this event
-- The first parameter is the function to be called and the second optional
-- parameter is the table it should be called on.
function Event:callback(callback, obj)
local reg = self._registry
if not reg[callback] then reg[callback] = setmetatable({}, weakkey) end
if obj then
reg[callback][obj] = true
else
reg[callback].standalone = true
end
end
-- Removes a callback from the event
function Event:removeCallback(callback, obj)
local reg = self._registry
if reg[callback] and obj then
reg[callback][obj] = nil
else
reg[callback] = nil
end
end
-- Triggers all callback functions
function Event:trigger(...)
local reg = self._registry
local arg = {...}
if next(reg) == nil then return end
for callback, t in pairs(reg) do
if next(t) then
for obj,_ in pairs(t) do
if type(obj) == "table" then
if self._condition(callback, obj) then
callback(obj, unpack(arg))
end
end
end
if t.standalone then
if self._condition(callback) then
callback(unpack(arg))
end
end
end
end
end
-- Clears all callbacks
function Event:clear()
self._registry = setmetatable({}, weakkey)
end
-- Sets a condition function to test the callbacks. The function is given
-- the callback function and object as parameters and must return
-- true or false specifying if the callback should be be called or not.
function Event:setCondition(funct)
self._condition = funct
end
-- The default condition. Always just returns true
local function defaultCondition() return true end
-- Unsets the condition
function Event:unsetCondition()
self._condition = defaultCondition
end
-- Creates and returns a new event
function Event:new()
tmp = {}
tmp._registry = setmetatable({}, weakkey)
tmp._condition = defaultCondition
for k,v in pairs(Event) do
tmp[k] = v
end
return tmp
end
-- Returns the event class
return Event
Code: Select all
Event = require "Event"
-- Create some events
updateEvent = Event:new()
drawEvent = Event:new()
-- Have the love callback functions trigger events
function love.update(dt) updateEvent:trigger(dt) end
function love.draw() drawEvent:trigger() end
-- Now you can give it whatever functions you want to call when triggered:
updateEvent:callback( updateSomething )
drawEvent:callback( drawSomething )
-- You can also give an object to call the function on.
-- These call object:update() and object:draw()
updateEvent:callback(object.update, object)
drawEvent:callback(object.draw, object)
-- Sets a condition where only objects with an x value greater than 50 will be drawn.
drawEvent:setCondition( function(funct, obj) return obj.x > 50 end)
- slime
- Solid Snayke
- Posts: 3170
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Share your Utils
Here's my event library.
Re: Share your Utils
One more: On demand resource loading and caching.
Resources are loaded on demand by specifying a loader function. The resource will only be loaded once.
"Why" you ask? Because this:
Resources are loaded on demand by specifying a loader function. The resource will only be loaded once.
Code: Select all
local function Proxy(loader)
return setmetatable({}, {__index = function(self, k)
local v = loader(k)
rawset(self, k, v)
return v
end})
end
Code: Select all
-- set up a few caches
Image = Proxy(function(k) return love.graphics.newImage('img/' .. k .. '.png') end)
Font = Proxy(function(k) return love.graphics.newFont('font/game_over.ttf', k) end)
State = Proxy(function(k) return assert(love.filesystem.load('states/'..k..'.lua')) end)
Sound = Proxy(function(k) return love.sound.newSoundData('sound/' .. k .. '.ogg') end)
-- now you are able to do this without prior loading of resources
love.graphics.draw(Image.player, player.x, player.y, player.angle,1,1, Image.player:getWidth()/2, Image.player:getHeight()/2)
love.graphics.setFont(Font[30])
love.graphics.print("Hello, world!", 10,10)
Gamestate.switch(State.intro) -- loads states/intro.lua which returns a gamestate. file returns a Gamestate.
-- with the "audio manager" from a few posts ago
love.audio.play(Sound.explosion)
- Roland_Yonaba
- Inner party member
- Posts: 1563
- Joined: Tue Jun 21, 2011 6:08 pm
- Location: Ouagadougou (Burkina Faso)
- Contact:
Re: Share your Utils
A simple function for Image naive-resizing...
Have Just written on-the-job for my project...
Have Just written on-the-job for my project...
Code: Select all
function resizeImage(filename,newX,newY)
local out = love.image.newImageData(newX,newY)
local source = love.image.newImageData(filename)
local w, h = source:getWidth(), source:getHeight()
for x = 1,newX-1 do
for y = 1, newY-1 do
local intX = math.floor(x*(w/newX))
local intY = math.floor(y*(h/newY))
local r,g,b,a = source:getPixel(intX,intY)
out:setPixel(x,y,r,g,b,a)
end
end
return love.graphics.newImage(out)
end
Re: Share your Utils
Why not set the image filter to 'nearest' and use the scale parameters in love.draw()?
- Roland_Yonaba
- Inner party member
- Posts: 1563
- Joined: Tue Jun 21, 2011 6:08 pm
- Location: Ouagadougou (Burkina Faso)
- Contact:
Re: Share your Utils
Hmm...I see.. Something like...
I didn't know it could work that way. Thanks so much for the tip, it works faster for me.
Code: Select all
local im = love.graphics.newImage(filename)
im:setFilter("nearest","nearest")
function love.draw()
love.graphics.draw (im,x,y,r,newX/im:getWidth(),newY/im:getHeight(),ox,oy)
end
makeInaccessible
First, sorry for my English
When you wanna make a entity that you save be inaccessible and show up an error when you try to access to it, here the solution:
First arg is the entity (a table), second arg is the error message you want to show up
One more thing: the function error(msg, level) is rock with param level. By default level = 1, but when level = 2 (like above), it will show the correct line of you code that you access the inaccessible entity. Try to use it
When you wanna make a entity that you save be inaccessible and show up an error when you try to access to it, here the solution:
First arg is the entity (a table), second arg is the error message you want to show up
Code: Select all
local function makeInaccessible(tb, errorMsg)
--make it nil, so the metatable below will work perfectly
for k, v in pairs(tb) do
tb[k] = nil
end
local mt = {}
local err = function () error(errorMsg, 2) end --2 here to make the error description at right code line
mt.__index = err
mt.__newindex = err
setmetatable(tb, mt)
end
Who is online
Users browsing this forum: No registered users and 2 guests