Intro
This is a new series following Cosplore3D, a raycaster game to learn 3D graphics. This project is part of 12 Months 12 Projects, a challenge I set myself.
In the last post we added enemies (that are visible through walls), but now we need to start dealing with them, so in this post we will be working on a HUD.
Changing The Player
Since we're adding a new feature it's going to impact the Player
, so we need to add a few properties.
type Player struct {
x float64
y float64
angle float64
camera *Camera
curLevel string
speed float64
haste float64
health float64
weapon Weapon
}
All we added was health and a weapon. Now, we don't have this weapon type, se we're going to have to create one.
type Weapon struct {
damage float64
rof uint8 // Rate Of Fire - How many frames between shots
mag uint8 // Magazine - How many bullets the weapon can hold
}
Drawing A HUD
In DOOM and Wolfenstien3D the HUD is drawn on a bar at the bottom, which is how we are going to do this HUD. The first thing we want is some sort of health visualization. We will start by drawing up some health first.
heartImg := g.images["heart"]
ogW, ogH := heartImg.Size()
newW := (float64(screenHeight)/8.0 - 20)
newH := (float64(screenHeight)/8.0 - 20)
for i := 0; i < 5; i++ {
if p.health < float64((i+1)*20) {
continue
}
op := ebiten.DrawImageOptions{}
op.GeoM.Scale(newW/float64(ogW), newH/float64(ogH))
op.GeoM.Translate(10*float64(i+1)+newW*float64(i), float64(screenHeight)/8.0*7+10)
screen.DrawImage(&heartImg, &op)
}
This will draw 5 hearts at the bottom of the screen. The lower the health the player has, the less hearts that will appear.
That's pretty good, but now we need to show a weapon on screen.
func (w *Weapon) draw(g *Game, screen *ebiten.Image) {
img := g.images["gun"]
ogW, ogH := img.Size()
sW := screenWidth / 6.0 / float64(ogW)
sH := screenHeight / 4.0 / float64(ogH)
op := ebiten.DrawImageOptions{}
op.GeoM.Scale(sW, sH)
op.GeoM.Translate(screenWidth/2.0-(sW*float64(ogW))/2.0, screenHeight/8.0*7-sH*float64(ogH))
screen.DrawImage(&img, &op)
}
Here's our result.
I know, it doesn't look like a gun, we're just going to pretend like it does, I will change it later.
Ammo
The last thing we need to show is how much ammo the player has left. We are going to do this with some text. Now there isn't much interesting code so I'm just going to show the result.
Next
The world is looking pretty bleak. Sure, I can add colored blocks in some places when I feel like it, but it would be really great to have images. Because of this, I will have to work on upgrading how levels are stored, by adding more codes and more information, such as ground and sky color.