利用python3 的pygame模塊實(shí)現(xiàn)塔防游戲
利用python3的pygame模塊基本實(shí)現(xiàn)塔防游戲的基本功能,包括血量和分?jǐn)?shù)顯示,bgm,防御塔建造,防御塔攻擊范圍內(nèi)的敵軍,暫停和加速功能。由于實(shí)在沒(méi)有素材,用的都是自己截圖P的,所以美化不好。但基本保證功能,其中有一個(gè)BUG,但不影響游戲效果。
1.運(yùn)行主類(lèi)
"""主程序"""
from pygame.locals import *
from TowerDefend.enemy import *
from TowerDefend.towerposSet import *
from TowerDefend.tower import *
import pygame
def run():
"""運(yùn)行函數(shù)"""
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))
# 創(chuàng)建分?jǐn)?shù)和血量
health_count = 5
score_count = 0
score = pygame.font.Font('font/score_health.ttf', 30)
health = pygame.font.Font('font/score_health.ttf', 30)
# 創(chuàng)建背景音樂(lè)
bg_music = pygame.mixer.music
bg_music.load('media/bg.mp3')
bg_music.set_volume(2)
# 創(chuàng)建敵軍類(lèi)
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]))
# 創(chuàng)建炮塔
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
# 設(shè)置炮塔位置
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]))
# 設(shè)置循環(huán)條件
running = True
clock = pygame.time.Clock()
paused = False
# 播放音樂(lè)
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)
# 繪制界面設(shè)置
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.炮塔類(lèi)
"""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.敵軍類(lèi)
import pygame
class Enemy(pygame.sprite.Sprite):
"""小兵類(lèi)"""
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):
"""移動(dòng)"""
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.炮塔建造位置類(lèi)
"""初始化炮塔可占據(jù)的位置"""
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.說(shuō)明
本游戲通過(guò)鼠標(biāo)左鍵點(diǎn)擊炮塔可以建造的位置倆建造炮塔。
6.效果圖

可以看到圖確實(shí)不好看,但美術(shù)功底不夠,所以不怎么好看。當(dāng)然需要素材的也可以給你。
相關(guān)文章
詳解Python 實(shí)現(xiàn)元胞自動(dòng)機(jī)中的生命游戲(Game of life)
本篇文章主要介紹了詳解Python 實(shí)現(xiàn)元胞自動(dòng)機(jī)中的生命游戲(Game of life),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
解決Keras TensorFlow 混編中 trainable=False設(shè)置無(wú)效問(wèn)題
這篇文章主要介紹了解決Keras TensorFlow 混編中 trainable=False設(shè)置無(wú)效問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
anaconda安裝后打不開(kāi)解決方式(親測(cè)有效)
Anaconda是一個(gè)和Canopy類(lèi)似的科學(xué)計(jì)算環(huán)境,但用起來(lái)更加方便,下面這篇文章主要給大家介紹了關(guān)于anaconda安裝后打不開(kāi)解決的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09
python調(diào)用golang中函數(shù)方法
由于simhash方法有多種實(shí)現(xiàn)方式,現(xiàn)python中simhash方法與golang中的不一樣,需要兩者代碼生成結(jié)果保持一致,故采用python中的代碼調(diào)用golang編譯的so文件來(lái)實(shí)現(xiàn),需要的朋友可以參考下2024-02-02
Python初學(xué)者必須掌握的25個(gè)內(nèi)置函數(shù)詳解
這篇文章主要介紹了Python25個(gè)常用內(nèi)置函數(shù)總結(jié),本文羅列了數(shù)學(xué)相關(guān) 、功能相關(guān)、類(lèi)型轉(zhuǎn)換、字符串處理、序列處理函數(shù)等常用內(nèi)置函數(shù),需要的朋友可以參考下2021-09-09
Python編寫(xiě)一個(gè)多線程的12306搶票程序的示例
對(duì)于很多人來(lái)說(shuō),搶購(gòu)火車(chē)票人們成了一個(gè)令人頭疼的問(wèn)題,本文主要介紹了Python編寫(xiě)一個(gè)多線程的12306搶票程序的示例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
Pycharm創(chuàng)建Django項(xiàng)目示例實(shí)踐
本文主要介紹了Pycharm創(chuàng)建Django項(xiàng)目示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03

