Page 1 of 1

'Send in x millisecs' performance hit with user interaction?

Posted: Mon Feb 24, 2014 6:35 pm
by thatkeith
I'm experimenting with a basic game-like toy – yes, a Flappy Birds thing (bows head in shame). It's a challenge, ok? Don't judge me! :D :wink:

It has a very few objects that scroll, a single object that the user controls, and basic collision detection. This is working ok-ish with very basic scripting - a custom handler that moves the scrolling objects sideways a few pixels, drops the user-controlled object down a few pixels, checks intersect() for them (using switch-case-break) and sends a trigger to itself every 30 millisecs if no collision is detected.

Moving the user-controlled object around is currently done with a card-level mouseDown handler. I've tried keyDown and arrowKey events too. Currently, this runs a small number of 'send handlerx to me in 20 millisecs' that moves the object up with a slight accellerate/decellerate feel before the above custom handler kicks in again.

This all works, BUT the side-scrolling object script execution does slow down appreciably when the user clicks the mouse or taps the key a lot. Is this an inevitable consequence of the way the engine works or is it possible to build something like this in a more optimal way? For example, should I be synchronising my 'send in x millisecs' to the same delay, or perhaps making them coincide less?

Re: 'Send in x millisecs' performance hit with user interact

Posted: Mon Feb 24, 2014 6:46 pm
by splash21
Adding a bunch of empty handlers to the card or stack script to prevent certain messages getting to the engine avoids some slow downs;

Code: Select all

on mouseDown
end mouseDown

on mouseDoubleDown
end mouseDoubleDown

on mouseUp
end mouseUp

on mouseDoubleUp
end mouseDoubleUp

on mouseRelease
end mouseRelease

on keyDown
end keyDown

on rawKeyDown
end rawKeyDown

on keyUp
end keyUp

on rawKeyUp
end rawKeyUp

If you can keep ALL code that moves objects in one animation loop that is called at regular intervals, then you shouldn't have any problems with user interaction slowing the animations down.

If you pick an interesting deviation from the original - flappy hippos maybe? - I'll definitely be downloading!

Re: 'Send in x millisecs' performance hit with user interact

Posted: Mon Feb 24, 2014 7:05 pm
by thatkeith
Thanks – making empty handlers to swallow related events sounds like a useful (and logical) suggestion. I'll try it in a sec.

I'm talking with my son about anternative takes on this - I'll mention Flappy Hippos to him, I'm sure it'll get a laugh!
He's a stop-motion animator, and we may try making all the game graphics as stop motion-style objects. :)

Re: 'Send in x millisecs' performance hit with user interact

Posted: Mon Feb 24, 2014 7:23 pm
by BvG
one way to avoid slowdown is, not to poll messages at all, but use a game loop repeating handler instead, and check user input in there. For example:

Code: Select all

on startGame
  send "eventLoop" to me in 20 miliseconds
end startGame

on eventLoop
  if the mouse is down then
    --flap the bird
  end if
  --update gui, move background image, etc.
  send "eventLoop" to me in 20 milliseconds
end eventLoop
to remove complexity, I suggest also to keep the amount of objects to a minimum, group everything, and reuse the pipes when they're off screen by moving them to the right again (don't create and delete objects either, that's slow).

Re: 'Send in x millisecs' performance hit with user interact

Posted: Mon Feb 24, 2014 8:08 pm
by thatkeith
Interesting that I can use animated GIFs and the intersect function's "opaque pixels" to detect a 'collision' with just the visible pixels, and it works across the frames. Very nice! :)

I also improved the performance by using the move command and the 'without waiting' parameter to have the user-controlled object move with moderate naturalness and without undue delays in the other repeating handler.

Interesting how there are generally half a dozen different ways to do things in LiveCode, each with their own advantages and drawbacks! :D

Re: 'Send in x millisecs' performance hit with user interact

Posted: Mon Feb 24, 2014 9:32 pm
by thatkeith
Thanks @BvG, I've been gravitating towards that, and your advice pushed me to complete the process:

Code: Select all

on startTheGame
   set the loc of image "person" to 170,165 -- move the character to the start position
   set the repeatCount of image "pipes.gif" to -1 -- loop the GIF
   runTheGame
end startTheGame

on runTheGame
   if the mouse is down then
      move image "person" relative 0,20 -- swim down
   else
      if the top of image "person" > 0 then
         set the top of image "person" to the top of image "person" - 3 -- float up
      end if
   end if
   if intersect(image "person", image "pipes.gif", "opaque pixels") then
         beep
         set the repeatCount of image "pipes.gif" to 0 -- stop the GIF
         set the currentFrame of image "pipes.gif" to 1 -- set the GIF to frame 1
         move image "person" to 266,383 in 80 ticks -- sink the character
         break
      else
         send runTheGame to me in 15 milliseconds -- loop all this!
   end if
end runTheGame

Re: 'Send in x millisecs' performance hit with user interact

Posted: Mon Feb 24, 2014 9:44 pm
by splash21
Much to my horror, I find myself interested in your project :shock:

I've played the original - and hated it! My kids can get scores of 28 and 40. I have managed .... 2.

I hope you post an update when it's up and running!

Re: 'Send in x millisecs' performance hit with user interact

Posted: Mon Feb 24, 2014 10:13 pm
by sefrojones
I've threw something like this together this week as well. Some of these suggestions could probably improve performance in my game. :)

http://www.youtube.com/watch?v=amQK8OIcruc

although I'm having trouble playing a sound on intersect with the coins, the sound seems to try to play several times, even after the image has been hidden....

edit: I should add, that i've never actually played the original "flappy Birds", so this is a loose impression from seeing it on youtube.

Re: 'Send in x millisecs' performance hit with user interact

Posted: Mon Feb 24, 2014 10:18 pm
by thatkeith
Heh. My youngest son has a score somewhere around 40, and I can't get past 2 either. It is *incredibly* infuriating – and very clever.
The plan is a stop-motion animated GIF for the character and side-scrolling clay-based landscapes and hazards. I'll shout out when I get to a stage worth trying. :)

Re: 'Send in x millisecs' performance hit with user interact

Posted: Mon Feb 24, 2014 10:20 pm
by sefrojones
Here's some public domain assets to use as placeholders for your very own flappy bird clone:

http://opengameart.org/content/tappy-plane

:wink:

Re: 'Send in x millisecs' performance hit with user interact

Posted: Mon Feb 24, 2014 10:32 pm
by splash21
@sefrojonesGAda40 - LOL. Love that name - "crappy chicken". Neat 8)

Re: 'Send in x millisecs' performance hit with user interact

Posted: Tue Feb 25, 2014 6:21 pm
by jacque
thatkeith wrote:Thanks @BvG, I've been gravitating towards that, and your advice pushed me to complete the process
I'd add just one more thing to speed it up a bit. Polling the mouse state is expensive, especially when it's repeated that often, so it's better to catch messages from the engine and use that to determine the state of the mouse. It's a minor change to your handler; just set a flag when the mouse goes down and change it when the card receives a mouseUp message.

Code: Select all

local sMouseIsDown

on startTheGame
   set the loc of image "person" to 170,165 -- move the character to the start position
   set the repeatCount of image "pipes.gif" to -1 -- loop the GIF
   runTheGame
end startTheGame

on mouseUp
  put false into sMouseIsDown
end mouseUp

on mouseDown
  put true into sMouseIsDown
end mouseDown

on runTheGame
   if sMouseIsDown then
      move image "person" relative 0,20 -- swim down
   else
      if the top of image "person" > 0 then
         set the top of image "person" to the top of image "person" - 3 -- float up
      end if
   end if
   if intersect(image "person", image "pipes.gif", "opaque pixels") then
         beep
         set the repeatCount of image "pipes.gif" to 0 -- stop the GIF
         set the currentFrame of image "pipes.gif" to 1 -- set the GIF to frame 1
         move image "person" to 266,383 in 80 ticks -- sink the character
         break
      else
         send runTheGame to me in 15 milliseconds -- loop all this!
   end if
end runTheGame

Re: 'Send in x millisecs' performance hit with user interact

Posted: Tue Feb 25, 2014 6:36 pm
by thatkeith
Nice! Thanks @jacque, this is useful stuff