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


Posted in Python onDecember 30, 2019

利用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.效果图

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

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

Python 相关文章推荐
测试、预发布后用python检测网页是否有日常链接
Jun 03 Python
在Python中使用base64模块处理字符编码的教程
Apr 28 Python
python实现判断数组是否包含指定元素的方法
Jul 15 Python
Python的CGIHTTPServer交互实现详解
Feb 08 Python
python获取微信企业号打卡数据并生成windows计划任务
Apr 30 Python
对django中foreignkey的简单使用详解
Jul 28 Python
python并发编程 Process对象的其他属性方法join方法详解
Aug 20 Python
python标准库OS模块详解
Mar 10 Python
Pycharm激活码激活两种快速方式(附最新激活码和插件)
Mar 12 Python
VSCode基础使用与VSCode调试python程序入门的图文教程
Mar 30 Python
Python实现计算图像RGB均值方式
Jun 04 Python
Python 实现微信自动回复的方法
Sep 11 Python
pytorch 批次遍历数据集打印数据的例子
Dec 30 #Python
python多线程使用方法实例详解
Dec 30 #Python
Python动态声明变量赋值代码实例
Dec 30 #Python
使用pytorch实现可视化中间层的结果
Dec 30 #Python
在Pytorch中计算自己模型的FLOPs方式
Dec 30 #Python
Pytorch之保存读取模型实例
Dec 30 #Python
Python爬虫解析网页的4种方式实例及原理解析
Dec 30 #Python
You might like
用PHP发电子邮件
2006/10/09 PHP
一个简单的域名注册情况查询程序
2006/10/09 PHP
PHP实现驼峰样式字符串(首字母大写)转换成下划线样式字符串的方法示例
2017/08/10 PHP
PHP使用Curl实现模拟登录及抓取数据功能示例
2018/04/27 PHP
PHP自动载入类文件函数__autoload的使用方法
2019/03/25 PHP
JS继承 笔记
2011/07/13 Javascript
js中split和replace的用法实例
2015/02/28 Javascript
在页面中输出当前客户端时间javascript实例代码
2016/03/02 Javascript
node.js插件nodeclipse安装图文教程
2020/10/19 Javascript
AngularJS 表达式详解及实例代码
2016/09/14 Javascript
vue使用原生js实现滚动页面跟踪导航高亮的示例代码
2018/10/25 Javascript
vue下使用nginx刷新页面404的问题解决
2019/08/02 Javascript
通过原生vue添加滚动加载更多功能
2019/11/21 Javascript
JS常用跨域方法实现原理解析
2020/12/09 Javascript
Python跳出循环语句continue与break的区别
2014/08/25 Python
Python常用算法学习基础教程
2017/04/13 Python
关于Python数据结构中字典的心得
2017/12/04 Python
python 实现倒排索引的方法
2018/12/25 Python
Python 字符串、列表、元组的截取与切片操作示例
2019/09/17 Python
python opencv实现信用卡的数字识别
2020/01/12 Python
Python3和PyCharm安装与环境配置【图文教程】
2020/02/14 Python
通过实例解析Python return运行原理
2020/03/04 Python
Python如何将模块打包并发布
2020/08/30 Python
编写python代码实现简单抽奖器
2020/10/20 Python
基于HTML5 Canvas 实现弹出框效果
2017/06/05 HTML / CSS
让IE下支持Html5的placeholder属性的插件
2014/09/02 HTML / CSS
医生实习工作总结的自我评价
2013/09/27 职场文书
会计电算化专业个人的自我评价
2013/11/24 职场文书
三好学生演讲稿范文
2014/04/26 职场文书
2014法制宣传日活动总结
2014/07/09 职场文书
干部作风整顿个人剖析材料
2014/10/06 职场文书
优秀团支部申报材料
2014/12/26 职场文书
2015年国庆节寄语
2015/08/17 职场文书
2019年教师节祝福语精选,给老师送上真诚的祝福
2019/09/09 职场文书
MySQL分区以及建索引的方法总结
2022/04/13 MySQL
SQL Server使用T-SQL语句批处理
2022/05/20 SQL Server