First of all, it really helps to run crystal tool format
on your files, since inconsistently indented code like
end
end
end
end
end
end
end
end
is pretty much guaranteed to confuse you at some point (and even more so others trying to read the code). There are many coding errors, which would’ve been prevented solely by correct indenting (for example, you’re only checking @@menu
for "main"
, but not for "charselect"
.
The latter check is in the code, but only after @@menu
is confirmed to be "main"
, so your check for "charselect"
will always be false.
Also, your code is still displaying the window multiple times per frame if buttons are pressed - this indicates to me that you don’t really understand the code yourself - and this is also the reason why I recommended you (see Crsfml sprite texture not updating on it's own - #3 by MagicSparklyGoldfish) to simplify your code to the bare minimum first.
Keep in mind that you set your window to VSync, so every time you display the window, your program will not display another window until ~16.67 ms have passed. Multiple calls of window.display
per frame will absolutely destroy your performance.
But to answer your initial question:
You are, in theory, creating one new fiber per frame. Each call of MenuElements.cursorFunc(window, @@menu)
leads to a spawn do
block, which then creates an infinite loop - so you’re essentially starting an increasing number of fibers that never stop.
I still STRONGLY recommend you to discard any concurrency entirely here, especially if you’re just starting to learn the language. Try to write a simple loop with completely separated logic, drawing and event handling. Something like this:
class Game
@window : SF::RenderWindow
def initialize
@window = SF::RenderWindow.new(...) # Insert parameters here
@window.vertical_sync_enabled = true
end
def run
while @window.open?
handle_events
update
draw
end
end
def handle_events
# Check events here, don't draw anything here
end
def update
# Put your logic here, also no drawing here
end
def draw
# Draw your stuff here - and nothing more
@window.display # Render the window as the last thing to do
end
end
Game.new.run
This simple model will bring so much clarity into your code and help you in avoiding annoying bugs. It will run perfectly fine, even without fibers (trust me - you REALLY don’t need them for 2D applications unless you make use of networking or heavy resource loading).