首页 > 编程问答 >当有两个或更多实体时,精灵会闪烁

当有两个或更多实体时,精灵会闪烁

时间:2024-08-06 04:01:27浏览次数:12  
标签:python python-3.x pyglet python-3.12

我在实体类方面遇到问题。下面是实体类的脚本:

import uuid, pyglet, random

class overworld_0001():

    resources = {}

    def __init__(self, engine, position, type_p, gender, **kwargs):
        super(overworld_0001, self).__init__(**kwargs)
        self.engine = engine

        self.type_entity = "pk"
        self.id = uuid.uuid4()
        self.type_p = type_p
        self.gender = gender

        self.x = position[0]
        self.y = position[1]
        self.target_x = self.x
        self.target_y = self.y
        self.stat = "stand"
        self.direction = 3
        self.overworld = True

        self.speed = engine.dict_pokemon["0001"]["overworld"]["speed"]

        resource = engine.resouces["0001"]
        self.resources["overworld"] = {}
        if not type_p + "-" + gender in resource["overworld"]:
            typ = resource["overworld"][type_p]
        else:
            typ = resource["overworld"][type_p + "-" + gender]
        for stat in typ:
            self.resources["overworld"][stat] = {}
            for count in typ[stat]:
                sprite = pyglet.sprite.Sprite(img=typ[stat][count], x=self.x, y=self.y)
                sprite.target_x = self.target_x
                sprite.target_y = self.target_y
                self.resources["overworld"][stat][count] = sprite

        self.current_sprite = self.resources["overworld"][self.stat][self.direction]
        self.width = self.current_sprite.width
        self.height = self.current_sprite.height
        self.size = max(self.width, self.height)

    def update(self, dt):
        self.entity = self.engine.list_sprite_layers["3"]
        if self.overworld:
            self.update_overworld(dt)

    def is_tile_free(self, x, y):
        for entity in self.engine.list_sprite_layers["3"]:
            if entity.id != self.id:
                if (x < entity.x + entity.width and
                    x + self.width > entity.x and
                    y < entity.y + entity.height and
                    y + self.height > entity.y):
                    return False
        return True

    def update_overworld(self, dt):
        if self.stat == "stand":
            directions = {
                0: (0, self.size),
                1: (self.size, 0),
                2: (-self.size, 0),
                3: (0, -self.size)
            }
            possible_moves = []

            for direction, (dx, dy) in directions.items():
                new_x = self.x + dx
                new_y = self.y + dy
                if self.is_tile_free(new_x, new_y):
                    possible_moves.append((direction, new_x, new_y))

            if possible_moves:
                chosen_move = random.choice(possible_moves)
                self.direction, self.target_x, self.target_y = chosen_move
                self.stat = "run"
                self.current_sprite.x = self.x
                self.current_sprite.y = self.y
            else:
                self.stat = "stand"

        if self.stat == "run":
            if self.target_x != self.x:
                direction_x = (self.target_x - self.x) / abs(self.target_x - self.x)
                self.x += direction_x * self.speed * dt
                if abs(self.target_x - self.x) < self.speed * dt:
                    self.x = self.target_x

            if self.target_y != self.y:
                direction_y = (self.target_y - self.y) / abs(self.target_y - self.y)
                self.y += direction_y * self.speed * dt
                if abs(self.target_y - self.y) < self.speed * dt:
                    self.y = self.target_y

            if self.x == self.target_x and self.y == self.target_y:
                self.stat = "stand"
                self.current_sprite.x = self.x
                self.current_sprite.y = self.y

        #self.current_sprite = self.resources["overworld"][self.stat][self.direction]
        self.current_sprite.x = self.x
        self.current_sprite.y = self.y

    def on_draw(self):
        self.current_sprite.draw()

我知道规则要求放置一个带有错误的脚本以便重现它,我想这样做,但不幸的是我不知道错误是什么。
照原样,它可以工作并且没有问题: 图像

但是如果在 update_overworld 我插入 self.current_sprite = self.resources["overworld"][self.stat][self.direction] 这就是我得到的: 图像

现在,我不知道错误是什么,但我假设可能有两个,这是因为实体在单个时可以工作,但是当我创建两个或更多时,它开始执行您在图像中看到的操作(并且我创建的实体越多,或者在 init 中,当从加载的资源中获取纹理并将其转换为精灵时,不是创建单个精灵,而是每个实体共享该精灵,并且每个实体都会修改其他实体的精灵.

  1. 每个实体的update_overworld函数中,除了修改自身之外,还修改了其他实体。

  2. 我想到这两个假设,主要是因为如果实体是单一的,则不会出现问题。您有什么意见或帮助吗?我使用的是 Pyglet 2.0.16 和 Python 3.12

These two hypotheses come to me, mostly because if the entity is single, the problem does not occur. Do you have any opinions or help? What I am using is Pyglet 2.0.16 and Python 3.12


问题出在你如何创建和更新精灵。你只创建了一组精灵,然后在所有实体之间共享这些精灵。这就是为什么当有多个实体时,你会看到它们闪烁 - 它们都在争夺同一个精灵资源。

你需要为每个实体实例化自己的精灵集。试试这个修改过的代码:

import uuid, pyglet, random

class overworld_0001():

    def __init__(self, engine, position, type_p, gender, **kwargs):
        super(overworld_0001, self).__init__(**kwargs)
        self.engine = engine

        self.type_entity = "pk"
        self.id = uuid.uuid4()
        self.type_p = type_p
        self.gender = gender

        self.x = position[0]
        self.y = position[1]
        self.target_x = self.x
        self.target_y = self.y
        self.stat = "stand"
        self.direction = 3
        self.overworld = True

        self.speed = engine.dict_pokemon["0001"]["overworld"]["speed"]

        # 为每个实体实例化精灵
        self.resources = self.load_resources(engine)

        self.current_sprite = self.resources["overworld"][self.stat][self.direction]
        self.width = self.current_sprite.width
        self.height = self.current_sprite.height
        self.size = max(self.width, self.height)

    def load_resources(self, engine):
        resources = {"overworld": {}}
        resource = engine.resouces["0001"]
        if not self.type_p + "-" + self.gender in resource["overworld"]:
            typ = resource["overworld"][self.type_p]
        else:
            typ = resource["overworld"][self.type_p + "-" + self.gender]
        for stat in typ:
            resources["overworld"][stat] = {}
            for count in typ[stat]:
                sprite = pyglet.sprite.Sprite(img=typ[stat][count], x=self.x, y=self.y)
                sprite.target_x = self.target_x
                sprite.target_y = self.target_y
                resources["overworld"][stat][count] = sprite
        return resources

    # ... rest of your code ... 

更改:

  1. 从类级别删除 resources resources 现在是在 __init__ 中每个实例加载,而不是在类级别共享。
  2. 为每个实体创建 resources load_resources 函数现在是在每个实体的 __init__ 中调用,为该特定实体创建一组唯一的精灵。

此更改可确保每个实体都有自己的一组精灵,从而防止闪烁问题。

标签:python,python-3.x,pyglet,python-3.12
From: 78836238

相关文章

  • Python 中的克隆和明显的指针问题
    我在克隆列表时遇到了困难。我已经尝试了我所知道的一切,但我的代码似乎仍然将errGrid、slopes1、slopes2和lopes视为同一个对象。为什么?!errOrder=[[]foriinrange(6)]errMethod=[errOrder.copy()foriinrange(AM)]errGrid=[errMethod.copy()foriinrange(U......
  • 【香橙派系列教程】(七)香橙派下的Python3安装
    【七】香橙派下的Python3安装为接下来的Linux图像识别智能垃圾桶做准备。图像处理使用京东SDK只支持pyhton和Java接口,目的是引入C语言的Python调用,感受大厂做的算法bug此接口是人工智能接口,京东识别模型是通过训练后的模型,精准度取决于训练程度,人工智能范畴在常规嵌入式......
  • vnpy,一个不可思议的Python库!
    vn.py是一个开源的Python交易编程框架,旨在帮助程序员快速搭建属于自己的量化交易平台。该框架支持股票、期货、外汇等多种金融产品的交易,提供了从数据获取、策略开发到交易执行的全流程支持。如何安装vnpy首先,要使用vnpy,您需要通过Python的包管理工具pip来安装它。以下......
  • Python回溯算法
    回溯算法回溯算法是一种系统的搜索算法,用于解决诸如排列组合、子集生成、图的路径、棋盘问题等问题。其核心思想是通过递归尝试各种可能的解决方案,遇到不满足条件的解时则回退(回溯),继续尝试其他可能性,直到找到所有的解决方案或确认无解。主要步骤:选择路径:在当前步骤选择一个可......
  • [python]使用gunivorn部署fastapi服务
    前言Gunicorn是一种流行的WSGIHTTP服务器,常用于部署Django和Flask等PythonWeb框架程序。Gunicorn具有轻量级、高稳定性和高性能等特性,可以轻易提高PythonWSGIApp运行时的性能。基本原理Gunicorn采用了pre-fork模型,也就是一个工作进程和多个worker进程的工作模式。在这个模......
  • python十六进制编辑器
    源代码:importtkinterastkfromtkinterimportfiledialogimportstructimportbinasciiimportosclassHexEditor:def__init__(self,master):self.master=masterself.master.title("十六进制编辑器")self.master.configure(bg......
  • python项目学习 mediapipe手势识别 opencv可视化显示
    importcv2importmediapipeimportnumpydefget_angle(vector1,vector2):#角度计算angle=numpy.dot(vector1,vector2)/(numpy.sqrt(numpy.sum(vector1*vector1))*numpy.sqrt(numpy.sum(vector2*vector2)))#cos(angle)=向量的点乘/向量的模angle=nump......
  • 【优秀python大屏】基于python flask的广州历史天气数据应用与可视化大屏
    摘要气象数据分析在各行各业中扮演着重要的角色,尤其对于农业、航空、海洋、军事、资源环境等领域。在这些领域中,准确的气象数据可以对预测未来的自然环境变化和采取行动来减轻负面影响的决策起到至关重要的作用。本系统基于PythonFlask框架,通过对气象数据的分析和处理来提供......
  • Python-MNE全套教程(官网翻译)-入门01:概述篇
    目的以牺牲深度为代价进行入门学习,简易学习基本方法开始导入相关库:#License:BSD-3-Clause#CopyrighttheMNE-Pythoncontributors.importnumpyasnpimportmne加载数据MNE-Python数据结构式基于fif格式的,但是对于其他格式也有阅读方法,如https://mne.tools/s......
  • Python-MNE全套教程(官网翻译)-入门05:关于传感器位置
    本教程描述了如何读取和绘制传感器位置,以及MNE-Python如何处理传感器的物理位置。像往常一样,我们将从导入我们需要的模块开始:frompathlibimportPathimportmatplotlib.pyplotaspltimportnumpyasnpimportmne关于montage和layout(蒙太奇和传感器布局)montage......