[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] Rain Generator
I always forget to attach files - here are the rain and snow I just talked about :P
import random
import pygame
import psyco
psyco.full()
screen = pygame.display.set_mode([320,240])
colmap = [[0 for x in range(320)] for y in range(240)]
col_width = len(colmap[0])
col_height = len(colmap)
lowestflake = [col_height]
windtunnel = [0,60,320,10]
windpower = [0,0]
buggy = [10,10,10,5]
def p_in_c(point):
"""Returns 1 if that coordinate is in the coordinate map"""
return point[1]<col_height and point[1]>=0 and point[0]<col_width and point[0]>=0
def getc(point):
"""Returns 1 if that point is out of bounds or if that point contains a snowflake"""
if p_in_c(point):
if point[0]>=buggy[0] and point[0]<=buggy[0]+buggy[2] and point[1]>=buggy[1] and point[1]<=buggy[1]+buggy[3]:
return 1
return colmap[point[1]][point[0]]
if point[1]<col_height:
if point[1]>lowestflake[0]:
return 1
return 0
return 1
def setc(point,val):
if p_in_c(point):
if point[1]<lowestflake[0]:
lowestflake[0] = point[1]
colmap[point[1]][point[0]] = val
img_flake = pygame.Surface([1,1])
img_flake.fill([255,255,255])
grav = 9.8/60.0
wind = [-20.0/60.0,-1.0/60.0]
class SnowFlake:
def __init__(self,pos):
self.lastpos = pos[:]
self.pos = pos[:]
#setc([int(x) for x in self.pos],1)
self.vel = [0,0.2]
self.lastsurf = pygame.Surface([1,1])
self.deadtime = 3
self.rolltime = 10
def move(self):
force = [0,grav]
if self.pos[0]>=windtunnel[0] and self.pos[0]<=windtunnel[0]+windtunnel[2] and self.pos[1]>=windtunnel[1] and self.pos[1]<=windtunnel[1]+windtunnel[3]:
force[0]+=windpower[0]
force[1]+=windpower[1]
self.lastpos = self.pos[:]
self.pos[0]+=self.vel[0]+0.2*random.choice([-1,1])+wind[0]
self.pos[1]+=self.vel[1]/20.0+wind[1]
self.vel[0]+=force[0]
self.vel[1]+=force[1]
lp = [int(x) for x in self.lastpos] #last pixel
np = [int(x) for x in self.pos] #Now pixel
dx = np[0]-lp[0] #x change in pixels
dy = np[1]-lp[1] #y change in pixels
if dx:
dx = dx/abs(dx) #Get direction of change x
if dy:
dy = dy/abs(dy) #Get directionof change y
#Draw line from last pixel to current pixel, find walls
lx,ly = lp[0],lp[1] #lastx pixel and lasty pixel
x,y=lp[0],lp[1]
p=None #p is a spot where we were blocked
while x!=np[0] or y!=np[1]:
lx,ly=x,y
if x!=np[0]:
x+=dx
if y!=np[1]:
y+=dy
if getc([x,y]):
p = [lx,ly] #blocked
break
x,y = np[0],np[1]
if getc([x,y]) and not p:
p = [lx,ly]
if p:
x,y = p
left = getc([x-1,y+1])
right = getc([x+1,y+1])
down = getc([x,y+1])
canroll = self.rolltime>0
if not down:
self.pos = [x,y+1]
elif left and not right:
self.pos = [x+1,y+1]
elif not left and right:
self.pos = [x-1,y+1]
elif not left and not right:
self.pos = [random.choice([x-1,x+1]),y]
else:
self.pos = [x,y]
np = [int(x) for x in self.pos]
self.deadtime -= 1
setc(np,1)
#if self.pos[0]<0:
# print "x out of bounds"
# raise Error
#if self.pos[1]>240:
# print "oops?",self.pos[1],p,lp,np
# raise Error
def draw(self):
np = [int(x) for x in self.pos]
self.lastsurf.blit(screen,np)
screen.blit(img_flake,np)
if self.lastpos != self.pos:
screen.blit(self.lastsurf,[int(x) for x in self.lastpos])
flakes = []
numflakes = 500
def addflake():
y = random.randint(-500,10)
x = random.randint(0,420)
f = SnowFlake([x,y])
f.vel[0] = random.choice([-1,1])*0.05
f.vel[1] = (y+1000)*.02
flakes.append(f)
[addflake() for i in range(numflakes)]
pygame.event.clear()
pygame.event.pump()
c = pygame.time.Clock()
pygame.draw.rect(screen,[255,0,0],[10,10,10,5])
while 1:
c.tick(60)
flakes = [f for f in flakes if f.deadtime>0]
[f.draw() for f in flakes]
pygame.display.update()
[f.move() for f in flakes]
pygame.event.pump()
if pygame.event.get(pygame.KEYDOWN):
break
[addflake() for x in xrange(numflakes-len(flakes))]
#init stuff
import pygame
import pygame.locals as l
import random
screen = pygame.display.set_mode([640,480])
class drop:
def __init__(self,posx,posy):
self.pos = [posx,posy]
def __getattr__(self,attr):
if attr=="x":
return self.pos[0]
if attr=="y":
return self.pos[1]
return drop.__get__(self,attr)
def __getitem__(self,it):
return self.pos[it]
class splash(drop):
def __init__(self,posx,posy,xdirection):
self.pos = [posx,posy]
self.xdir = xdirection
self.ydir = -1
self.bounces = 0
drops = [] #list of points where a drop is
splashes = [] #list of points/direction/time [x,y,dx,dy,t] where a splash is
lands = [[0,100,110],[233,400,300],[200,300,150]] #list of lines (x1,x2,y) for land
maxdrops = 50
maxsplashes = 400
def addDrop(posx,posy):
if len(drops)<maxdrops:
drops.append(drop(posx,posy))
def addSplash(posx,posy,xdirection):
if len(splashes)<maxsplashes:
splashes.append(splash(posx,posy,xdirection))
#For cool fading, darken the background each frame
dark = screen.convert()
dark.fill([0,0,0])
dark.set_alpha(5)
#Faster than drawing lines
splashsurf = pygame.Surface([1,1])
splashsurf.fill([0,0,255])
rainsurf = pygame.Surface([1,20])
rainsurf.fill([0,0,255])
mousesurf = pygame.Surface([20,20])
mousesurf.fill([200,200,200])
meep = pygame.Surface([10,10])
meep.fill([200,20,30])
meepx = 0
meepy = screen.get_height()-10
meepdir = 1
#Keep track of the clock
c = pygame.time.Clock()
#main loop
die = 0
keys = pygame.key.get_pressed()
while not keys[l.K_ESCAPE] and not die:
c.tick(60)
pygame.event.pump()
keys = pygame.key.get_pressed()
#make current screen darker
screen.blit(dark,[0,0])
mx,my = pygame.mouse.get_pos()
#Draw land
for line in lands:
pygame.draw.line(screen,[0,200,0],[line[0],line[2]],[line[1],line[2]],2)
#draw meep
screen.blit(meep,[meepx-5,meepy])
#maybe meep changes direction?
if random.randint(0,100)>80:
meepdir = random.randint(-1,1)
#he should head to the right
if random.randint(0,100)>20:
meepdir = 1
#move meep
if meepx>0 and meepdir == -1 or meepx<screen.get_width() and meepdir == 1:
meepx += meepdir
#draw all drops and update their position
for d in drops:
pos = d.pos
d.pos[1]+=20
dosplash = 0
if abs(d.x-mx)<20 and abs(d.y-my)<20:
d.pos[1] = my-20
dosplash = 1
else:
for line in lands:
if d.pos[0]>=line[0] and d.pos[0]<=line[1] and d.pos[1]>line[2]:
d.pos[1] = line[2]
dosplash = 1
if not dosplash and d.y>=meepy and d.x>=meepx-5 and d.x<=meepx+5:
die = 1
dosplash = 1
if not dosplash and d.y>screen.get_height():
d.pos[1] = screen.get_height()
dosplash = 1
if dosplash:
addSplash(d.x,d.y,random.choice([-1,1]))
drops.remove(d)
screen.blit(rainsurf,[pos[0],pos[1]-20])
#Draw all splashes and update their position
for s in splashes:
screen.blit(splashsurf,s.pos)
#pygame.draw.line(screen,[0,0,255],s.pos,s.pos,1)
if s.y>screen.get_height():
s.y = screen.get_height()
s.ydir = -1
s.bounces += 1
if abs(s.x-mx)<20 and abs(s.y-my)<20:
s.y = my-20
s.ydir = -1
s.bounces += 1
if s.x<0 or s.x>screen.get_width() or s.bounces>10:
splashes.remove(s)
else:
s.pos[0]+=s.xdir*3
s.pos[1]+=s.ydir*3 #move in y direction
s.ydir+=.1
#make new drops
for i in range(5):
x = random.randint(0,screen.get_width())
#y = random.randint(0,screen.get_height())
addDrop(x,0)
#Update screen
screen.blit(mousesurf,[mx-10,my-10])
pygame.display.flip()
while not keys[l.K_ESCAPE]:
pygame.event.pump()
keys = pygame.key.get_pressed()