python画城堡_Python制作的一个塔防游戏一

游戏规则简介:

玩家通过建造箭塔抵御敌人的进攻。

每隔一段时间,将会有一波敌人从左上角的洞穴中诞生,并冲向右下角的城堡。玩家需要做的,则是通过建造箭塔射杀敌人,避免城堡受到敌人攻击,同时,每当你射杀一个敌人,将获得一定的金钱奖励。

游戏失败:

每有一个敌人冲进城堡,城堡的生命值下降一定的数值,当城堡的生命值为0时,则游戏失败。

游戏胜利:

随着时间的推移,敌人的实力会越来越强,数量也会越来越多,所以你是不可能胜利的,哈哈。

游戏进行中的界面说明:

T1-T3代表不同的箭塔类型,不同的箭塔类型具有不同的价格以及能力;

XXX代表出售箭塔(半价);

Pause代表暂停游戏;

Quit代表退出游戏。

玩家通过左键选中箭塔/出售箭塔标识,右键放弃当前选中的内容。鼠标中间箭用于控制箭塔射击的方向,否则箭塔将自由射击。

选中箭塔后,将其移动到你认为合适的位置,点击鼠标左键即可在该位置建造一个箭塔(当然前提是你账户余额买得起箭塔,不然只能打怪攒钱了);选中出售箭塔后,将出售箭塔标识放在已建造的箭塔上,点击鼠标左键,即可出售选中的箭塔。

# 游戏进行中界面

# 作者: Charles

import sys

import json

import math

import random

import pygame

sys.path.append('..')

from sprites import Enemy

from sprites import Turret

from interface import PAUSE

from pygame.locals import *

from collections import namedtuple

# 按钮类: 位置、文本、点击触发的事件

Button = namedtuple('Button', ['rect', 'text', 'onClick'])

# 定义一些颜色

info_color = (120, 20, 50)

red = (255, 0, 0)

green = (0, 255, 0)

black = (0, 0, 0)

white = (255, 255, 255)

grey = (127, 127, 127)

button_color1 = (0, 200, 0)

button_color2 = (0, 100, 0)

# 游戏进行中界面

class GAMING():

def __init__(self, WIDTH=800, HEIGHT=600):

self.WIDTH = WIDTH

self.HEIGHT = HEIGHT

# 游戏地图大小

map_w = WIDTH

map_h = 500

# 按钮大小和位置

button_w = 60

button_h = 60

button_y = 520

# 间隙

gap = 20

# 按钮放在工具栏, 工具栏两端各有一个信息显示框

toolbar_w = gap * 7 + button_w * 6

info_w = (WIDTH - toolbar_w) // 2

info_h = HEIGHT - map_h

toolbar_h = HEIGHT - map_h

# 界面布置

self.map_rect = pygame.Rect(0, 0, map_w, map_h)

self.map_surface = pygame.Surface((map_w, map_h))

self.leftinfo_rect = pygame.Rect(0, map_h, info_w, info_h)

self.rightinfo_rect = pygame.Rect(WIDTH-info_w, map_h, info_w, info_h)

self.toolbar_rect = pygame.Rect(info_w, map_h, toolbar_w, toolbar_h)

# 草

self.grass = pygame.image.load("./resource/imgs/game/grass.png")

# 岩石(铺路用的)

self.rock = pygame.image.load("./resource/imgs/game/rock.png")

# 污垢

self.dirt = pygame.image.load("./resource/imgs/game/dirt.png")

# 水

self.water = pygame.image.load("./resource/imgs/game/water.png")

# 灌木

self.bush = pygame.image.load("./resource/imgs/game/bush.png")

# 纽带

self.nexus = pygame.image.load("./resource/imgs/game/nexus.png")

# 洞穴

self.cave = pygame.image.load("./resource/imgs/game/cave.png")

# 获取地图元素的大小,请保证素材库里组成地图的元素图大小一致

# 一些字体

self.info_font = pygame.font.Font('./resource/fonts/Calibri.ttf', 14)

self.button_font = pygame.font.Font('./resource/fonts/Calibri.ttf', 20)

# 可以放炮塔的地方

self.placeable =

# 地图元素字典(数字对应.map文件中的数字)

self.map_elements = {

0: self.grass,

1: self.rock,

2: self.dirt,

3: self.water,

4: self.bush,

5: self.nexus,

6: self.cave

}

# 用于记录地图中的道路

self.path_list = []

# 当前的地图,将地图导入到这里面

self.currentMap = dict()

# 当前鼠标携带的图标(即选中道具) -> [道具名, 道具]

self.mouseCarried = []

# 在地图上建造好了的炮塔

self.builtTurretGroup = pygame.sprite.Group()

# 所有的敌人

self.EnemiesGroup = pygame.sprite.Group()

# 所有射出的箭

self.arrowsGroup = pygame.sprite.Group()

# 玩家操作用的按钮

self.buttons = [

Button(pygame.Rect((info_w+gap), button_y, button_w, button_h), 'T1', self.takeT1),

Button(pygame.Rect((info_w+gap*2+button_w), button_y, button_w, button_h), 'T2', self.takeT2),

Button(pygame.Rect((info_w+gap*3+button_w*2), button_y, button_w, button_h), 'T3', self.takeT3),

Button(pygame.Rect((info_w+gap*4+button_w*3), button_y, button_w, button_h), 'XXX', self.takeXXX),

Button(pygame.Rect((info_w+gap*5+button_w*4), button_y, button_w, button_h), 'Pause', self.pauseGame),

Button(pygame.Rect((info_w+gap*6+button_w*5), button_y, button_w, button_h), 'Quit', self.quitGame)

]

# 开始游戏

def start(self, screen, map_path=None, difficulty_path=None):

# 读取游戏难度对应的参数

with open(difficulty_path, 'r') as f:

difficulty_dict = json.load(f)

self.money = difficulty_dict.get('money')

self.health = difficulty_dict.get('health')

self.max_health = difficulty_dict.get('health')

difficulty_dict = difficulty_dict.get('enemy')

# 每60s生成一波敌人

GenEnemiesEvent = pygame.constants.USEREVENT + 0

# 生成敌人的flag和当前已生成敌人的总次数

genEnemiesFlag = False

genEnemiesNum = 0

# 每0.5秒出一个敌人

GenEnemyEvent = pygame.constants.USEREVENT + 1

genEnemyFlag = False

# 防止变量未定义

enemyRange = None

numEnemy = None

# 是否手动操作箭塔射击

Manualshot = False

has_control = False

while True:

if self.health

return

if event.type == pygame.QUIT:

pygame.quit()

sys.exit()

if event.type == pygame.MOUSEBUTTONUP:

# 左键选物品

if event.button == 1:

# 鼠标点击在地图上

if self.map_rect.collidepoint(event.pos):

if self.mouseCarried:

if self.mouseCarried[0] == 'turret':

self.buildTurret(event.pos)

elif self.mouseCarried[0] == 'XXX':

self.sellTurret(event.pos)

# 鼠标点击在工具栏

elif self.toolbar_rect.collidepoint(event.pos):

for button in self.buttons:

if button.text == 'T1':

button.onClick()

elif button.text == 'T2':

button.onClick()

elif button.text == 'T3':

button.onClick()

elif button.text == 'XXX':

button.onClick()

elif button.text == 'Pause':

button.onClick(screen)

elif button.text == 'Quit':

button.onClick()

# 显然只能有一个按钮被点击

break

# 右键释放物品

if event.button == 3:

self.mouseCarried = []

# 按中间键手动控制炮塔射箭方向一次,否则自由射箭

if event.button == 2:

Manualshot = True

if event.type == GenEnemiesEvent:

genEnemiesFlag = True

if event.type == GenEnemyEvent:

genEnemyFlag = True

# 生成敌人

# 生成的敌人随当前已生成敌人的总次数的增加而变强变多

if genEnemiesFlag:

genEnemiesFlag = False

genEnemiesNum += 1

idx = 0

for key, value in difficulty_dict.items():

idx += 1

if idx == len(difficulty_dict.keys()):

enemyRange = value['enemyRange']

numEnemy = value['numEnemy']

break

if genEnemiesNum

enemyRange = value['enemyRange']

numEnemy = value['numEnemy']

break

if genEnemyFlag and numEnemy:

genEnemyFlag = False

numEnemy -= 1

enemy = Enemy.Enemy(random.choice(range(enemyRange)))

self.EnemiesGroup.add(enemy)

# 射箭

for turret in self.builtTurretGroup:

if not Manualshot:

position = turret.position[0] + self.elementSize // 2, turret.position[1]

arrow = turret.shot(position)

else:

position = turret.position[0] + self.elementSize // 2, turret.position[1]

angle = math.atan((mouse_pos[1]-position[1])/(mouse_pos[0]-position[0]+1e-6))

arrow = turret.shot(position, angle)

has_control = True

if arrow:

self.arrowsGroup.add(arrow)

else:

has_control = False

if has_control:

has_control = False

Manualshot = False

# 移动箭和碰撞检测

for arrow in self.arrowsGroup:

arrow.move()

if (not self.map_rect.collidepoint(points[0])) and (not self.map_rect.collidepoint(points[1])) and \

(not self.map_rect.collidepoint(points[2])) and (not self.map_rect.collidepoint(points[3])):

self.arrowsGroup.remove(arrow)

del arrow

continue

for enemy in self.EnemiesGroup:

enemy.life_value -= arrow.attack_power

self.arrowsGroup.remove(arrow)

del arrow

break

self.draw(screen, map_path)

# 将场景画到游戏界面上

def draw(self, screen, map_path):

self.drawToolbar(screen)

self.loadMap(screen, map_path)

self.drawMouseCarried(screen)

self.drawBuiltTurret(screen)

self.drawEnemies(screen)

self.drawArrows(screen)

# 画出所有射出的箭

def drawArrows(self, screen):

for arrow in self.arrowsGroup:

screen.blit(arrow.image, arrow.rect)

# 画敌人

def drawEnemies(self, screen):

for enemy in self.EnemiesGroup:

if enemy.life_value

self.money += enemy.reward

self.EnemiesGroup.remove(enemy)

del enemy

continue

res = enemy.move(self.elementSize)

if res:

coord = self.find_next_path(enemy)

if coord:

enemy.reached_path.append(enemy.coord)

enemy.coord = coord

enemy.position = self.coord2pos(coord)

else:

self.health -= enemy.damage

self.EnemiesGroup.remove(enemy)

del enemy

continue

# 画血条

greenLen = max(0, enemy.life_value / enemy.max_life_value) * self.elementSize

if greenLen > 0:

if greenLen

screen.blit(enemy.image, enemy.rect)

# 画已经建造好的炮塔

def drawBuiltTurret(self, screen):

for turret in self.builtTurretGroup:

screen.blit(turret.image, turret.rect)

# 画鼠标携带物

def drawMouseCarried(self, screen):

if self.mouseCarried:

coord = self.pos2coord(position)

position = self.coord2pos(coord)

代码来源于小甲鱼论坛,如有不便请留言删除

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值