The solution is called a double buffer. If you like, a second copy of the screen that isn't visible. The screen is just a large block of memory with bytes representing RGB values. Modern video cards too have special fast memory for this very purpose.
So, one does all ones drawing to the off-screen buffer, and then in one foul swoop copy the contents of that invisible buffer to the visible buffer.
Creating the off-screen buffer is simple in java-script. We just create another canvas (but not one that lives inside the DOM, the visible HTML if you like).
As you can see, this is completely compatible with the drawing routines we looked at before. I've made the "offscreenCanvas" in this example 1024 pixels wide and 768 pixels high. Usually your double buffer would be exactly the same size as the visible canvas we will be copying it to. You can however have more than one offscreen buffer. The reason you'd do this is to perhaps draw something like a split screen (e.g. two players on one screen in their own seperate areas). You could make the offscreenCanvas smaller than the destination buffer and leave some room on the destination buffer for status displays etc.
How do we copy the contents of this offscreen buffer to the real one? Simple: given that "screenContext" is the 2d context of the canvas on the screen, we use yet another variant of drawImage. This one takes the offscreen CANVAS as a parameter, and the location of this buffer inside the other one. (0,0) is the top left corner. It is important to not get confused between the CANVAS and the CONTEXT.
The CONTEXT is the thing that gets drawn into. The CANVAS is the thing that is displayed. The first parameter in the double buffer copy is the offscreen CANVAS, NOT its CONTEXT. A CANVAS also has a "width" and a "height" (dimensions). The CONTEXT doesn't!
So lets create a simple sample using this. We need to use a timer, because we want to have something move around.
Each frame/timer event we:
1. Clear the offscreen buffer with fillRect()
2. Draw whatever we need to inside the offscreen buffer
3. Copy the offscreen buffer to the screen buffer (if they are the same size we won't need to do any cleaning of the screen buffer since it will be cleared by the content of the offscreen buffer.
In this sample I will make red "balls" move around the screen. To do this we need to introduce a new drawing function for drawing circles. Its called "arc". "arc" takes 5 parameters, they are:
where: x, y, is the center of the circle
startAngle the start angle in radians
endAngle tne end angle in radians
counterClockwise a boolean variable requesting the circle be drawn counter clockwise (or clockwise if false)
"arc" is actually a very versatile function that can draw many different kind of shapes. In particular it is good at drawing pac-man. We only need it to draw a circle though (sorry to spoil the fun, the fun comes later!)
We introduce two classes. The first class is our BouncyBall class, shown below.
Now you're going to get another lecture in object oriented programming. The class above is a self contained class that can both move, and draw a ball. Nothing too complex. It is always important to seperate the MOVING (the logic) from the DRAWING (the rendering). The real power of the object oriented-ness of this class will come about through the Controller class below.
Creating the ball takes the following parameters (x, y, colour, speed, size, width, height, canvas). The x,y is its starting position on the screen. The colour is its colour. The speed how fast it moves. The size, how big it is. The width and height are the CONTEXT's size - so that the ball knows when its hit the edges of the screen. Canvas, the last parameter, is where to draw the ball (the offscreen buffer in this case.
The second class is the "controller" (or scene) class. It draws the balls and moves the balls. It coordinates everything and is the thing that is called by the timer.
I mentioned "object oriented" and "power" in the same sentence. This wasn't an oxymoron! The controller class with just a few lines of code can control 100s of balls all at once. Our example only uses 25 balls. I'd encourage you to download the sample below and play with it. Finally - the "scene" and the timer are created
The java-script and html for this sample can be downloaded here.
The final little ball demo is quite mesmerizing. Different sized balls moving at different speeds and all moving in different directions.
No comments:
Post a Comment