Deal with combos ...

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Deal with combos ...

Post by Roland_Yonaba »

I was wondering...

Assuming one wants to make a 2d fighting game... where some fighters can make special moves when players hits a specific sequence of keys...
How would you manage that ?

For instance :
Hitting consecutively up-up-down-down : Fighter makes an extra jump!
Hitting consecutively up-left- (down+up) : Fighter starts flying...

And the whole like....
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Deal with combos ...

Post by bartbes »

There are several ways, I'll tell you about two.
The first is keeping a table around of the n last keypresses (where n is the maximum combo length), after every keypress you test if a combo has been made, and then act upon it.
The second is instead keeping a 'combo position' variable, that indicates the position in the combo keylist for a certain combo. So for a combo aabb, when a is pressed, it is 1, when a is pressed again, it is 2, when a is pressed again, it will be 0. (Because it doesn't match.)
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Deal with combos ...

Post by Roland_Yonaba »

Well, i'am not a genius... So what do you think of that snippet ?
Can I improve this ? How ?

Code: Select all

local combos = { 'aabb', 'abab','ccded','zzeru' }
local message = 'waiting for combo'
local sequence = ''
local refresh = 0

function love.update(dt)
refresh = refresh+dt
	if refresh > 1.5 then
	refresh = 0
	sequence = ''
	end
end


function love.draw()
	love.graphics.print(message,10,10)
	love.graphics.print('refresh : '..refresh,10,30)
	love.graphics.print(sequence,10,50)	
end

function love.keypressed(key,unicode)
	sequence = sequence..key
	sequence = (sequence:len() > 5) and (sequence:sub(2,sequence:len())) or sequence
	for i,combo in ipairs(combos) do
		if sequence:find(combo) then
		message = 'combo '..combo..' entered!'
		sequence = ''
		break
		end
	end		
end
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Deal with combos ...

Post by Robin »

That would work, but it might not be the best way of doing things, especially when considering keys like "shift" and "return".

Also, I would set refresh to 0 when a key is pressed, because otherwise a combo might be cut off in the middle if you have bad luck.

Thirdly, it might be a better idea to make the combo string the key in the combos table, especially because this allows you to use functions like this:

Code: Select all

local combos = {}
function combos.aabb ()
	message = "Awesome!"
end
function combos.abab()
	message = "Another combo"
end
-- ... <snip> ...
function love.keypressed(key,unicode)
	sequence = sequence..key
	sequence = (#sequence > 5) and (sequence:sub(2,#sequence)) or sequence
	if combos[sequence] then
		combos[sequence]()
		sequence = ''
		refresh = 0
	end		
end
Help us help you: attach a .love.
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Deal with combos ...

Post by Roland_Yonaba »

You're definitely right...and I'm pretty sure it saves a lot of ressources that running a for loop anytime keypressed callback is triggered.
Well, I think I'm up for a key-pairs table...But i'll use simple strings, instead of functions. Here's the whole code.

Code: Select all

local combos = {['aabb'] = 'aabb - Awesome!',
                ['abab'] = 'abab - Well-done!',
                ['cdef'] = 'cdef - C-c-c-combo breaker!!!'}
				
local message = 'waiting for combo'
local sequence = ''
local refresh = 0

function love.update(dt)
refresh = refresh+dt
	if refresh > 1.5 then
	refresh = 0
	sequence = ''
	end
end


function love.draw()
	love.graphics.print(message,10,10)
	love.graphics.print('refresh : '..refresh,10,30)
	love.graphics.print(sequence,10,50)	
end

function love.keypressed(key,unicode)
	if unicode > 31 and unicode < 166 then
	sequence = sequence..key
	sequence = (#sequence > 5) and (sequence:sub(2,#sequence)) or sequence
	    if combos[sequence] then
		message = combos[sequence]
		sequence = ''
		refresh = 0
	    end 
	end
end
It works fine.. Thanks bartbes and Robin for the tip!
User avatar
miko
Party member
Posts: 410
Joined: Fri Nov 26, 2010 2:25 pm
Location: PL

Re: Deal with combos ...

Post by miko »

Robin wrote:That would work, but it might not be the best way of doing things, especially when considering keys like "shift" and "return".
You can check also my sample code here:
https://github.com/miko/Love2d-samples/ ... odeCapture
My lovely code lives at GitHub: http://github.com/miko/Love2d-samples
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 2 guests