这一次将运用三角函数的相关知识以及前面学过的相关知识,如声音、精灵图像等来设计Tank Battle游戏,即坦克大战。

Tank Battle游戏

为了实现该游戏,需要再向MyLibrary.py文件中添加一些东西:

# 计算两个点之间的角度
def target_angle(x1, y1, x2, y2):delta_x = x2 - x1delta_y = y2 - y1angle_radians = math.atan2(delta_y, delta_x)angle_degrees = math.degrees(angle_radians)return angle_degreesdef angular_velocity(angle):vel = Point(0, 0)vel.x = math.cos(math.radians(angle))vel.y = math.sin(math.radians(angle))return vel

即用于实现旋转角度的一些函数

精灵类

涉及的精灵类有玩家坦克、敌方坦克和子弹类:

class Tank(MySprite):def __init__(self, tank_file="tank.png", turret_file="turret.png"):MySprite.__init__(self)self.load(tank_file, 50, 60, 4)self.speed = 0.0self.scratch = Noneself.float_pos = Point(0, 0)self.velocity = Point(0, 0)self.turret = MySprite()self.turret.load(turret_file, 32, 64, 4)self.fire_timer = 0def update(self, ticks):MySprite.update(self, ticks, 100)self.rotation = wrap_angle(self.rotation)self.scratch = pygame.transform.rotate(self.image, -self.rotation)angle = wrap_angle(self.rotation - 90)self.velocity = angular_velocity(angle)self.float_pos.x += self.velocity.xself.float_pos.y += self.velocity.y# 保证坦克会一直留在界面上if self.float_pos.x < -50:self.float_pos.x = 800elif self.float_pos.x > 800:self.float_pos.x = -50if self.float_pos.y < -60:self.float_pos.y = 600elif self.float_pos.y > 600:self.float_pos.y = -60self.X = int(self.float_pos.x)self.Y = int(self.float_pos.y)self.turret.position = (self.X, self.Y)self.turret.last_frame = 0self.turret.update(ticks, 100)self.turret.rotation = wrap_angle(self.turret.rotation)angle = self.turret.rotation + 90self.turret.scratch = pygame.transform.rotate(self.turret.image, -angle)def draw(self, surface):width, height = self.scratch.get_size()center = Point(width / 2, height / 2)surface.blit(self.scratch, (self.X - center.x, self.Y - center.y))# 绘制炮塔width, height = self.turret.scratch.get_size()center = Point(width / 2, height / 2)surface.blit(self.turret.scratch, (self.turret.X - center.x, self.turret.Y - center.y))def __str__(self):return MySprite.__str__(self) + ", " + str(self.velocity)class EnemyTank(Tank):def __init__(self, tank_file="enemy_tank.png", turret_file="enemy_turret.png"):Tank.__init__(self, tank_file, turret_file)def update(self, ticks):self.turret.rotation = wrap_angle(self.rotation - 90)Tank.update(self, ticks)def draw(self, surface):Tank.draw(self, surface)class Bullet(object):def __init__(self, position):self.alive = Trueself.color = (250, 20, 20)self.position = Point(position.x, position.y)self.velocity = Point(0, 0)self.rect = Rect(0, 0, 4, 4)self.owner = ""def update(self, ticks):self.position.x += self.velocity.x * 10.0self.position.y += self.velocity.y * 10.0if self.position.x < 0 or self.position.x > 800 or self.position.y < 0 or self.position.y > 600:self.alive = Falseself.rect = Rect(self.position.x, self.position.y, 4, 4)def draw(self, surface):pos = (int(self.position.x), int(self.position.y))pygame.draw.circle(surface, self.color, pos, 4, 0)

为了实现子弹类,还需要三个辅助函数用以实现双方坦克发射炮弹:

# 坦克发射炮弹
def fire_cannon(tank):position = Point(tank.turret.X, tank.turret.Y)bullet = Bullet(position)angle = tank.turret.rotationbullet.velocity = angular_velocity(angle)bullets.append(bullet)play_sound(shoot_sound)return bullet# 玩家发射炮弹
def player_fire_cannon():bullet = fire_cannon(player)bullet.owner = "player"bullet.color = (30, 250, 30)# 敌方发射炮弹
def enemy_fire_cannon():bullet = fire_cannon(enemy_tank)bullet.owner = "enemy"bullet.color = (250, 30, 30)

游戏初始化操作

# 游戏的一些初始化操作
def game_init():global screen, backbuffer, font, timer, player_group, player, enemy_tank, bullets, crosshair, crosshair_grouppygame.init()screen = pygame.display.set_mode((800, 600))backbuffer = pygame.Surface((800, 600))pygame.display.set_caption("Tank Battle Game")font = pygame.font.Font(None, 30)timer = pygame.time.Clock()pygame.mouse.set_visible(False)# 加载鼠标光标crosshair = MySprite()crosshair.load("crosshair.png")crosshair_group = pygame.sprite.GroupSingle()crosshair_group.add(crosshair)# 创建玩家的坦克player = Tank()player.float_pos = Point(400, 300)# 创建敌方坦克enemy_tank = EnemyTank()enemy_tank.float_pos = Point(random.randint(50, 760), 50)enemy_tank.rotation = 135# 创建子弹精灵组bullets = list()

还有声音的相关函数:

# 用于初始化加载声音
def audio_init():global shoot_sound, boom_soundpygame.mixer.init()shoot_sound = pygame.mixer.Sound("shoot.wav")boom_sound = pygame.mixer.Sound("boom.wav")# 播放声音
def play_sound(sound):channel = pygame.mixer.find_channel(True)channel.set_volume(0.5)channel.play(sound)

完整源代码

源代码如下:

import random
import sys
import pygame
from pygame.locals import *
from MyLibrary import *class Tank(MySprite):def __init__(self, tank_file="tank.png", turret_file="turret.png"):MySprite.__init__(self)self.load(tank_file, 50, 60, 4)self.speed = 0.0self.scratch = Noneself.float_pos = Point(0, 0)self.velocity = Point(0, 0)self.turret = MySprite()self.turret.load(turret_file, 32, 64, 4)self.fire_timer = 0def update(self, ticks):MySprite.update(self, ticks, 100)self.rotation = wrap_angle(self.rotation)self.scratch = pygame.transform.rotate(self.image, -self.rotation)angle = wrap_angle(self.rotation - 90)self.velocity = angular_velocity(angle)self.float_pos.x += self.velocity.xself.float_pos.y += self.velocity.y# 保证坦克会一直留在界面上if self.float_pos.x < -50:self.float_pos.x = 800elif self.float_pos.x > 800:self.float_pos.x = -50if self.float_pos.y < -60:self.float_pos.y = 600elif self.float_pos.y > 600:self.float_pos.y = -60self.X = int(self.float_pos.x)self.Y = int(self.float_pos.y)self.turret.position = (self.X, self.Y)self.turret.last_frame = 0self.turret.update(ticks, 100)self.turret.rotation = wrap_angle(self.turret.rotation)angle = self.turret.rotation + 90self.turret.scratch = pygame.transform.rotate(self.turret.image, -angle)def draw(self, surface):width, height = self.scratch.get_size()center = Point(width / 2, height / 2)surface.blit(self.scratch, (self.X - center.x, self.Y - center.y))# 绘制炮塔width, height = self.turret.scratch.get_size()center = Point(width / 2, height / 2)surface.blit(self.turret.scratch, (self.turret.X - center.x, self.turret.Y - center.y))def __str__(self):return MySprite.__str__(self) + ", " + str(self.velocity)class EnemyTank(Tank):def __init__(self, tank_file="enemy_tank.png", turret_file="enemy_turret.png"):Tank.__init__(self, tank_file, turret_file)def update(self, ticks):self.turret.rotation = wrap_angle(self.rotation - 90)Tank.update(self, ticks)def draw(self, surface):Tank.draw(self, surface)class Bullet(object):def __init__(self, position):self.alive = Trueself.color = (250, 20, 20)self.position = Point(position.x, position.y)self.velocity = Point(0, 0)self.rect = Rect(0, 0, 4, 4)self.owner = ""def update(self, ticks):self.position.x += self.velocity.x * 10.0self.position.y += self.velocity.y * 10.0if self.position.x < 0 or self.position.x > 800 or self.position.y < 0 or self.position.y > 600:self.alive = Falseself.rect = Rect(self.position.x, self.position.y, 4, 4)def draw(self, surface):pos = (int(self.position.x), int(self.position.y))pygame.draw.circle(surface, self.color, pos, 4, 0)# 坦克发射炮弹
def fire_cannon(tank):position = Point(tank.turret.X, tank.turret.Y)bullet = Bullet(position)angle = tank.turret.rotationbullet.velocity = angular_velocity(angle)bullets.append(bullet)play_sound(shoot_sound)return bullet# 玩家发射炮弹
def player_fire_cannon():bullet = fire_cannon(player)bullet.owner = "player"bullet.color = (30, 250, 30)# 敌方发射炮弹
def enemy_fire_cannon():bullet = fire_cannon(enemy_tank)bullet.owner = "enemy"bullet.color = (250, 30, 30)# 游戏的一些初始化操作
def game_init():global screen, backbuffer, font, timer, player_group, player, enemy_tank, bullets, crosshair, crosshair_grouppygame.init()screen = pygame.display.set_mode((800, 600))backbuffer = pygame.Surface((800, 600))pygame.display.set_caption("Tank Battle Game")font = pygame.font.Font(None, 30)timer = pygame.time.Clock()pygame.mouse.set_visible(False)# 加载鼠标光标crosshair = MySprite()crosshair.load("crosshair.png")crosshair_group = pygame.sprite.GroupSingle()crosshair_group.add(crosshair)# 创建玩家的坦克player = Tank()player.float_pos = Point(400, 300)# 创建敌方坦克enemy_tank = EnemyTank()enemy_tank.float_pos = Point(random.randint(50, 760), 50)enemy_tank.rotation = 135# 创建子弹精灵组bullets = list()# 用于初始化加载声音
def audio_init():global shoot_sound, boom_soundpygame.mixer.init()shoot_sound = pygame.mixer.Sound("shoot.wav")boom_sound = pygame.mixer.Sound("boom.wav")# 播放声音
def play_sound(sound):channel = pygame.mixer.find_channel(True)channel.set_volume(0.5)channel.play(sound)if __name__ == "__main__":game_init()audio_init()game_over = Falseplayer_score = 0enemy_score = 0last_time = 0mouse_x = mouse_y = 0while True:timer.tick(30)ticks = pygame.time.get_ticks()mouse_up = mouse_down = 0mouse_up_x = mouse_up_y = 0mouse_down_x = mouse_down_y = 0for event in pygame.event.get():if event.type == QUIT:sys.exit()elif event.type == MOUSEMOTION:mouse_x, mouse_y = event.posmov_x, mov_y = event.relelif event.type == MOUSEBUTTONDOWN:mouse_down = event.buttonmouse_down_x, mouse_down_y = event.poselif event.type == MOUSEBUTTONUP:mouse_up = event.buttonmouse_up_x, mouse_up_y = event.poskeys = pygame.key.get_pressed()if keys[K_ESCAPE]:sys.exit()# 左右键用于控制旋转elif keys[K_a] or keys[K_LEFT]:player.rotation -= 2.0elif keys[K_d] or keys[K_RIGHT]:player.rotation += 2.0# 按空格键或者按鼠标则发射炮弹if keys[K_SPACE] or mouse_up > 0:if ticks > player.fire_timer + 1000:player.fire_timer = ticksplayer_fire_cannon()if not game_over:crosshair.position = (mouse_x, mouse_y)crosshair_group.update(ticks)angle = target_angle(player.turret.X, player.turret.Y,crosshair.X + crosshair.frame_width / 2,crosshair.Y + crosshair.frame_height / 2)player.turret.rotation = angleplayer.update(ticks)enemy_tank.update(ticks)# 设置敌方坦克每隔1秒发射一枚炮弹if ticks > enemy_tank.fire_timer + 1000:enemy_tank.fire_timer = ticksenemy_fire_cannon()# 对每一枚炮弹做相应的处理for bullet in bullets:bullet.update(ticks)if bullet.owner == "player":if pygame.sprite.collide_rect(bullet, enemy_tank):player_score += 1bullet.alive = Falseplay_sound(boom_sound)elif bullet.owner == "enemy":if pygame.sprite.collide_rect(bullet, player):enemy_score += 1bullet.alive = Falseplay_sound(boom_sound)backbuffer.fill((100, 100, 20))for bullet in bullets:bullet.draw(backbuffer)enemy_tank.draw(backbuffer)player.draw(backbuffer)crosshair_group.draw(backbuffer)screen.blit(backbuffer, (0, 0))if not game_over:print_text(font, 0, 0, "PLAYER:" + str(player_score))print_text(font, 700, 0, "ENEMY:" + str(enemy_score))else:print_text(font, 0, 0, "G A M E O V E R")# 命中的子弹消失for bullet in bullets:if bullet.alive == False:bullets.remove(bullet)pygame.display.update()

运行结果如下:

Pygame学习笔记11:三角函数及Tank Battle游戏相关推荐

  1. Pygame学习笔记13:Dungeon角色扮演游戏

    这一次就来学习设计一款ASCII 文本的RPG--Dungeon角色扮演游戏,这一章的内容会结合前面所学的知识. Dungeon游戏 地图的构建 关于地图构建的相关的操作都封装在一个Dungeon类中 ...

  2. Python学习笔记11:函数修饰符

    Python学习笔记11:函数修饰符 Python有很多有趣的特性,其中函数修饰符就是一个. 我们在之前的那个web应用示例中用过如下写法: @web.route('/log') @符号后边的,就是一 ...

  3. SpringMVC:学习笔记(11)——依赖注入与@Autowired

    SpringMVC:学习笔记(11)--依赖注入与@Autowired 使用@Autowired 从Spring2.5开始,它引入了一种全新的依赖注入方式,即通过@Autowired注解.这个注解允许 ...

  4. Hadoop学习笔记—11.MapReduce中的排序和分组

    Hadoop学习笔记-11.MapReduce中的排序和分组 一.写在之前的 1.1 回顾Map阶段四大步骤 首先,我们回顾一下在MapReduce中,排序和分组在哪里被执行: 从上图中可以清楚地看出 ...

  5. HALCON 20.11:深度学习笔记(11)---目标检测

    HALCON 20.11:深度学习笔记(11)---目标检测 HALCON 20.11.0.0中,实现了深度学习方法. 本章讲解了如何使用基于深度学习的对象检测. 通过对象检测,我们希望在图像中找到不 ...

  6. 台大李宏毅Machine Learning 2017Fall学习笔记 (11)Convolutional Neural Network

    台大李宏毅Machine Learning 2017Fall学习笔记 (11)Convolutional Neural Network 本博客主要整理自: http://blog.csdn.net/x ...

  7. Pygame学习笔记 4 —— 时间与运动

        还记得我们在之前的程序中如何让兔子动起来的吗,没错,使用event模块检测键盘事件,改变绘图的坐标,画面刷新后兔子就移动了.接下来我们细说如何精确控制时间和运动. 主要内容: pygame的时 ...

  8. Pygame学习笔记 6 —— 3D游戏

        pygame是是上世纪的产品,虽然不适合最3D游戏,但我可以使用pygame来绘制简单的3D图形,就像在白纸上画立体图形一样. 主要内容: 视觉上的远近.3D空间.绘制一个空间图形 一.视觉上 ...

  9. Python第三方库pygame学习笔记(一)

    Pygame Python最经典的2D游戏开发第三方库,也支持3D游戏开发 Pygame适合用于游戏逻辑验证.游戏入门及系统演示验证 Pygame是一种游戏开发引擎,基本逻辑具有参考价值 pygame ...

最新文章

  1. 【转】Mac下安装和配置Redis
  2. Linux文件atime ctime mtime
  3. 6个班的计算机课平均分给,计算机六道题
  4. Algorithm I assignment Collinear
  5. c# 字符串格式化为日期格式
  6. 排序算法之七 计数排序(C++版本)
  7. 第二十三章:触发器和行为(九)
  8. 使用css控制gridview控件的样式,GridView 样式美化及应用.doc
  9. 备战金九银十!2022Java面试必刷461道大厂架构面试真题汇总+面经+简历模板都放这了,注意划重点!!
  10. 强制推广鸿蒙系统,鸿蒙系统凭实力占市场,无需通过禁止安卓系统来推广
  11. 安卓模拟位置之夜神模拟器
  12. ubuntu清空回收站命令
  13. 初识ELK(日志系统)
  14. Python之面相对象-封装 多态 约束 super()
  15. 使用系统导航栏,设置成全透明的方法
  16. Unity3D网络游戏0.3
  17. UnauthorizedAccessException:Access to the path “/xx/xx.xx“ is denied
  18. Shell 学习(七)-----杂项
  19. HDU1430,魔板
  20. virtuoso如何打开matlab,Virtuoso AMS Designer Virtuoso XL Layout Editor培训(Cadence)

热门文章

  1. 使用认知UX设计原则对认知可及性的adhd阅读障碍观点
  2. 新钛云服助力国际连锁酒店集团实现高效安全运维
  3. 开放平台:网络淘金下一站
  4. 【TensorFlow2.0】如何搭建网络模型?
  5. 神州租车确定将从港股退市:上半年亏43亿元,联想控股彻底退出
  6. 映射、散射、漫射、影射
  7. python远程控制局域网电脑_局域网web远程控制软件 python开发
  8. 现实版终结者?杀手机器人预计2017年问世
  9. jmeter非GUI模式如何压测并生成测试报告
  10. Monkey测试手机BUG重现及解决方法