gpt4 book ai didi

python-3.x - Pygame 水物理无法按预期工作

转载 作者:行者123 更新时间:2023-12-03 16:21:00 26 4
gpt4 key购买 nike

所以,我一直在尝试根据本教程在 pygame 中实现水物理
https://gamedevelopment.tutsplus.com/tutorials/make-a-splash-with-dynamic-2d-water-effects--gamedev-236
问题是,当我在 pygame 中实现这段代码时,水决定它不会产生很好的涟漪效应,而是会发疯并在整个屏幕上摆动,直到最终崩溃。
我环顾了一些不和谐的服务器,发现其他人试图实现同样的事情,并遇到了同样的问题。他们的代码基本上和我的一样,只是组织得更整齐,所以我会发布它而不是我的。

import pygame, random
import math as m

from pygame import *

pygame.init()

WINDOW_SIZE = (854, 480)

screen = pygame.display.set_mode(WINDOW_SIZE,0,32) # initiate the window

clock = pygame.time.Clock()

font = pygame.font.SysFont("Arial", 18)

class surface_water_particle():
def __init__(self, x,y):
self.x_pos = x
self.y_pos = y
self.target_y = y
self.velocity = 0
self.k = 0.02
self.d = 0.02
self.time = 1

def update(self):
x = -(self.target_y - self.y_pos)
a = -(self.k * x - self.d * self.velocity)

self.y_pos += self.velocity
self.velocity += a

class water():
def __init__(self, x_start, x_end, y_start, y_end, segment_length):
self.springs = []
self.x_start = x_start
self.y_start = y_start
self.x_end = x_end
self.y_end = y_end - 10
for i in range(abs(x_end - x_start) // segment_length):
self.springs.append(surface_water_particle(i * segment_length + x_start, y_end))

def update(self, spread):
for i in range(len(self.springs)):
self.springs[i].update()

leftDeltas = [0] * len(self.springs)
rightDeltas = [0] * len(self.springs)

for i in range(0, len(self.springs) ):
if i > 0:
leftDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i - 1].y_pos)
self.springs[i - 1].velocity += leftDeltas[i]
if i < len(self.springs) - 1:
rightDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i + 1].y_pos)
self.springs[i + 1].velocity += rightDeltas[i]

for i in range(0, len(self.springs) ):
if i > 0:
self.springs[i - 1].velocity += leftDeltas[i]
if i < len(self.springs) - 1:
self.springs[i + 1].velocity += rightDeltas[i]


def splash(self, index, speed):
if index > 0 and index < len(self.springs) :
self.springs[index].velocity = speed

def draw(self):
water_surface = pygame.Surface((abs(self.x_start - self.x_end), abs(self.y_start - self.y_end))).convert_alpha()
water_surface.fill((0,0,0,0))
water_surface.set_colorkey((0,0,0,0))
polygon_points = []
polygon_points.append((self.x_start, self.y_start))
for spring in range(len(self.springs)):
polygon_points.append((water_test.springs[spring].x_pos, water_test.springs[spring].y_pos))
polygon_points.append((water_test.springs[len(self.springs) - 1].x_pos, self.y_start))

#pygame.draw.polygon(water_surface, (0,0,255), polygon_points)

for spring in range(0,len(self.springs) - 1):
pygame.draw.line(screen, (0,0,255), (water_test.springs[spring].x_pos, water_test.springs[spring].y_pos), (water_test.springs[spring + 1].x_pos, water_test.springs[spring + 1].y_pos), 2)

#water_surface.set_alpha(100)

return water_surface

def update_fps():
fps_text = font.render(str(int(clock.get_fps())), 1, pygame.Color("coral"))
screen.blit(fps_text, (0,0))

water_test = water(0,800,200,80, 20)

while True:
screen.fill((255,255,255))
water_test.update(0.5)
screen.blit(water_test.draw(), (0,0))

for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
if event.type == MOUSEBUTTONDOWN:
water_test.splash(10,0.1)

pygame.display.update()

clock.tick(60)
我试图寻找我们的教程实现的任何问题,但我找不到任何似乎不合适的地方。然后我尝试添加一个阻力函数,该函数可以在每次更新时划分水流速度。然而这并没有解决问题。
有谁知道做错了什么以及如何解决这个问题?

最佳答案

许多与其他帖子相同的观察结果。我评论了一些事情,稍微改变了你的速度声明。在“传播”中,我添加了通行证。
稍微修改一下数字,并得到了一些非常好的飞溅。 (比公认的解决方案更好!:(大声笑。
如果您需要对此进行更多故障排除,我建议您注释掉扩散片(或将其值设为零),然后您可以自行检查水的弹性。这使得 T/S 变得更容易。

import pygame, random
import math as m

from pygame import *

pygame.init()

WINDOW_SIZE = (854, 480)

screen = pygame.display.set_mode(WINDOW_SIZE,0,32) # initiate the window

clock = pygame.time.Clock()

font = pygame.font.SysFont("Arial", 18)

class surface_water_particle():
k = 0.04 # spring constant
d = 0.08 # damping constant
def __init__(self, x,y):
self.x_pos = x
self.y_pos = y
self.target_y = y
self.velocity = 0

def update(self):
x = self.y_pos - self.target_y # displacement of "spring"
a = -self.k * x - self.d * self.velocity # unit of acceleration

self.y_pos += self.velocity
self.velocity += a

class water():

def __init__(self, x_start, x_end, y_start, y_end, segment_length):
self.springs = []
self.x_start = x_start
self.y_start = y_start
self.x_end = x_end
self.y_end = y_end - 10
for i in range(abs(x_end - x_start) // segment_length):
self.springs.append(surface_water_particle(i * segment_length + x_start, y_end))

def update(self, spread):
passes = 4 # more passes = more splash spreading
for i in range(len(self.springs)):
self.springs[i].update()

leftDeltas = [0] * len(self.springs)
rightDeltas = [0] * len(self.springs)
for p in range(passes):
for i in range(0, len(self.springs) -1 ):
if i > 0:
leftDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i - 1].y_pos)
self.springs[i - 1].velocity += leftDeltas[i]
if i < len(self.springs) - 1:
rightDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i + 1].y_pos)
self.springs[i + 1].velocity += rightDeltas[i]

for i in range(0, len(self.springs) -1):
if i > 0:
self.springs[i - 1].y_pos += leftDeltas[i] # you were updating velocity here!
if i < len(self.springs) - 1:
self.springs[i + 1].y_pos += rightDeltas[i]



def splash(self, index, speed):
if index > 0 and index < len(self.springs) :
self.springs[index].velocity = speed

def draw(self):
water_surface = pygame.Surface((abs(self.x_start - self.x_end), abs(self.y_start - self.y_end))).convert_alpha()
water_surface.fill((0,0,0,0))
water_surface.set_colorkey((0,0,0,0))
polygon_points = []
polygon_points.append((self.x_start, self.y_start))
for spring in range(len(self.springs)):
polygon_points.append((water_test.springs[spring].x_pos, water_test.springs[spring].y_pos))
polygon_points.append((water_test.springs[len(self.springs) - 1].x_pos, self.y_start))

#pygame.draw.polygon(water_surface, (0,0,255), polygon_points)

for spring in range(0,len(self.springs) - 1):
pygame.draw.line(screen, (0,0,255), (water_test.springs[spring].x_pos, water_test.springs[spring].y_pos), (water_test.springs[spring + 1].x_pos, water_test.springs[spring + 1].y_pos), 2)

#water_surface.set_alpha(100)

return water_surface

def update_fps():
fps_text = font.render(str(int(clock.get_fps())), 1, pygame.Color("coral"))
screen.blit(fps_text, (0,0))

water_test = water(0,800,200,200, 3)

while True:
screen.fill((255,255,255))
water_test.update(0.025)
screen.blit(water_test.draw(), (0,0))

for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
if event.type == MOUSEBUTTONDOWN:
water_test.splash(50,100)

pygame.display.update()

clock.tick(60)

关于python-3.x - Pygame 水物理无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62499733/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com