小学生python游戏编程arcade----精灵调用图片的两种类
创始人
2024-02-23 15:37:00
0

小学生python游戏编程arcade----精灵调用图片的两种类

    • 前言
    • 精灵调用图片的两种类
      • 1、第一种类的定义
        • 1.1 以文件名及缩放比例做初始参数
        • 1.2 利用变换图片的颜色更换角色的使用
        • 1.3 代码分析
  • 转换文件来不及调用,时间问题??????
      • 2、第二种方法,通过sprite的texture直接赋值
        • 2.1精灵的两种加载图片方式
        • 2.2 两种方式,上述类是一种以文件形赋值的 # 添加角色.
        • 2.3 修改类
        • 2.4 调用第二种类的代码实现
    • 源码获取

前言

接上篇文章继续解绍arcade游戏编程的基本知识。精灵调用图片纹理的两种类的实现,一种直接引用图片文件,一种利用arcade.load_texture的过度,直接给精灵赋值。如上次写的,游戏升级时,通过程序换精灵的颜色,用后种方法定义的类较好。

精灵调用图片的两种类

1、第一种类的定义

1.1 以文件名及缩放比例做初始参数

class Enemy_tank(arcade.Sprite):def __init__(self, filename, scale, x, y, speed_to_player=0.2):super().__init__(filename, scale)self.center_x = xself.center_y = yself.word = 'book'self.hz = '书'self.life = 1  # 生命条数,即挨几颗子弹消失self.speed_to_player = speed_to_player  # 面向角色移动的速度def draw_word(self, x, y, fcolor=arcade.csscolor.WHITE_SMOKE, fsize=18, text=None):xs=fsizeif text:arcade.draw_rectangle_filled(x+len(self.word)*xs//2-10,y+5,len(text)*xs,30,(128,138,135))arcade.draw_text(text, x, y, fcolor, fsize)else:arcade.draw_rectangle_filled(x+len(self.word)*xs//2-10,y+5,len(self.word)*xs, 30,(128,138,135))arcade.draw_text(self.word, x, y, fcolor, fsize)def update(self):super().update()if self.speed_to_player:# 敌人向角色移动变量self.change_x = math.cos(self.angle) * 0.2self.change_y = math.sin(self.angle) * 0.2

1.2 利用变换图片的颜色更换角色的使用

    def setup_enemy(self):# passself.scene.add_sprite_list_after(LAYER_tanks, 'wj')if len(self.word_keys) == 0:if self.danyuan==len(self.gk[self.year]):self.level += 1self.year =self.years[self.level]else:self.danyuan += 1self.setup_word(self.danyuan, self.year)if len(self.word_keys) > 0:self.key = self.word_dict[self.word_keys[0]]  # 朋友# print('key',self.key)xsword = {}xsword[self.word_keys[0]] = self.word_dict[self.word_keys[0]]# 随机取3sankey = random.sample(self.word_dict.keys(), 3)if self.word_keys[0] in sankey:sankey.remove(self.word_keys[0])# 增加两个敌人xsword[sankey[0]] = self.word_dict[sankey[0]]xsword[sankey[1]] = self.word_dict[sankey[1]]# 增加随机坦克posx=[]random_x= random.random()*SCREEN_width/3for jj in range(3):tempx=random_x+400*jjif tempx>self.end_of_map:tempx=random.random()*SCREEN_width/2posx.append(tempx)random_y = random.random() * self.top_of_map / 3random.shuffle(posx)  # 打乱顺序# print(posx)j=0# 转换文件来不及调用,时间问题??????tempcolorh = random.random()# print('color',tempcolorh)tempic = change_color_tmpic(Image.open("images/坦克2.png"), tempcolorh)tempfile = 'images/temp'+str(tempcolorh)+'.png'tempic.save(tempfile)for x in xsword:tank = Enemy_tank(tempfile, 0.5, posx[j], random_y)tank.word = xtank.hz = xsword[x]self.scene.add_sprite(LAYER_tanks, tank)j +=1if (os.path.exists(tempfile)):# 存在,则删除文件os.remove(tempfile)# 去掉已显示单词self.word_keys.remove(self.word_keys[0])# 增加子弹层self.scene.add_sprite_list_after(LAYER_bullet, 'wj')# 增加爆炸粒子列表self.scene.add_sprite_list_after(LAYER_explosions, 'wj')

1.3 代码分析

转换文件来不及调用,时间问题??????

        tempcolorh = random.random()# print('color',tempcolorh)tempic = change_color_tmpic(Image.open("images/坦克2.png"), tempcolorh)tempfile = 'images/temp'+str(tempcolorh)+'.png'tempic.save(tempfile)for x in xsword:tank = Enemy_tank(tempfile, 0.5, posx[j], random_y)tank.word = xtank.hz = xsword[x]self.scene.add_sprite(LAYER_tanks, tank)j +=1if (os.path.exists(tempfile)):# 存在,则删除文件os.remove(tempfile)# 去掉已显示单词self.word_keys.remove(self.word_keys[0])此用需要借助临时文件,再生成精灵,中间还遇到个问题,使用tempfile做为过度赋值,结果游戏敌人坦克不变色,最后通过每次生成文件名不同,可以实现效果。

2、第二种方法,通过sprite的texture直接赋值

2.1精灵的两种加载图片方式

通过查看sprite的类的定义原码,如下

class Sprite:"""Class that represents a 'sprite' on-screen. Most games center around sprites.For examples on how to use this class, see:https://api.arcade.academy/en/latest/examples/index.html#sprites:param str filename: Filename of an image that represents the sprite.:param float scale: Scale the image up or down. Scale of 1.0 is none.:param float image_x: X offset to sprite within sprite sheet.:param float image_y: Y offset to sprite within sprite sheet.:param float image_width: Width of the sprite:param float image_height: Height of the sprite:param float center_x: Location of the sprite:param float center_y: Location of the sprite:param bool flipped_horizontally: Mirror the sprite image. Flip left/right across vertical axis.:param bool flipped_vertically: Flip the image up/down across the horizontal axis.:param bool flipped_diagonally: Transpose the image, flip it across the diagonal.:param str hit_box_algorithm: One of None, 'None', 'Simple' or 'Detailed'.Defaults to 'Simple'. Use 'Simple' for the :data:`PhysicsEngineSimple`,:data:`PhysicsEnginePlatformer`and 'Detailed' for the :data:`PymunkPhysicsEngine`.:param Texture texture: Specify the texture directly. 直接指定纹理:param float angle: The initial rotation of the sprite in degreesThis will ignore all hit box and image size arguments... figure:: ../images/hit_box_algorithm_none.png:width: 40%hit_box_algorithm = "None".. figure:: ../images/hit_box_algorithm_simple.png:width: 55%hit_box_algorithm = "Simple".. figure:: ../images/hit_box_algorithm_detailed.png:width: 75%hit_box_algorithm = "Detailed":param float hit_box_detail: Float, defaults to 4.5. Used with 'Detailed' to hit boxAttributes::alpha: Transparency of sprite. 0 is invisible, 255 is opaque.:angle: Rotation angle in degrees. Sprites rotate counter-clock-wise.:radians: Rotation angle in radians. Sprites rotate counter-clock-wise.:bottom: Set/query the sprite location by using the bottom coordinate. \This will be the 'y' of the bottom of the sprite.:boundary_left: Used in movement. Left boundary of moving sprite.:boundary_right: Used in movement. Right boundary of moving sprite.:boundary_top: Used in movement. Top boundary of moving sprite.:boundary_bottom: Used in movement. Bottom boundary of moving sprite.:center_x: X location of the center of the sprite:center_y: Y location of the center of the sprite:change_x: Movement vector, in the x direction.:change_y: Movement vector, in the y direction.:change_angle: Change in rotation.:color: Color tint the sprite:collision_radius: Used as a fast-check to see if this item is close \enough to another item. If this check works, we do a slower more accurate check. \You probably don't want to use this field. Instead, set points in the \hit box.:cur_texture_index: Index of current texture being used.:guid: Unique identifier for the sprite. Useful when debugging.:height: Height of the sprite.:force: Force being applied to the sprite. Useful when used with Pymunk \for physics.:hit_box: Points, in relation to the center of the sprite, that are used \for collision detection. Arcade defaults to creating a hit box via the \'simple' hit box algorithm \that encompass the image. If you are creating a ramp or making better \hit-boxes, you can custom-set these.:left: Set/query the sprite location by using the left coordinate. This \will be the 'x' of the left of the sprite.:position: A list with the (x, y) of where the sprite is.:right: Set/query the sprite location by using the right coordinate. \This will be the 'y=x' of the right of the sprite.:sprite_lists: List of all the sprite lists this sprite is part of.:texture: :class:`arcade.Texture` class with the current texture. Setting a new texture does \**not** update the hit box of the sprite. This can be done with \``my_sprite.hit_box = my_sprite.texture.hit_box_points``. New textures will be centered \on the current center_x/center_y.:textures: List of textures associated with this sprite.:top: Set/query the sprite location by using the top coordinate. This \will be the 'y' of the top of the sprite.:scale: Scale the image up or down. Scale of 1.0 is original size, 0.5 \is 1/2 height and width.:velocity: Change in x, y expressed as a list. (0, 0) would be not moving.:width: Width of the spriteIt is common to over-ride the `update` method and provide mechanics onmovement or other sprite updates."""def __init__(self,filename: str = None,scale: float = 1,image_x: float = 0,image_y: float = 0,image_width: float = 0,image_height: float = 0,center_x: float = 0,center_y: float = 0,repeat_count_x: int = 1,  # Unusedrepeat_count_y: int = 1,  # Unusedflipped_horizontally: bool = False,flipped_vertically: bool = False,flipped_diagonally: bool = False,hit_box_algorithm: Optional[str] = "Simple",hit_box_detail: float = 4.5,texture: Texture = None,angle: float = 0,):""" Constructor """# Position, size and orientation propertiesself._width: float = 0.0self._height: float = 0.0self._scale: float = scaleself._position: Point = (center_x, center_y)self._angle = angleself.velocity = [0.0, 0.0]self.change_angle: float = 0.0# Hit box and collision propertyself._points: Optional[PointList] = Noneself._point_list_cache: Optional[PointList] = Noneself._hit_box_shape: Optional[ShapeElementList] = Noneself._hit_box_algorithm = hit_box_algorithmself._hit_box_detail = hit_box_detailself._collision_radius: Optional[float] = None# Colorself._color: RGB = (255, 255, 255)self._alpha: int = 255# Custom sprite propertiesself._properties: Optional[Dict[str, Any]] = None# Boundaries for moving platforms in tilemapsself.boundary_left: Optional[float] = Noneself.boundary_right: Optional[float] = Noneself.boundary_top: Optional[float] = Noneself.boundary_bottom: Optional[float] = None# Texture propertiesself._texture: Optional[Texture] = Noneself.textures: List[Texture] = []self.cur_texture_index: int = 0self.sprite_lists: List["SpriteList"] = []self.physics_engines: List[Any] = []self._sprite_list: Optional["SpriteList"] = None  # Used for Sprite.draw()# Pymunk specific propertiesself._pymunk: Optional[PyMunk] = Noneself.force = [0, 0]# Debug propertiesself.guid: Optional[str] = None# Sanity check valuesif image_width < 0:raise ValueError("Width of image can't be less than zero.")if image_height < 0:raise ValueError("Height entered is less than zero. Height must be a positive float.")if image_width == 0 and image_height != 0:raise ValueError("Width can't be zero.")if image_height == 0 and image_width != 0:raise ValueError("Height can't be zero.")if hit_box_algorithm not in ["Simple", "Detailed", "None", None]:raise ValueError("hit_box_algorithm must be 'Simple', 'Detailed', 'None' or None")if texture:self._texture = textureself._textures = [texture]self._width = self._texture.width * scaleself._height = self._texture.height * scaleelif filename is not None:self._texture = load_texture(filename,image_x,image_y,image_width,image_height,flipped_horizontally=flipped_horizontally,flipped_vertically=flipped_vertically,flipped_diagonally=flipped_diagonally,hit_box_algorithm=hit_box_algorithm,hit_box_detail=hit_box_detail,)self.textures = [self._texture]# Ignore the texture's scale and use oursself._width = self._texture.width * scaleself._height = self._texture.height * scaleif self._texture and not self._points:self._points = self._texture.hit_box_points

2.2 两种方式,上述类是一种以文件形赋值的 # 添加角色.

一以文件引用
image_source = “images/bird.png”
self.player_sprite = arcade.Sprite(image_source, CHARACTER_SCALING)
self.player_sprite.center_x = 64
self.player_sprite.center_y = 128
self.player_list.append(self.player_sprite)
二 以texture引用
# 添加角色.
# image_source = “images/bird.png”
texture = arcade.load_texture(f"images/bird.png")
# self.player_sprite = arcade.Sprite(image_source, CHARACTER_SCALING)
self.player_sprite = arcade.Sprite(texture=texture, scale=CHARACTER_SCALING)
self.player_sprite.center_x = 64
self.player_sprite.center_y = 128
self.player_list.append(self.player_sprite)

2.3 修改类

# 不调用文件,直接给texture给值
class Enemy_tank_pic(arcade.Sprite):def __init__(self, texture, scale, x, y, speed_to_player=0.2):super().__init__(texture=texture, scale=scale)self.center_x = xself.center_y = yself.word = 'book'self.hz = '书'self.life = 1  # 生命条数,即挨几颗子弹消失self.speed_to_player = speed_to_player  # 面向角色移动的速度def draw_word(self, x, y, fcolor=arcade.csscolor.WHITE_SMOKE, fsize=18, text=None):xs=fsizeif text:arcade.draw_rectangle_filled(x+len(self.word)*xs//2-10,y+5,len(text)*xs,30,(128,138,135))arcade.draw_text(text, x, y, fcolor, fsize)else:arcade.draw_rectangle_filled(x+len(self.word)*xs//2-10,y+5,len(self.word)*xs, 30,(128,138,135))arcade.draw_text(self.word, x, y, fcolor, fsize)def update(self):super().update()if self.speed_to_player:# 敌人向角色移动变量self.change_x = math.cos(self.angle) * 0.2self.change_y = math.sin(self.angle) * 0.2

2.4 调用第二种类的代码实现

在这里插入图片描述

            # 转换文件来不及调用,时间问题??????tempcolorh = random.random()tempic = change_color_tmpic(Image.open("images/坦克2.png"), tempcolorh)tempfile = 'images/temp.png'tempic.save(tempfile)texture = arcade.load_texture(tempfile)for x in xsword:tank = Enemy_tank_pic(texture, 0.5, posx[j], random_y)tank.word = xtank.hz = xsword[x]self.scene.add_sprite(LAYER_tanks, tank)j +=1# 去掉已显示单词self.word_keys.remove(self.word_keys[0])

问题一样存在
调整如下

            # 转换文件来不及调用,时间问题??????tempcolorh = random.random()tempic = change_color_tmpic(Image.open("images/坦克2.png"), tempcolorh)# tempfile = 'images/temp.png'# tempic.save(tempfile)# texture = arcade.load_texture(tempfile)for x in xsword:tank = Enemy_tank_pic(tempic, 0.5, posx[j], random_y)tank.word = xtank.hz = xsword[x]self.scene.add_sprite(LAYER_tanks, tank)j +=1# 去掉已显示单词self.word_keys.remove(self.word_keys[0])

出现问题:

  File "E:\pgame\arcadegame\tank.py", line 135, in __init__super().__init__(texture=texture, scale=scale)File "E:\pgame\venv\lib\site-packages\arcade\sprite.py", line 274, in __init__self._points = self._texture.hit_box_pointsFile "E:\pgame\venv\lib\site-packages\PIL\Image.py", line 548, in __getattr__raise AttributeError(name)
AttributeError: hit_box_points

源码获取

关注博主后,私聊博主免费获取
需要技术指导,育娃新思考,企业软件合作等更多服务请联系博主

今天是以此模板持续更新此育儿专栏的第35/50次。
可以关注我,点赞我、评论我、收藏我啦。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...