小游戏毕设 - 愤怒的小鸟游戏设计与实现 (源码)

2023-11-25 13:20

本文主要是介绍小游戏毕设 - 愤怒的小鸟游戏设计与实现 (源码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 0 项目简介
  • 1 游戏介绍
  • 2 实现效果
  • 3 开发工具
    • 3.1 环境配置
    • 3.2 Pygame介绍
  • 4 具体实现
  • 5 最后


0 项目简介

🔥 Hi,各位同学好呀,这里是L学长!

🥇今天向大家分享一个今年(2022)最新完成的毕业设计项目作品

愤怒的小鸟游戏设计与实现

🥇 学长根据实现的难度和等级对项目进行评分(最低0分,满分5分)

  • 难度系数:3分

  • 工作量:3分

  • 创新点:4分

  • 项目获取:https://gitee.com/sinonfin/system-sharing


1 游戏介绍

利用Python实现的简易版愤怒的小鸟小游戏。

游戏规则

游戏中小鸟需要将弹弓上的小鸟弹出去,砸到绿色的肥猪,将肥猪全部砸到就能过关。鸟儿的弹出角度和力度由你的手指来控制,要注意考虑好力度和角度的综合计算,这样才能更准确的砸到肥猪。而被弹出的鸟儿会留下弹射轨迹,可供参考角度和力度的调整。游戏中玩家需要消灭所有的肥猪才能胜利。

2 实现效果

在这里插入图片描述

在这里插入图片描述

3 开发工具

3.1 环境配置

  • Python版本:3.6.4

  • 相关模块:

  • pygame模块;

  • 以及一些Python自带的模块。

3.2 Pygame介绍

简介

Pygame是一系列专门为编写电子游戏而设计的Python模块(modules)。Pygame在已经非常优秀的SDL库的基础上增加了许多功能。这让你能够用Python语言编写出丰富多彩的游戏程序。

Pygame可移植性高,几乎能在任何平台和操作系统上运行。

Pygame已经被下载过数百万次。

Pygame免费开源。它在LGPL许可证(Lesser General Public License,GNU宽通用公共许可证)下发行。使用Pygame,你可以创造出免费开源,可共享,或者商业化的游戏。详情请见LGPL许可证。

优点

  • 能够轻松使用多核CPU(multi core CPUs) :如今双核CPU很常用,8核CPU在桌面系统中也很便宜,而利用好多核系统,能让你在你的游戏中实现更多东西。特定的pygame函数能够释放令人生畏的python GIL(全局解释器锁),这几乎是你用C语言才能做的事。

  • 核心函数用最优化的C语言或汇编语言编写:C语言代码通常比Python代码运行速度快10-20倍。而汇编语言编写的代码(assembly code)比Python甚至快到100多倍。

  • 安装便捷:一般仅需包管理程序或二进制系统程序便能安装。

  • 真正地可移植:支持Linux (主要发行版), Windows (95, 98, ME, 2000, XP, Vista, 64-bit Windows,), Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX等操作系统.也能支持AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS and OS/2,但是还没有受到官方认可。你也可以在手持设备,游戏控制台, One Laptop Per Child (OLPC) computer项目的电脑等设备中使用pygame.

  • 用法简单:无论是小孩子还是大人都能学会用pygame来制作射击类游戏。

  • 很多Pygame游戏已发行:其中包括很多游戏大赛入围作品、非常受欢迎的开源可分享的游戏。

  • 由你来控制主循环:由你来调用pygame的函数,pygame的函数并不需要调用你的函数。当你同时还在使用其他库来编写各种各种的程序时,这能够为你提供极大的掌控权。

  • 不需要GUI就能使用所有函数:仅在命令行中,你就可以使用pygame的某些函数来处理图片,获取游戏杆输入,播放音乐……

  • 对bug反应迅速:很多bug在被上报的1小时内就能被我们修复。虽然有时候我们确实会卡在某一个bug上很久,但大多数时候我们都是很不错的bug修复者。如今bug的上报已经很少了,因为许多bug早已被我们修复。

  • 代码量少:pygame并没有数以万计的也许你永远用不到的冗杂代码。pygame的核心代码一直保持着简洁特点,其他附加物诸如GUI库等,都是在核心代码之外单独设计研发的。

  • 模块化:你可以单独使用pygame的某个模块。想要换着使用一个别的声音处理库?没问题。pygame的很多核心模块支持独立初始化与使用。

最小开发框架

import pygame,sys #sys是python的标准库,提供Python运行时环境变量的操控pygame.init()  #内部各功能模块进行初始化创建及变量设置,默认调用
size = width,height = 800,600  #设置游戏窗口大小,分别是宽度和高度
screen = pygame.display.set_mode(size)  #初始化显示窗口
pygame.display.set_caption("小游戏程序")  #设置显示窗口的标题内容,是一个字符串类型
while True:  #无限循环,直到Python运行时退出结束for event in pygame.event.get():  #从Pygame的事件队列中取出事件,并从队列中删除该事件if event.type == pygame.QUIT:  #获得事件类型,并逐类响应sys.exit()   #用于退出结束游戏并退出          pygame.display.update()  #对显示窗口进行更新,默认窗口全部重绘

代码执行流程

在这里插入图片描述

4 具体实现

简单介绍一下游戏的实现原理。首先是游戏的开始界面,大概是长这样的,比较简约:
在这里插入图片描述

主要包括两个部分,即游戏的标题和游戏的开始以及退出按钮,这两部分的代码实现如下:

'''按钮类'''
class Button(pygame.sprite.Sprite):def __init__(self, screen, x, y, width, height, action=None, color_not_active=(189, 195, 199), color_active=(189, 195, 199)):pygame.sprite.Sprite.__init__(self)self.x = xself.y = yself.width = widthself.height = heightself.action = actionself.screen = screenself.color_active = color_activeself.color_not_active = color_not_active'''添加文字'''def addtext(self, text, size=20, font='Times New Roman', color=(0, 0, 0)):self.font = pygame.font.Font(font, size)self.text = self.font.render(text, True, color)self.text_pos = self.text.get_rect()self.text_pos.center = (self.x + self.width / 2, self.y + self.height / 2)'''是否被鼠标选中'''def selected(self):pos = pygame.mouse.get_pos()if (self.x < pos[0] < self.x + self.width) and (self.y < pos[1] < self.y + self.height):return Truereturn False'''画到屏幕上'''def draw(self):if self.selected():pygame.draw.rect(self.screen, self.color_active, (self.x, self.y, self.width, self.height))else:pygame.draw.rect(self.screen, self.color_not_active, (self.x, self.y, self.width, self.height))if hasattr(self, 'text'):self.screen.blit(self.text, self.text_pos)'''文字标签类'''
class Label(pygame.sprite.Sprite):def __init__(self, screen, x, y, width, height):pygame.sprite.Sprite.__init__(self)self.x = xself.y = yself.width = widthself.height = heightself.screen = screen'''添加文字'''def addtext(self, text, size=20, font='Times New Roman', color=(0, 0, 0)):self.font = pygame.font.Font(font, size)self.text = self.font.render(text, True, color)self.text_pos = self.text.get_rect()self.text_pos.center = (self.x + self.width / 2, self.y + self.height / 2)'''画到屏幕上'''def draw(self):if hasattr(self, 'text'):self.screen.blit(self.text, self.text_pos)

实现起来其实都比较简单,按钮类就是多了一个被鼠标选中之后(也就是鼠标的位置落在按钮的区域范围内时)改变颜色以直观地告诉玩家该按钮已经被选中了的功能。

如果玩家点击退出键(QUIT),则退出游戏:

def quitgame():pygame.quit()sys.exit()

若点击开始游戏按钮,则开始游戏:

def startgame():game_levels = GameLevels(cfg, screen)game_levels.start()

玩家获胜的方法就是操作有限数量的小鸟将所有入侵的猪干掉,换句话说就是利用弹弓发射小鸟,让小鸟击中场上的所有猪。若小鸟全部发射完之后场上仍然有猪没有被击中,则玩家失败。判断游戏胜负关系的代码实现起来其实蛮简单的,大概是这样的:

'''游戏状态'''
def status(self, pigs, birds):status_codes = {'gaming': 0,'failure': 1,'victory': 2,}if len(pigs) == 0: return status_codes['victory']elif len(birds) == 0: return status_codes['failure']else: return status_codes['gaming']

接着,为了实现游戏,我们先定义一下所有我们需要的游戏精灵类。首先,是我们的主角,愤怒的小鸟:

'''小鸟'''
class Bird(pygame.sprite.Sprite):def __init__(self, screen, imagepaths, loc_info, velocity=None, color=(255, 255, 255), **kwargs):pygame.sprite.Sprite.__init__(self)assert len(loc_info) == 3assert len(imagepaths) == 1# 设置必要的属性常量self.color = colorself.screen = screenself.loc_info = list(loc_info)self.imagepaths = imagepathsself.velocity = VelocityVector() if velocity is None else velocityself.type = 'bird'self.fly_path = []self.is_dead = Falseself.elasticity = 0.8self.is_loaded = Falseself.is_selected = Falseself.inverse_friction = 0.99self.gravity = VelocityVector(0.2, math.pi)# 屏幕大小self.screen_size = screen.get_rect().sizeself.screen_size = (self.screen_size[0], self.screen_size[1] - 50)# 导入图像self.image = pygame.image.load(imagepaths[0])'''画到屏幕上'''def draw(self):if not self.is_loaded:for point in self.fly_path:pygame.draw.ellipse(self.screen, self.color, (point[0], point[1], 3, 3), 1)position = self.loc_info[0] - self.loc_info[2], self.loc_info[1] - self.loc_info[2]self.screen.blit(self.image, position)'''判断有没有被鼠标选中'''def selected(self):pos = pygame.mouse.get_pos()dx, dy = pos[0] - self.loc_info[0], pos[1] - self.loc_info[1]dist = math.hypot(dy, dx)if dist < self.loc_info[2]:return Truereturn False'''加载到弹弓上'''def load(self, slingshot):self.loc_info[0], self.loc_info[1] = slingshot.x, slingshot.yself.is_loaded = True'''重新设置位置'''def reposition(self, slingshot):pos = pygame.mouse.get_pos()if self.selected:self.loc_info[0], self.loc_info[1] = pos[0], pos[1]dx, dy = slingshot.x - self.loc_info[0], slingshot.y - self.loc_info[1]self.velocity.magnitude = min(int(math.hypot(dx, dy) / 2), 80)self.velocity.angle = math.pi / 2 + math.atan2(dy, dx)'''显示发射小鸟的路径'''def projectpath(self):if self.is_loaded:path = []bird = Bird(self.screen, self.imagepaths, self.loc_info, velocity=self.velocity)for i in range(30):bird.move()if i % 5 == 0: path.append((bird.loc_info[0], bird.loc_info[1]))for point in path:pygame.draw.ellipse(self.screen, self.color, (point[0], point[1], 2, 2))'''移动小鸟'''def move(self):# 根据重力改变小鸟的速度向量self.velocity = VectorAddition(self.velocity, self.gravity)self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)self.velocity.magnitude *= self.inverse_friction# 宽度超出屏幕if self.loc_info[0] > self.screen_size[0] - self.loc_info[2]:self.loc_info[0] = 2 * (self.screen_size[0] - self.loc_info[2]) - self.loc_info[0]self.velocity.angle *= -1self.velocity.magnitude *= self.elasticityelif self.loc_info[0] < self.loc_info[2]:self.loc_info[0] = 2 * self.loc_info[2] - self.loc_info[0]self.velocity.angle *= -1self.velocity.magnitude *= self.elasticity# 高度超出屏幕if self.loc_info[1] > self.screen_size[1] - self.loc_info[2]:self.loc_info[1] = 2 * (self.screen_size[1] - self.loc_info[2]) - self.loc_info[1]self.velocity.angle = math.pi - self.velocity.angleself.velocity.magnitude *= self.elasticityelif self.loc_info[1] < self.loc_info[2]:self.loc_info[1] = 2 * self.loc_info[2] - self.loc_info[1]self.velocity.angle = math.pi - self.velocity.angleself.velocity.magnitude *= self.elasticity

实现它主要需要考虑的是小鸟其实存在五种状态:

  • 排队状态,即在左下角等待进入弹弓时的状态,静止不动即可;

  • 就绪状态,即进入弹弓准备被发射的状态,其需要跟着鼠标不断地移动,使得玩家知道自己目前调整小鸟所到的位置被发射出去之后大概会是什么样的角度和路径;

  • 飞行状态,即被弹弓发射出去之后的状态,需要根据重力和小鸟的初速度来计算其飞行路径并不断地移动;

  • 碰撞状态,即在飞行过程中撞击到其他物体例如小猪和木桩等时,运动状态发生了改变;

  • 静止状态,即小鸟完成飞行状态之后最终静止时的状态。

接着来实现一下小猪:

'''猪'''
class Pig(pygame.sprite.Sprite):def __init__(self, screen, imagepaths, loc_info, velocity=None, **kwargs):pygame.sprite.Sprite.__init__(self)assert len(loc_info) == 3assert len(imagepaths) == 3# 设置必要的属性常量self.screen = screenself.loc_info = list(loc_info)self.imagepaths = imagepathsself.velocity = VelocityVector() if velocity is None else velocityself.type = 'pig'self.is_dead = Falseself.elasticity = 0.8self.switch_freq = 20self.animate_count = 0self.inverse_friction = 0.99self.gravity = VelocityVector(0.2, math.pi)# 屏幕大小self.screen_size = screen.get_rect().sizeself.screen_size = (self.screen_size[0], self.screen_size[1] - 50)# 导入图像self.pig_images = []for imagepath in imagepaths: self.pig_images.append(pygame.image.load(imagepath))# 设置当前图像self.image = random.choice(self.pig_images[:2])'''画到屏幕上'''def draw(self):self.animate_count += 1if (self.animate_count % self.switch_freq == 0) and (not self.is_dead):self.animate_count = 0self.image = random.choice(self.pig_images[:2])position = self.loc_info[0] - self.loc_info[2], self.loc_info[1] - self.loc_info[2]self.screen.blit(self.image, position)'''移动猪'''def move(self):# 根据重力改变猪的速度向量self.velocity = VectorAddition(self.velocity, self.gravity)self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)self.velocity.magnitude *= self.inverse_friction# 宽度超出屏幕if self.loc_info[0] > self.screen_size[0] - self.loc_info[2]:self.loc_info[0] = 2 * (self.screen_size[0] - self.loc_info[2]) - self.loc_info[0]self.velocity.angle *= -1self.velocity.magnitude *= self.elasticityelif self.loc_info[0] < self.loc_info[2]:self.loc_info[0] = 2 * self.loc_info[2] - self.loc_info[0]self.velocity.angle *= -1self.velocity.magnitude *= self.elasticity# 高度超出屏幕if self.loc_info[1] > self.screen_size[1] - self.loc_info[2]:self.loc_info[1] = 2 * (self.screen_size[1] - self.loc_info[2]) - self.loc_info[1]self.velocity.angle = math.pi - self.velocity.angleself.velocity.magnitude *= self.elasticityelif self.loc_info[1] < self.loc_info[2]:self.loc_info[1] = 2 * self.loc_info[2] - self.loc_info[1]self.velocity.angle = math.pi - self.velocity.angleself.velocity.magnitude *= self.elasticity'''猪死掉了'''def setdead(self):self.is_dead = Trueself.image = self.pig_images[-1]

猪在游戏中主要包括三种状态:

  • 静止状态,即未被击中时静止在某处的状态;

  • 被击中后的运动状态,即被其他物体击中之后根据动量守恒原理也一起运行时的状态;

  • 被击中后的静止状态,即因为被击中而产生运动之后又恢复静止时的状态、

游戏中的木块实现原理与小猪类似:

'''地图里的木块'''
class Block(pygame.sprite.Sprite):def __init__(self, screen, imagepaths, loc_info, velocity=None, **kwargs):pygame.sprite.Sprite.__init__(self)assert len(loc_info) == 3assert len(imagepaths) == 2# 设置必要的属性常量self.type = 'block'self.screen = screenself.loc_info = list(loc_info)self.imagepaths = imagepathsself.velocity = VelocityVector() if velocity is None else velocityself.elasticity = 0.7self.is_destroyed = Falseself.inverse_friction = 0.99self.gravity = VelocityVector(0.2, math.pi)# 导入图像self.block_images = []for imagepath in imagepaths: self.block_images.append(pygame.transform.scale(pygame.image.load(imagepath), (100, 100)))# 屏幕大小self.screen_size = screen.get_rect().sizeself.screen_size = (self.screen_size[0], self.screen_size[1] - 50)# 设置当前图像self.image = self.block_images[0]self.rect = self.image.get_rect()self.rotate_angle = math.radians(0)'''画到屏幕上'''def draw(self):pygame.transform.rotate(self.image, self.rotate_angle)self.screen.blit(self.image, (self.loc_info[0] - self.rect.width // 2, self.loc_info[1]))'''设置为损坏状态'''def setdestroy(self):self.is_destroyed = Trueself.image = self.block_images[1]'''移动木块'''def move(self):# 根据重力改变木块的速度向量self.velocity = VectorAddition(self.velocity, self.gravity)self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)self.velocity.magnitude *= self.inverse_friction# 宽度超出屏幕if self.loc_info[0] > self.screen_size[0] - self.rect.width:self.loc_info[0] = 2 * (self.screen_size[0] - self.rect.width) - self.loc_info[0]self.velocity.angle *= -1self.rotate_angle = -self.velocity.angleself.velocity.magnitude *= self.elasticityelif self.loc_info[0] < self.rect.width:self.loc_info[0] = 2 * self.rect.width - self.loc_info[0]self.velocity.angle *= -1self.rotate_angle = -self.velocity.angleself.velocity.magnitude *= self.elasticity# 高度超出屏幕if self.loc_info[1] > self.screen_size[1] - self.rect.height:self.loc_info[1] = 2 * (self.screen_size[1] - self.rect.height) - self.loc_info[1]self.velocity.angle = math.pi - self.velocity.angleself.rotate_angle = math.pi - self.velocity.angleself.velocity.magnitude *= self.elasticityelif self.loc_info[1] < self.rect.height:self.loc_info[1] = 2 * self.rect.height - self.loc_info[1]self.velocity.angle = math.pi - self.velocity.angleself.rotate_angle = math.pi - self.velocity.angleself.velocity.magnitude *= self.elasticity

最后,我们来实现一下墙和弹弓就可以啦:

'''弹弓'''
class Slingshot(pygame.sprite.Sprite):def __init__(self, screen, x, y, width, height, color=(66, 73, 73), line_color=(100, 30, 22), **kwargs):pygame.sprite.Sprite.__init__(self)self.x = xself.y = yself.color = colorself.width = widthself.height = heightself.screen = screenself.line_color = line_colorself.type = 'slingshot''''画到屏幕上'''def draw(self, bird=None):pygame.draw.rect(self.screen, self.color, (self.x, self.y + self.height * 1 / 3, self.width, self.height * 2 / 3))if bird is not None and bird.is_loaded:pygame.draw.line(self.screen, self.line_color, (self.x, self.y + self.height / 6), (bird.loc_info[0], bird.loc_info[1] + bird.loc_info[2] / 2), 10)pygame.draw.line(self.screen, self.line_color, (self.x + self.width, self.y + self.height / 6), (bird.loc_info[0] + bird.loc_info[2], bird.loc_info[1] + bird.loc_info[2] / 2), 10)pygame.draw.rect(self.screen, self.color, (self.x - self.width / 4, self.y, self.width / 2, self.height / 3), 5)pygame.draw.rect(self.screen, self.color, (self.x + self.width * 3 / 4, self.y, self.width / 2, self.height / 3), 5)'''墙'''
class Slab(pygame.sprite.Sprite):def __init__(self, screen, imagepaths, x, y, width, height, color=(255, 255, 255)):pygame.sprite.Sprite.__init__(self)self.x = xself.y = yself.color = colorself.width = widthself.height = heightself.screen = screenself.imagepaths = imagepathsif self.width > self.height:self.image = pygame.image.load(self.imagepaths[0])else:self.image = pygame.image.load(self.imagepaths[1])self.image = pygame.transform.scale(self.image, (self.width, self.height))self.type = 'wall''''画到屏幕上'''def draw(self):self.screen.blit(self.image, (self.x, self.y))

由此,我们完成了所有游戏精灵的定义,可以开始实现游戏的主循环啦,具体的代码实现如下:

'''开始游戏'''
def start(self):# 导入所有游戏精灵game_sprites = self.loadlevelmap()birds, pigs, blocks, walls = game_sprites['birds'], game_sprites['pigs'], game_sprites['blocks'], game_sprites['walls']slingshot = Slingshot(self.screen, 200, self.screen_size[1] - 200, 30, 200)birds[0].load(slingshot)score_label = Label(self.screen, 50, 10, 100, 50)score_label.addtext(f'SCORE: {self.score}', 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))birds_remaining_label = Label(self.screen, 120, 50, 100, 50)birds_remaining_label.addtext(f"BIRDS REMAINING: {len(birds)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))pigs_remaining_label = Label(self.screen, 110, 90, 100, 50)pigs_remaining_label.addtext(f"PIGS REMAINING: {len(pigs)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))carles_label = Label(self.screen, self.screen_size[0] - 270, self.screen_size[1] - 20, 300, 100)carles_label.addtext('CARLES', 60, self.cfg.FONTPATH['arfmoochikncheez'], (113, 125, 126))# 游戏主循环clock = pygame.time.Clock()blocks_to_remove, pigs_to_remove = [], []while True:# --按键检测for event in pygame.event.get():if event.type == pygame.QUIT:self.quitgame()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_q:self.quitgame()elif event.key == pygame.K_r:self.start()elif event.key == pygame.K_p or event.key == pygame.K_ESCAPE:self.pauseinterface()elif event.type == pygame.MOUSEBUTTONDOWN:if birds[0].selected():birds[0].is_selected = Trueelif event.type == pygame.MOUSEBUTTONUP:if birds[0].is_selected:birds[0].is_selected = Falsebirds[0].start_flying = True# --背景颜色填充color = self.cfg.BACKGROUND_COLORfor i in range(3):color = (color[0] + 5, color[1] + 5, color[2] + 5)pygame.draw.rect(self.screen, color, (0, i * 300, self.screen_size[0], 300))pygame.draw.rect(self.screen, (77, 86, 86), (0, self.screen_size[1], self.screen_size[0], 50))# --判断游戏是否结束,若没有则导入新的小鸟if (not birds[0].is_loaded) and self.still(pigs + birds + blocks):birds.pop(0)if self.status(pigs, birds) == 2:self.score += len(birds) * 100self.switchlevelinterface()elif self.status(pigs, birds) == 1:self.failureinterface()birds[0].load(slingshot)birds[0].start_flying = False# --重置小鸟的位置if birds[0].is_selected:birds[0].reposition(slingshot)if hasattr(birds[0], 'start_flying') and birds[0].start_flying:birds[0].is_loaded = False# --弹弓slingshot.draw(birds[0])# --判断猪是否撞上木桩for i in range(len(pigs)):for j in range(len(blocks)):pig_magnitude_1, block_magnitude_1 = pigs[i].velocity.magnitude, blocks[j].velocity.magnitudepigs[i], blocks[j], is_collision = self.collision(pigs[i], blocks[j])pig_magnitude_2, block_magnitude_2 = pigs[i].velocity.magnitude, blocks[j].velocity.magnitudeif is_collision:if abs(pig_magnitude_2 - pig_magnitude_2) > 2:blocks_to_remove.append(blocks[j])blocks[j].setdestroy()if abs(block_magnitude_2 - block_magnitude_1) > 2:pigs_to_remove.append(pigs[i])pigs[i].setdead()# --判断鸟是否撞上木桩for i in range(len(birds)):if not (birds[i].is_loaded or birds[i].velocity.magnitude == 0):for j in range(len(blocks)):bird_magnitude_1, block_magnitude_1 = birds[i].velocity.magnitude, blocks[j].velocity.magnitudebirds[i], blocks[j], is_collision = self.collision(birds[i], blocks[j])bird_magnitude_2, block_magnitude_2 = birds[i].velocity.magnitude, blocks[j].velocity.magnitudeif is_collision:if abs(bird_magnitude_1 - bird_magnitude_2) > 2:if blocks[j] not in blocks_to_remove:blocks_to_remove.append(blocks[j])blocks[j].setdestroy()# --判断猪是否撞上猪或者猪撞墙for i in range(len(pigs)):pigs[i].move()for j in range(i+1, len(pigs)):pig1_magnitude_1, pig2_magnitude_1 = pigs[i].velocity.magnitude, pigs[j].velocity.magnitudepigs[i], pigs[j], is_collision = self.collision(pigs[i], pigs[j])pig1_magnitude_2, pig2_magnitude_2 = pigs[i].velocity.magnitude, pigs[j].velocity.magnitudeif abs(pig1_magnitude_1 - pig1_magnitude_2) > 2:if pigs[j] not in pigs_to_remove:pigs_to_remove.append(pigs[j])pigs[j].setdead()if abs(pig2_magnitude_1 - pig2_magnitude_2) > 2:if pigs[i] not in pigs_to_remove:pigs_to_remove.append(pigs[i])pigs[i].setdead()for wall in walls: pigs[i] = self.collision(pigs[i], wall)[0]pigs[i].draw()# --判断鸟是否撞到猪或者鸟是否撞到墙for i in range(len(birds)):if (not birds[i].is_loaded) and (birds[i].velocity.magnitude):birds[i].move()for j in range(len(pigs)):bird_magnitude_1, pig_magnitude_1 = birds[i].velocity.magnitude, pigs[j].velocity.magnitudebirds[i], pigs[j], is_collision = self.collision(birds[i], pigs[j])bird_magnitude_2, pig_magnitude_2 = birds[i].velocity.magnitude, pigs[j].velocity.magnitudeif is_collision:if abs(bird_magnitude_2 - bird_magnitude_1) > 2:if pigs[j] not in pigs_to_remove:pigs_to_remove.append(pigs[j])pigs[j].setdead()if birds[i].is_loaded: birds[i].projectpath()for wall in walls: birds[i] = self.collision(birds[i], wall)[0]birds[i].draw()# --判断木桩是否撞到了木桩或者木桩撞到墙for i in range(len(blocks)):for j in range(i+1, len(blocks)):block1_magnitude_1, block2_magnitude_1 = blocks[i].velocity.magnitude, blocks[j].velocity.magnitudeblocks[i], blocks[j], is_collision = self.collision(blocks[i], blocks[j])block1_magnitude_2, block2_magnitude_2 = blocks[i].velocity.magnitude, blocks[j].velocity.magnitudeif is_collision:if abs(block1_magnitude_2 - block1_magnitude_1) > 2:if blocks[j] not in blocks_to_remove:blocks_to_remove.append(blocks[j])blocks[j].setdestroy()if abs(block2_magnitude_2 - block2_magnitude_1) > 2:if blocks[i] not in blocks_to_remove:blocks_to_remove.append(blocks[i])blocks[i].setdestroy()blocks[i].move()for wall in walls: blocks[i] = self.collision(blocks[i], wall)[0]blocks[i].draw()# --墙for wall in walls: wall.draw()# --显示文字score_label.addtext(f'SCORE: {self.score}', 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))score_label.draw()birds_remaining_label.addtext(f"BIRDS REMAINING: {len(birds)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))birds_remaining_label.draw()pigs_remaining_label.addtext(f"PIGS REMAINING: {len(pigs)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))pigs_remaining_label.draw()carles_label.draw()# --画面刷新pygame.display.update()clock.tick(self.cfg.FPS)# --删除无效的元素if self.still(birds + pigs + blocks):for pig in pigs_to_remove:if pig in pigs:pigs.remove(pig)self.score += 100for block in blocks_to_remove:if block in blocks:blocks.remove(block)self.score += 50pigs_to_remove = []blocks_to_remove = []

其他就是一些按键检测和碰撞检测以及一些分数之类的游戏状态实时更新,感觉没啥好讲的,总之,现在我们大功告成啦~

5 最后

项目获取:https://gitee.com/sinonfin/system-sharing

这篇关于小游戏毕设 - 愤怒的小鸟游戏设计与实现 (源码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/423882

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

在线装修管理系统的设计

管理员账户功能包括:系统首页,个人中心,管理员管理,装修队管理,用户管理,装修管理,基础数据管理,论坛管理 前台账户功能包括:系统首页,个人中心,公告信息,论坛,装修,装修队 开发系统:Windows 架构模式:B/S JDK版本:Java JDK1.8 开发工具:IDEA(推荐) 数据库版本: mysql5.7 数据库可视化工具: navicat 服务器:SpringBoot自带 ap

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

DDei在线设计器-API-DDeiSheet

DDeiSheet   DDeiSheet是代表一个页签,一个页签含有一个DDeiStage用于显示图形。   DDeiSheet实例包含了一个页签的所有数据,在获取后可以通过它访问其他内容。DDeiFile中的sheets属性记录了当前文件的页签列表。   一个DDeiFile实例至少包含一个DDeiSheet实例。   本篇最后提供的示例可以在DDei文档直接预览 属性 属性名说明数

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

springboot家政服务管理平台 LW +PPT+源码+讲解

3系统的可行性研究及需求分析 3.1可行性研究 3.1.1技术可行性分析 经过大学四年的学习,已经掌握了JAVA、Mysql数据库等方面的编程技巧和方法,对于这些技术该有的软硬件配置也是齐全的,能够满足开发的需要。 本家政服务管理平台采用的是Mysql作为数据库,可以绝对地保证用户数据的安全;可以与Mysql数据库进行无缝连接。 所以,家政服务管理平台在技术上是可以实施的。 3.1

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页:

探索蓝牙协议的奥秘:用ESP32实现高质量蓝牙音频传输

蓝牙(Bluetooth)是一种短距离无线通信技术,广泛应用于各种电子设备之间的数据传输。自1994年由爱立信公司首次提出以来,蓝牙技术已经经历了多个版本的更新和改进。本文将详细介绍蓝牙协议,并通过一个具体的项目——使用ESP32实现蓝牙音频传输,来展示蓝牙协议的实际应用及其优点。 蓝牙协议概述 蓝牙协议栈 蓝牙协议栈是蓝牙技术的核心,定义了蓝牙设备之间如何进行通信。蓝牙协议