python

超轻量级php框架startmvc

利用python3 的pygame模块实现塔防游戏

更新时间:2020-08-17 11:00:01 作者:startmvc
利用python3的pygame模块基本实现塔防游戏的基本功能,包括血量和分数显示,bgm,防御塔建

利用python3的pygame模块基本实现塔防游戏的基本功能,包括血量和分数显示,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()

2.炮塔类

"""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

3.敌军类


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

4.炮塔建造位置类


"""初始化炮塔可占据的位置"""
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.说明

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

6.效果图

可以看到图确实不好看,但美术功底不够,所以不怎么好看。当然需要素材的也可以给你。

pygame塔防游戏 python3 pygame