Scoring & Health Bars
Subscribe to Tech with Tim
Score
For simplicity we are simply going to be increasing the score each time a bullet hits our goblin/enemy.
We are going to start by creating a variable at the top of our program called score.
score = 0
Next we are going to increment the score from our main loop where we check if the goblin is hit.
# This code exists inside the main loop for bullet in bullets: if bullet.y - bullet.radius < goblin.hitbox[1] + goblin.hitbox[3] and bullet.y + bullet.radius > goblin.hitbox[1]: if bullet.x + bullet.radius > goblin.hitbox[0] and bullet.x - bullet.radius < goblin.hitbox[0] + goblin.hitbox[2]: goblin.hit() score += 1 # NEW CODE bullets.pop(bullets.index(bullet))
We would like to display this score to the screen. To do this we must first create a font object.
font = pygame.font.SysFont("comicsans", 30, True) # The first argument is the font, next is size # and then True to make our font bold
After we create our font we need to render some text and blit it to the screen.
# This should go inside the redrawGameWindow function text = font.render("Score: " + str(score), 1, (0,0,0)) # Arguments are: text, anti-aliasing, color win.blit(text, (390, 10))
Health Bar
What we are going to do now is give our enemy health and a health bar. This way we can see when we should remove it from the screen. To create the health bar we are going to draw two rectangles. One green and one red. We will change the width of the green rectangle (which will overlay the red one) each time the enemy is hit.
To do this we must modify the enemy class like so.
class enemy(object): walkRight = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'), pygame.image.load('R3E.png'), pygame.image.load('R4E.png'), pygame.image.load('R5E.png'), pygame.image.load('R6E.png'), pygame.image.load('R7E.png'), pygame.image.load('R8E.png'), pygame.image.load('R9E.png'), pygame.image.load('R10E.png'), pygame.image.load('R11E.png')] walkLeft = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'), pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'), pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png'), pygame.image.load('L10E.png'), pygame.image.load('L11E.png')] def __init__(self, x, y, width, height, end): self.x = x self.y = y self.width = width self.height = height self.end = end self.path = [self.x, self.end] self.walkCount = 0 self.vel = 3 self.hitbox = (self.x + 17, self.y + 2, 31, 57) self.health = 10 # NEW self.visible = True # NEW def draw(self,win): self.move() if self.visible: # NEW if self.walkCount + 1 >= 33: self.walkCount = 0 if self.vel > 0: win.blit(self.walkRight[self.walkCount //3], (self.x, self.y)) self.walkCount += 1 else: win.blit(self.walkLeft[self.walkCount //3], (self.x, self.y)) self.walkCount += 1 pygame.draw.rect(win, (255,0,0), (self.hitbox[0], self.hitbox[1] - 20, 50, 10)) # NEW pygame.draw.rect(win, (0,128,0), (self.hitbox[0], self.hitbox[1] - 20, 50 - (5 * (10 - self.health)), 10)) # NEW self.hitbox = (self.x + 17, self.y + 2, 31, 57) #pygame.draw.rect(win, (255,0,0), self.hitbox,2) def move(self): if self.vel > 0: if self.x + self.vel < self.path[1]: self.x += self.vel else: self.vel = self.vel * -1 self.walkCount = 0 else: if self.x - self.vel > self.path[0]: self.x += self.vel else: self.vel = self.vel * -1 self.walkCount = 0 def hit(self): # ALL NEW if self.health > 0: self.health -= 1 else: self.visible = False print('hit')
Now we have a health bar that will move down as our goblin is hit.
Full Code
If you are confused by any of this code the video above offers more in depth explanations.
import pygame pygame.init() win = pygame.display.set_mode((500,480)) pygame.display.set_caption("First Game") walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'), pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')] walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'), pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'), pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')] bg = pygame.image.load('bg.jpg') char = pygame.image.load('standing.png') clock = pygame.time.Clock() score = 0 class player(object): def __init__(self,x,y,width,height): self.x = x self.y = y self.width = width self.height = height self.vel = 5 self.isJump = False self.left = False self.right = False self.walkCount = 0 self.jumpCount = 10 self.standing = True self.hitbox = (self.x + 17, self.y + 11, 29, 52) def draw(self, win): if self.walkCount + 1 >= 27: self.walkCount = 0 if not(self.standing): if self.left: win.blit(walkLeft[self.walkCount//3], (self.x,self.y)) self.walkCount += 1 elif self.right: win.blit(walkRight[self.walkCount//3], (self.x,self.y)) self.walkCount +=1 else: if self.right: win.blit(walkRight[0], (self.x, self.y)) else: win.blit(walkLeft[0], (self.x, self.y)) self.hitbox = (self.x + 17, self.y + 11, 29, 52) #pygame.draw.rect(win, (255,0,0), self.hitbox,2) class projectile(object): def __init__(self,x,y,radius,color,facing): self.x = x self.y = y self.radius = radius self.color = color self.facing = facing self.vel = 8 * facing def draw(self,win): pygame.draw.circle(win, self.color, (self.x,self.y), self.radius) class enemy(object): walkRight = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'), pygame.image.load('R3E.png'), pygame.image.load('R4E.png'), pygame.image.load('R5E.png'), pygame.image.load('R6E.png'), pygame.image.load('R7E.png'), pygame.image.load('R8E.png'), pygame.image.load('R9E.png'), pygame.image.load('R10E.png'), pygame.image.load('R11E.png')] walkLeft = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'), pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'), pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png'), pygame.image.load('L10E.png'), pygame.image.load('L11E.png')] def __init__(self, x, y, width, height, end): self.x = x self.y = y self.width = width self.height = height self.end = end self.path = [self.x, self.end] self.walkCount = 0 self.vel = 3 self.hitbox = (self.x + 17, self.y + 2, 31, 57) self.health = 10 self.visible = True def draw(self,win): self.move() if self.visible: if self.walkCount + 1 >= 33: self.walkCount = 0 if self.vel > 0: win.blit(self.walkRight[self.walkCount //3], (self.x, self.y)) self.walkCount += 1 else: win.blit(self.walkLeft[self.walkCount //3], (self.x, self.y)) self.walkCount += 1 pygame.draw.rect(win, (255,0,0), (self.hitbox[0], self.hitbox[1] - 20, 50, 10)) pygame.draw.rect(win, (0,128,0), (self.hitbox[0], self.hitbox[1] - 20, 50 - (5 * (10 - self.health)), 10)) self.hitbox = (self.x + 17, self.y + 2, 31, 57) #pygame.draw.rect(win, (255,0,0), self.hitbox,2) def move(self): if self.vel > 0: if self.x + self.vel < self.path[1]: self.x += self.vel else: self.vel = self.vel * -1 self.walkCount = 0 else: if self.x - self.vel > self.path[0]: self.x += self.vel else: self.vel = self.vel * -1 self.walkCount = 0 def hit(self): if self.health > 0: self.health -= 1 else: self.visible = False print('hit') def redrawGameWindow(): win.blit(bg, (0,0)) text = font.render('Score: ' + str(score), 1, (0,0,0)) win.blit(text, (390, 10)) man.draw(win) goblin.draw(win) for bullet in bullets: bullet.draw(win) pygame.display.update() #mainloop font = pygame.font.SysFont('comicsans', 30, True) man = player(200, 410, 64,64) goblin = enemy(100, 410, 64, 64, 450) shootLoop = 0 bullets = [] run = True while run: clock.tick(27) if shootLoop > 0: shootLoop += 1 if shootLoop > 3: shootLoop = 0 for event in pygame.event.get(): if event.type == pygame.QUIT: run = False for bullet in bullets: if bullet.y - bullet.radius < goblin.hitbox[1] + goblin.hitbox[3] and bullet.y + bullet.radius > goblin.hitbox[1]: if bullet.x + bullet.radius > goblin.hitbox[0] and bullet.x - bullet.radius < goblin.hitbox[0] + goblin.hitbox[2]: goblin.hit() score += 1 bullets.pop(bullets.index(bullet)) if bullet.x < 500 and bullet.x > 0: bullet.x += bullet.vel else: bullets.pop(bullets.index(bullet)) keys = pygame.key.get_pressed() if keys[pygame.K_SPACE] and shootLoop == 0: if man.left: facing = -1 else: facing = 1 if len(bullets) < 5: bullets.append(projectile(round(man.x + man.width //2), round(man.y + man.height//2), 6, (0,0,0), facing)) shootLoop = 1 if keys[pygame.K_LEFT] and man.x > man.vel: man.x -= man.vel man.left = True man.right = False man.standing = False elif keys[pygame.K_RIGHT] and man.x < 500 - man.width - man.vel: man.x += man.vel man.right = True man.left = False man.standing = False else: man.standing = True man.walkCount = 0 if not(man.isJump): if keys[pygame.K_UP]: man.isJump = True man.right = False man.left = False man.walkCount = 0 else: if man.jumpCount >= -10: neg = 1 if man.jumpCount < 0: neg = -1 man.y -= (man.jumpCount ** 2) * 0.5 * neg man.jumpCount -= 1 else: man.isJump = False man.jumpCount = 10 redrawGameWindow() pygame.quit()