Rendering Improvements

This weekend I took the game code and swapped out the custom code I had written to update the HTML Canvas element with rectangles and text and swapped in an open source library called Pixi.JS. Although my canvas renderer was working fine, it was not in a place where I could use it to animate the application and I felt more and more that in order to do some more advanced things, I needed to have a game engine capable of more than handling user input and outputting a static image that would remain present until the user did something else.

My early prototype tests were telling me that combat was confusing. You couldn't tell when you were getting hit, and displaying health in the sidebar wasn't very prominent and tended to not let you know that your death was imminent. Because of this, I felt that some form of animation and better rendering techniques were needed early on just to make sure the player had a good heads up display containing the vital information pertaining to their situation.

Because of this, I went with Pixi.JS is a widely-used library that is very good at rendering sprites and performing animation. Pixi.JS also works with or without WebGL and serves as the rendering backbone of the Phaser game engine (or at least a forked version of Phaser does). Phaser is a fairly popular web-based game framework, particularly for platformers, but I didn't want the constraints or handholding that came with that and instead opted to host my own canvas and manage a UI built around that canvas, using only a rendering library. I hope the decision holds strong, but I have no regrets about it at the moment.

I abstracted away my presentation logic so that I could swap out the component responsible for the rendering (either today or down the road if Pixi.JS doesn't work out) and I hooked up Pixi.JS and was astounded by how much slower it was than my engine. That's not to say that Pixi.JS is a poorly done library or that you  shouldn't use it, just that Pixi.JS was not optimized at all to handle massive amounts of text blocks like you'd need to present an ASCII-based roguelike.

Instead of giving up, I dug in, created a sprite sheet where each tile on the sheet was a letter from my font, and then I had Pixi.JS render the tile for the sprite corresponding to the character code onto the screen. Since my spritesheet consisted of all white text, I was able to use Pixi.JS to tint the bitmap to my desired color before displaying it to the screen.

This approach ultimately worked remarkably and I now have an engine rendering at 60 FPS and functioning quite well.

I did add a pair of animations to demonstrate and justify the early investment in rendering technology: Each actor now pulses a bit in a color animation, helping draw attention to them as opposed to the world around them. The rate of the animation increases as actors get closer and closer to death.

Additionally, when any actor you can see is hit (including yourself), a red square appears behind them and slowly fades out. This helps draw your attention to the fact that they were just injured.

I also did some work around Field of View rendering and rendering the world in a fog of war when tiles are known but no longer visible. These are both operational and should hit sometime this week, depending on when I feel the new rendering system is stable enough to replace the existing prototype as I'm still verifying that the application renders properly both with and without WebGL.

Leave a comment

Log in with your account to leave a comment.