利用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 相关文章推荐
python3.5仿微软计算器程序
Mar 30 Python
基于python元祖与字典与集合的粗浅认识
Aug 23 Python
python实现外卖信息管理系统
Jan 11 Python
Python检测网络延迟的代码
May 15 Python
python 使用plt画图,去除图片四周的白边方法
Jul 09 Python
浅谈Pytorch中的torch.gather函数的含义
Aug 18 Python
Python测试Kafka集群(pykafka)实例
Dec 23 Python
Pytorch提取模型特征向量保存至csv的例子
Jan 03 Python
jupyter修改文件名方式(TensorFlow)
Apr 21 Python
Anaconda3中的Jupyter notebook添加目录插件的实现
May 18 Python
Python 实现RSA加解密文本文件
Dec 30 Python
关于python中readlines函数的参数hint的相关知识总结
Jun 24 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
中东人咖啡哲学
2021/03/03 咖啡文化
PHP5新特性: 更加面向对象化的PHP
2006/11/18 PHP
PHP编程中字符串处理的5个技巧小结
2007/11/13 PHP
WINDOWS下php5.2.4+mysql6.0+apache2.2.4+ZendOptimizer-3.3.0配置
2008/03/28 PHP
浅谈PHP强制类型转换,慎用!
2013/06/06 PHP
讲解WordPress开发中一些常用的debug技巧
2015/12/18 PHP
php静态成员方法和静态的成员属性的使用方法
2017/10/26 PHP
JS网页图片按比例自适应缩放实现方法
2014/01/15 Javascript
JavaScript中的slice()方法使用详解
2015/06/06 Javascript
AngularJS入门心得之directive和controller通信过程
2016/01/25 Javascript
基于jQuery实现仿51job城市选择功能实例代码
2016/03/02 Javascript
实现React单页应用的方法详解
2016/08/02 Javascript
JS控制HTML元素的显示和隐藏的两种方法
2016/09/27 Javascript
JavaScript门道之标准库
2018/05/26 Javascript
node.js使用mongoose操作数据库实现购物车的增、删、改、查功能示例
2019/12/23 Javascript
vue组件中节流函数的失效的原因和解决方法
2020/12/02 Vue.js
JS实现公告上线滚动效果
2021/01/10 Javascript
[00:36]DOTA2上海特级锦标赛 LGD战队宣传片
2016/03/04 DOTA
Python基础之函数用法实例详解
2014/09/10 Python
Python实现的单向循环链表功能示例
2017/11/10 Python
python实现Decorator模式实例代码
2018/02/09 Python
python读取文本绘制动态速度曲线
2018/06/21 Python
python 连续不等式语法糖实例
2020/04/15 Python
英国知名的护肤彩妆与时尚配饰大型综合零售电商:Unineed
2016/11/21 全球购物
德国健康生活方式网上商店:Landkaufhaus Mayer
2019/03/12 全球购物
Java提供了哪些企业应用编程接口
2015/02/13 面试题
单位实习证明怎么写
2014/01/17 职场文书
绿化先进工作者事迹材料
2014/01/30 职场文书
求职信需要的五点内容
2014/02/01 职场文书
销售助理岗位职责
2014/02/21 职场文书
企业优秀员工事迹材料
2014/05/28 职场文书
升学宴演讲稿
2014/09/01 职场文书
2015年度党员自我评价范文
2015/03/03 职场文书
2015年幼儿园班主任个人工作总结
2015/10/22 职场文书
2016廉政教育学习心得体会
2016/01/25 职场文书
Python中的np.argmin()和np.argmax()函数用法
2021/06/02 Python