Circle Walk

In an attempt to create systems with entities which influence each other I created ‘Circle Walk’. In this program you can spawn in entities which will go around the center with variant speed. When two entities get near each other, they will randomly change their distance to the center and eventually get away from one another.

Usage

  • Click with the left mouse button to spawn in a new entity

The First ExampleThe Second ExampleThe Third Example


# Python 2.7.7 Code
# Pygame 1.9.1 (for Python 2.7.7)
# Jonathan Frech 15th of March, 2015
#         edited 30th of March, 2015

# gets the distance between two points
def getDistance(p1, p2):
	return int(math.sqrt((p2[0] - p1[0])**2 + (p2[1] - p1[1])**2))

# gets the scaled mouse position
def getMousePos():
	return [pygame.mouse.get_pos()[0] / main.SCALE, pygame.mouse.get_pos()[1] / main.SCALE]

# validates color integer
# extra feature: _min and _max implementation
def colorValid(_color, _min = 0, _max = 255):
	newColor = math.fabs(_color)
	n = _max - _min
	
	if newColor > n:
		if int(newColor / n) % 2 == 0:
			newColor = newColor % n
		else:
			newColor = n - (newColor % n)
	
	return int(newColor) + _min

# gets the position on a circle
# circle center                           : '_pos'
# circle radius                           : '_radius'
# angle from center to point on the circle: '_angle'
def getCirclePos(_pos, _radius, _angle):
	return [
				int(_pos[0] + _radius * math.cos(math.radians(_angle))),
				int(_pos[1] + _radius * math.sin(math.radians(_angle)))
			]

# entity class
class entity():
	def __init__(self, _startPos):
		self.startPos = _startPos
		self.pos = self.startPos[:]
		
		self.angle = random.randint(0, 359)
		self.anglespeed = random.randint(1, 10) / 10.0
		self.distance = 200
		self.destination = main.MIDDLEINT
		
		self.radius = 25
	
	# render function
	def render(self, _surface):
		# calculate color based on position
		col = [
			colorValid(255.0 / main.WIDTH  * self.pos[0]),
			colorValid(255.0 / main.HEIGHT * self.pos[1]),
			42
		]
		
		# draw the entity
		pygame.draw.circle(_surface, col, [int(self.pos[0]), int(self.pos[1])], self.radius)
		# draw a line to the center of the display
		pygame.draw.line(_surface, [255, 0, 0], self.pos, main.MIDDLEINT)
		# draw a circle (entity's path)
		pygame.draw.circle(_surface, [30, 30, 80], main.MIDDLEINT, getDistance(self.pos, main.MIDDLEINT), 1)
	
	# tick function
	def tick(self):
		# update angle (to move along the path)
		self.angle += self.anglespeed
		if self.angle >= 360:
			self.angle = self.angle % 360
		
		# update destination
		self.destination = getCirclePos(main.MIDDLE, self.distance, self.angle)
		
		# calculate distance to destination (for smooth movement)
		dist = [
			self.destination[0] - self.pos[0],
			self.destination[1] - self.pos[1]
		]
		# move to destination (/ 5.0 defines the speed)
		self.pos[0] += dist[0] / 5.0
		self.pos[1] += dist[1] / 5.0

# tick function
def tick():
	# handle events
	for event in pygame.event.get():
		# quit program
		if event.type == pygame.QUIT:
				sys.exit()
		
		# spawn in new entities
		if event.type == pygame.MOUSEBUTTONDOWN:
			if event.button == 1:
				main.ENTITIES.append(entity(getMousePos()))
	
	# handle entities
	# (and checks if two points are too near to each other)
	w = -1
	for _ in main.ENTITIES:
		w += 1
		
		needToChange = False
		ww = -1
		for __ in main.ENTITIES:
			ww += 1
			if w != ww and getDistance(_.pos, __.pos) <= 100 * _.anglespeed:
				needToChange = True
				break
		
		if needToChange:
			_.distance += random.randint(-1, 1) * 50
		
		if _.distance < 0:
			_.distance = -_.distance
		if _.distance = 1:
			ticks += 1
			main.TICKS += 1
			tick()
			delta -= 1
			shouldRender = True
		
		if shouldRender:
			frames += 1
			render()
		
		if time.time() * 1000 - lastTimer >= 1000:
			lastTimer += 1000
			
			# debug
			#print("Frames: " + str(frames) + ", ticks: " + str(ticks))
			
			frames = 0
			ticks = 0

# dummy class for global variables
class dummy():
	pass

# init
import pygame, sys, time, math, os, random

main = dummy()

main.TICKS = 0
main.WIDTH, main.HEIGHT = 1080, 720
main.MIDDLE = [main.WIDTH / 2.0, main.HEIGHT / 2.0]
main.MIDDLEINT = [main.WIDTH / 2, main.HEIGHT / 2]
main.SIZE = [main.WIDTH, main.HEIGHT]
main.SURF = pygame.Surface(main.SIZE)

main.SCALE = 1
main.SCALEDSIZE = [int(main.WIDTH * main.SCALE), int(main.HEIGHT * main.SCALE)]
main.SCREEN = pygame.display.set_mode(main.SCALEDSIZE)
pygame.display.set_caption("Circle Walk")

main.ENTITIES = []
main.ANGLEADD = .5

# start program
run()
Advertisements

One thought on “Circle Walk

  1. Pingback: Circle Walk II | J-Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s