Page 2 of 2

Re: waitkey()

Posted: Sun Mar 15, 2009 11:17 am
by appleide
How's this? Does same thing as my previous example, but this time uses coroutines. No visible difference, so I wont bother making .love and just post the code here.

Code: Select all

--MAIN.LUA
love.filesystem.require("waitkey.lua")

local rX=0;
local rY=100;

function load()

end

function update()
	rX=rX+1;
	if rX==100 then
		waitKey(waitkeypressed)
	end
	
end
function draw()
	love.graphics.rectangle(1, rX, rY, 100, 100);
end

function keypressed()
	error("hey")
end

function waitkeypressed(key)
	rY=rY+key
end

Code: Select all

-- WAITKEY.LUA
function waitKey(waitFunction)
	local oldkp=keypressed;
	local oldupdate=update;
	
	local _coroutine=coroutine.create(function()
		coroutine.yield(true);
	end)
	local currentCoroutine=_coroutine;
	
	function update()
		if currentCoroutine~=nil then
			local result, waiting = coroutine.resume(currentCoroutine);
			currentCoroutine=nil;
		end
		if waiting then
			currentCoroutine=_coroutine;
		end
	end
	function keypressed(key)
		currentCoroutine=nil;
		if oldkp~=nil then
			keypressed=oldkp;
		end
		if oldupdate~=nil then
			update=oldupdate;
		end
		waitFunction(key);
	end
end
P.S I still don't fully understand how coroutines works; Just copied the magic off your example. :/ I'm not even sure if coroutines are doing the work... I dont think they are :s

Re: waitkey()

Posted: Sun Mar 15, 2009 12:51 pm
by appleide
Okay, I finally get everything...
In here:

Code: Select all

function load()
	waitKeyLoad();
end
...
function update()
	if rX==100 then
		waitKey(waitFn)
		rY=300
	end
	if rX==600 then
		waitKey(waitFn)-- parameter function is executed after key press
		rY=200
	end
	
	rX=(rX+1)%800;
end
...
rY is only set after key press caused from waitKey().

I've uploaded another demo. This is what you REALLY want...
The previous one didn't really use those coroutines.

After doing all this I want to forget everything... This multi-threaded-ness makes my brain feel like being tied up and twisted and squeezed... Arrggh.

I've taken your coroutine example and hidden it from view. 8-)

Documentation:
To use:
put the "waitkey.lua" inside the love file into your game.
require it thus:

Code: Select all

love.filesystem.require("waitkey.lua");
then, in your game's load() method, add this line:

Code: Select all

function load()
  ..your code..
  waitKeyLoad();
end
When you want to pause your game until a key press, just call waitKey(waitFunction) in your update method, where waitFunction is of the form

Code: Select all

function(key)
end
waitKey MUST be called in the update method!!

You could wrap it like

Code: Select all

function update(dt)
  ..your code..
  if pause=true then
    waitKey(function(key) pause=false; end);
  end
  ..your code..
end
The variable "pause" would probably be set to true in the keypressed(key) callback in this case.

Post is in public domain.

Re: waitkey()

Posted: Sun Mar 15, 2009 1:39 pm
by osuf oboys
phoku wrote:*cough*

This is possible with coroutines. I have attached the proof of concept before.
The question was not whether it's possible, but how to do it good :-)
Using coroutines produces, in my opinion, unorganized and inflexible code, even if it potentially saves you a few lines for this particular case. Rather, I would argue that you forward the callbacks of the system to your scene/phase handler which updates the status as appropriate. This is fairly easy, minimizes coupling, and allows you to separate the view and the control. For example, def titlePhase:keypressed(key) if self.atIntroSplash and key == .. then text = ...; self.atIntroSplash = false end.

Re: waitkey()

Posted: Wed Mar 18, 2009 11:05 am
by appleide
Finally worked out how to make working compressed .love files. :/