pygame 筆記-7 生命值/血條處理
阿新 • • 發佈:2018-12-23
通常遊戲中的角色都有所謂的生命值,而且頭頂上會有一個血條顯示。生命值無非就是一個屬性而已,很容易在Player.py類中增加,頭頂上的血條其實就是繪製二個矩形,疊加在一起。
以上節的Player.py為例:
import pygame # 主角 class Player(object): def __init__(self, x, y, width, height, img_base_path): self.x = x self.y = y self.width = width self.height = height self.speed = 5 self.left = False self.right = True self.isJump = False self.walkCount = 0 self.t = 10 self.speed = 5 # 生命值 self.life = 10 self.char = pygame.image.load(img_base_path + 'standing.png') self.walkRight = [pygame.image.load(img_base_path + 'actor/R1.png'), pygame.image.load(img_base_path + 'actor/R2.png'), pygame.image.load(img_base_path + 'actor/R3.png'), pygame.image.load(img_base_path + 'actor/R4.png'), pygame.image.load(img_base_path + 'actor/R5.png'), pygame.image.load(img_base_path + 'actor/R6.png'), pygame.image.load(img_base_path + 'actor/R7.png'), pygame.image.load(img_base_path + 'actor/R8.png'), pygame.image.load(img_base_path + 'actor/R9.png')] self.walkLeft = [pygame.image.load(img_base_path + 'actor/L1.png'), pygame.image.load(img_base_path + 'actor/L2.png'), pygame.image.load(img_base_path + 'actor/L3.png'), pygame.image.load(img_base_path + 'actor/L4.png'), pygame.image.load(img_base_path + 'actor/L5.png'), pygame.image.load(img_base_path + 'actor/L6.png'), pygame.image.load(img_base_path + 'actor/L7.png'), pygame.image.load(img_base_path + 'actor/L8.png'), pygame.image.load(img_base_path + 'actor/L9.png')] self.hit_box = (self.x + 17, self.y + 11, 29, 52) def draw(self, win): if self.walkCount >= 9: self.walkCount = 0 if self.left: win.blit(self.walkLeft[self.walkCount % 9], (self.x, self.y)) self.walkCount += 1 elif self.right: win.blit(self.walkRight[self.walkCount % 9], (self.x, self.y)) self.walkCount += 1 else: win.blit(self.char, (self.x, self.y)) self.hit_box = (self.x + 17, self.y + 11, 29, 52) # 血條(頭頂的綠色背景矩形) pygame.draw.rect(win, (0, 128, 0), (self.hit_box[0], self.hit_box[1] - 10, 40, 8)) # 血條(頭頂的紅色背景矩形,即:消耗的血) pygame.draw.rect(win, (255, 0, 0), (self.hit_box[0] + self.life * 4, self.hit_box[1] - 10, 40 - self.life * 4, 8))
敵人類Enemy.py也是類似處理:
import pygame class Enemy(object): def __init__(self, x, y, width, height, end, img_base_path): self.x = x self.y = y self.width = width self.height = height self.path = [x, end] self.walkCount = 0 self.vel = 3 self.walkRight = [pygame.image.load(img_base_path + 'enemy/R1E.png'), pygame.image.load(img_base_path + 'enemy/R2E.png'), pygame.image.load(img_base_path + 'enemy/R3E.png'), pygame.image.load(img_base_path + 'enemy/R4E.png'), pygame.image.load(img_base_path + 'enemy/R5E.png'), pygame.image.load(img_base_path + 'enemy/R6E.png'), pygame.image.load(img_base_path + 'enemy/R7E.png'), pygame.image.load(img_base_path + 'enemy/R8E.png'), pygame.image.load(img_base_path + 'enemy/R9E.png'), pygame.image.load(img_base_path + 'enemy/R10E.png'), pygame.image.load(img_base_path + 'enemy/R11E.png')] self.walkLeft = [pygame.image.load(img_base_path + 'enemy/L1E.png'), pygame.image.load(img_base_path + 'enemy/L2E.png'), pygame.image.load(img_base_path + 'enemy/L3E.png'), pygame.image.load(img_base_path + 'enemy/L4E.png'), pygame.image.load(img_base_path + 'enemy/L5E.png'), pygame.image.load(img_base_path + 'enemy/L6E.png'), pygame.image.load(img_base_path + 'enemy/L7E.png'), pygame.image.load(img_base_path + 'enemy/L8E.png'), pygame.image.load(img_base_path + 'enemy/L9E.png'), pygame.image.load(img_base_path + 'enemy/L10E.png'), pygame.image.load(img_base_path + 'enemy/L11E.png')] self.hit_box = (self.x + 17, self.y + 2, 31, 57) #生命值 self.life = 10 def draw(self, win): if self.life > 0: self.move() if self.walkCount >= 11: self.walkCount = 0 if self.vel > 0: win.blit(self.walkRight[self.walkCount % 11], (self.x, self.y)) self.walkCount += 1 else: win.blit(self.walkLeft[self.walkCount % 11], (self.x, self.y)) self.walkCount += 1 self.hit_box = (self.x + 17, self.y + 2, 31, 57) # 血條 pygame.draw.rect(win, (0, 128, 0), (self.hit_box[0], self.hit_box[1] - 12, 40, 8)) pygame.draw.rect(win, (255, 0, 0), (self.hit_box[0] + self.life * 4, self.hit_box[1] - 12, 40 - self.life * 4, 8)) def move(self): if self.vel > 0: if self.x < self.path[1] + self.vel: self.x += self.vel else: self.vel = self.vel * -1 self.x += self.vel self.walkCount = 0 else: if self.x > self.path[0] - self.vel: self.x += self.vel else: self.vel = self.vel * -1 self.x += self.vel self.walkCount = 0
然後主類裡,碰撞檢測到後,將各自的生命值減1:
import os from bullet import * from player import * from enemy import * WIN_WIDTH, WIN_HEIGHT = 500, 500 pygame.init() win = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT)) pygame.display.set_caption("first game") img_base_path = os.getcwd() + '/img/' bg = pygame.image.load(img_base_path + 'bg.jpg') clock = pygame.time.Clock() def redraw_game_window(): win.blit(bg, (0, 0)) you_win = font.render('YOU WIN! ', 1, (0, 0, 255)) you_lost = font.render('YOU LOST! ', 1, (255, 0, 0)) # 敵人消滅,結束 if enemy.life <= 0: win.blit(you_win, (200, 230)) pygame.display.update() return # 主角被打死,結束 if man.life <= 0: win.blit(you_lost, (200, 230)) pygame.display.update() return # 主角的生命值 life_text = font.render('Life: ' + str(man.life), 1, (0, 0, 0)) win.blit(life_text, (20, 10)) # 顯示擊中後的得分 text = font.render('Score: ' + str(score), 1, (0, 0, 0)) win.blit(text, (370, 10)) man.draw(win) enemy.draw(win) for bullet in bullets: bullet.draw(win) pygame.display.update() def collision_check(a, b): temp1 = (b.x <= a.x + a.width <= b.x + b.width) temp2 = (b.y <= a.y + a.height <= b.y + b.height) return temp1 and temp2 # main font = pygame.font.SysFont('comicsans', 30, True) man = Player(200, 410, 64, 64, img_base_path) enemy = Enemy(100, 414, 64, 64, 400, img_base_path) run = True score = 0 bullets = [] while run: clock.tick(27) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False # 如果被敵人打到了,主角生命值-1 if collision_check(man, enemy) or collision_check(enemy, man): man.life -= 1 # 自動跳躍,防止血降得太快 man.isJump = True for b in bullets: # 碰撞檢測 if collision_check(b, enemy) or collision_check(enemy, b): score += 1 enemy.life -= 1 bullets.pop(bullets.index(b)) if WIN_WIDTH > b.x > 0: b.x += b.vel else: bullets.pop(bullets.index(b)) keys = pygame.key.get_pressed() if keys[pygame.K_SPACE]: if man.left: direction = -1 else: direction = 1 if len(bullets) < 5: bullets.append(Bullet(man.x + man.width // 2, man.y + man.height // 2, direction, img_base_path)) if keys[pygame.K_LEFT] and man.x > 0: man.x -= man.speed man.left = True man.right = False elif keys[pygame.K_RIGHT] and man.x < win.get_size()[0] - man.width: man.x += man.speed man.left = False man.right = True else: man.walkCount = 0 if not man.isJump: if keys[pygame.K_UP]: man.isJump = True man.walkCount = 0 else: if man.t >= -10: a = 1 if man.t < 0: a = -1 man.y -= 0.5 * a * (man.t ** 2) man.t -= 1 else: man.isJump = False man.t = 10 redraw_game_window() pygame.quit()