蟒蛇做一个塔防游戏

利用python3pygame模块基本实现塔防游戏的基本功能,包括血量和分数显示,bgm,防御塔建造,防御塔攻击范围内的敌军,暂停和加速功能。由于实在没有素材,用的都是自己截图P的,所以美化不好。但基本保证功能,其中有一个BUG,但不影响游戏效果。

1.运行主类

"""主程序"""

from pygame.locals import *

from TowerDefend.enemy import *

from TowerDefend.towerposSet import *

from TowerDefend.tower import *

import pygame

 

 

def run():

    """运行函数"""

    pygame.init()

    size = width, height = 1200, 600

    screen = pygame.display.set_mode(size)

    background_img = pygame.image.load(r'image/background.png').convert_alpha()

    background_img = pygame.transform.scale(background_img, (width, height))

    # 创建分数和血量

    health_count = 5

    score_count = 0

    score = pygame.font.Font('font/score_health.ttf', 30)

    health = pygame.font.Font('font/score_health.ttf', 30)

    # 创建背景音乐

    bg_music = pygame.mixer.music

    bg_music.load('media/bg.mp3')

    bg_music.set_volume(2)

    # 创建敌军类

    enemies = pygame.sprite.Group()

    ENEMY_NUM = 5

    position = [[258, 600], [258, 670], [258, 740], [258, 810], [258, 880]]

    for i in range(ENEMY_NUM):

        enemies.add(Enemy(position[i]))

    # 创建炮塔

    towers = pygame.sprite.Group()

    # 加载暂停键

    pause_img = pygame.image.load('image/pause.png').convert_alpha()

    pause_rect = pause_img.get_rect()

    pause_rect.left, pause_rect.top = 1145, 0

    # 加载血量和金币显示

    health_money_img = pygame.image.load('image/health_money.png').convert_alpha()

    health_money_rect = health_money_img.get_rect()

    health_money_rect.left, health_money_rect.top = 0, 0

    # 加载加速键

    speed_img = pygame.image.load('image/speed.png').convert_alpha()

    speed_rect = speed_img.get_rect()

    speed_rect.left, speed_rect.top = 1090, 0

    # 设置炮塔位置

    towers_pos = pygame.sprite.Group()

    position_list = [[225, 495], [264, 428], [312, 428], [362, 428], [410, 428], [460, 428], [508, 428], [561, 428],

                     [561, 373], [377, 373]]

    for i in range(len(position_list)):

        towers_pos.add(Position(position_list[i]))

    # 设置循环条件

    running = True

    clock = pygame.time.Clock()

    paused = False

    # 播放音乐

    if not bg_music.get_busy():

        bg_music.play(-1)

    while running:

        clock.tick(100)

        for event in pygame.event.get():

            if event.type == QUIT:

                running = False

            if event.type == MOUSEBUTTONDOWN:

                if event.button == 1:

                    if speed_rect.collidepoint(event.pos):

                        for each in enemies:

                            each.accelerate *= 2

                    if pause_rect.collidepoint(event.pos):

                        paused = not paused

                    for each in towers_pos:

                        if each.rect.collidepoint(event.pos):

                            tower = Tower([each.rect.left, each.rect.top])

                            towers.add(tower)

                            towers_pos.remove(each)

        if not paused:

            for enemy in enemies:

                if enemy.active:

                    enemy.move()

                else:

                    if enemy.rect.top <= 180:

                        health_count -= 1

                    if enemy.rect.top > 180:

                        score_count += 20

                    enemies.remove(enemy)

        # 绘制界面设置

        screen.blit(background_img, (0, 0))

        screen.blit(health.render(str(health_count), True, (255, 255, 255)), (60, 0.3))

        screen.blit(score.render(str(score_count), True, (255, 255, 255)), (130, 0.5))

        screen.blit(health_money_img, health_money_rect)

        screen.blit(pause_img, pause_rect)

        screen.blit(speed_img, speed_rect)

        # 绘制炮塔

        for each in towers:

            each.draw(screen, enemies)

            each.hit(enemies)

        # 绘制炮塔位置

        towers_pos.draw(screen)

        # 敌军若存活则绘制其和血量

        for enemy in enemies:

            if enemy.active:

                screen.blit(enemy.img, enemy.rect)

                enemy.drawhealth(screen)

        pygame.display.flip()

 

    pygame.quit()

 

 

if __name__ == "__main__":

run()

炮塔类

"""TOWER"""

import pygame

import math

 

 

class Tower(pygame.sprite.Sprite):

    """tower"""

 

    def __init__(self, pos):

        pygame.sprite.Sprite.__init__(self)

        self.img0 = pygame.image.load('image/tower0.png')

        self.img1 = pygame.image.load('image/tower1.png')

        self.img2 = pygame.image.load('image/tower2.png')

        self.rect = self.img0.get_rect()

        self.rect.left, self.rect.top = pos

        self.count = 1

 

    def draw(self, screen, enemies):

        """绘制"""

        if self.count > 90:

            self.count = 1

        if 1 <= self.count < 30:

            screen.blit(self.img0, self.rect)

        elif 30 <= self.count < 60:

            screen.blit(self.img1, self.rect)

        else:

            screen.blit(self.img2, self.rect)

        for enemy in enemies:

            distance = math.sqrt(

                math.pow((self.rect.left - enemy.rect.left), 2) + math.pow((self.rect.top - enemy.rect.top), 2))

            if distance < 50 and enemy.active is True:

                self.count += 1

 

    def hit(self, enemies):

        """攻击"""

        for enemy in enemies:

            distance = math.sqrt(

                math.pow((self.rect.left - enemy.rect.left), 2) + math.pow((self.rect.top - enemy.rect.top), 2))

            if distance < 50:

                enemy.health -= 1

            if enemy.health == 0:

                enemy.active = False

敌军类

import pygame

 

 

class Enemy(pygame.sprite.Sprite):

    """外汇返佣"""

 

    def __init__(self, position):

        pygame.sprite.Sprite.__init__(self)

        self.img = pygame.image.load(r'image/enemy.png').convert_alpha()

        self.rect = self.img.get_rect()

        self.init_pos = position

        self.rect.left, self.rect.top = self.init_pos

        self.accelerate = 1

        self.speed = [0, -self.accelerate]

        self.active = True

        self.health = 500

        # 竖直

        self.status = 'UP'

 

    def move(self):

        """移动"""

        self.rect = self.rect.move(self.speed)

        if self.rect.top <= 448 and self.rect.left == 258:

            self.rect.top = 448

            self.status = 'R'

            self.img = pygame.transform.rotate(self.img, 270)

            self.speed = [self.accelerate, 0]

        if self.rect.top == 448 and self.rect.left >= 597:

            self.rect.left = 597

            self.status = 'UP'

            self.img = pygame.transform.rotate(self.img, 90)

            self.speed = [0, -self.accelerate]

        if 320 < self.rect.top <= 335 and self.rect.left == 597:

            self.rect.top = 335

            self.status = 'L'

            self.img = pygame.transform.rotate(self.img, 90)

            self.speed = [-self.accelerate, 0]

        if self.rect.top == 335 and self.rect.left <= 370:

            self.rect.left = 370

            self.status = 'UP'

            self.img = pygame.transform.rotate(self.img, 270)

            self.speed = [0, -self.accelerate]

        if self.rect.top <= 216 and self.rect.left == 370:

            self.rect.top = 216

            self.status = 'R'

            self.img = pygame.transform.rotate(self.img, 270)

            self.speed = [self.accelerate, 0]

        if self.rect.top == 216 and 800 > self.rect.left >= 746:

            self.rect.left = 746

            self.status = 'DW'

            self.img = pygame.transform.rotate(self.img, 270)

            self.speed = [0, self.accelerate]

        if self.rect.top >= 330 and self.rect.left == 746:

            self.rect.top = 330

            self.status = 'R'

            self.img = pygame.transform.rotate(self.img, 90)

            self.speed = [self.accelerate, 0]

        if self.rect.top == 330 and self.rect.left >= 930:

            self.rect.left = 930

            self.status = 'UP'

            self.img = pygame.transform.rotate(self.img, 90)

            self.speed = [0, -self.accelerate]

        if self.rect.top < 180:

            self.active = False

    def drawhealth(self, screen):

        """绘制血量"""

        BLACK = (0, 0, 0)

        RED = (255, 0, 0)

        GREEN = (0, 255, 0)

        health_percentage = float(self.health) / 500

        if self.status == 'UP':

            start = self.rect.left + 8

            pygame.draw.line(screen, BLACK, (start, self.rect.top - 3),

                             (start + 32, self.rect.top - 3), 4)

            if health_percentage > 0.5:

                pygame.draw.line(screen, GREEN, (start, self.rect.top - 3),

                                 (start + 32 * health_percentage, self.rect.top - 3), 4)

            else:

                pygame.draw.line(screen, RED, (start, self.rect.top - 3),

                                 (start + 32 * health_percentage, self.rect.top - 3), 4)

        elif self.status == 'DW':

            start = self.rect.left + 8

            pygame.draw.line(screen, BLACK, (start, self.rect.bottom + 3),

                             (start + 32, self.rect.bottom + 3), 4)

            if health_percentage > 0.5:

                pygame.draw.line(screen, GREEN, (start, self.rect.bottom + 3),

                                 (start + 32 * health_percentage, self.rect.bottom + 3), 4)

            else:

                pygame.draw.line(screen, RED, (start, self.rect.bottom + 3),

                                 (start + 32 * health_percentage, self.rect.bottom + 3), 4)

        elif self.status == 'R':

            start = self.rect.bottom - 8

            pygame.draw.line(screen, BLACK, (self.rect.right + 3, start),

                             (self.rect.right + 3, start - 32), 4)

            if health_percentage > 0.5:

                pygame.draw.line(screen, GREEN, (self.rect.right + 3, start),

                                 (self.rect.right + 3, start - 32 * health_percentage), 4)

            else:

                pygame.draw.line(screen, RED, (self.rect.right + 3, start),

                                 (self.rect.right + 3, start - 32 * health_percentage), 4)

        else:

            start = self.rect.bottom - 8

            pygame.draw.line(screen, BLACK, (self.rect.left - 3, start),

                             (self.rect.left - 3, start - 30), 4)

            if health_percentage > 0.5:

                pygame.draw.line(screen, GREEN, (self.rect.left - 3, start),

                                 (self.rect.left - 3, start - 30 * health_percentage), 4)

            else:

                pygame.draw.line(screen, RED, (self.rect.left - 3, start),

                                 (self.rect.left - 3, start - 30 * health_percentage), 4)

 

    def reset(self):

        """reset the position"""

        self.rect.left, self.rect.top = self.init_pos

炮塔建造位置类

"""初始化炮塔可占据的位置"""

import pygame

 

 

class Position(pygame.sprite.Sprite):

    """pos"""

 

    def __init__(self, pos):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load('image/pt.png')

        self.rect = self.image.get_rect()

        self.rect.left, self.rect.top = pos

5.说明

本游戏通过鼠标左键点击炮塔可以建造的位置俩建造炮塔。

原文链接:https://blog.csdn.net/qq_41620823/article/details/103741989

 

猜你喜欢

转载自www.cnblogs.com/benming/p/12119490.html