178. 3D Dungeon – Posters, body parts and hitpoints
I have a new respect for the developers of FPS shooters. There is a lot of work.
I’ve just included the ability to put text and pictures on dungeon walls, and also programmed the damage system, ie what happens when you shoot something. This means figuring out how damage fits into the classes I have already.
I also laboriously broke the spider model into different parts so a head shot would do more damage than a leg shot.
So that’s what I’ll talk about here.
Damage system
When you shoot (say) a spider, the damage you cause depends on several things, including
- how accurate you are
- where you hit it
- the weapon you are using (which may affect accuracy too)
So I’m approaching it like this.
Accuracy
When you touch the screen, I will adjust for accuracy by adding a random change to the x,y position, the size of which may depend on things like your weapon, how tired or hungry you are, etc. I haven’t programmed this yet, but it will be easy.
Hit points and health
I am giving hitpoints to each weapon and health to each enemy object. When you hit an object, the damage caused will equal the hitpoints of the weapon, adjusted for the body part you hit (if available for that object). Some objects may not be affected by certain weapons, too.
This should not be programmed in the main draw function, nor in the player class. Object damage should be handled by the target that you hit. So when I identify the target, I run a function in that target’s class, to calculate damage, and give it the name of the weapon, and the body part I hit. The function gets the weapon hitpoints, adjusts them for body part hit (eg if head, multiply by 3, but if legs, multiply by 0.2), and deducts them from the target’s health.
Death
The target dies when the health goes to zero or less. What happens then?
I’d like to delete the target object, but at the time I find out it is dead, I am inside a function in that same object class, and an object can’t delete itself.
So what I do is add it to a table of objects to be deleted, and I get the main draw function to loop through that table each frame, deleting anything in it.
I will think about special effects for death, but not yet. Keep it simple at first. Right now, dead targets just disappear.
I also thought about showing the health of the target on the screen, but I haven’t really begun designing the display, so that will be for later, too.
Breaking models up into parts
My spider model came in one piece. Using Blender, I managed to break it roughly into three parts – head, body and legs – but it was very manual, requiring me to delete vertices manually to create breaks in the model, and not much fun. I hope I can find a better way for my other models.
Anyway, my spider model now comes into Codea in three chunks, each of which goes into a separate mesh, enabling me to tell which part I shot.
Putting posters and text on the walls
The dungeon walls get a bit boring after a while. I can use different textures for the walls, with a little effort, or I can decorate the walls with text or images.
It’s pretty easy to add 2D images to walls. I simply tell Codea the image name, the tile location, the rotation angle (0, 90, 180, or 270 degrees), and the scaling (eg 0.05) to apply to the image. The rotation angle is needed because Codea needs to turn the image the right way, and it also needs to place the image slightly in front of the wall. I find one pixel in front works fine for the dungeon (if you draw the image much closer to the wall, this confuses OpenGL, and the image will flicker).
For text images, I downloaded some bloody Halloween fonts and found a good one, used an image editor to create an image with some text, then imported them to Codea. When creating the images, I set the transparency below 100%, so that when it is placed over the wall, some of the wall texture shows through, making it look more real.
I realise I’ve skated over the details in this post, but I didn’t want to bore you with a lot of code that might not interest you. Write to me if you want to discuss anything.