Rocket code flow.
WinMain SoundMgrCreate MainCreate GameCreate AttractCreate SoundCreate ItemsCreate CreateItems CreateItem MyD2DCreate CreateClass CreateWindow MainLoop MsgCreate MsgPaint ImgCreate ImgResize GameSetImage CreateThread(UpdateLoop) MsgResized GameSetArena ImgResize MainDestroy SoundMgrDestroy
The purpose here is to generate frames as quickly as possible, but with enough idle time that the motion is always smooth. I set a target frame rate and use QueryPerformanceCounter() to make sure each frame is presented on time, neither early nor late.
For applications that do not require a high frame rate or are refreshed only occasionally, GameUpdate() could be placed in the WM_TIMER message and ImgPaint() in WM_PAINT. Higher frame rates and smooth playback require a dedicated thread.
GameUpdate ImgPaint
Depends on the current game Mode, ATTRACT or PLAY. ATTRACT mode disables sounds and all user input except FIRE (used to exit ATTRACT mode), and updates the Attract objects.
No graphics rendering is performed during GameUpdate(), it is just updating the information.
UpdateAttract ItemsUpdate ImgBegin ItemsPlace AttractUpdate ImgEnd UpdatePlay ItemsUpdate Sounds ImgBegin ItemsPlace ImgEnd
The new positions for every item is calculated and stored in the associated Sprite object. Afterward, the Sprite will hold the previous location and current location. Collisions are detected using the new locations, which may result in Sprites being added, removed, or modified. This phase does not include any graphics rendering.
foreach(Item) { ItemUpdate } foreach(Item) { ItemCollision }
The sprites are added to the graphics rendering queue in hImg. This is just adding the sprites to the queue, nothing is being rendered.
This is when all the graphics rendering is performed.
The new frame is drawn and the sprites rendered to the offscreen image bitmap. The offscreen bitmap is then copied onto the window. I had originally assumed the copy to the window was slowing down the frame rate, but after extensive testing and comparison with the SwapChain method I determined that this Paint method delivers exactly the same performance as the SwapChain method. The only difference is that the Paint method will always wait for a vertical sync, limiting the maximum frame rate to 60Hz or 120Hz, depending on the hardware. In practical use, this is not a significant limitation since running at faster refresh rates results in choppy, glitchy motion.
DrawCreate Redraw BeginDraw GetBitmap DrawBitmap EndDraw
This is where the graphics are rendered to the back buffer (offscreen image bitmap). DrawBackground clears the frame; each frame is built from scratch. The sprites are rendered in the order they are found in the Sprites[] list. AttractDraw() is called only when in ATTRACT mode.
During testing I was able to render over 5000 sprites per frame in full screen (2160x1440).
BeginDraw DrawBackground DrawSprites DrawStatus AttractDraw EndDraw