利用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环境下搭建属于自己的pip源的教程
May 05 Python
Pycharm远程调试openstack的方法
Nov 21 Python
python实现远程通过网络邮件控制计算机重启或关机
Feb 22 Python
python解决pandas处理缺失值为空字符串的问题
Apr 08 Python
浅谈Python中重载isinstance继承关系的问题
May 04 Python
Python模拟自动存取款机的查询、存取款、修改密码等操作
Sep 02 Python
python如何实现代码检查
Jun 28 Python
浅谈Python3 numpy.ptp()最大值与最小值的差
Aug 24 Python
pygame实现贪吃蛇游戏(下)
Oct 29 Python
Python单元测试模块doctest的具体使用
Feb 10 Python
Python3如何在Windows和Linux上打包
Feb 25 Python
python实现同一局域网下传输图片
Mar 20 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常用函数小技巧
2008/09/11 PHP
PHP正则验证Email的方法
2015/06/15 PHP
PHP的Yii框架中使用数据库的配置和SQL操作实例教程
2016/03/17 PHP
PHP多维数组排序array详解
2017/11/21 PHP
javascript显示选择目录对话框的代码
2008/11/10 Javascript
页面中body onload 和 window.onload 冲突的问题的解决
2009/07/01 Javascript
html中的input标签的checked属性jquery判断代码
2012/09/19 Javascript
JQuery对id中含有特殊字符的转义处理示例
2013/09/06 Javascript
javascript获取浏览器类型和版本的方法(js获取浏览器版本)
2014/03/13 Javascript
JavaScript中Function()函数的使用教程
2015/06/04 Javascript
JavaScript取得键盘按下方向键是哪个的方法
2015/08/04 Javascript
详解javascript函数的参数
2015/11/10 Javascript
在AngularJS中使用jQuery的zTree插件的方法
2016/04/21 Javascript
Bootstrap布局之栅格系统详解
2016/06/13 Javascript
URL的参数中有加号传值变为空格的问题(URL特殊字符)
2016/11/04 Javascript
Angularjs中数据绑定的实例详解
2017/08/25 Javascript
微信小程序实现tab左右切换效果
2020/11/15 Javascript
简单说说如何使用vue-router插件的方法
2019/04/08 Javascript
JS数组及对象遍历方法代码汇总
2020/06/16 Javascript
解决vue 使用setTimeout,离开当前路由setTimeout未销毁的问题
2020/07/21 Javascript
[00:10]神之谴戒
2019/03/06 DOTA
Python素数检测的方法
2015/05/11 Python
深入浅出学习python装饰器
2017/09/29 Python
解决python中用matplotlib画多幅图时出现图形部分重叠的问题
2019/07/07 Python
用python建立两个Y轴的XY曲线图方法
2019/07/08 Python
Django1.11配合uni-app发起微信支付的实现
2019/10/12 Python
Django REST框架创建一个简单的Api实例讲解
2019/11/05 Python
Django 批量插入数据的实现方法
2020/01/12 Python
如何更换python默认编辑器的背景色
2020/08/10 Python
Clarisonic美国官网:科莱丽声波洁面仪
2017/10/12 全球购物
英国的一家创新礼品和小工具零售商:Menkind
2019/08/24 全球购物
最畅销的视频游戏享受高达90%的折扣:CDKeys
2020/02/10 全球购物
社区工作者思想汇报
2014/01/13 职场文书
食品安全汇报材料
2014/08/18 职场文书
KTV员工管理制度
2015/08/06 职场文书
Go语言实现Snowflake雪花算法
2021/06/08 Golang