As you know, I’m doing some improvements on my game.
instead of paint “all” in only one layer, i’m painting the background, the maze, the title on a myCanvas_layer0 and the snacks, cat, mouse on myCanvas (this is for now, for tests…)
there are N-O-T-H-I-N-G calling a refresh on myCanvas_layer0… so why paint event is called all the time?
canvas.paint has an auto-refresh built in?
this next two images, are without and with a layer, showing the number of calls to draw the maze walls. i put a quit just after the last canvas has paint.
I think you are doing it wrong with ‘layers’. Take a look at the little Asteroids game I made.
Use a timer set to 13 (60fps) and draw the objects.
No need to refresh the canvas the way you are doing. That’s just overloading and way too slow.
Paint is triggered by the refresh, it does not cause a refresh. Your canvas can be refreshed at other times too, such as when switching focus or when another window passes over it. Use paint as “here’s what should be on the canvas at this point in time” and the refresh won’t matter.
Usually I recommend not ever writing to any properties inside a paint event. It’s a view-only event. There have been times when I’ve broken that rule, but it’s always made my life more difficult.
You should perform all of your drawing in a single canvas instead of trying to overlap controls. There was an example project that demonstrated this. Not sure if it is still included.
Perhaps you misunderstood the advice you;ve been given. Instead of using multiple Canvas controls to stack your drawing, use multiple Picture objects. That reduces your Paint event to a couple of g.DrawPicture calls. As well as drawing the parts that change all the time, like the mouse and cat.
For example, in Paint you have c_game.paintWalls(g). You want to replace that call with a pre-rendered picture. Fortunately, you’re passing g as graphics to the method, which means the method doesn’t care where g came from. So add a property wallPicture as Picture to the window and in the window Opening event
wallPicture = new Picture(width, height)
c_game.paintWalls(wallPicture.Graphics)
You only call paintWalls once to render the walls and then use the picture in the canvas paint event instead of paintWalls.
do not overlap controls, use one single canvas as mentioned.
a canvas has no buffer, if it get invalid because a window or something overlap and move
it start the paint event for a refresh/redraw.
should be part of the game class and create at game start / level change via method
c_game.wallPicture = new Picture(width, height)
c_game.paintWalls(wallPicture.Graphics)
You should only use one canvas. Not canvas layers.
I said it before and say it again - you are doing it wrong.
And again .. check the Asteroid game I provided. It should give you a lot of pointers how to create simple games running smoothly (60fps)
i think it could be one layer labyrinth walls, score text, lives, level number, the collect pieces via one method which return a picture. (with your sub methods for drawing the parts)
the moving mouse and cat on top in every frame.
and if the mouse collect one item redraw into a static picture again,
if she not collect draw the same picture again because nothing change.
Here’s the web page intro text: This book “I Wish I Knew How to … Program Threads and Timers with Xojo Desktop” shows you how to use timers to refresh the GUI and threads to perform background tasks with your computer to increase the program execution speed.
Yes, that happens.
Avoid overlapping controls at all cost.
Render all the painting to an in-memory picture, and paint that picture to the canvas in the paint event.
Invalidate the canvas instead of refreshing, and it will only redraw when it needs to.