Paste: path collisions in pygame

Author: Daniel Gabriele
Mode: python
Date: Fri, 26 Jun 2009 14:13:52
Plain Text |
#!/usr/bin/env python
# path.py

import random
import itertools
import pygame
from pygame.color import THECOLORS as COLORS
import colorlib
pygame.init()

SCRSIZE = (800, 600)
SCRW, SCRH = SCRSIZE

class Path(object):

	def __init__(self, **kwargs):
		
		# defaults
		self.dx = 1
		self.dy = 0

		for kw in kwargs:
			setattr(self, kw, kwargs[kw])


	@property
	def slope(self):
		if not self.dx: return None 
		return self.dy / float(self.dx)	
	
	def set_slope(self, dx, dy):
		self.dx, self.dy = dx, dy

	def get_points(self, point):
		x, y = point
		if self.slope is not None:
			b = y - self.slope * x
			return [(x, int(self.slope * x + b)) for x in range(SCRW)]
		else:
			return [(x, i) for i in range(SCRW)]
	
	def plot(self, surface, intercept):
		i = 0
		for point in self.get_points(intercept):
			if i % 8 == 0:
				pygame.draw.circle(surface, COLORS["indianred"], point, 2)
			i += 1



class Trajector(pygame.sprite.Sprite):

	def __init__(self, size, position):
		pygame.sprite.Sprite.__init__(self)
		
		# set up image
		self.image = pygame.Surface(size)
		self._init_image()
		
		# set up dimensions
		self.position = position
		self.size = size
		self.rect = pygame.Rect(position + size)
		
		# set up path
		self.dx = self.dy = 0
		self.path = Path(dx=self.dx, dy=self.dy)
	

	def _init_image(self):
		self.image.fill(COLORS["purple"])
		self.image.set_alpha(120)

	@property
	def clrect(self):
		x, y, w, h = self.rect
		return pygame.Rect(x-4, y-4, w+8, h+8)

	def load_image(self, path):
		image = pygame.image.load(path)
		image = pygame.transform.smoothscale(image, self.size)
		self.image = image

	def update(self):
		self.path.set_slope(self.dx, self.dy)
		self.rect = self.rect.move(self.dx, self.dy)



class TestBlock(pygame.sprite.Sprite):

	def __init__(self):
		self.image = pygame.Surface((25, 25))
		self.rect = self.image.get_rect()
		self._init_image()
	
	def _init_image(self):
		self.image.fill(COLORS["forestgreen"])




# TESTING
if __name__ == "__main__":
	
	running = True
	screen = pygame.display.set_mode(SCRSIZE)
	screen.fill(COLORS["white"])
	font = pygame.font.SysFont(None, 48)
	clock = pygame.time.Clock()

	trsize = (50, 50)
	trpos = (200, 100)

	traj = Trajector(trsize, trpos)
	#traj.load_image("/home/daniel/sprites/redpepper.png")
	#traj.image.set_colorkey(COLORS["white"])

	bg = pygame.Surface(SCRSIZE)
	bg.fill(COLORS["white"])
	bg.set_alpha(20)

	BGFILL = pygame.USEREVENT
	pygame.time.set_timer(BGFILL, 60)

	for i in range(0, SCRW, 6):
		if i % 48 == 0:
			pygame.draw.aaline(bg, COLORS["darkgray"], (i, 0), (i, SCRH), 1)
		else:
			pygame.draw.aaline(bg, COLORS["lightgray"], (i, 0), (i, SCRH), 1)
	for i in range(0, SCRH, 6):
		if i % 48 == 0:
			pygame.draw.aaline(bg, COLORS["darkgray"], (0, i), (SCRW, i), 1)
		else:
			pygame.draw.aaline(bg, COLORS["lightgray"], (0, i), (SCRW, i), 1)
	
	
	blocks = [TestBlock() for i in range(20)]
	colorcycle = itertools.cycle([colorlib.randcolor() for i in range(10)])


	x = random.randrange(SCRW)
	y = random.randrange(SCRH)
	for b in blocks:
		b.rect = b.rect.move(x, y)
		screen.blit(b.image, b.rect.topleft)
		x = random.randrange(SCRW)
		y = random.randrange(SCRH)


	screen.blit(bg, (0, 0))
	pygame.display.flip()
	


	while running:
		clock.tick(36)
		for e in pygame.event.get():
			if e.type == BGFILL:
				screen.blit(bg, (0, 0))
			
			if not hasattr(e, "key") or e.type == pygame.KEYUP:
				continue
			
			if e.key == pygame.K_q:
				running = False
			elif e.key == pygame.K_LEFT:
				traj.dx -= 1
			elif e.key == pygame.K_RIGHT:
				traj.dx += 1
			elif e.key == pygame.K_DOWN:
				traj.dy += 1
			elif e.key == pygame.K_UP:
				traj.dy -= 1

		traj.update()

		for b in blocks:
			screen.blit(b.image, b.rect.topleft)
			for p in traj.path.get_points(traj.rect.center):
				if p[0] > b.rect.left and p[0] < b.rect.right \
					and p[1] > b.rect.top and p[1] < b.rect.bottom:
						b.image.fill(colorcycle.next())


		traj.path.plot(screen, traj.rect.center)
		pygame.draw.circle(screen, COLORS["white"], traj.rect.center, 40)
		screen.blit(traj.image, traj.rect.topleft)
	
		slopesurf = font.render("slope: %s/%s" % (traj.dy, -traj.dx), True, COLORS["black"])
		screen.blit(slopesurf, (10, 10))


#		update_rects = [b.rect for b in blocks] + [traj.rect]
#		pygame.display.update(update_rects)
		pygame.display.flip()





















New Annotation

Summary:
Author:
Mode:
Body: