【发布时间】:2020-06-05 18:25:17
【问题描述】:
我目前正在尝试在 python/pygame(来自 java,p5 来自编码火车视频:https://www.youtube.com/watch?v=BZUdGqeOD0w)中复制水波纹效果。
我无法让它工作,屏幕保持空白(黑色:背景颜色)或者我给了我错误:
Traceback (most recent call last): File "/Users/vicki/Documents/Atom Test/Water Ripple.py", line 39, in <module> screen.fill((current[i][j],current[i][j],current[i][j]),(i,j,1,1)) TypeError: invalid color argument
实际上我发现这是正常的,因为我们从 0 开始使用正数来获取像素的颜色:
current[i][j] = (previous[i-1][j]+previous[i+1][j]+ previous[i][j+1]+ previous[i][j-1])/ 2 - current[i][j]
:previous[i-1][j]、previous[i+1][j]、previous[i][j-1]、previous[i][j+1] 都等于 0,而current[I][j] 是一个正数,所以逻辑上它应该给出一个负颜色值。
也许这与数组在 Python 和 Java 中的工作方式有关?
如需更多帮助,这里是用于制作他的视频的网站编码火车:https://web.archive.org/web/20160418004149/http://freespace.virgin.net/hugo.elias/graphics/x_water.htm
这是我的代码:
import pygame
pygame.init()
width = 200
height = 200
cols = width
rows = height
#dampening = how fast the ripple effect stops.
dampening = 0.999
#Arrays that hold the colors of the screen.
current = [[0]*cols]*rows
previous = [[0]*cols]*rows
screen = pygame.display.set_mode((width,height))
#Sets the initial background to black
screen.fill((0,0,0))
#Mainloop
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
#if the user clicks the screen, it sets the pixel the user clicked upon white
mouse_pos = pygame.mouse.get_pos()
current[mouse_pos[0]][mouse_pos[1]] = 255
#This part seems to be the problem
for i in range(1,rows-1):
for j in range(1,cols-1):
#This computation is weird: we are substracting positive/zero number from a null number which should normally give us a negative number. A color value (RGB) cannot be a negative number!
current[i][j] = (previous[i-1][j]+previous[i+1][j]+ previous[i][j+1]+ previous[i][j-1])/ 2 - current[i][j]
current[i][j] *= dampening
#This line is where it gives me the error
screen.fill((current[i][j],current[i][j],current[i][j]),(i,j,1,1))
#Switching the arrays, have also tried: previous, current = current, previous (doesn't work either)
temp = previous
previous = current
current = temp
pygame.display.flip()
这是编码火车的代码(在java P5中): (注意:他使用的是 mousedraft 而不是 mouseTouch(在视频中他使用的是 mousetouch),但这并不重要。)
// Daniel Shiffman
// http://codingtra.in
// http://patreon.com/codingtrain
// 2D Water Ripples
// Video: https://youtu.be/BZUdGqeOD0w
// Algorithm: https://web.archive.org/web/20160418004149/http://freespace.virgin.net/hugo.elias/graphics/x_water.htm
int cols;
int rows;
float[][] current;// = new float[cols][rows];
float[][] previous;// = new float[cols][rows];
float dampening = 0.99;
void setup() {
size(600, 400);
cols = width;
rows = height;
current = new float[cols][rows];
previous = new float[cols][rows];
}
void mouseDragged() {
previous[mouseX][mouseY] = 500;
}
void draw() {
background(0);
loadPixels();
for (int i = 1; i < cols-1; i++) {
for (int j = 1; j < rows-1; j++) {
current[i][j] = (
previous[i-1][j] +
previous[i+1][j] +
previous[i][j-1] +
previous[i][j+1]) / 2 -
current[i][j];
current[i][j] = current[i][j] * dampening;
int index = i + j * cols;
pixels[index] = color(current[i][j]);
}
}
updatePixels();
float[][] temp = previous;
previous = current;
current = temp;
}
【问题讨论】:
-
有一种更快的方法可以使用卷积(可以在 scipy 的库中找到)。以github.com/salt-die/ripple/blob/master/ripple.py 为例
标签: python pygame simulation