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

这篇教程介绍了如何利用Python3的Pygame模块创建一个基础的塔防游戏,包括血量和分数显示、背景音乐、防御塔建设、敌军行动、暂停与加速功能。虽然游戏视觉效果简单,但具备基本功能,且存在一个小BUG但不影响游戏体验。
摘要由CSDN通过智能技术生成

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值