实现功能:

1:敌人的绵绵不断的前进,拿着各种各样的武器(叉子,斧头,宝剑),挥动武器攻击我方城堡,对我方城堡造成伤害!

2:我方城堡发现敌人可手动点击鼠标左键来发起子弹攻击,对日人造成致命伤害,让其死亡!

3:完备的数据显示,攻击敌人获取金币,累计得分,当前管卡的级别,我方城堡生命值的显示等等,击杀敌人获取的金币可以兑换额外属性来装备回复加强我方堡垒!

4:项目的布局界面优美干净,结合添加的纯音乐游戏背景和攻击音效以及实时的动画显示(如我方城堡的外观会随着我方城堡生命值的降低而发生改变,也就是变得会破败一些等等)以此让项目更加具有可玩性!

5:拿该项目练手或者作为一个python简单的课程设计也是一个可以的选择!

6:项目总代码700行左右

用到的编程知识:

python基础,os文件读写,pygame模块以及面向对象思想!

代码如下:

enemy.py类文件(100行代码左右)

import pygameclass Enemy(pygame.sprite.Sprite):def __init__(self, health, animation_list, x, y, speed):pygame.sprite.Sprite.__init__(self)self.alive = Trueself.speed = speedself.health = healthself.last_attack = pygame.time.get_ticks()self.attack_cooldown = 1000self.animation_list = animation_listself.frame_index = 0self.action = 0#0: walk, 1: attack, 2: deathself.update_time = pygame.time.get_ticks()#select starting imageself.image = self.animation_list[self.action][self.frame_index]self.rect = pygame.Rect(0, 0, 25, 40)self.rect.center = (x, y)def update(self, surface, target, bullet_group):if self.alive:#check for collision with bulletsif pygame.sprite.spritecollide(self, bullet_group, True):#lower enemy healthself.health -= 25#check if enemy has reached the castleif self.rect.right > target.rect.left:self.update_action(1)#move enemyif self.action == 0:#update rectangle positionself.rect.x += self.speed#attackif self.action == 1:#check if enough time has passed since last attackif pygame.time.get_ticks() - self.last_attack > self.attack_cooldown:target.health -= 25if target.health < 0:target.health = 0self.last_attack = pygame.time.get_ticks()#check if health has dropped to zeroif self.health <= 0:target.money += 100target.score += 100self.update_action(2)#deathself.alive = Falseself.update_animation()#draw image on screensurface.blit(self.image, (self.rect.x - 10, self.rect.y - 15))def update_animation(self):#define animation cooldownANIMATION_COOLDOWN = 50#update image depending on current actionself.image = self.animation_list[self.action][self.frame_index]#check if enough time has passed since the last updateif pygame.time.get_ticks() - self.update_time > ANIMATION_COOLDOWN:self.update_time = pygame.time.get_ticks()self.frame_index += 1#if the animation has run out then reset back to the startif self.frame_index >= len(self.animation_list[self.action]):if self.action == 2:self.frame_index = len(self.animation_list[self.action]) - 1else:self.frame_index = 0def update_action(self, new_action):#check if the new action is different to the previous oneif new_action != self.action:self.action = new_action#update the animation settingsself.frame_index = 0self.update_date = pygame.time.get_ticks()

castle.py类文件(500行代码左右)

# 导入库
import pygame
import math
import os
import sys
import random
import button
from pygame import mixer
# 初始化pygame
pygame.init()# 定义游戏窗口高度和宽度
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
# 加载背景音乐
pygame.mixer.music.load("sound/bjmusic.WAV")
pygame.mixer.music.set_volume(0.3)
jump_fx = pygame.mixer.Sound("sound/bullet.wav")
jump_fx.set_volume(0.5)# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("城堡防卫战")clock = pygame.time.Clock()
FPS = 60# 定义游戏变量
level = 1
high_score = 0
level_difficulty = 0
target_difficulty = 1000
DIFFICULTY_MULTIPLIER = 1.1
game_over = False
next_level = False
ENEMY_TIMER = 1000
last_enemy = pygame.time.get_ticks()
enemies_alive = 0
max_towers = 4
TOWER_COST = 5000
# 定义炮塔位置的列表
tower_positions = [
[SCREEN_WIDTH - 250, SCREEN_HEIGHT - 200],
[SCREEN_WIDTH - 200, SCREEN_HEIGHT - 150],
[SCREEN_WIDTH - 150, SCREEN_HEIGHT - 150],
[SCREEN_WIDTH - 100, SCREEN_HEIGHT - 150]
]# 加载最高分
if os.path.exists('socre.txt'):with open('socre.txt', 'r') as file:high_score = int(file.read())# 定义颜色
WHITE = (255, 255, 255)
GREY = (100, 100, 100)# 定义字体
font = pygame.font.SysFont('华文彩云', 30)
font_60 = pygame.font.SysFont('华文行楷', 60)# 加载图片
bg = pygame.image.load('img/bg.png').convert_alpha()
# 城堡
castle_img_100 = pygame.image.load('img/castle/castle_100.png').convert_alpha()
castle_img_50 = pygame.image.load('img/castle/castle_50.png').convert_alpha()
castle_img_25 = pygame.image.load('img/castle/castle_25.png').convert_alpha()# 炮塔
tower_img_100 = pygame.image.load('img/tower/tower_100.png').convert_alpha()
tower_img_50 = pygame.image.load('img/tower/tower_50.png').convert_alpha()
tower_img_25 = pygame.image.load('img/tower/tower_25.png').convert_alpha()# 子弹图像
bullet_img = pygame.image.load('img/bullet.png').convert_alpha()
b_w = bullet_img.get_width()
b_h = bullet_img.get_height()
bullet_img = pygame.transform.scale(bullet_img, (int(b_w * 0.075), int(b_h * 0.075)))# 创建敌人类
class Enemy(pygame.sprite.Sprite):def __init__(self, health, animation_list, x, y, speed):super().__init__()self.alive = Trueself.speed = speedself.health = healthself.last_attack = pygame.time.get_ticks()self.attack_cooldown = 1000self.animation_list = animation_listself.frame_index = 0self.action = 0self.update_time = pygame.time.get_ticks()# 选择动画开始的图片self.image = self.animation_list[self.action][self.frame_index]self.rect = pygame.Rect(0, 0, 25, 40)self.rect.center = (x, y)def update(self, surface, target, bullet_group):if self.alive:# 检查敌人与子弹的碰撞if pygame.sprite.spritecollide(self, bullet_group, True):# 减少健康self.health -= 25# 检查敌人是否已经到达城堡if self.rect.right > target.rect.left:self.update_action(1)# 移动敌人if self.action == 0:self.rect.x += 1# 攻击城堡if self.action == 1:# 检测冷却时间if pygame.time.get_ticks() - self.last_attack > self.attack_cooldown:target.health -= 25if target.health < 0:target.health = 0self.last_attack = pygame.time.get_ticks()# 检查敌人血条是否为0if self.health <= 0:target.money += 100target.score += 100self.update_action(2)self.alive = False# 调用更新动画self.update_animation()# 绘制敌人# pygame.draw.rect(surface, (255, 255, 255), self.rect, 1)surface.blit(self.image, (self.rect.x - 10, self.rect.y - 15))def update_animation(self):# 定义动画冷却时间ANIMATION_COOLDOWN = 50# 根据选择的冬瓜更新帧self.image = self.animation_list[self.action][self.frame_index]# 判断多久更新一次帧if pygame.time.get_ticks() - self.update_time > ANIMATION_COOLDOWN:self.update_time = pygame.time.get_ticks()self.frame_index += 1# 检查帧数不能超过最大帧数if self.frame_index >= len(self.animation_list[self.action]):if self.action == 2:self.frame_index = len(self.animation_list[self.action]) - 1else:self.frame_index = 0def update_action(self, new_action):# 检查新动作与上一个动作是否相同if new_action != self.action:self.action = new_action# 更新动画重置self.frame_index = 0self.update_time = pygame.time.get_ticks()# 加载敌人列表
enemy_animations = []
enemy_tpyes = ['knight', 'goblin', 'purple_goblin', 'red_goblin']
enemy_health = [75, 100, 125, 150]animation_types = ['walk', 'attack', 'death']
for enemy in enemy_tpyes:# 加载动画列表animation_list = []for animation in animation_types:# 创建临时列表temp_list = []# 定义帧数num_of_frames = 20for i in range(num_of_frames):img = pygame.image.load(f'img/enemies/{enemy}/{animation}/{i}.png').convert_alpha()e_w = img.get_width()e_h = img.get_height()img = pygame.transform.scale(img, (int(e_w * 0.2), int(e_h * 0.2)))temp_list.append(img)animation_list.append(temp_list)enemy_animations.append(animation_list)#  加载按钮图片
repair_img = pygame.image.load('img/repair.png').convert_alpha()
armour_img = pygame.image.load('img/armour.png').convert_alpha()# 在屏幕上输出文本信息
def draw_text(text, font, text_color, x, y):img = font.render(text, True, text_color)screen.blit(img, (x, y))# 定义一个显示状态的函数
def show_info():draw_text('钱数:' + str(castle.money), font, GREY, 10, 10)draw_text('分数:' + str(castle.score), font, GREY, 180, 10)draw_text('最分数:' + str(high_score), font, GREY, 180, 50)draw_text('级别:' + str(level), font, GREY, SCREEN_WIDTH // 2, 10)draw_text('健康:' + str(castle.health) + "/" + str(castle.max_health), font, GREY, SCREEN_WIDTH - 230, SCREEN_HEIGHT - 50)draw_text('1000', font, GREY, SCREEN_WIDTH - 250, 70)draw_text(str(TOWER_COST), font, GREY, SCREEN_WIDTH - 150, 70)draw_text('500', font, GREY, SCREEN_WIDTH - 70, 70)# 城堡类
class Castle():def __init__(self, image100, image50, image25,  x, y, scale):self.health = 1000self.max_health = self.healthself.fired = Falseself.money = 0self.score = 0width = image100.get_width()height = image100.get_height()self.image100 = pygame.transform.scale(image100, (int(width * scale), int(height * scale)))self.image50 = pygame.transform.scale(image50, (int(width * scale), int(height * scale)))self.image25 = pygame.transform.scale(image25, (int(width * scale), int(height * scale)))self.rect = self.image100.get_rect()self.rect.x = xself.rect.y = ydef shoot(self):pos = pygame.mouse.get_pos()x_dist = pos[0] - self.rect.midleft[0]y_dist = -(pos[1] - self.rect.midleft[1])self.angle = math.degrees(math.atan2(y_dist, x_dist))# 在该位置点击鼠标if pygame.mouse.get_pressed()[0] and self.fired == False and pos[1] > 70:self.fired = Truebullet = Bullet(bullet_img, self.rect.midleft[0], self.rect.midleft[1], self.angle)bullet_group.add(bullet)jump_fx.play()# 重置鼠标点击if pygame.mouse.get_pressed()[0] == False:self.fired = Falsedef draw(self):# 根据血量判断加载那张图片if self.health <= 250:self.image = self.image25elif self.health <= 500:self.image = self.image50else:self.image = self.image100screen.blit(self.image, self.rect)def repair(self):if self.money >= 1000 and self.health < self.max_health:self.health += 500self.money -= 1000if castle.health > castle.max_health:castle.health = castle.max_healthdef armour(self):if self.money >= 500:self.max_health += 250self.money -= 500# 炮塔类
class Tower(pygame.sprite.Sprite):def __init__(self, image100, image50, image25, x, y, scale):super().__init__()self.got_target = Falseself.angle = 0self.last_shot = pygame.time.get_ticks()width = image100.get_width()height = image100.get_height()self.image100 = pygame.transform.scale(image100, (int(width * scale), int(height * scale)))self.image50 = pygame.transform.scale(image50, (int(width * scale), int(height * scale)))self.image25 = pygame.transform.scale(image25, (int(width * scale), int(height * scale)))self.image = self.image100self.rect = self.image100.get_rect()self.rect.x = xself.rect.y = ydef update(self, enemy_group):self.got_target = Falsefor e in enemy_group:if e.alive:target_x, target_y = e.rect.midbottomself.got_target = Truebreakif self.got_target:x_dist = target_x - self.rect.midleft[0]y_dist = -(target_y - self.rect.midleft[1])self.angle = math.degrees(math.atan2(y_dist, x_dist))# pygame.draw.line(screen, WHITE, (self.rect.midleft[0], self.rect.midleft[1]), (target_x, target_y))shot_cooldown = 1000# 开火if pygame.time.get_ticks() - self.last_shot > shot_cooldown:self.last_shot = pygame.time.get_ticks()bullet = Bullet(bullet_img, self.rect.midleft[0], self.rect.midleft[1], self.angle)bullet_group.add(bullet)# 根据城堡血量判断加载那张图片if castle.health <= 250:self.image = self.image25elif castle.health <= 500:self.image = self.image50else:self.image = self.image100# 创建子弹类
class Bullet(pygame.sprite.Sprite):def __init__(self, image, x, y, angle):super().__init__()self.image = imageself.rect = self.image.get_rect()self.rect.x = xself.rect.y = yself.angle = math.radians(angle) # 角度转换为弧度self.speed = 10# 根据角度计算水平和垂直的速度self.dx = math.cos(self.angle) * self.speedself.dy = -(math.sin(self.angle) * self.speed)def update(self):# 检测子弹是否已经超出窗口if self.rect.right < 0 or self.rect.left > SCREEN_WIDTH or self.rect.bottom < 0 or self.rect.top > SCREEN_HEIGHT:self.kill()# 移动子弹self.rect.x += self.dxself.rect.y += self.dy# 创建十字准心
class Crosshair():def __init__(self, scale):image = pygame.image.load("img/crosshair.png").convert_alpha()width = image.get_width()height = image.get_height()self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))self.rect = self.image.get_rect()# 隐藏鼠标指针pygame.mouse.set_visible(False)def draw(self):mx, my = pygame.mouse.get_pos()self.rect.center = (mx, my)screen.blit(self.image, self.rect)# 创建城堡
castle = Castle(castle_img_100, castle_img_50, castle_img_25,  SCREEN_WIDTH - 250, SCREEN_HEIGHT - 300, 0.2)# 实例化十字准心
crosshair = Crosshair(0.025)# 创建按钮
repair_button = button.Button(SCREEN_WIDTH - 240, 10, repair_img, 0.5)
tower_button = button.Button(SCREEN_WIDTH - 130, 10, tower_img_100, 0.1)
armour_button = button.Button(SCREEN_WIDTH - 75, 10, armour_img, 1.5)# 创建组
bullet_group = pygame.sprite.Group()
enemy_group = pygame.sprite.Group()
tower_group = pygame.sprite.Group()# 穿件临时塔
# tower = Tower(tower_img_100, tower_img_50, tower_img_25, SCREEN_WIDTH - 350, SCREEN_HEIGHT - 200, 0.2)
# tower_group.add(tower)# 游戏循环显示窗口
pygame.mixer.music.unpause()
pygame.mixer.music.play(-1)
run = True
while run:clock.tick(FPS)if game_over == False:screen.blit(bg, (0, 0))# 显示城堡castle.draw()castle.shoot()# 显示炮塔tower_group.draw(screen)tower_group.update(enemy_group)# 显示十字准心crosshair.draw()# 绘制子弹到屏幕bullet_group.update()bullet_group.draw(screen)# 绘制敌人enemy_group.update(screen, castle, bullet_group)# 显示详细信息show_info()# 显示按钮 修理和铠甲按钮if repair_button.draw(screen):castle.repair()if tower_button.draw(screen):# 检查是否有足够的金钱来建造炮塔if castle.money >= TOWER_COST and len(tower_group) < max_towers:tower = Tower(tower_img_100,tower_img_50,tower_img_25,tower_positions[len(tower_group)][0],tower_positions[len(tower_group)][1],0.2)tower_group.add(tower)# 减去消耗的金钱数castle.money -= TOWER_COSTif armour_button.draw(screen):castle.armour()# 创建不同的敌人if level_difficulty < target_difficulty:if pygame.time.get_ticks() - last_enemy > ENEMY_TIMER:# 创建敌人实例e = random.randint(0, len(enemy_tpyes) - 1)enemy = Enemy(enemy_health[e], enemy_animations[e], -100, SCREEN_HEIGHT - 100, 1)enemy_group.add(enemy)last_enemy = pygame.time.get_ticks()level_difficulty += enemy_health[e]# 检测是所有的的敌人都产生了if level_difficulty >= target_difficulty:# 检查有多少敌人仍然是活着的enemies_alive = 0for e in enemy_group:if e.alive == True:enemies_alive += 1# 检测如果活着的敌人都被消灭了则当前级别就完成了if enemies_alive == 0 and next_level == False:next_level = Truelevel_reset_time = pygame.time.get_ticks()# 判断是否进入下一关if next_level == True:draw_text('关卡已完成', font_60, WHITE, 200, 300)# 更新最高分if castle.score > high_score:high_score = castle.scorewith open('socre.txt', 'w') as file:file.write(str(high_score))if pygame.time.get_ticks() - level_reset_time > 1500:next_level = Falselevel += 1last_enemy = pygame.time.get_ticks()target_difficulty *= DIFFICULTY_MULTIPLIERlevel_difficulty = 0enemy_group.empty()# 检查游戏是否结束if castle.health <= 0:game_over = Trueelse:draw_text('游戏结束!', font, GREY, 300, 300)draw_text('按下"A"重新进入游戏', font, GREY, 250, 350)pygame.mouse.set_visible(True)key = pygame.key.get_pressed()if key[pygame.K_a]:# 重置游戏game_over = Falselevel = 1target_difficulty = 1000level_difficulty = 0last_enemy = pygame.time.get_ticks()enemy_group.empty()tower_group.empty()castle.score = 0castle.health = 1000castle.max_health = castle.healthcastle.money = 0pygame.mouse.set_visible(False)for event in pygame.event.get():if event.type == pygame.QUIT:run = Falsepygame.quit()sys.exit()pygame.display.update()

button.py类文件(50行代码左右)

import pygame# 按钮类
class Button():def __init__(self, x, y, image, scale):width = image.get_width()height = image.get_height()self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))self.rect = self.image.get_rect()self.rect.topleft = (x, y)self.clicked = Falsedef draw(self, surface):action = False# 得到鼠标的位置pos = pygame.mouse.get_pos()# 检测鼠标指针的碰撞if self.rect.collidepoint(pos):if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:self.clicked = Trueaction = Trueif pygame.mouse.get_pressed()[0] == 0:self.clicked = False# 画按钮到屏幕上surface.blit(self.image, (self.rect.x, self.rect.y))return action

部分运行截图:

python--城堡保卫战相关推荐

  1. Python城堡漫游记之第0章误入游戏空间

    & 本章用到的计算机知识有: 操作系统.程序.进程.线程.编程等软件概念: CPU.总线.内存.外存等硬件概念: 本章是Python学习的引入点,上课老师不用讲解.对以上概念感兴趣的学生可以上 ...

  2. python画城堡_Python游戏设计—Part1

    原标题:Python游戏设计-Part1 程序演示图:兔子要保卫自己的城堡家园(4个城堡),右侧方随机出现罐来袭击,兔子需要瞄准并射击罐,从而保卫自己的城堡. [开始]安装Python 如果你想在Wi ...

  3. python画城堡_Python 13 简单项目-堡垒机

    本节内容 项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多人觉得,堡垒机就是跳板机,其实这个认识是不全面的,跳板功 ...

  4. 积木城堡看C和Python的速度差异

    题目描述 XC的儿子小XC最喜欢玩的游戏用积木垒漂亮的城堡.城堡是用一些立方体的积木垒成的,城堡的每一层是一块积木.小XC是一个比他爸爸XC还聪明的孩子,他发现垒城堡的时候,如果下面的积木比上面的积木 ...

  5. python画彩色城墙_Python绘制城堡-(有惊喜!!!)

    大城堡在这 importturtleimporttime turtle.setup(1000,1000,200,200)'''背景'''turtle.bgcolor('#191970')'''笔的大小 ...

  6. Python --深入浅出Apriori关联分析算法(二) Apriori关联规则实战

    上一篇我们讲了关联分析的几个概念,支持度,置信度,提升度.以及如何利用Apriori算法高效地根据物品的支持度找出所有物品的频繁项集. Python --深入浅出Apriori关联分析算法(一) 这次 ...

  7. 【青少年编程】黄羽恒:Python

    「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复[Scratch]或[Python],即可进入.如果加入了之前的社群不需要重复加入. 微信后台回复"资料下载&quo ...

  8. 媲美Pandas?一文入门Python的Datatable操作

    作者 | Parul Pandey 译者 | linstancy 责编 | Jane 出品 | Python大本营(id:pythonnews) [导读]工具包 datatable 的功能特征与 Pa ...

  9. 这可能是Python面向对象编程的最佳实践

    作者 | 崔庆才 来源 | 进击的Coder(ID:FightingCoder) Python 是支持面向对象的,很多情况下使用面向对象编程会使得代码更加容易扩展,并且可维护性更高,但是如果你写的多了 ...

  10. python 玩公众号游戏_Python入门太难?不如从玩塔防小游戏开始,玩通关就能学会编程...

    我一直认为,在python入门阶段学习基础理论,太枯燥.所以我们整理了很多有关python的项目案例,有详细教程还有源码,希望能帮助更多对python感兴趣的人. 这是其中一个适合入门的Python项 ...

最新文章

  1. grep检索关键字的命令_linux系统中java线上问题常用排查命令
  2. Ubuntu中如何使用root用户
  3. matlab产生mif 文件,生成.mif文件的matlab程序
  4. 边缘计算、区块链、5G,哪个能走的更远
  5. 深度解读鸿蒙轻内核CPU占用率
  6. 海滨学院计算机基础知识,北京交通大学海滨学院计算机基础考试卷-网络应用基础...
  7. c语言遗传算法百度云,遗传算法c语言程序.doc
  8. smobiler中实现页面切换_使用Smobiler实现类似美团的界面
  9. SecureCRT for mac 破解安装
  10. stm32 iap升级
  11. Stealing Harry Potter‘s Precious BFS+DFS
  12. 三星内存编码_三星内存铭牌的详细说明|三星记忆棒标签存储参数的详细说明...
  13. OC中类目(Catagory)和扩展(Extension)的使用
  14. SPSS(基础篇09)--拆分数据文件
  15. Excel2021单元格怎么做下拉菜单
  16. com.sec.android.ofvi,恶意软件分析 URL链接扫描 免费在线病毒分析平台 | 魔盾安全分析...
  17. origin 双Y轴堆积条形图
  18. 这个彬彬就是逊啦—才搞懂小学知识求最小公倍数
  19. 用于音频信号去噪的谱相减和陷波滤波的比较(Matlab代码实现)
  20. Educoder/头歌JAVA——jQuery动画

热门文章

  1. 我的世界java甘蔗机_我的世界全自动甘蔗机器制作教程
  2. 气传导和骨传导耳机哪个好?简单科普这两种蓝牙耳机
  3. 李沐d2l《动手学深度学习》第二版——风格迁移源码详解
  4. Ubuntu输入正确密码,屏幕一闪,又回到登录界面
  5. FreeType2使用总结
  6. java如何处理锯齿_java – 平滑锯齿的路径
  7. Canvas笔触调整-8
  8. Kafka 安装、使用
  9. 2019年实习过的同学来领钱啦!我可以退4000多!附:退税攻略
  10. 下雨打雷效果(动态)html