当前位置: 首页 > news >正文

湘潭做网站 搜搜磐石网络/女教师遭网课入侵视频大全集

湘潭做网站 搜搜磐石网络,女教师遭网课入侵视频大全集,想开发一个旧物交易网站应该怎么做,西安旅游必去十大景点Python制作流浪气球游戏(导弹射击类)教学课程代码(分步教学版)1、构建全局通用代码结构2、构建气球精灵类3、构建导弹精灵类4、碰撞检测5、构建游戏信息类 (最终完整代码)教学课程代码(分步教学…

Python制作流浪气球游戏(导弹射击类)

    • 教学课程代码(分步教学版)
      • 1、构建全局通用代码结构
      • 2、构建气球精灵类
      • 3、构建导弹精灵类
      • 4、碰撞检测
      • 5、构建游戏信息类 (最终完整代码)

在这里插入图片描述

教学课程代码(分步教学版)

实时同步文件:Python制作流浪气球游戏(射击类)
B站视频教学地址:浪淘三千
(代码和素材是完整的,对应视频也已更新完毕)
以下是静态样式展示:
在这里插入图片描述

1、构建全局通用代码结构

"""
本游戏制作了导弹拦截流浪气球的基本代码 有 音效、音乐、精灵、碰撞、轨迹计算 等知识的应用
当基础功能学会以后,可以教大家平面地图文件的绘制和使用 制作更丰富精彩的游戏场景
视频教学地址,会陆续更新 https://space.bilibili.com/455954948
欢迎积极交流更好的改进建议,一起升级游戏   (代码已同步 链接见视频评论区)
"""
import arcade# 常量 窗口大小和标题
SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Arcade 游戏教学 流浪气球"# arcade_game_202302 流浪气球Ⅰ 教学版
class LiuLangQiQiu(arcade.View):""" 视图程序,用于在窗体内展示. """def __init__(self):# 初始化父类的属性super().__init__()self.background_image = None# 鼠标的图片self.couser_pic = None# 游戏背景音乐self.background_sound = arcade.load_sound("../声音文件/忍者神龟背景音乐.mp3")# 在初始化时调用的一些准备工作代码self.set_up()def set_up(self):""" 进行一些游戏准备工作,让游戏主逻辑从这开始,以便于在有需要时重开游戏. """# 背景图片 当作精灵加载进来self.background_image = arcade.Sprite("../图片文件/世界卫星地图.png")# 播放并记录游戏背景音乐self.current_play = self.background_sound.play(volume=0.4, loop=True)# 设置精灵素材中心点的位置self.background_image.center_x = self.window.width // 3self.background_image.center_y = self.window.height // 2# 鼠标图片加载self.couser_pic = arcade.Sprite('../图片文件/瞄准.png', scale=0.2)# 画面渲染绘制def on_draw(self):""" 负责渲染画面 速率: 60帧/秒. """# 清除上一帧绘制的画面self.clear()# 绘制背景图片self.background_image.draw()# 绘制鼠标self.couser_pic.draw()# 控制每次刷新时的变化def on_update(self, delta_time: float):""" 负责逻辑变化 速率: 60帧/秒. """passdef on_mouse_press(self, x, y, button, modifiers):""" 监听鼠标点击事件. """mouse_buttons = {1: "左键", 2: "中键", 4: "右键"}print(f"当前点击的坐标是{x,y}")def on_mouse_release(self, x: float, y: float, button: int, modifiers: int):""" 监听鼠标释放事件. """passdef on_mouse_motion(self, x: float, y: float, dx: float, dy: float):""" 监听鼠标移动事件 """self.couser_pic.center_x = xself.couser_pic.center_y = ydef on_key_press(self,key, modifiers):"""监听键盘按键点击事件modifiers:None = 16,shift= 1(17) ctrl= 2(18) alt= 4(20) """print("---键盘按键按下了:--",key,"--修饰键编号的和是:---", modifiers)def on_key_release(self, key, modifiers):print("---键盘按键抬起了:--",key,"--剩余修饰键编号的和是:---", modifiers)def on_resize(self, width: int, height: int):# 重新设置精灵素材中心点的位置self.background_image.center_x = self.window.width // 2self.background_image.center_y = self.window.height // 2# 重新设置精灵素材宽度和高度self.background_image.width = self.window.widthself.background_image.height = self.window.heightdef main():# 设置窗体的宽、高、名字、是否支持缩放window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, resizable=True)# 设置窗体的 logo 图标import pygletwindow.set_icon(pyglet.image.load('../图片文件/浪淘三千.png'))# 设置鼠标形状cursor = window.get_system_mouse_cursor(window.CURSOR_HAND)window.set_mouse_cursor(cursor)# 实例化定义的某个窗体start_view = LiuLangQiQiu()# 设置当前应该显示哪个窗体window.show_view(start_view)# 保持程序持续运行arcade.run()if __name__ == "__main__":main()

2、构建气球精灵类

"""
本游戏制作了导弹拦截流浪气球的基本代码 有 音效、音乐、精灵、碰撞、轨迹计算 等知识的应用
当基础功能学会以后,可以教大家平面地图文件的绘制和使用 制作更丰富精彩的游戏场景
视频教学地址,会陆续更新 https://space.bilibili.com/455954948
欢迎积极交流更好的改进建议,一起升级游戏   (代码已同步 链接见视频评论区)
"""
import arcade
import os,random# 常量 窗口大小和标题
SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Arcade 游戏教学 流浪气球"class QiQiu(arcade.Sprite):def __init__(self, filename, change_x, change_y, init_x, init_y):super(QiQiu, self).__init__(filename,hit_box_algorithm = "Simple")# 导弹精灵的飞行变化速度self.change_x = change_xself.change_y = change_y# 导弹精灵的初始中心点(init_x,init_y)self.center_x = init_xself.center_y = init_y# 记录气球单次持续垂直移动的距离self.total_change_y = 0# 是否被追踪 一旦被追踪则不再被别的导弹追踪self.is_tracked = False# 初始中心点不在界面左侧,则是从右向左飞行的,因为原始图片都朝向右侧,向左飞行的要水平翻转if self.center_x > 0:self.append_texture((arcade.load_texture(filename, mirrored=True)))# texture_right_forward = arcade.load_texture(filename, mirrored=True)self.set_texture(1)def update(self, window_height=800):self.total_change_y += self.change_y# 当单次垂直移动距离超过50就重新随机选择方向 这个数字通过自己测试调整得到if abs(self.total_change_y) > 50:# 随机改变气球纵向移动方向self.change_y *= random.choice([-1, 1])# 再次重新计算持续垂直移动的距离self.total_change_y = 0if self.center_y > window_height- self.height or self.center_y < self.height:self.change_y = 0self.total_change_y = 0self.center_x += self.change_xself.center_y += self.change_y# arcade_game_202302 流浪气球Ⅰ教学版
class LiuLangQiQiu(arcade.View):""" 视图程序,用于在窗体内展示. """def __init__(self):# 初始化父类的属性super().__init__()self.background_image = None# 气球类self.qi_qiu = Noneself.qi_qiu_list = None# 所有气球文件self.all_qi_qiu = None# 游戏背景音乐self.background_sound = arcade.load_sound("../声音文件/忍者神龟背景音乐.mp3")# 鼠标的图片self.couser_pic = None# 在初始化时调用的一些准备工作代码self.set_up()def set_up(self,init_qi_qiu_num=3):""" 进行一些游戏准备工作,让游戏主逻辑从这开始,以便于在有需要时重开游戏. """# 背景图片 当作精灵加载进来self.background_image = arcade.Sprite("../图片文件/世界卫星地图.png")# 播放并记录游戏背景音乐self.current_play = self.background_sound.play(volume=0.4, loop=True)# 气球精灵列表self.qi_qiu_list = arcade.SpriteList()# 获取文件夹中所有的飞艇图片self.all_qi_qiu = os.listdir("../图片文件/气球飞艇")print(self.all_qi_qiu)# 设置精灵素材中心点的位置self.background_image.center_x = self.window.width // 3self.background_image.center_y = self.window.height // 2# 初始状态时创建自定义个气球(默认3个)self.creat_qi_qiu(init_qi_qiu_num)self.couser_pic = arcade.Sprite('../图片文件/瞄准.png', scale=0.2)def creat_qi_qiu(self, num):"""创建气球"""for i in range(1, num+1):self.qi_qiu = QiQiu(filename=f"../图片文件/气球飞艇/{random.choice(self.all_qi_qiu)}",change_x=random.choice([0.5,0.5,1,2,2]), change_y=random.choice([1,2]),init_x=random.choice([-80, self.window.width + 200]),init_y=random.randint(200, self.window.height - num*50))self.qi_qiu.width = 60self.qi_qiu.height = 40# self.qi_qiu.scale = 0.5if self.qi_qiu.center_x > self.window.width//2:self.qi_qiu.change_x = -self.qi_qiu.change_xself.qi_qiu_list.append(self.qi_qiu)# 画面渲染绘制def on_draw(self):""" 负责渲染画面 速率: 60帧/秒. """# 清除上一帧绘制的画面self.clear()# 绘制背景图片self.background_image.draw()# 绘制气球精灵组self.qi_qiu_list.draw()# 绘制鼠标self.couser_pic.draw()# 控制每次刷新时的变化def on_update(self, delta_time: float):""" 负责逻辑变化 速率: 60帧/秒. """for qi_qiu_id, qi_qiu in enumerate(self.qi_qiu_list):# 气球移动qi_qiu.update(self.window.height)if qi_qiu.center_x not in range(-230, self.window.width+230):# 气球飞出屏幕一定距离后 则消失qi_qiu.remove_from_sprite_lists()# 再次创建气球self.creat_qi_qiu(1)def on_mouse_press(self, x, y, button, modifiers):""" 监听鼠标点击事件. """mouse_buttons = {1: "左键", 2: "中键", 4: "右键"}print(f"当前点击的坐标是{x,y}")def on_mouse_release(self, x: float, y: float, button: int, modifiers: int):""" 监听鼠标释放事件. """passdef on_mouse_motion(self, x: float, y: float, dx: float, dy: float):""" 监听鼠标移动事件 """self.couser_pic.center_x = xself.couser_pic.center_y = ydef on_key_press(self,key, modifiers):"""监听键盘按键点击事件modifiers:None = 16,shift= 1(17) ctrl= 2(18) alt= 4(20) """print("---键盘按键按下了:--",key,"--修饰键编号的和是:---", modifiers)def on_key_release(self, key, modifiers):print("---键盘按键抬起了:--",key,"--剩余修饰键编号的和是:---", modifiers)def on_resize(self, width: int, height: int):# 重新设置精灵素材中心点的位置self.background_image.center_x = self.window.width // 2self.background_image.center_y = self.window.height // 2# 重新设置精灵素材宽度和高度self.background_image.width = self.window.widthself.background_image.height = self.window.heightdef main():# 设置窗体的宽、高、名字、是否支持缩放window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, resizable=True)# 设置窗体的 logo 图标import pygletwindow.set_icon(pyglet.image.load('../图片文件/浪淘三千.png'))# 设置鼠标形状cursor = window.get_system_mouse_cursor(window.CURSOR_HAND)window.set_mouse_cursor(cursor)# 实例化定义的某个窗体start_view = LiuLangQiQiu()# 设置当前应该显示哪个窗体window.show_view(start_view)# 保持程序持续运行arcade.run()if __name__ == "__main__":main()

3、构建导弹精灵类

"""
本游戏制作了导弹拦截流浪气球的基本代码 有 音效、音乐、精灵、碰撞、轨迹计算 等知识的应用
当基础功能学会以后,可以教大家平面地图文件的绘制和使用 制作更丰富精彩的游戏场景
视频教学地址,会陆续更新 https://space.bilibili.com/455954948
欢迎积极交流更好的改进建议,一起升级游戏   (代码已同步 链接见视频评论区)
"""
import arcade
import os,random,math# 常量 窗口大小和标题
SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Arcade 游戏教学 流浪气球"class QiQiu(arcade.Sprite):def __init__(self, filename, change_x, change_y, init_x, init_y):super(QiQiu, self).__init__(filename,hit_box_algorithm = "Simple")# 导弹精灵的飞行变化速度self.change_x = change_xself.change_y = change_y# 导弹精灵的初始中心点(init_x,init_y)self.center_x = init_xself.center_y = init_y# 记录气球单次持续垂直移动的距离self.total_change_y = 0# 是否被追踪 一旦被追踪则不再被别的导弹追踪self.is_tracked = False# 初始中心点不在界面左侧,则是从右向左飞行的,因为原始图片都朝向右侧,向左飞行的要水平翻转if self.center_x > 0:self.append_texture((arcade.load_texture(filename, mirrored=True)))# texture_right_forward = arcade.load_texture(filename, mirrored=True)self.set_texture(1)def update(self, window_height=800):self.total_change_y += self.change_y# 当单次垂直移动距离超过50就重新随机选择方向 这个数字通过自己测试调整得到if abs(self.total_change_y) > 50:# 随机改变气球纵向移动方向self.change_y *= random.choice([-1, 1])# 再次重新计算持续垂直移动的距离self.total_change_y = 0if self.center_y > window_height- self.height or self.center_y < self.height:self.change_y = 0self.total_change_y = 0self.center_x += self.change_xself.center_y += self.change_yclass DaoDan(arcade.Sprite):"""目前是设计成了自动搜寻目标 然后攻击的模式"""def __init__(self, filename, change_x, change_y, init_x, init_y, target_x=None, target_y=None):super(DaoDan, self).__init__(filename,hit_box_algorithm = "Simple")# self.load_animated_gif(filename)# 导弹精灵的飞行变化速度self.change_x = change_xself.change_y = change_yself.change_y_init = change_y# 记录导弹精灵的初始点self.init_x = init_xself.init_y = init_y# 导弹精灵的初始中心点(init_x,init_y)self.center_x = init_xself.center_y = init_y# 要追踪的目标self.target_x = target_xself.target_y = target_y# 导弹是否还在地面上(没有发射)self.is_on_ground = True# 是否正在追踪 初始是未开始追踪self.is_tracking = False# 导弹点火发射音效self.fire_sound = arcade.load_sound("../声音文件/火焰推进器.mp3")# 导弹爆炸音效self.explode_sound = arcade.load_sound("../声音文件/中距离爆炸.mp3")def track_target(self, target_x, target_y, change_angle=0.1):# 当被调用的时候,开始追踪目标气球# 计算导弹和气球飞艇之间的弧度值 Π = 3.14(弧度) = 180°(角度) 向左转角度要加 向右转角度要减target_radians_angle = math.atan2(target_y-self.center_y,target_x-self.center_x)# 将上一步计算出的弧度转换为角度值# 都要减去90 因为导弹的初始方向是向上的,所以有一个默认的90°角,减去后恢复到 0°再计算。target_degree_angle = math.degrees(target_radians_angle)-90# print(f"角度是:{target_degree_angle}")self.center_x += self.change_x if self.center_x < target_x else -self.change_xself.center_y += self.change_y if self.center_y < target_y else -self.change_yself.change_y = 0 if abs(self.center_y - target_y) < 5 else self.change_y_init# print("2222", self.center_y, target_y, self.change_y)if abs(target_degree_angle) in range(0,8):self.angle = 0elif abs(target_degree_angle) in range(172,188):self.angle = 180else:self.angle = target_degree_angle# 定义一个弹道导弹类 继承导弹基类 ,因为追踪逻辑不一样,所以需要重写其追踪方法
class DanDaoDaoDan(DaoDan):# def __init__(self):#     super().__init__()def track_target(self):"""开始计算固定飞行轨迹 y = a(x-h)²+k  h 和 k 为抛物线的顶点横纵坐标将鼠标点击的(self.target_x,self.target_y)点作为顶点,则有【抛物线函数 y = a(x-self.target_x)²+self.target_y 】将导弹的起点坐标带入上述方程 可以求出 a 值 于是就可以求出抛物线的函数式【抛物线函数 init_y = a(init_x-self.target_x)²+self.target_y 】a = (init_y - self.target_y)/(init_x-self.target_x)²"""# 如果开口向下,a小于0;开口向上,a大于0.a = (self.init_y - self.target_y)/(self.init_x-self.target_x)**2# print(f"a的值是:{a}")self.center_x += self.change_x# 将横坐标带入方程求纵坐标self.center_y = a*(int(self.center_x - self.target_x)**2)+self.target_y# print(f"{self.center_y} = {a}*({int(self.center_x - self.target_x)})**2+{self.target_y}")# 计算导弹和气球飞艇之间的弧度值 Π = 3.14(弧度) = 180°(角度)target_radians_angle = math.atan2(self.target_y-self.center_y,self.target_x-self.center_x)# 将上一步计算出的弧度转换为角度值# 都要减去90 因为导弹的初始方向是向上的,所以有一个默认的90°角,减去后恢复到 0°再计算。target_degree_angle = math.degrees(target_radians_angle)-90if (self.target_x-self.init_x)*(self.target_x-self.center_x) < 0:# 值小于0 的时候说明导弹飞行中已经超过了设定好的最高点target_degree_angle = target_degree_angle + 180# print(f"角度是:{target_degree_angle}")if abs(target_degree_angle) in range(0,8):self.angle = 0elif abs(target_degree_angle) in range(172,188):self.angle = 180else:self.angle = target_degree_angleclass BaoZhaYanWu(arcade.Sprite):def __init__(self):super(BaoZhaYanWu, self).__init__()# 初始中心点不在界面左侧,则是从右向左飞行的,因为原始图片都朝向右侧,向左飞行的要水平翻转all_explore_pic = os.listdir("../图片文件/images11")for pic_name in all_explore_pic:self.append_texture((arcade.load_texture(f"../图片文件/images11/{pic_name}")))# 记下一共有多少纹理图self.textures_num_len = len(all_explore_pic)self.texture_index_now = 0def update(self, texture_index: int = None):# 如果状态是 True 则开始计算绘制位置if self.texture_index_now < self.textures_num_len:self.set_texture(self.texture_index_now)self.texture_index_now += 1return Falseelse:# 收到为True的返回值时 销毁烟雾精灵return True# arcade_game_202302 流浪气球Ⅰ教学版
class LiuLangQiQiu(arcade.View):""" 视图程序,用于在窗体内展示. """def __init__(self):# 初始化父类的属性super().__init__()self.background_image = Noneself.dao_dan = None# 气球类self.qi_qiu = Noneself.qi_qiu_list = None# 导弹类self.dao_dan = Noneself.dao_dan_list = None# 弹道导弹类self.dan_dao_dao_dan = Noneself.dan_dao_dao_dan_list = None# 所有气球文件self.all_qi_qiu = None# 游戏背景音乐self.background_sound = arcade.load_sound("../声音文件/忍者神龟背景音乐.mp3")# 导弹发射车self.dao_dan_che_image = None# 爆炸烟雾self.explode_smoke = Noneself.explode_smoke_list = None# 鼠标的图片self.couser_pic = None# 在初始化时调用的一些准备工作代码self.set_up()def set_up(self,init_qi_qiu_num=3):""" 进行一些游戏准备工作,让游戏主逻辑从这开始,以便于在有需要时重开游戏. """# 背景图片 当作精灵加载进来self.background_image = arcade.Sprite("../图片文件/世界卫星地图.png")# 游戏背景音乐self.current_play = self.background_sound.play(volume=0.4, loop=True)# 气球精灵列表self.qi_qiu_list = arcade.SpriteList()# 导弹精灵列表self.dao_dan_list = arcade.SpriteList()# 弹道导弹精灵列表self.dan_dao_dao_dan_list = arcade.SpriteList()# 爆炸烟雾精灵self.explode_smoke_list = arcade.SpriteList()# 获取文件夹中所有的飞艇图片self.all_qi_qiu = os.listdir("../图片文件/气球飞艇")print(self.all_qi_qiu)# 设置精灵素材中心点的位置self.background_image.center_x = self.window.width // 3self.background_image.center_y = self.window.height // 2# 导弹发射车 在on_resize()里设置绘制位置self.dao_dan_che_image = arcade.Sprite("../图片文件/东风41.png")self.dao_dan_che_image.width = 70self.dao_dan_che_image.height = 70# 初始状态时创建自定义个气球(默认3个)self.creat_qi_qiu(init_qi_qiu_num)self.couser_pic = arcade.Sprite('../图片文件/瞄准.png', scale=0.2)def creat_qi_qiu(self, num):"""创建气球"""for i in range(1, num+1):self.qi_qiu = QiQiu(filename=f"../图片文件/气球飞艇/{random.choice(self.all_qi_qiu)}",change_x=random.choice([0.5,0.5,1,2,2]), change_y=random.choice([1,2]),init_x=random.choice([-80, self.window.width + 200]),init_y=random.randint(200, self.window.height - num*50))self.qi_qiu.width = 60self.qi_qiu.height = 40# self.qi_qiu.scale = 0.5if self.qi_qiu.center_x > self.window.width//2:self.qi_qiu.change_x = -self.qi_qiu.change_xself.qi_qiu_list.append(self.qi_qiu)def creat_zhui_zong_dao_dan(self):dao_dan = DaoDan("../图片文件/导弹.gif", change_x=4, change_y=3,init_x=self.window.width // 3, init_y=self.window.height // 2)self.dao_dan_list.append(dao_dan)dao_dan.fire_sound.play()def creat_dan_dao_dao_dan(self,x,y):# 弹道导弹  如果剩余的弹道弹数量大于0 就接受命令进行创建init_x = self.window.width // 3init_y = self.window.height // 2speed = 1 if abs(x - init_x) < 200 else 3# 如果目标点在右侧 则导弹向右飞行 横坐标变化为正数 否则为负数change_x = speed if x > self.window.width // 3 else - speeddan_dao_dao_dan = DanDaoDaoDan("../图片文件/弹道导弹.png", change_x=change_x, change_y=3,init_x=init_x, init_y=init_y,target_x=x, target_y=y)dan_dao_dao_dan.scale = 0.7self.dan_dao_dao_dan_list.append(dan_dao_dao_dan)dan_dao_dao_dan.fire_sound.play()def creat_yan_wu(self,center_x, center_y):yan_wu = BaoZhaYanWu()yan_wu.center_x = center_xyan_wu.center_y = center_yself.explode_smoke_list.append(yan_wu)# 画面渲染绘制def on_draw(self):""" 负责渲染画面 速率: 60帧/秒. """# 清除上一帧绘制的画面self.clear()# 绘制背景图片self.background_image.draw()# 导弹发射车self.dao_dan_che_image.draw()# 绘制气球精灵组self.qi_qiu_list.draw()# 绘制导弹精灵组self.dao_dan_list.draw()# 绘制弹道导弹精灵组self.dan_dao_dao_dan_list.draw()# 绘制爆炸烟雾self.explode_smoke_list.draw()# 绘制鼠标self.couser_pic.draw()# 控制每次刷新时的变化def on_update(self, delta_time: float):""" 负责逻辑变化 速率: 60帧/秒. """for qi_qiu_id, qi_qiu in enumerate(self.qi_qiu_list):# 处理气球和自动追踪导弹的移动qi_qiu.update(self.window.height)if qi_qiu_id <= len(self.dao_dan_list)-1:dao_dan = self.dao_dan_list[qi_qiu_id]dao_dan.track_target(qi_qiu.center_x, qi_qiu.center_y, change_angle=-0.5)# else:#     print("请尽快发射导弹")if qi_qiu.center_x not in range(-230, self.window.width+230):# 气球飞出屏幕一定距离后 则消失qi_qiu.remove_from_sprite_lists()# 再次创建气球self.creat_qi_qiu(1)# 处理按下鼠标发射的弹道导弹for dan_dao_dao_dan in self.dan_dao_dao_dan_list:# 处理气球和弹道导弹的移动dan_dao_dao_dan.track_target()# 如果导弹飞出了屏幕 则销毁if dan_dao_dao_dan.center_x not in range(-230, self.window.width+230):dan_dao_dao_dan.remove_from_sprite_lists()def on_mouse_press(self, x, y, button, modifiers):""" 监听鼠标点击事件. """mouse_buttons = {1: "左键", 2: "中键", 4: "右键"}# print(f"当前点击的坐标是{x,y}")# 创建弹道导弹self.creat_dan_dao_dao_dan(x,y)def on_mouse_release(self, x: float, y: float, button: int, modifiers: int):""" 监听鼠标释放事件. """passdef on_mouse_motion(self, x: float, y: float, dx: float, dy: float):""" 监听鼠标移动事件 """self.couser_pic.center_x = xself.couser_pic.center_y = ydef on_key_press(self,key, modifiers):"""监听键盘按键点击事件modifiers:None = 16,shift= 1(17) ctrl= 2(18) alt= 4(20) """print("---键盘按键按下了:--",key,"--修饰键编号的和是:---", modifiers)if key == arcade.key.SPACE:self.creat_zhui_zong_dao_dan()def on_key_release(self, key, modifiers):print("---键盘按键抬起了:--",key,"--剩余修饰键编号的和是:---", modifiers)def on_resize(self, width: int, height: int):# 重新设置精灵素材中心点的位置self.background_image.center_x = self.window.width // 2self.background_image.center_y = self.window.height // 2# 重新设置精灵素材宽度和高度self.background_image.width = self.window.widthself.background_image.height = self.window.height# 设置导弹车精灵素材中心点的位置self.dao_dan_che_image.center_x = self.window.width // 3 - 30self.dao_dan_che_image.center_y = self.window.height // 2def main():# 设置窗体的宽、高、名字、是否支持缩放window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, resizable=True)# 设置窗体的 logo 图标import pygletwindow.set_icon(pyglet.image.load('../图片文件/浪淘三千.png'))# 设置鼠标形状cursor = window.get_system_mouse_cursor(window.CURSOR_HAND)window.set_mouse_cursor(cursor)# 实例化定义的某个窗体start_view = LiuLangQiQiu()# 设置当前应该显示哪个窗体window.show_view(start_view)# 保持程序持续运行arcade.run()if __name__ == "__main__":main()

4、碰撞检测

"""
本游戏制作了导弹拦截流浪气球的基本代码 有 音效、音乐、精灵、碰撞、轨迹计算 等知识的应用
当基础功能学会以后,可以教大家平面地图文件的绘制和使用 制作更丰富精彩的游戏场景
视频教学地址,会陆续更新 https://space.bilibili.com/455954948
欢迎积极交流更好的改进建议,一起升级游戏   (代码已同步 链接见视频评论区)
"""
import arcade
import os,random,math# 常量 窗口大小和标题
SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Arcade 游戏教学 流浪气球"class QiQiu(arcade.Sprite):def __init__(self, filename, change_x, change_y, init_x, init_y):super(QiQiu, self).__init__(filename,hit_box_algorithm = "Simple")# 导弹精灵的飞行变化速度self.change_x = change_xself.change_y = change_y# 导弹精灵的初始中心点(init_x,init_y)self.center_x = init_xself.center_y = init_y# 记录气球单次持续垂直移动的距离self.total_change_y = 0# 是否被追踪 一旦被追踪则不再被别的导弹追踪self.is_tracked = False# 初始中心点不在界面左侧,则是从右向左飞行的,因为原始图片都朝向右侧,向左飞行的要水平翻转if self.center_x > 0:self.append_texture((arcade.load_texture(filename, mirrored=True)))# texture_right_forward = arcade.load_texture(filename, mirrored=True)self.set_texture(1)def update(self, window_height=800):self.total_change_y += self.change_y# 当单次垂直移动距离超过50就重新随机选择方向 这个数字通过自己测试调整得到if abs(self.total_change_y) > 50:# 随机改变气球纵向移动方向self.change_y *= random.choice([-1, 1])# 再次重新计算持续垂直移动的距离self.total_change_y = 0if self.center_y > window_height- self.height or self.center_y < self.height:self.change_y = 0self.total_change_y = 0self.center_x += self.change_xself.center_y += self.change_yclass DaoDan(arcade.Sprite):"""目前是设计成了自动搜寻目标 然后攻击的模式"""def __init__(self, filename, change_x, change_y, init_x, init_y, target_x=None, target_y=None):super(DaoDan, self).__init__(filename,hit_box_algorithm = "Simple")# self.load_animated_gif(filename)# 导弹精灵的飞行变化速度self.change_x = change_xself.change_y = change_yself.change_y_init = change_y# 记录导弹精灵的初始点self.init_x = init_xself.init_y = init_y# 导弹精灵的初始中心点(init_x,init_y)self.center_x = init_xself.center_y = init_y# 要追踪的目标self.target_x = target_xself.target_y = target_y# 导弹是否还在地面上(没有发射)self.is_on_ground = True# 是否正在追踪 初始是未开始追踪self.is_tracking = False# 导弹点火发射音效self.fire_sound = arcade.load_sound("../声音文件/火焰推进器.mp3")# 导弹爆炸音效self.explode_sound = arcade.load_sound("../声音文件/中距离爆炸.mp3")def track_target(self, target_x, target_y, change_angle=0.1):# 当被调用的时候,开始追踪目标气球# 计算导弹和气球飞艇之间的弧度值 Π = 3.14(弧度) = 180°(角度) 向左转角度要加 向右转角度要减target_radians_angle = math.atan2(target_y-self.center_y,target_x-self.center_x)# 将上一步计算出的弧度转换为角度值# 都要减去90 因为导弹的初始方向是向上的,所以有一个默认的90°角,减去后恢复到 0°再计算。target_degree_angle = math.degrees(target_radians_angle)-90# print(f"角度是:{target_degree_angle}")self.center_x += self.change_x if self.center_x < target_x else -self.change_xself.center_y += self.change_y if self.center_y < target_y else -self.change_yself.change_y = 0 if abs(self.center_y - target_y) < 5 else self.change_y_init# print("2222", self.center_y, target_y, self.change_y)if abs(target_degree_angle) in range(0,8):self.angle = 0elif abs(target_degree_angle) in range(172,188):self.angle = 180else:self.angle = target_degree_angle# 定义一个弹道导弹类 继承导弹基类 ,因为追踪逻辑不一样,所以需要重写其追踪方法
class DanDaoDaoDan(DaoDan):# def __init__(self):#     super().__init__()def track_target(self):"""开始计算固定飞行轨迹 y = a(x-h)²+k  h 和 k 为抛物线的顶点横纵坐标将鼠标点击的(self.target_x,self.target_y)点作为顶点,则有【抛物线函数 y = a(x-self.target_x)²+self.target_y 】将导弹的起点坐标带入上述方程 可以求出 a 值 于是就可以求出抛物线的函数式【抛物线函数 init_y = a(init_x-self.target_x)²+self.target_y 】a = (init_y - self.target_y)/(init_x-self.target_x)²"""# 如果开口向下,a小于0;开口向上,a大于0.a = (self.init_y - self.target_y)/(self.init_x-self.target_x)**2# print(f"a的值是:{a}")self.center_x += self.change_x# 将横坐标带入方程求纵坐标self.center_y = a*(int(self.center_x - self.target_x)**2)+self.target_y# print(f"{self.center_y} = {a}*({int(self.center_x - self.target_x)})**2+{self.target_y}")# 计算导弹和气球飞艇之间的弧度值 Π = 3.14(弧度) = 180°(角度)target_radians_angle = math.atan2(self.target_y-self.center_y,self.target_x-self.center_x)# 将上一步计算出的弧度转换为角度值# 都要减去90 因为导弹的初始方向是向上的,所以有一个默认的90°角,减去后恢复到 0°再计算。target_degree_angle = math.degrees(target_radians_angle)-90if (self.target_x-self.init_x)*(self.target_x-self.center_x) < 0:# 值小于0 的时候说明导弹飞行中已经超过了设定好的最高点target_degree_angle = target_degree_angle + 180# print(f"角度是:{target_degree_angle}")if abs(target_degree_angle) in range(0,8):self.angle = 0elif abs(target_degree_angle) in range(172,188):self.angle = 180else:self.angle = target_degree_angleclass BaoZhaYanWu(arcade.Sprite):def __init__(self):super(BaoZhaYanWu, self).__init__()# 初始中心点不在界面左侧,则是从右向左飞行的,因为原始图片都朝向右侧,向左飞行的要水平翻转all_explore_pic = os.listdir("../图片文件/images11")for pic_name in all_explore_pic:self.append_texture((arcade.load_texture(f"../图片文件/images11/{pic_name}")))# 记下一共有多少纹理图self.textures_num_len = len(all_explore_pic)self.texture_index_now = 0def update(self, texture_index: int = None):# 如果状态是 True 则开始计算绘制位置if self.texture_index_now < self.textures_num_len:self.set_texture(self.texture_index_now)self.texture_index_now += 1return Falseelse:# 收到为True的返回值时 销毁烟雾精灵return True# arcade_game_202302 流浪气球Ⅰ教学版
class LiuLangQiQiu(arcade.View):""" 视图程序,用于在窗体内展示. """def __init__(self):# 初始化父类的属性super().__init__()self.background_image = Noneself.dao_dan = None# 气球类self.qi_qiu = Noneself.qi_qiu_list = None# 导弹类self.dao_dan = Noneself.dao_dan_list = None# 弹道导弹类self.dan_dao_dao_dan = Noneself.dan_dao_dao_dan_list = None# 所有气球文件self.all_qi_qiu = None# 游戏背景音乐self.background_sound = arcade.load_sound("../声音文件/忍者神龟背景音乐.mp3")# 导弹发射车self.dao_dan_che_image = None# 爆炸烟雾self.explode_smoke = Noneself.explode_smoke_list = None# 为了有节奏的控制游戏刷新时个别元素的刷新速度 设置一个记录时间间隔变量self.interval_time = 0# 鼠标的图片self.couser_pic = None# 在初始化时调用的一些准备工作代码self.set_up()def set_up(self,init_qi_qiu_num=3):""" 进行一些游戏准备工作,让游戏主逻辑从这开始,以便于在有需要时重开游戏. """# 背景图片 当作精灵加载进来self.background_image = arcade.Sprite("../图片文件/世界卫星地图.png")# 游戏背景音乐self.current_play = self.background_sound.play(volume=0.4, loop=True)# 气球精灵列表self.qi_qiu_list = arcade.SpriteList()# 导弹精灵列表self.dao_dan_list = arcade.SpriteList()# 弹道导弹精灵列表self.dan_dao_dao_dan_list = arcade.SpriteList()# 爆炸烟雾精灵self.explode_smoke_list = arcade.SpriteList()# 获取文件夹中所有的飞艇图片self.all_qi_qiu = os.listdir("../图片文件/气球飞艇")print(self.all_qi_qiu)# 设置精灵素材中心点的位置self.background_image.center_x = self.window.width // 3self.background_image.center_y = self.window.height // 2# 导弹发射车 在on_resize()里设置绘制位置self.dao_dan_che_image = arcade.Sprite("../图片文件/东风41.png")self.dao_dan_che_image.width = 70self.dao_dan_che_image.height = 70# 初始状态时创建自定义个气球(默认3个)self.creat_qi_qiu(init_qi_qiu_num)self.couser_pic = arcade.Sprite('../图片文件/瞄准.png', scale=0.2)def creat_qi_qiu(self, num):"""创建气球"""for i in range(1, num+1):self.qi_qiu = QiQiu(filename=f"../图片文件/气球飞艇/{random.choice(self.all_qi_qiu)}",change_x=random.choice([0.5,0.5,1,2,2]), change_y=random.choice([1,2]),init_x=random.choice([-80, self.window.width + 200]),init_y=random.randint(200, self.window.height - num*50))self.qi_qiu.width = 60self.qi_qiu.height = 40# self.qi_qiu.scale = 0.5if self.qi_qiu.center_x > self.window.width//2:self.qi_qiu.change_x = -self.qi_qiu.change_xself.qi_qiu_list.append(self.qi_qiu)def creat_zhui_zong_dao_dan(self):dao_dan = DaoDan("../图片文件/导弹.gif", change_x=4, change_y=3,init_x=self.window.width // 3, init_y=self.window.height // 2)self.dao_dan_list.append(dao_dan)dao_dan.fire_sound.play()def creat_dan_dao_dao_dan(self,x,y):# 弹道导弹  如果剩余的弹道弹数量大于0 就接受命令进行创建init_x = self.window.width // 3init_y = self.window.height // 2speed = 1 if abs(x - init_x) < 200 else 3# 如果目标点在右侧 则导弹向右飞行 横坐标变化为正数 否则为负数change_x = speed if x > self.window.width // 3 else - speeddan_dao_dao_dan = DanDaoDaoDan("../图片文件/弹道导弹.png", change_x=change_x, change_y=3,init_x=init_x, init_y=init_y,target_x=x, target_y=y)dan_dao_dao_dan.scale = 0.7self.dan_dao_dao_dan_list.append(dan_dao_dao_dan)dan_dao_dao_dan.fire_sound.play()def creat_yan_wu(self,center_x, center_y):yan_wu = BaoZhaYanWu()yan_wu.center_x = center_xyan_wu.center_y = center_yself.explode_smoke_list.append(yan_wu)# 画面渲染绘制def on_draw(self):""" 负责渲染画面 速率: 60帧/秒. """# 清除上一帧绘制的画面self.clear()# 绘制背景图片self.background_image.draw()# 导弹发射车self.dao_dan_che_image.draw()# 绘制气球精灵组self.qi_qiu_list.draw()# 绘制导弹精灵组self.dao_dan_list.draw()# 绘制弹道导弹精灵组self.dan_dao_dao_dan_list.draw()# 绘制爆炸烟雾self.explode_smoke_list.draw()# 绘制鼠标self.couser_pic.draw()# 控制每次刷新时的变化def on_update(self, delta_time: float):""" 负责逻辑变化 速率: 60帧/秒. """for qi_qiu_id, qi_qiu in enumerate(self.qi_qiu_list):# 处理气球和自动追踪导弹的碰撞及逻辑qi_qiu.update(self.window.height)if qi_qiu_id <= len(self.dao_dan_list)-1:dao_dan = self.dao_dan_list[qi_qiu_id]dao_dan.track_target(qi_qiu.center_x, qi_qiu.center_y, change_angle=-0.5)# else:#     print("请尽快发射导弹")collision = arcade.check_for_collision_with_list(qi_qiu, self.dao_dan_list)if len(collision) > 0:print(f"发生碰撞了,相撞的{qi_qiu_id}号导弹和气球都被移除")# 移除碰到的气球qi_qiu.remove_from_sprite_lists()# 创建气球self.creat_qi_qiu(1)# 移除碰到的追踪导弹for collision_obj in collision:collision_obj.remove_from_sprite_lists()collision_obj.explode_sound.play()# 创建烟雾 坐标为所碰撞气球的坐标self.creat_yan_wu(qi_qiu.center_x,qi_qiu.center_y)if qi_qiu.center_x not in range(-230, self.window.width+230):# 气球飞出屏幕一定距离后 则消失qi_qiu.remove_from_sprite_lists()# 再次创建气球self.creat_qi_qiu(1)# 处理按下鼠标发射的弹道导弹for dan_dao_dao_dan in self.dan_dao_dao_dan_list:# 处理气球和弹道导弹的碰撞及逻辑dan_dao_dao_dan.track_target()collision2 = arcade.check_for_collision_with_list(dan_dao_dao_dan, self.qi_qiu_list)for collision_obj2 in collision2:collision_obj2.remove_from_sprite_lists()dan_dao_dao_dan.remove_from_sprite_lists()dan_dao_dao_dan.explode_sound.play()# 创建气球self.creat_qi_qiu(1)# 创建烟雾self.creat_yan_wu(collision_obj2.center_x, collision_obj2.center_y)# 如果导弹飞出了屏幕 则销毁if dan_dao_dao_dan.center_x not in range(-230, self.window.width+230):dan_dao_dao_dan.remove_from_sprite_lists()# 烟雾的绘制for smoke in self.explode_smoke_list:self.interval_time += delta_timeif self.interval_time > 0.08:res = smoke.update()self.interval_time = 0if res:smoke.remove_from_sprite_lists()def on_mouse_press(self, x, y, button, modifiers):""" 监听鼠标点击事件. """mouse_buttons = {1: "左键", 2: "中键", 4: "右键"}# print(f"当前点击的坐标是{x,y}")# 创建弹道导弹self.creat_dan_dao_dao_dan(x,y)def on_mouse_release(self, x: float, y: float, button: int, modifiers: int):""" 监听鼠标释放事件. """passdef on_mouse_motion(self, x: float, y: float, dx: float, dy: float):""" 监听鼠标移动事件 """self.couser_pic.center_x = xself.couser_pic.center_y = ydef on_key_press(self,key, modifiers):"""监听键盘按键点击事件modifiers:None = 16,shift= 1(17) ctrl= 2(18) alt= 4(20) """print("---键盘按键按下了:--",key,"--修饰键编号的和是:---", modifiers)if key == arcade.key.SPACE:self.creat_zhui_zong_dao_dan()def on_key_release(self, key, modifiers):print("---键盘按键抬起了:--",key,"--剩余修饰键编号的和是:---", modifiers)def on_resize(self, width: int, height: int):# 重新设置精灵素材中心点的位置self.background_image.center_x = self.window.width // 2self.background_image.center_y = self.window.height // 2# 重新设置精灵素材宽度和高度self.background_image.width = self.window.widthself.background_image.height = self.window.height# 设置导弹车精灵素材中心点的位置self.dao_dan_che_image.center_x = self.window.width // 3 - 30self.dao_dan_che_image.center_y = self.window.height // 2def main():# 设置窗体的宽、高、名字、是否支持缩放window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, resizable=True)# 设置窗体的 logo 图标import pygletwindow.set_icon(pyglet.image.load('../图片文件/浪淘三千.png'))# 设置鼠标形状cursor = window.get_system_mouse_cursor(window.CURSOR_HAND)window.set_mouse_cursor(cursor)# 实例化定义的某个窗体start_view = LiuLangQiQiu()# 设置当前应该显示哪个窗体window.show_view(start_view)# 保持程序持续运行arcade.run()if __name__ == "__main__":main()

5、构建游戏信息类 (最终完整代码)

"""
本游戏制作了导弹拦截流浪气球的基本代码 有 音效、音乐、精灵、碰撞、轨迹计算 等知识的应用
当基础功能学会以后,可以教大家平面地图文件的绘制和使用 制作更丰富精彩的游戏场景
视频教学地址,会陆续更新 https://space.bilibili.com/455954948
欢迎积极交流更好的改进建议,一起升级游戏   (代码已同步 链接见视频评论区)
"""
import arcade
import os,random,math# 常量 窗口大小和标题
SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Arcade 游戏教学 流浪气球"class QiQiu(arcade.Sprite):def __init__(self, filename, change_x, change_y, init_x, init_y):super(QiQiu, self).__init__(filename,hit_box_algorithm = "Simple")# 导弹精灵的飞行变化速度self.change_x = change_xself.change_y = change_y# 导弹精灵的初始中心点(init_x,init_y)self.center_x = init_xself.center_y = init_y# 记录气球单次持续垂直移动的距离self.total_change_y = 0# 是否被追踪 一旦被追踪则不再被别的导弹追踪self.is_tracked = False# 初始中心点不在界面左侧,则是从右向左飞行的,因为原始图片都朝向右侧,向左飞行的要水平翻转if self.center_x > 0:self.append_texture((arcade.load_texture(filename, mirrored=True)))# texture_right_forward = arcade.load_texture(filename, mirrored=True)self.set_texture(1)def update(self, window_height=800):self.total_change_y += self.change_y# 当单次垂直移动距离超过50就重新随机选择方向 这个数字通过自己测试调整得到if abs(self.total_change_y) > 50:# 随机改变气球纵向移动方向self.change_y *= random.choice([-1, 1])# 再次重新计算持续垂直移动的距离self.total_change_y = 0if self.center_y > window_height- self.height or self.center_y < self.height:self.change_y = 0self.total_change_y = 0self.center_x += self.change_xself.center_y += self.change_yclass DaoDan(arcade.Sprite):"""目前是设计成了自动搜寻目标 然后攻击的模式"""def __init__(self, filename, change_x, change_y, init_x, init_y, target_x=None, target_y=None):super(DaoDan, self).__init__(filename,hit_box_algorithm = "Simple")# self.load_animated_gif(filename)# 导弹精灵的飞行变化速度self.change_x = change_xself.change_y = change_yself.change_y_init = change_y# 记录导弹精灵的初始点self.init_x = init_xself.init_y = init_y# 导弹精灵的初始中心点(init_x,init_y)self.center_x = init_xself.center_y = init_y# 要追踪的目标self.target_x = target_xself.target_y = target_y# 导弹是否还在地面上(没有发射)self.is_on_ground = True# 是否正在追踪 初始是未开始追踪self.is_tracking = False# 导弹点火发射音效self.fire_sound = arcade.load_sound("../声音文件/火焰推进器.mp3")# 导弹爆炸音效self.explode_sound = arcade.load_sound("../声音文件/中距离爆炸.mp3")def track_target(self, target_x, target_y, change_angle=0.1):# 当被调用的时候,开始追踪目标气球# 计算导弹和气球飞艇之间的弧度值 Π = 3.14(弧度) = 180°(角度) 向左转角度要加 向右转角度要减target_radians_angle = math.atan2(target_y-self.center_y,target_x-self.center_x)# 将上一步计算出的弧度转换为角度值# 都要减去90 因为导弹的初始方向是向上的,所以有一个默认的90°角,减去后恢复到 0°再计算。target_degree_angle = math.degrees(target_radians_angle)-90# print(f"角度是:{target_degree_angle}")self.center_x += self.change_x if self.center_x < target_x else -self.change_xself.center_y += self.change_y if self.center_y < target_y else -self.change_yself.change_y = 0 if abs(self.center_y - target_y) < 5 else self.change_y_init# print("2222", self.center_y, target_y, self.change_y)if abs(target_degree_angle) in range(0,8):self.angle = 0elif abs(target_degree_angle) in range(172,188):self.angle = 180else:self.angle = target_degree_angle# 定义一个弹道导弹类 继承导弹基类 ,因为追踪逻辑不一样,所以需要重写其追踪方法
class DanDaoDaoDan(DaoDan):# def __init__(self):#     super().__init__()def track_target(self):"""开始计算固定飞行轨迹 y = a(x-h)²+k  h 和 k 为抛物线的顶点横纵坐标将鼠标点击的(self.target_x,self.target_y)点作为顶点,则有【抛物线函数 y = a(x-self.target_x)²+self.target_y 】将导弹的起点坐标带入上述方程 可以求出 a 值 于是就可以求出抛物线的函数式【抛物线函数 init_y = a(init_x-self.target_x)²+self.target_y 】a = (init_y - self.target_y)/(init_x-self.target_x)²"""# 如果开口向下,a小于0;开口向上,a大于0.a = (self.init_y - self.target_y)/(self.init_x-self.target_x)**2# print(f"a的值是:{a}")self.center_x += self.change_x# 将横坐标带入方程求纵坐标self.center_y = a*(int(self.center_x - self.target_x)**2)+self.target_y# print(f"{self.center_y} = {a}*({int(self.center_x - self.target_x)})**2+{self.target_y}")# 计算导弹和气球飞艇之间的弧度值 Π = 3.14(弧度) = 180°(角度)target_radians_angle = math.atan2(self.target_y-self.center_y,self.target_x-self.center_x)# 将上一步计算出的弧度转换为角度值# 都要减去90 因为导弹的初始方向是向上的,所以有一个默认的90°角,减去后恢复到 0°再计算。target_degree_angle = math.degrees(target_radians_angle)-90if (self.target_x-self.init_x)*(self.target_x-self.center_x) < 0:# 值小于0 的时候说明导弹飞行中已经超过了设定好的最高点target_degree_angle = target_degree_angle + 180# print(f"角度是:{target_degree_angle}")if abs(target_degree_angle) in range(0,8):self.angle = 0elif abs(target_degree_angle) in range(172,188):self.angle = 180else:self.angle = target_degree_angleclass BaoZhaYanWu(arcade.Sprite):def __init__(self):super(BaoZhaYanWu, self).__init__()# 初始中心点不在界面左侧,则是从右向左飞行的,因为原始图片都朝向右侧,向左飞行的要水平翻转all_explore_pic = os.listdir("../图片文件/images11")for pic_name in all_explore_pic:self.append_texture((arcade.load_texture(f"../图片文件/images11/{pic_name}")))# 记下一共有多少纹理图self.textures_num_len = len(all_explore_pic)self.texture_index_now = 0def update(self, texture_index: int = None):# 如果状态是 True 则开始计算绘制位置if self.texture_index_now < self.textures_num_len:self.set_texture(self.texture_index_now)self.texture_index_now += 1return Falseelse:# 收到为True的返回值时 销毁烟雾精灵return Trueclass InfoPanel:"""信息板 以后可以优化为游戏公共信息类"""def __init__(self):super(InfoPanel, self).__init__()self.game_info = {}self.set_up()def set_up(self,init_qi_qiu_num=0,game_limit_time=10,zhui_zong_dao_dan_num=10,dan_dao_dao_dan_num=20,difficulty_level=2):self.game_info.clear()self.game_info["game_status"] = True  # 游戏状态(能玩和不能玩)self.game_info["game_pause"] = False  # 游戏暂停状态self.game_info["player_score"] = 0  # 玩家分数self.game_info["player_use_time"] = 0  # 玩家用时self.game_info["game_limit_time"] = game_limit_time  # 游戏限时 单位秒self.game_info["difficulty_level"] = difficulty_level  # 游戏难度(平均几个弹道导弹 VS 一个气球)self.game_info["surplus_dan_dao_dao_dan_num"] = dan_dao_dao_dan_num  # surplus:剩余 弹道导弹数量self.game_info["surplus_zhui_zong_dao_dan_num"] = zhui_zong_dao_dan_num  # 剩余追踪弹的数量# 得分要求为 追踪导弹的数量个数 加上 弹道导弹数量个数的一半self.game_info["player_target_score"] = zhui_zong_dao_dan_num + dan_dao_dao_dan_num//max(1,difficulty_level)  # 玩家目标分数self.game_info["init_qi_qiu_num"] = init_qi_qiu_num  # 初始气球数量设置为self.game_info["surplus_qi_qiu_num"] = 0  # 剩余气球数量self.game_info["all_qi_qiu_num"] = 0  # 全部出现过的气球数量self.game_info["zhui_zong_dao_dan_pic"] = arcade.Sprite("../图片文件/导弹.gif")self.game_info["dan_dao_dao_dan_pic"] = arcade.Sprite("../图片文件/弹道导弹.png")# 游戏胜利图片self.game_info["game_win_pic"] = arcade.Sprite("../图片文件/win.png")# 游戏失败图片self.game_info["game_over_pic"] = arcade.Sprite("../图片文件/game_over.png")# 游戏暂停图片self.game_info["game_pause_pic"] = arcade.Sprite("../图片文件/游戏暂停.png")# 游戏胜利音乐self.game_info["game_win_sound"] = arcade.sound.load_sound("../声音文件/成功.mp3")# 游戏失败音乐self.game_info["game_over_sound_1"] = arcade.sound.load_sound("../声音文件/马里奥游戏结束.mp3")# 游戏失败嘲讽self.game_info["game_over_sound_2"] = arcade.sound.load_sound("../声音文件/马里奥哈哈嘲讽.mp3")# 游戏暂停音效self.game_info["game_pause_sound"] = arcade.sound.load_sound("../声音文件/暂停.mp3")# # 游戏暂停后重新开始音效# self.game_info["game_continue_sound"] = arcade.sound.load_sound("../声音文件/暂停后开始.mp3")def draw_game_info(self,x,y):# x: 屏幕宽度 y:屏幕高度font_size = 20# 第一行# 描述游戏信息的字符串self.game_info["game_info_txt"] = f"难度:{self.game_info['difficulty_level']} vs 1" \f" 得分:{self.game_info['player_score']} /{self.game_info['player_target_score']}"\f" 命中率:{self.game_info['player_score']}/{self.game_info['all_qi_qiu_num']}"\f" 计时:{self.game_info['player_use_time']}/{self.game_info['game_limit_time']}"arcade.Text(self.game_info["game_info_txt"], 10, y - font_size*2,color=arcade.color.SAE, font_size=font_size, width=x, font_name="站酷快乐体2016修订版",bold=True, align="left", anchor_x="left", multiline=False).draw()# 第二行# 绘制追踪导弹信息self.game_info["zhui_zong_dao_dan_pic"].width = font_size*2self.game_info["zhui_zong_dao_dan_pic"].height = font_size*2self.game_info["zhui_zong_dao_dan_pic"].center_x = 10 + font_size // 2self.game_info["zhui_zong_dao_dan_pic"].center_y = y - font_size * 3.5self.game_info["zhui_zong_dao_dan_pic"].draw()arcade.Text(f"X {self.game_info['surplus_zhui_zong_dao_dan_num']}", 10 + font_size*2 , y - font_size *4,color=arcade.color.SAE, font_size=font_size, width=x, font_name="站酷快乐体2016修订版",bold=True, align="left", anchor_x="left", multiline=True).draw()# 绘制弹道导弹信息 (第二行 追踪导弹后面的内容)self.game_info["dan_dao_dao_dan_pic"].width = font_size*2self.game_info["dan_dao_dao_dan_pic"].height = font_size*2self.game_info["dan_dao_dao_dan_pic"].center_x = 10 + font_size * 2 + 5*font_sizeself.game_info["dan_dao_dao_dan_pic"].center_y = y - font_size * 3.5self.game_info["dan_dao_dao_dan_pic"].draw()arcade.Text(f"X {self.game_info['surplus_dan_dao_dao_dan_num']}", 10 + font_size * 2 + 6*font_size, y - font_size *4,color=arcade.color.SAE, font_size=font_size, width=x, font_name="站酷快乐体2016修订版",bold=True, align="left", anchor_x="left", multiline=True).draw()# 游戏失败时持续执行if not self.game_info["game_status"] and self.game_info["player_use_time"] >= self.game_info["game_limit_time"]:self.game_info["game_over_pic"].center_x = x // 2self.game_info["game_over_pic"].center_y = y // 2self.game_info["game_over_pic"].draw()arcade.Text(f"~~按右侧 SHIFT 键重新开始~~", x//2,y//2 - 200,color=arcade.color.WHITE, font_size=font_size*2, width=x, font_name="站酷快乐体2016修订版",bold=True, align="left", anchor_x="center", multiline=False).draw()# 游戏胜利时持续执行if not self.game_info["game_status"] and (self.game_info["player_score"] >= self.game_info['player_target_score']):self.game_info["game_win_pic"].center_x = x // 2self.game_info["game_win_pic"].center_y = y // 2self.game_info["game_win_pic"].draw()# 触发游戏暂停时持续执行if self.game_info["game_status"] and self.game_info["game_pause"]:self.game_info["game_pause_pic"].center_x = x // 2self.game_info["game_pause_pic"].center_y = y // 2self.game_info["game_pause_pic"].draw()arcade.Text(f"~~按 Enter 键继续~~", x // 2, y // 2 - 200,color=arcade.color.WHITE, font_size=font_size*2, width=x, font_name="站酷快乐体2016修订版",bold=True, align="left", anchor_x="center", multiline=False).draw()def check_game_status(self, bgm):# 游戏失败时执行if self.game_info["game_status"] and self.game_info["player_use_time"] >= self.game_info["game_limit_time"]:self.game_info["game_status"] = Falsearcade.stop_sound(bgm)self.game_info["game_over_sound_1"].play()self.game_info["game_over_sound_2"].play()# 游戏胜利时执行if self.game_info["game_status"] and (self.game_info["player_score"] >= self.game_info['player_target_score']):self.game_info["game_status"] = Falsearcade.stop_sound(bgm)self.game_info["game_win_sound"].play()# 游戏暂停时执行if self.game_info["game_pause"]:return Falsereturn self.game_info["game_status"]# arcade_game_202302 流浪气球Ⅰ
class LiuLangQiQiu(arcade.View):""" 视图程序,用于在窗体内展示. """def __init__(self):# 初始化父类的属性super().__init__()self.background_image = Noneself.dao_dan = None# 气球类self.qi_qiu = Noneself.qi_qiu_list = None# 导弹类self.dao_dan = Noneself.dao_dan_list = None# 弹道导弹类self.dan_dao_dao_dan = Noneself.dan_dao_dao_dan_list = None# 所有气球文件self.all_qi_qiu = None# 游戏背景音乐self.background_sound = arcade.load_sound("../声音文件/忍者神龟背景音乐.mp3")# 导弹发射车self.dao_dan_che_image = None# 爆炸烟雾self.explode_smoke = Noneself.explode_smoke_list = None# 为了有节奏的控制游戏刷新时个别元素的刷新速度 设置一个记录时间间隔变量self.interval_time = 0# 游戏信息面板self.info_panel = None# 鼠标的图片self.couser_pic = None# 在初始化时调用的一些准备工作代码self.set_up()# 有规律的调用time_clock函数,每次调用间隔设置为1秒arcade.schedule(self.time_clock, 1)def set_up(self,init_qi_qiu_num = 5,zhui_zong_dao_dan_num = 20,dan_dao_dao_dan_num=30,difficulty_level=3):"difficulty_level:难度等级 代表平均至少用几个弹道导弹就击中一个气球 ,会以此来计算玩家的目标分数 数字越大越简单 最小是1"""" 进行一些游戏准备工作,让游戏主逻辑从这开始,以便于在有需要时重开游戏. """# 实例化游戏信息类self.info_panel = InfoPanel()self.info_panel.set_up(init_qi_qiu_num=init_qi_qiu_num,game_limit_time=zhui_zong_dao_dan_num * 1 + dan_dao_dao_dan_num*2,zhui_zong_dao_dan_num=zhui_zong_dao_dan_num, dan_dao_dao_dan_num=dan_dao_dao_dan_num,difficulty_level=difficulty_level)# 游戏背景音乐self.current_play = self.background_sound.play(volume=0.4, loop=True)# 气球精灵列表self.qi_qiu_list = arcade.SpriteList()# 导弹精灵列表self.dao_dan_list = arcade.SpriteList()# 弹道导弹精灵列表self.dan_dao_dao_dan_list = arcade.SpriteList()# 爆炸烟雾精灵self.explode_smoke_list = arcade.SpriteList()# 获取文件夹中所有的飞艇图片self.all_qi_qiu = os.listdir("../图片文件/气球飞艇")print(self.all_qi_qiu)# 背景图片 当作精灵加载进来self.background_image = arcade.Sprite("../图片文件/世界卫星地图.png")# 设置精灵素材中心点的位置self.background_image.center_x = self.window.width // 3self.background_image.center_y = self.window.height // 2# 导弹发射车 在on_resize()里设置绘制位置self.dao_dan_che_image = arcade.Sprite("../图片文件/东风41.png")self.dao_dan_che_image.width = 70self.dao_dan_che_image.height = 70# 初始状态时创建自定义个气球(默认3个)self.creat_qi_qiu(init_qi_qiu_num)self.couser_pic = arcade.Sprite('../图片文件/瞄准.png', scale=0.2)# 括号里的这个参数必须写,他是一个时间间隔,代表上次调用 到本次调用之间的时间差 不严格等于我们设置的1秒def time_clock(self, delta_time):# print(delta_time)# 因为我们要更改TIME_CLOCK的值,所以使用global 让函数可以改变这个全局变量if self.info_panel.game_info["game_status"] and not self.info_panel.game_info["game_pause"]:self.info_panel.game_info["player_use_time"] += 1def creat_qi_qiu(self, num):"""创建气球"""for i in range(1, num+1):self.qi_qiu = QiQiu(filename=f"../图片文件/气球飞艇/{random.choice(self.all_qi_qiu)}",change_x=random.choice([0.5,0.5,1,2,2]), change_y=random.choice([1,2]),init_x=random.choice([-80, self.window.width + 200]),init_y=random.randint(200, self.window.height - num*50))self.qi_qiu.width = 60self.qi_qiu.height = 40# self.qi_qiu.scale = 0.5if self.qi_qiu.center_x > self.window.width//2:self.qi_qiu.change_x = -self.qi_qiu.change_xself.qi_qiu_list.append(self.qi_qiu)# 每次创建过气球后 都将统计到游戏信息面板中self.info_panel.game_info["all_qi_qiu_num"] += numdef creat_zhui_zong_dao_dan(self):# 追踪导弹  如果剩余的追踪弹数量大于0 就接受命令进行创建if self.info_panel.game_info["surplus_zhui_zong_dao_dan_num"] > 0:dao_dan = DaoDan("../图片文件/导弹.gif", change_x=4, change_y=3,init_x=self.window.width // 3, init_y=self.window.height // 2)self.dao_dan_list.append(dao_dan)dao_dan.fire_sound.play()self.info_panel.game_info["surplus_zhui_zong_dao_dan_num"] -= 1def creat_dan_dao_dao_dan(self,x,y):# 弹道导弹  如果剩余的弹道弹数量大于0 就接受命令进行创建if self.info_panel.game_info["surplus_dan_dao_dao_dan_num"] > 0:init_x = self.window.width // 3init_y = self.window.height // 2speed = 1 if abs(x - init_x) < 200 else 3# 如果目标点在右侧 则导弹向右飞行 横坐标变化为正数 否则为负数change_x = speed if x > self.window.width // 3 else - speeddan_dao_dao_dan = DanDaoDaoDan("../图片文件/弹道导弹.png", change_x=change_x, change_y=3,init_x=init_x, init_y=init_y,target_x=x, target_y=y)dan_dao_dao_dan.scale = 0.7self.dan_dao_dao_dan_list.append(dan_dao_dao_dan)dan_dao_dao_dan.fire_sound.play()# 创建完毕后 剩余弹道导弹数量 -1self.info_panel.game_info["surplus_dan_dao_dao_dan_num"] -= 1def creat_yan_wu(self,center_x, center_y):yan_wu = BaoZhaYanWu()yan_wu.center_x = center_xyan_wu.center_y = center_yself.explode_smoke_list.append(yan_wu)# 画面渲染绘制def on_draw(self):""" 负责渲染画面 速率: 60帧/秒. """# 清除上一帧绘制的画面self.clear()# 绘制背景图片self.background_image.draw()# 导弹发射车self.dao_dan_che_image.draw()# 绘制气球精灵组self.qi_qiu_list.draw()# 绘制导弹精灵组self.dao_dan_list.draw()# 绘制弹道导弹精灵组self.dan_dao_dao_dan_list.draw()# 绘制爆炸烟雾self.explode_smoke_list.draw()# 绘制游戏信息self.info_panel.draw_game_info(self.window.width, self.window.height)# 绘制鼠标self.couser_pic.draw()# 控制每次刷新时的变化def on_update(self, delta_time: float):""" 负责逻辑变化 速率: 60帧/秒. """if self.info_panel.check_game_status(self.current_play):# 如果检测游戏的状态为True 则继续刷新 否则不再执行后续逻辑for qi_qiu_id, qi_qiu in enumerate(self.qi_qiu_list):# 处理气球和自动追踪导弹的碰撞及逻辑qi_qiu.update(self.window.height)if qi_qiu_id <= len(self.dao_dan_list)-1:dao_dan = self.dao_dan_list[qi_qiu_id]dao_dan.track_target(qi_qiu.center_x, qi_qiu.center_y, change_angle=-0.5)# else:#     print("请尽快发射导弹")collision = arcade.check_for_collision_with_list(qi_qiu, self.dao_dan_list)if len(collision) > 0:print(f"发生碰撞了,相撞的{qi_qiu_id}号导弹和气球都被移除")# 移除碰到的气球qi_qiu.remove_from_sprite_lists()# 剩余气球数量 -1self.info_panel.game_info["surplus_qi_qiu_num"] -= 1# 玩家分数 +1self.info_panel.game_info["player_score"] += 1# 创建气球self.creat_qi_qiu(1)# 移除碰到的追踪导弹for collision_obj in collision:collision_obj.remove_from_sprite_lists()collision_obj.explode_sound.play()# 追踪导弹数量-1 因为在创建时候就减去了1 所以这里不再减# self.info_panel.game_info["surplus_zhui_zong_dao_dan_num"] -= 1# 创建烟雾 坐标为所碰撞气球的坐标self.creat_yan_wu(qi_qiu.center_x,qi_qiu.center_y)if qi_qiu.center_x not in range(-230, self.window.width+230):# 气球飞出屏幕一定距离后 则消失qi_qiu.remove_from_sprite_lists()# 剩余气球数量 -1self.info_panel.game_info["surplus_qi_qiu_num"] -= 1# 再次创建气球self.creat_qi_qiu(1)# 处理按下鼠标发射的弹道导弹for dan_dao_dao_dan in self.dan_dao_dao_dan_list:# 处理气球和弹道导弹的碰撞及逻辑dan_dao_dao_dan.track_target()collision2 = arcade.check_for_collision_with_list(dan_dao_dao_dan, self.qi_qiu_list)for collision_obj2 in collision2:collision_obj2.remove_from_sprite_lists()dan_dao_dao_dan.remove_from_sprite_lists()dan_dao_dao_dan.explode_sound.play()# 剩余气球数量 -1self.info_panel.game_info["surplus_qi_qiu_num"] -= 1# 玩家分数 +1self.info_panel.game_info["player_score"] += 1# 创建气球self.creat_qi_qiu(1)# 创建烟雾self.creat_yan_wu(collision_obj2.center_x, collision_obj2.center_y)# 如果导弹飞出了屏幕 则销毁if dan_dao_dao_dan.center_x not in range(-230, self.window.width+230):dan_dao_dao_dan.remove_from_sprite_lists()# 将原来创建气球的时机改为每当有一个气球消失 就创建一个 下面代码不再使用# if len(self.qi_qiu_list) <= 3:#     self.creat_qi_qiu(3)for smoke in self.explode_smoke_list:self.interval_time += delta_timeif self.interval_time > 0.08:res = smoke.update()self.interval_time = 0if res:smoke.remove_from_sprite_lists()def on_mouse_press(self, x, y, button, modifiers):""" 监听鼠标点击事件. """mouse_buttons = {1: "左键", 2: "中键", 4: "右键"}# print(f"当前点击的坐标是{x,y}")if self.info_panel.game_info["game_status"] and not self.info_panel.game_info["game_pause"]:# 创建弹道导弹self.creat_dan_dao_dao_dan(x,y)def on_mouse_release(self, x: float, y: float, button: int, modifiers: int):""" 监听鼠标释放事件. """passdef on_mouse_motion(self, x: float, y: float, dx: float, dy: float):""" 监听鼠标移动事件 """self.couser_pic.center_x = xself.couser_pic.center_y = ydef on_key_press(self,key, modifiers):"""监听键盘按键点击事件modifiers:None = 16,shift= 1(17) ctrl= 2(18) alt= 4(20) """print("---键盘按键按下了:--",key,"--修饰键编号的和是:---", modifiers)if key == arcade.key.SPACE and self.info_panel.game_info["game_status"] \and not self.info_panel.game_info["game_pause"]:self.creat_zhui_zong_dao_dan()if key == arcade.key.RSHIFT and not self.info_panel.game_info["game_status"]:# 让游戏重新开始  并且重置屏幕大小为上一次的大小self.set_up()self.on_resize(self.window.width,self.window.height)def on_key_release(self, key, modifiers):print("---键盘按键抬起了:--",key,"--剩余修饰键编号的和是:---", modifiers)print("---键盘按下之前:--",self.info_panel.game_info["game_pause"])if key == arcade.key.ENTER and self.info_panel.game_info["game_status"]:self.info_panel.game_info["game_pause"] = not self.info_panel.game_info["game_pause"]self.info_panel.game_info["game_pause_sound"].play()print("---键盘按下之后:--", self.info_panel.game_info["game_pause"])def on_resize(self, width: int, height: int):# 重新设置精灵素材中心点的位置self.background_image.center_x = self.window.width // 2self.background_image.center_y = self.window.height // 2# 重新设置精灵素材宽度和高度self.background_image.width = self.window.widthself.background_image.height = self.window.height# 设置导弹车精灵素材中心点的位置self.dao_dan_che_image.center_x = self.window.width // 3 - 30self.dao_dan_che_image.center_y = self.window.height // 2for jing_ling in (self.dan_dao_dao_dan_list,self.dao_dan_list,self.qi_qiu_list):# 界面在玩耍时侯如果缩放,会使导弹和气球位置发生相对于地图的偏移passdef main():# 设置窗体的宽、高、名字、是否支持缩放window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, resizable=True)# 设置窗体的 logo 图标import pygletwindow.set_icon(pyglet.image.load('../图片文件/浪淘三千.png'))# 设置鼠标形状cursor = window.get_system_mouse_cursor(window.CURSOR_HAND)window.set_mouse_cursor(cursor)# 实例化定义的某个窗体start_view = LiuLangQiQiu()# 设置当前应该显示哪个窗体window.show_view(start_view)# 保持程序持续运行arcade.run()if __name__ == "__main__":main()

相关文章:

【日常点滴019】Python制作流浪气球游戏(导弹射击类)

Python制作流浪气球游戏&#xff08;导弹射击类&#xff09;教学课程代码&#xff08;分步教学版&#xff09;1、构建全局通用代码结构2、构建气球精灵类3、构建导弹精灵类4、碰撞检测5、构建游戏信息类 &#xff08;最终完整代码&#xff09;教学课程代码&#xff08;分步教学…...

effective c++阅读之旅---条款29

为"异常安全"而努力是值得的&#xff01; 什么是异常安全&#xff1f; 所谓的"异常安全"&#xff0c;往往值得是函数接口的异常安全&#xff0c;它要求函数满足两个条件&#xff1a; 异常抛出时&#xff1a; 1、不泄露任何资源 2、不允许数据被破坏 异常安…...

Android system — 进程生命周期与ADJ

Android system — 进程oom_adj0. 引言1. 进程的生命周期1.1 Foreground process1.2 Visible process1.3 Service process1.4 Background process1.5 Empty process2. Lowmemorykiller2.1 ADJ级别2.2 进程state级别2.3 lmk策略2.4 如何查看应用oom_adj值3. 注意0. 引言 本文主要…...

vue3+ts+node个人博客系统(三)

一.主页顶部和中心面板布局 &#xff08;1&#xff09; 首先先去element-plus选择合适的布局el-container (2)在头部处编写相应的菜单栏el-menu,在这里要注意动态绑定路由的问题:default-active"$route.path"。将default-active设置为$route.path&#xff0c;el-me…...

Python第三方模块

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的绽放&#xff0…...

怎样查询PMP成绩?

【如何查询成绩】1、输入网址&#xff08;PMI官网&#xff0c;不知道网址的私戳&#xff09;&#xff0c;点击 Log In如果忘记 PMI 的账号和密码了&#xff0c;怎么办&#xff1f;可以在你报名机构官网的个人中心的学习中心的我的报名处查看 PMI 的注册名和密码2、点击 Exam An…...

说说变量 __name__ 和它可能取到的一个值 __main__

结合 例子 弄懂 变量__name__ 和它的值’ main’这两个东西。 首先&#xff0c;明白两个定义&#xff0c; __name__是一个变量&#xff0c; __main__是个普通字符串&#xff0c;不是变量&#xff0c;但可以作为变量的值。 例子&#xff1a; 1.py 代码如下&#xff1a; if _…...

软考高级-信息系统管理师之整体管理(最新版)

整体管理 1、项目整体管理概述2、制定项目章程(选择,案例,论文)制定项目章程过程制定项目章程的依据1、协议2.项目工作说明书:3、商业论证4、事业环境因素包括,但不限于如下事项。5、组织过程资产:项目选择方法项目启动会议项目目标引导技术3、制订项目管理计划(选择)项目管…...

JVM学习篇垃圾收集器ParNewCMS与底层三色标记算法详解

1. 垃圾收集算法 2. 分代收集理论 当前虚拟机的垃圾收集都采用分代收集算法&#xff0c;这种算法没有什么新的思想&#xff0c;只是根据对象存活周期的不同将内存分为几块。一般将java堆分为新生代和老年代&#xff0c;这样我们就可以根据各个年代的特点选择合适的垃圾收集算法…...

基于FFmpeg和Screen Capturer Recorder实现屏幕和声音的录制

当我们看到一些精彩的视频画面&#xff0c;但无法下载时&#xff0c;可以通过录屏的方式将视频和音频录制下来。 这个时候我们需要安装采集视频和音频的工具screen-capture-recorder。 以下是在windows10环境下&#xff0c;基于FFmpeg和Screen Capturer Recorder实现屏幕和声音…...

猿人学14题详解

目测重点在于cookie&#xff1a;mz和m 获取mz.js: https://match.yuanrenxue.com/static/match/match14/m.js 获取设置m&#xff1a; https://match.yuanrenxue.com/api/match/14/m 一、还原16进制 const fs require(fs); const parser require(babel/parser); const gen…...

Allegro如何快速把推挤的走线变平滑操作指导

Allegro如何快速把推挤的走线变平滑操作指导 Allegro有个非常强大的功能,推挤命令,可以快速的让走线以不报DRC的形式避让目标 推挤后的效果如下图 但是走线不够平滑,如果每一段都去再推一下比较费时间,下面介绍allegro本身自带的优化类似走线的功能 具体操作如下 点击Rout…...

nginx基础学习

作为前端开发者&#xff0c;也很有必要了解一些运维部署知识。 nginx的作用有哪些&#xff1f; 负载平衡动静分离反向代理 何为反向代理&#xff1f; 反向代理即是&#xff0c;用户访问nginx服务器&#xff0c;nginx又将请求转发到真正服务器上&#xff0c;为什么用户不能直…...

【HDFS】FsDatasetImpl#recoverClose方法

recoverClose的目的recoverClose的过程recoverClose的调用点一、前言 HDFS客户端写文件时,如果某个datanode发生错误或者异常。客户端会把这个datanode从pipeline里踢除,然后进行pipiline recovery,用剩余datanodes去写或者满足一定的条件时补充新的datanode到pipeline中写…...

加油站会员管理小程序实战开发教程15 完结篇

这篇是本次实战课程的最后一篇,我们在上篇还有两个问题没解决。一个是会员卡类型显示不对,一个是不同的会员卡我们希望背景色显示不同。我们先处理一下这两个问题 1 显示会员卡类型 在列表上直接显示会员卡类型,目前显示的是数字,这个是因为枚举类型导致的。枚举类型在数…...

学习 Python 之 Pygame 开发坦克大战(五)

学习 Python 之 Pygame 开发坦克大战&#xff08;五&#xff09;坦克大战完善地图1. 创建砖墙2. 给砖墙增加子弹击中的碰撞效果3. 给砖墙添加坦克不能通过的碰撞效果4. 添加石墙5. 添加玩家基地6. 最终效果坦克大战完善地图 我的素材放到了百度网盘里&#xff0c;里面还有原版…...

【ROS】Windows系统安装ROS体验

大家平时玩ROS都是在Ubuntu系统上&#xff0c;那Windows系统可以安装吗&#xff0c;答案是&#xff1a;可以的&#xff01;Windows为了发展自家的物联网生态&#xff0c;已经在Windows系统支持ROS了。 文章目录1.安装VS 20172.安装Chocolatey & Git3.安装ROS4.运行ROS例程1…...

第1讲-初步认识数据库系统(测试题总结)

一、测试题 数据库系统 包含 数据库管理系统 详细版&#xff1a; 数据库管理系统DBMS是数据管理软件&#xff0c;在用户和操作系统之间。 数据库系统DBS由数据库&#xff0c;数据库管理系统&#xff08;及其应用开发工具&#xff09;、应用程序和数据库管理员DBA组成的存储、管…...

进程-操作系统结构

进程-操作系统结构 中文仅本人理解&#xff0c;有错误请联系我。 操作系统为不同方面服务&#xff0c;有不同的设计角度。 为用户&#xff1a; 使用 为程序员&#xff1a;创造 程序员需要关注的就是system call接口的调度 file systems&#xff1a;ntfs&#xff0c;ext4 commu…...

【网络原理6】数据链路层协议——以太网

数据链路层负责的是相邻两个网络节点之间的数据以帧为单位进行传输。 具体关于数据链路层的介绍&#xff0c;已经在这一篇文章当中提到了。 初识网络&#xff1a;IP、端口、网络协议、TCP-IP五层模型_革凡成圣211的博客-CSDN博客TCP/IP五层协议详解https://blog.csdn.net/weix…...

组合数学原理与例题

目录 一、前言 二、计数原理 1、加法原理 2、分割立方体&#xff08;lanqiaoOJ题号1620&#xff09; 3、乘法原理 4、挑选子串&#xff08;lanqiaoOJ题号1621&#xff09; 5、糊涂人寄信&#xff08;lanqiaoOJ题号1622&#xff09; 6、战斗吧N皇后&#xff08;lanqiaoO…...

【机器学习 深度学习】通俗讲解集成学习算法

目录&#xff1a;集成学习一、机器学习中的集成学习1.1 定义1.2 分类器(Classifier)1.2.1 决策树分类器1.2.2 朴素贝叶斯分类器1.2.3 AdaBoost算法1.2.4 支持向量机1.2.5 K近邻算法1.3 集成学习方法1.3.1 自助聚合(Bagging)1.3.2 提升法(Boosting)1.3.2.1 自适应adaboost1.3.3 …...

汉字----dgfont

Abstract 字符生成是一个具有挑战性的问题,特别是对于一些由大量字符组成的书写系统,近年来受到了广泛的关注。然而,现有的字体生成方法通常是在监督学习中。它们需要大量的配对数据,这是劳动密集型和昂贵的收集。此外,常见的图像到图像转换模型通常将风格定义为纹理和颜…...

C# chart绘图 鼠标响应

1、图形自动滚动设置 chart1.ChartAreas[0].AxisX.Maximum 横坐标显示区域最大值 chart1.ChartAreas[0].AxisX.Minimum 横坐标显示区域最小值 显示宽度 chart1.ChartAreas[0].AxisX.Maximum - chart1.ChartAreas[0].AxisX.Minimum chart1.ChartAreas[0].AxisX.Maximum x_d…...

结构体与引用

1.结构体基本概念结构体属于用户自定义的数据类型&#xff0c;允许用户存储不同的数据类型2.结构体定义和使用语法: struct 结构体 { 结构体成员列表 };通过结构体创建变量的方式有三种:struct 结构体名 变量名struct 结构体名 变量名 { 成员1值&#xff0c;成员2值...}定义结构…...

13.罗马数字转整数

罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。字符 数值I 1V 5X 10L 50C 100D 500M 1000例如&#xff0c; 罗马数字 2 写做 II &#xff0c;即为两个并列的 1 。12 写做 XII &#xff0c;即为 X II 。 27 写做 XX…...

JVM垃圾回收机制

垃圾回收机制&#xff08;GC&#xff09; 内存管理 Java的内存管理很大程度指的就是对象的管理&#xff0c;其中包括对象空间的分配和释放。 对象空间的分配&#xff1a;使用new关键字创建对象即可 对象空间的释放&#xff1a;将对象赋值null即可。垃圾回收器将负责所有“不…...

Java File类、IO流、Properties属性类

文章目录一、补充二、File类File类的含义创建多级文件File类的常见方法三、IO流IO流分类输入输出流FileOutputStreamInputStreamInputStream与OutputStream的实例ReaderWriterFileReader和FileWriter的实例缓冲流转换流序列化与ObjectInputStream、ObjectOutputStream打印流Pro…...

MySQL备份恢复(十二)

文章目录1. MySQL数据损坏类型1.1 物理损坏1.2 逻辑损坏2. DBA运维人员备份/恢复职责2.1 设计备份/容灾策略2.1.1 备份策略2.1.2 容灾策略2.2 定期的备份/容灾检查2.3 定期的故障恢复演练2.4 数据损坏时的快速准确恢复2.5 数据迁移工作3. MySQL常用备份工具3.1 逻辑备份方式3.2…...

【Java|golang】1792. 最大平均通过率---封装最小堆

一所学校里有一些班级&#xff0c;每个班级里有一些学生&#xff0c;现在每个班都会进行一场期末考试。给你一个二维数组 classes &#xff0c;其中 classes[i] [passi, totali] &#xff0c;表示你提前知道了第 i 个班级总共有 totali 个学生&#xff0c;其中只有 passi 个学…...