[Numpy-discussion] how can i optimize this function further more?
Victor Noagbodji
noagbodjivictor@gmail....
Tue Aug 18 12:11:14 CDT 2009
hello, i'm fairly new to numpy. i need help with a snow effect done
with pygame. the entire code is below. the performance drops in the
snowfall function. the original c code and a demo can be found here :
http://sol.gfxile.net/gp/ch04.html
as you can see. the original c code went the pixel by pixel way, but i
couldn't do that with pygame. i'm asking here because i think there
might be a way numpy could help. the idea of the snowfall function is
to plot white pixel one line down (while avoiding the green ground,
thus the test array1-array2 == white)
thanks a lot in advance for your help.
ps. sorry for the ugly code. this is the result of several
optimizations, plus help from the pygame mailing list.
import numpy
import cProfile
from math import sin, cos
from random import randint
from sys import exit, stdout
import pygame
import pygame.event as event
import pygame.display as display
from pygame.locals import *
from pygame import Surface
from pygame.time import Clock, get_ticks
from pygame.surfarray import pixels2d, blit_array, make_surface
WIDTH = 640
HEIGHT = 480
RESOLUTION = (WIDTH, HEIGHT)
def init(screen_array, green=int(0x007f00)):
lowest_level = 0
for i in xrange(WIDTH):
sins = (sin((i + 3247) * 0.02) * 0.3 +
sin((i + 2347) * 0.04) * 0.1 +
sin((i + 4378) * 0.01) * 0.6)
p = int(sins * 100 + 380)
lowest_level = max(p, lowest_level)
for j in range(p, HEIGHT):
screen_array[i, j] = green
return lowest_level
def newsnow(screen_array, white=int(0xffffff), density=1):
new_indices = numpy.array([randint(1, WIDTH-2) for i in xrange(density)])
screen_array[new_indices, 0] = white
def snowfall(screen_array,
white=int(0xffffff),
fallrng=xrange(HEIGHT-2, -1, -1)):
screen_array = numpy.transpose(screen_array)
snow_in_next_layer = numpy.zeros(WIDTH, dtype=int)
for j in fallrng:
array1 = screen_array[j]
array2 = screen_array[j+1]
indices_where_snow_moved_down = numpy.where(array1-array2 == white)[0]
snow_in_next_layer.fill(0)
snow_in_next_layer[indices_where_snow_moved_down] = white
screen_array[j ] = array1 - snow_in_next_layer
screen_array[j+1] = array2 + snow_in_next_layer
screen_array = numpy.transpose(screen_array)
def main():
pygame.init()
screen_surf = display.set_mode(RESOLUTION)
screen_rect = screen_surf.get_rect()
screen_array = pixels2d(screen_surf)
lowest_level = init(screen_array)
display.update(screen_rect)
fallrng = xrange(lowest_level-2, -1, -1)
white = int(0xffffff)
black = 0
c = Clock()
while True:
newsnow(screen_array, density=8)
snowfall(screen_array)
display.update(screen_rect)
for e in event.get():
type = e.type
if type == QUIT:
exit()
elif type == KEYUP and e.key == K_ESCAPE:
return
c.tick()
stdout.write('fps: ~%s\r' % round(c.get_fps()))
stdout.flush()
if __name__ == '__main__':
cProfile.runctx('main()', globals(), {'main': main}, 'last_gp3_stats')
--
paul victor noagbodji
More information about the NumPy-Discussion
mailing list