Python 具有Pygame的类流体特征
所以我试图用pygame编写一个小的模拟器,但我被卡住了 我试图使粒子落下并沉淀,但我希望它们在撞击墙壁时堆叠并停止 这听起来可能令人困惑,因此下面是一个示例: 我想制作类似于上面游戏中的糖的粒子: 我开始尝试:Python 具有Pygame的类流体特征,python,pygame,physics,game-physics,Python,Pygame,Physics,Game Physics,所以我试图用pygame编写一个小的模拟器,但我被卡住了 我试图使粒子落下并沉淀,但我希望它们在撞击墙壁时堆叠并停止 这听起来可能令人困惑,因此下面是一个示例: 我想制作类似于上面游戏中的糖的粒子: 我开始尝试: if pygame.sprite.spritecollideany(self, self.game.block_list): self.rect.x += 0 self.rect.y += 0 但是粒子只是停下来,不会从倾斜的表面滚下来 我还需要知道如何检查一个精灵
if pygame.sprite.spritecollideany(self, self.game.block_list):
self.rect.x += 0
self.rect.y += 0
但是粒子只是停下来,不会从倾斜的表面滚下来
我还需要知道如何检查一个精灵是否与其组中的任何其他精灵发生碰撞
所以,如果有人知道我如何在pygame中复制这种类似液体的粒子运动,那就太棒了
谢谢大家! 如上所述,我试图用pygame编写完全相同的游戏,但没有完成。
首先,我不喜欢将这些粒子存储为不同的对象。相反,我用字典来存储它们的坐标。我这样做是因为有数百个这样的碰撞,你必须每秒检查碰撞50次。如果你试图让它们都成为不同的对象,在某个时候可能会失控。
检测到碰撞后,为了使它们沿斜面向下滚动,请让它们也沿对角线移动。首先检查下面的单元格,如果该单元格不是空的,请检查粒子左下角和右下角的单元格。
顺便说一句,我找到了移动粒子的函数,但它不是真正可读的
我也试着用pygame写一个精确的游戏。让我查找代码,但我没有完成。酷游戏顺便说一句:)你可以使用pyBox2d进行物理模拟,pygame进行渲染。这里有一个落沙的例子:所以不要使用精灵?只做一个对象?我创建了一个字典和一个糖坐标列表。当我需要移动它们时,我迭代列表并在字典和列表中更改它们的值。我将尝试在我的回答中添加一个伪代码。我知道这看起来很可怕,但这是因为我写这篇文章时并不关心可读性,这就像一个实验。现在我添加了评论行,你至少应该能够理解这一点。非常感谢,我来试一试!我不确定使用dict如何提高性能(除非我遗漏了什么)您确实需要一个四叉树,或者某种分而治之的方法来显著减少碰撞检查的数量。
def spawnSugar(spawnPoint) :
global sugarList,mapDict
mapDict[spawnPoint] = 1
sugarList.append(spawnPoint)
def moveAll() :
global mapDict,sugarList
sugarListTmp = sugarList
sugarList = []
for sugarX,sugarY in sugarListTmp :
# m stands for the vertical movement (1 for down, 0 for staying still)
# k stands for horizontal movement (-1 for left, +1 for right)
m = 1
if mapDict[( sugarX , (sugarY+1)%mapSizeY )]==0:
# checks whether the coordinate below this particle is empty
k = randint( -(mapDict[((sugarX-1)%mapSizeX , (sugarY+1)%mapSizeY)]==0) , mapDict[((sugarX+1)%mapSizeX , (sugarY+1)%mapSizeY)]==0 )
# If it is empty; randomly chooses 1 of the 3 coordinates below the particle (1 of them is just below and the other 2 are diagonally below)
elif mapDict[((sugarX-1)%mapSizeX,(sugarY+1)%mapSizeY)]==0 and mapDict[((sugarX-1)%mapSizeX,(sugarY)%mapSizeY)]==0 and mapDict[((sugarX+1)%mapSizeX,(sugarY+1)%mapSizeY)]==0 and mapDict[((sugarX+1)%mapSizeX,(sugarY)%mapSizeY)]==0:
# If the coordinate below the particle is not empty but other 2 diagonals are empty
k = -1 if randint(0,1) else 1 #chooses 1 of them randomly
else : # If at most 1 of these 2 diagonal coordinates are empty
k = (mapDict[((sugarX+1)%mapSizeX,(sugarY+1)%mapSizeY)]==0 and mapDict[((sugarX+1)%mapSizeX,(sugarY)%mapSizeY)]==0) or -(mapDict[((sugarX-1)%mapSizeX,(sugarY+1)%mapSizeY)]==0 and mapDict[((sugarX-1)%mapSizeX,(sugarY)%mapSizeY)]==0)
if not k: # If none of them are empty
m = 0
mapDict[(sugarX,sugarY)] = 0
mapDict[((sugarX+k)%mapSizeX,(sugarY+m)%mapSizeY)] = 1
sugarList.append(((sugarX+k)%mapSizeX,(sugarY+m)%mapSizeY))
# Values to assign before entering the main loop
mapDict = {}
sugarList = []
for x in range(mapSizeX):
for y in range(mapSizeY):
mapDict[(x,y)] = 0