鱼C论坛

 找回密码
 立即注册
查看: 1576|回复: 24

[已解决]PyGame 问题

[复制链接]
发表于 2023-7-21 18:07:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 歌者文明清理员 于 2023-7-21 18:12 编辑

这个问题gpt不能解答,我也问过他了

代码:gpthelxdo ow9 9oxuwoe uo uexoiw1oi2 1hwyx9iyiu3w xy iu3wynxeiuwy uianlisxh wqooxdgnekuxgi832qk gpt垃圾
import pygame
pygame.init()

########## 可更改:引力的大小 ##########
引力常数 = 30

class 天体:
    def __init__(self, 名称, x, y, x速度, y速度, 质量):
        self.名称 = 名称
        self.x = x
        self.y = y
        self.x速度 = x速度
        self.y速度 = y速度
        self.质量 = 质量

    @property
    def 基本信息(self):
        return self.x, self.y, self.x速度, self.y速度, self.质量

class 天体动画精灵(pygame.sprite.Sprite):
    def __init__(self, 天体, 半径, 颜色):
        pygame.sprite.Sprite.__init__(self)
        self.天体 = 天体
        self.image = pygame.Surface((半径 * 2, 半径 * 2)).convert_alpha()
        self.image.fill((0, 0, 0, 0))
        pygame.draw.circle(self.image, 颜色, (半径, 半径), 半径, 0)
        self.rect = self.image.get_rect()
        self.刷新rect属性()

    def 刷新rect属性(self):
        self.rect.centerx = self.天体.x
        self.rect.centery = self.天体.y

def 移动全部天体(时间):
    要删除的天体 = []
    for 天体精灵1 in 天体动画精灵列表:
        天体1 = 天体精灵1.天体
        if 天体1 in 要删除的天体:
            continue
        x1, y1, x速度1, y速度1, 质量1 = 天体1.基本信息
        x加速度1, y加速度1 = 0, 0
        for 天体精灵2 in 天体动画精灵列表:
            天体2 = 天体精灵2.天体
            if 天体2 in 要删除的天体:
                continue
            if 天体1 == 天体2:
                continue
            x2, y2, x速度2, y速度2, 质量2 = 天体2.基本信息
            x距离 = x2 - x1
            y距离 = y2 - y1
            距离 = (x距离 ** 2 + y距离 ** 2) ** 0.5
            if 距离 < 50:
                # 太近了
                if 天体1.质量 > 天体2.质量:
                    要删除的天体.append(天体2)
                else:
                    要删除的天体.append(天体1)
                continue
            力 = 引力常数 * 质量1 * 质量2 / (距离 ** 2)
            加速度 = 力 / 质量1
            x加速度1 += 加速度 * (x距离 / 距离)
            y加速度1 += 加速度 * (y距离 / 距离)
        x, y = (
            x1 + x速度1 * 时间 + 0.5 * x加速度1 * (时间 ** 2),
            y1 + y速度1 * 时间 + 0.5 * y加速度1 * (时间 ** 2)
        )
        天体1.x = x
        天体1.y = y
        天体精灵1.刷新rect属性()
    for 动画精灵 in 天体动画精灵列表:
        if 动画精灵.天体 in 要删除的天体:
            天体动画精灵列表.remove(动画精灵)

screen = pygame.display.set_mode((1000, 1000))

天体动画精灵列表 = [
    天体动画精灵(天体("planet1", 500, 100, 1, 0, 1e4), 50, "orange"),
    天体动画精灵(天体("planet2", 500, 900, -1, 0, 1e4), 50, "blue")
]

clock = pygame.time.Clock()
running = True
while running:
    screen.fill((0, 0, 0))
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    ########## 可更改:天体移动速度 ##########
    移动全部天体(2)
    for 天体动画精灵 in 天体动画精灵列表:
        screen.blit(天体动画精灵.image, 天体动画精灵.rect)
    pygame.display.flip()
fandui ndoinuoixnuxoiu2n09 u0219enx790nn 291n x0neh icxbueo2un09xmsdix- openai的垃圾请不要回复
第五行的引力常数改大就碰撞,改小就往两边走

2023-07-21-18-06-31.gif
最佳答案
2023-7-22 14:34:43
你的代码可能有这样的bug:
你在定义了天体之后从来没有改变过它的“x速度”和“y速度”(分别是(1,0)与(-1,0)),导致在运行的过程中它就好像被无形的力拉走了,而你所说将引力参数调大就“正常”,无非是因为两个天体之间的引力超过了这个无形的力,让这两个星球还是渐渐靠近的。你需要在运行过程中实时改变天体“x速度”与“y速度”的值,而不是将它们视作常量。你可以在你发送的代码第40行与第41行之间插入这样的代码以更加明显地观察到这个问题:
print(x速度1, y速度1)
在打印的数据中,你会经常看见“1 0”与“-1 0”两个数,这就是bug所在。
希望对你有帮助。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-7-21 18:08:06 | 显示全部楼层
代码中有一个问题,引力常数的赋值没有找到。你可以在代码中添加以下行来给引力常数赋值:
引力常数 = 30
这样,你就可以根据需要修改引力常数的大小,控制天体之间的吸引力大小。如果你想要碰撞效果,可以逐渐增大引力常数的值;如果你想让天体向两边移动,可以逐渐减小引力常数的值。记得在代码中的合适位置调用移动全部天体()函数来更新天体的位置。希望这能帮到你!

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-21 18:08:26 | 显示全部楼层
你的问题似乎是关于如何调整两个天体之间的引力常数以控制它们的运动。根据你的描述,当你增大引力常数时,天体会碰撞;而当你减小引力常数时,天体会分开。

这是因为你的模拟程序遵循牛顿的万有引力定律,该定律说明了两个物体之间的引力是与它们的质量成正比、距离的平方成反比的。在你的代码中,这个定律被定义在“移动全部天体”函数中的“力 = 引力常数 * 质量1 * 质量2 / (距离 ** 2)”这一行。

如果你增大引力常数,那么在给定质量和距离的情况下,天体之间的引力就会增大,导致它们更容易碰撞。相反,如果你减小引力常数,天体之间的引力就会减小,它们就会更倾向于分开。

要使天体保持适当的距离并且不碰撞也不分开,你可能需要根据天体的质量和初始速度精细调整引力常数。对于这个问题,没有固定的解决方案,因为正确的引力常数取决于你的具体需求,包括天体的质量、初始速度和期望的行为等。

如果你希望两个天体彼此环绕,你可能需要调整它们的初始速度使它们在没有外力作用的情况下可以维持一个稳定的轨道,或者可以尝试实现一个更复杂的物理模型,例如考虑空气阻力或者其他形式的阻尼。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-21 18:08:56 | 显示全部楼层
isdkz 发表于 2023-7-21 18:08
你的问题似乎是关于如何调整两个天体之间的引力常数以控制它们的运动。根据你的描述,当你增大引力常数时, ...

《阻尼》
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-21 18:09:30 | 显示全部楼层
陶远航 发表于 2023-7-21 18:08
根据你提供的代码,我看到你正在使用Pygame模块创建一个天体运动的动画。问题是,在第五行的代码中,存在乱 ...

所以呢?解决方案呢?
就只知道求最佳答案是吧?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-21 18:10:42 | 显示全部楼层
歌者文明清理员 发表于 2023-7-21 18:09
所以呢?解决方案呢?
就只知道求最佳答案是吧?

对的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-21 18:22:28 | 显示全部楼层
我最近也想写三体运行轨迹
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-21 18:26:43 | 显示全部楼层
歌者文明清理员 发表于 2023-7-21 18:09
所以呢?解决方案呢?
就只知道求最佳答案是吧?

看陶远航的回答我有好几次笑出了猪叫

不是针对,是真的值得一乐
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-21 18:50:22 | 显示全部楼层
isdkz 发表于 2023-7-21 18:26
看陶远航的回答我有好几次笑出了猪叫

不是针对,是真的值得一乐

如果你想让两个天体保持一个稳定的轨道,你可以尝试调整它们的初始位置和速度,让它们的动能和引力势能达到平衡。
你可以参考一些轨道力学的知识,它是研究火箭和其他航天器在引力作用下的运动的学科。你可以用牛顿运动定律万有引力定律来计算两个天体之间的受力和加速度,然后用开普勒第三定律来求出它们的轨道周期。 你还可以用能量守恒定律角动量守恒定律来简化计算。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-21 19:08:43 | 显示全部楼层
这个问题需要比较高深的数学知识,或许可以通过二分查找算法求出引力常数合适的近似值。
比如设查找的范围为1-100,将引力常数赋值为50,判断两星是否相撞。然后将查找范围再缩小一半。最终求出一个让两颗星在较长时间内既不相撞也不往两边走的值。
你也可以询问身边的物理数学老师或通过自己计算求解。如果回答帮助不大,还请各位大神原谅
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-21 19:16:20 | 显示全部楼层
我尝试输入一个小数,最后你的两个星球几乎停止了,一定是你的算法少算或者多算了什么
import pygame
pygame.init()

########## 可更改:引力的大小 ##########
引力常数 = 30

class 天体:
    def __init__(self, 名称, x, y, x速度, y速度, 质量):
        self.名称 = 名称
        self.x = x
        self.y = y
        self.x速度 = x速度
        self.y速度 = y速度
        self.质量 = 质量

    @property
    def 基本信息(self):
        return self.x, self.y, self.x速度, self.y速度, self.质量

class 天体动画精灵(pygame.sprite.Sprite):
    def __init__(self, 天体, 半径, 颜色):
        pygame.sprite.Sprite.__init__(self)
        self.天体 = 天体
        self.image = pygame.Surface((半径 * 2, 半径 * 2)).convert_alpha()
        self.image.fill((0, 0, 0, 0))
        pygame.draw.circle(self.image, 颜色, (半径, 半径), 半径, 0)
        self.rect = self.image.get_rect()
        self.刷新rect属性()

    def 刷新rect属性(self):
        self.rect.centerx = self.天体.x
        self.rect.centery = self.天体.y

def 移动全部天体(时间):
    要删除的天体 = []
    时间2 = 0
    if type(时间) == float:
        时间2 += 时间 - int(时间)
    时间 = int(时间)
    if 时间2 > 1:
        时间2-=1
    for 天体精灵1 in 天体动画精灵列表:
        天体1 = 天体精灵1.天体
        if 天体1 in 要删除的天体:
            continue
        x1, y1, x速度1, y速度1, 质量1 = 天体1.基本信息
        x加速度1, y加速度1 = 0, 0
        for 天体精灵2 in 天体动画精灵列表:
            天体2 = 天体精灵2.天体
            if 天体2 in 要删除的天体:
                continue
            if 天体1 == 天体2:
                continue
            x2, y2, x速度2, y速度2, 质量2 = 天体2.基本信息
            x距离 = x2 - x1
            y距离 = y2 - y1
            距离 = (x距离 ** 2 + y距离 ** 2) ** 0.5
            if 距离 < 50:
                # 太近了
                if 天体1.质量 > 天体2.质量:
                    要删除的天体.append(天体2)
                else:
                    要删除的天体.append(天体1)
                continue
            力 = 引力常数 * 质量1 * 质量2 / (距离 ** 2)
            加速度 = 力 / 质量1
            x加速度1 += 加速度 * (x距离 / 距离)
            y加速度1 += 加速度 * (y距离 / 距离)
        x, y = (
            x1 + x速度1 * (时间+时间2) + 0.5 * x加速度1 * ((时间+时间2) ** 2),
            y1 + y速度1 * (时间+时间2) + 0.5 * y加速度1 * ((时间+时间2) ** 2)
        )
        天体1.x = x
        天体1.y = y
        天体精灵1.刷新rect属性()
    for 动画精灵 in 天体动画精灵列表:
        if 动画精灵.天体 in 要删除的天体:
            天体动画精灵列表.remove(动画精灵)

screen = pygame.display.set_mode((1000, 1000))

天体动画精灵列表 = [
    天体动画精灵(天体("planet1", 500, 100, 1, 0, 1e4), 50, "orange"),
    天体动画精灵(天体("planet2", 500, 900, -1, 0, 1e4), 50, "blue")
]

clock = pygame.time.Clock()
running = True
while running:
    screen.fill((0, 0, 0))
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    ########## 可更改:天体移动速度 ##########
    移动全部天体(2.1357917)
    for 天体动画精灵 in 天体动画精灵列表:
        screen.blit(天体动画精灵.image, 天体动画精灵.rect)
    pygame.display.flip()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-21 19:21:12 | 显示全部楼层
或许是你没有计算惯性?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-21 19:24:00 | 显示全部楼层
cjjJasonchen 发表于 2023-7-21 19:21
或许是你没有计算惯性?

不懂这个,网上捡来的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-22 14:34:43 | 显示全部楼层    本楼为最佳答案   
你的代码可能有这样的bug:
你在定义了天体之后从来没有改变过它的“x速度”和“y速度”(分别是(1,0)与(-1,0)),导致在运行的过程中它就好像被无形的力拉走了,而你所说将引力参数调大就“正常”,无非是因为两个天体之间的引力超过了这个无形的力,让这两个星球还是渐渐靠近的。你需要在运行过程中实时改变天体“x速度”与“y速度”的值,而不是将它们视作常量。你可以在你发送的代码第40行与第41行之间插入这样的代码以更加明显地观察到这个问题:
print(x速度1, y速度1)
在打印的数据中,你会经常看见“1 0”与“-1 0”两个数,这就是bug所在。
希望对你有帮助。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-22 14:45:17 | 显示全部楼层
hellomyprogram 发表于 2023-7-22 14:34
你的代码可能有这样的bug:
你在定义了天体之后从来没有改变过它的“x速度”和“y速度”(分别是(1,0)与(- ...

感谢回答,代码修改如下:
import pygame
pygame.init()

########## 可更改:引力的大小 ##########
引力常数 = 6

class 天体:
    def __init__(self, 名称, x, y, x速度, y速度, 质量):
        self.名称 = 名称
        self.x = x
        self.y = y
        self.x速度 = x速度
        self.y速度 = y速度
        self.质量 = 质量

    @property
    def 基本信息(self):
        return self.x, self.y, self.x速度, self.y速度, self.质量

class 天体动画精灵(pygame.sprite.Sprite):
    def __init__(self, 天体, 半径, 颜色):
        pygame.sprite.Sprite.__init__(self)
        self.天体 = 天体
        self.image = pygame.Surface((半径 * 2, 半径 * 2)).convert_alpha()
        self.image.fill((0, 0, 0, 0))
        pygame.draw.circle(self.image, 颜色, (半径, 半径), 半径, 0)
        self.rect = self.image.get_rect()
        self.刷新rect属性()

    def 刷新rect属性(self):
        print(self.天体.x, self.天体.y)
        self.rect.centerx = self.天体.x
        self.rect.centery = self.天体.y

def 移动全部天体(时间):
    要删除的天体 = []
    for 天体精灵1 in 天体动画精灵列表:
        天体1 = 天体精灵1.天体
        if 天体1 in 要删除的天体:
            continue
        x1, y1, x速度1, y速度1, 质量1 = 天体1.基本信息
        x加速度1, y加速度1 = 0, 0
        for 天体精灵2 in 天体动画精灵列表:
            天体2 = 天体精灵2.天体
            if 天体2 in 要删除的天体:
                continue
            if 天体1 == 天体2:
                continue
            x2, y2, x速度2, y速度2, 质量2 = 天体2.基本信息
            x距离 = x2 - x1
            y距离 = y2 - y1
            距离 = (x距离 ** 2 + y距离 ** 2) ** 0.5
            if 距离 < 50:
                # 太近了
                if 天体1.质量 > 天体2.质量:
                    要删除的天体.append(天体2)
                else:
                    要删除的天体.append(天体1)
                continue
            力 = 引力常数 * 质量1 * 质量2 / (距离 ** 2)
            加速度 = 力 / 质量1
            x加速度1 += 加速度 * (x距离 / 距离)
            y加速度1 += 加速度 * (y距离 / 距离)
        x, y = (
            x1 + x速度1 * 时间 + 0.5 * x加速度1 * (时间 ** 2),
            y1 + y速度1 * 时间 + 0.5 * y加速度1 * (时间 ** 2)
        )
        临时x, 临时y = 天体1.x, 天体1.y
        天体1.x, 天体1.y = x, y
        天体1.x速度 = (x - 临时x) / 时间
        天体1.y速度 = (y - 临时x) / 时间
        天体精灵1.刷新rect属性()
    for 动画精灵 in 天体动画精灵列表:
        if 动画精灵.天体 in 要删除的天体:
            天体动画精灵列表.remove(动画精灵)

screen = pygame.display.set_mode((900, 900))

天体动画精灵列表 = [
    天体动画精灵(天体("planet1", 500, 100, 1, 0, 1e4), 50, "orange"),
    天体动画精灵(天体("planet2", 500, 900, -1, 0, 1e4), 50, "blue")
]

clock = pygame.time.Clock()
running = True
while running:
    screen.fill((0, 0, 0))
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    ########## 可更改:天体移动速度 ##########
    移动全部天体(1)
    for 天体动画精灵 in 天体动画精灵列表:
        screen.blit(天体动画精灵.image, 天体动画精灵.rect)
    pygame.display.flip()

为什么:
F:\Python399\python.exe E:\Python123\k\main.py 
pygame 2.5.0 (SDL 2.28.0, Python 3.9.9)
Hello from the pygame community. https://www.pygame.org/contribute.html
500 100
500 900
501.0 100.046875
499.00005860391354 899.9531196162419
501.99988277582344 -299.85936445073924
498.00016931204163 1299.8853995820643
502.99973624312133 -1100.7070065216924
497.00029086182343 2100.765534831006
503.9995842253675 -2703.4109688415697
496.0004143053315 3703.5296005337195
504.9994312951553 -5909.820943092084
495.0005380527121 6910.058585588716
505.9992782225723 -12323.641287871671
494.0006618464668 13324.116675776857
506.9991251286537 -25152.281961432465
493.0007856470674 26153.232793236668
507.9989720316255 -50810.56318969043
492.00090944865497 51812.46491956223
508.99881893415323 -102128.12550166092
491.0010332503823 103131.92905221145
509.99866583661856 -204764.24997464143
490.0011570521292 205771.8571946578
510.9985127390752 -410037.49876803905
489.00128085387877 411052.7133559861
511.9983596415306 -820584.9962018703
488.0014046556287 821615.4255549003
512.9982065439859 -1641680.9909164684
487.00152845737864 1642741.849828942
513.9980534464412 -3283873.9801925756
486.0016522591286 3284995.698253227
514.9979003488965 -6568260.958591695
485.00177606087857 6569504.394977996
515.9977472513517 -13137035.915236836
484.00189986262853 13138522.788303733
516.997594153807 -26274586.82837402
483.0020236643785 26276560.574831404
517.9974410562622 -52549689.65449529
482.00214746612846 52552637.14776295
518.9972879587175 -105099896.30658475
481.0022712678784 105104791.29350223
519.9971348611728 -210200310.61061054
480.0023950696284 210209100.584857
520.996981763628 -420401140.2185091
479.00251887137836 420417720.1674427
521.9968286660833 -840802800.4341531
478.0026426731283 840834960.3324902
522.9966755685385 -1681606121.8652878
477.0027664748783 1681669441.6624615
523.9965224709938 -3363212765.727404
Traceback (most recent call last):
  File "E:\Python123\k\main.py", line 93, in <module>
    移动全部天体(1)
  File "E:\Python123\k\main.py", line 72, in 移动全部天体
    天体精灵1.刷新rect属性()
  File "E:\Python123\k\main.py", line 33, in 刷新rect属性
    self.rect.centery = self.天体.y
TypeError: invalid rect assignment, expected value between -2147483648 < x < 2147483647

进程已结束,退出代码1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-22 14:51:02 | 显示全部楼层
歌者文明清理员 发表于 2023-7-22 14:45
感谢回答,代码修改如下:

@isdkz @sfqxx
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-22 15:01:58 | 显示全部楼层

你的代码看起来像伪代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-22 15:02:15 | 显示全部楼层
我一般通过
    一个角度和
    一个速度

然后把角度转化成弧度,接着再用 这个弧度的sin和cos乘以速度得出xv和yv

可以去看看我的新帖里面模拟车辆移动是如何计算移动的 -> 通过一个角度(移动方向) 和一个 xy的速度和 来计算出x和y的速度
https://fishc.com.cn/thread-2309 ... ead-230950-1-1.html (出处: 鱼C论坛)[/url]


                               
登录/注册后可看大图

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-22 15:05:01 | 显示全部楼层
sfqxx 发表于 2023-7-22 15:01
你的代码看起来像伪代码

哦,本人喜欢使用中文编写代码,不用写注释

点评

我很赞同!: 5.0
我很赞同!: 5
现在大环境逐渐开始支持用中文写代码了  发表于 2023-7-22 16:38
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-7-22 17:08:24 | 显示全部楼层
你在第71行代码中提到
天体1.y速度 = (y - 临时x) / 时间

这里你写的“临时x”应该是“临时y”吧。
在将“临时x”改成“临时y”之后运行效果看起来就是正确的了。
求最佳答案(

评分

参与人数 1鱼币 +5 贡献 +1 收起 理由
歌者文明清理员 + 5 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-22 10:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表