In which we show the player’s health and score, indicate how healthy the enemy is, and add some feedback to hits
As things stand, damage is being done to our characters, but that damage isn’t terribly apparent. Furthermore, there’s little feedback on achieving a hit, or taking damage. So let’s change that.
This is another lesson that won’t touch on many new Panda-specific matters, and which I thus intend to somewhat skim over. Once again however, I do intend to at least in brief describe what I’m doing!
First of all, let’s display the player’s health and score, both near the top-left of the screen.
The score will simply be text, and we’ll show it via Panda’s handy “OnscreenText” class, which allows one to quickly and easily throw some text onto the screen. This class can be limiting at times, and for more complex purposes, Panda offers other, more-powerful text-classes. But for our purposes here, OnscreenText will be fine.
The player’s health will be displayed as a row of “heart”-icons, using a similar class: “OnscreenImage”. In terms of logic, we’ll simply keep a list of these icons, and display the appropriate number of them for the player’s current health. It’s not an elegant or efficient approach, but it’s simple.
In “GameObject.py”:
As for the Walking Enemy’s health, we’ll simply shade its model to black as it becomes more damaged. This is achieved by applying a colour-scale to its Actor–that is, a colour by which the model’s colours will be multiplied.
Now we can see the effect of damage done, on both our player-character and the enemy!
Next, let’s attend to our laser. It’s not all that satisfying to hit enemies with it–it does damage, but there’s little feedback as it does. A hit looks no different to a miss.
So, we’re going to add two effects that will show up when we hit a Walking Enemy (but not a Trap Enemy, as they’re invulnerable): First, a sort of hit-flash will appear, pulsing and randomly changing its orientation to give the impression of coruscating rays of light. And second, we’re going to add a point-light, to give it a bit more glow.
We’ll be adding lines within the ‘if keys[“shoot”]’ code-section that we already have in Player’s “update” method. So, instead of just showing the new lines, I’m going to show the full section of code and mark the new lines with “# NEW!!!”:
And finally, some more cleaning up:
Before we move on, I want to talk about how we used the point-light above. Specifically, these lines:
NodePaths have two means of preventing a light from affecting them (and their children): “clearLight” and “setLightOff”. These seem similar, but aren’t. The “clearLight” method removes a light that has been applied to the node via “setLight”. The “setLightOff” method places a note of sorts on the node that indicates that the light in question shouldn’t affect it–regardless of where the light was applied. This can be useful for specifying that a given node should not be lit, despite “setLight” having been applied to one of its parents, for example.
So why not use “setLightOff” here? Because those “notes” (called “attribs”) accumulate. By calling “setLightOff”, we’re not removing the light from the node, we’re adding successive attribs saying “don’t light this”.
With all that done, our laser should now be a bit more striking when it hits a Walking Enemy!
And finally, we’ll turn the tables and add a hit-flash that shows that the player has taken damage.
Functionally, this will be pretty much the same as the hit-flash that we used for the laser, except that instead of pulsing continuously, it will pulse just once.
Furthermore, since our player-character has only five health-points, let’s make a hit to the player very obvious, and so make our hit-flash rather large.
Now hits against the player should hopefully feel a bit more impactful, too!
Of course, as things stand, neither enemy nor player actually suffers from losing health. We’ll get to the player later, but let’s change this for our Walking Enemies next. Indeed, let’s get them both dying and spawning next…