1. 程式人生 > >pygame 筆記-7 生命值/血條處理

pygame 筆記-7 生命值/血條處理

通常遊戲中的角色都有所謂的生命值,而且頭頂上會有一個血條顯示。生命值無非就是一個屬性而已,很容易在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()

 

原始碼下載: https://github.com/yjmyzz/pygame_tutorial