Circle Crawler

In this program there are entities equally positioned around the center. As the entities begin to move, they can either go toward the center, away from the center or stay. You can toggle if the entities move and if the screen gets refilled. The code is based on ‘Circle Walk II’, but the calculation for the entities to move in relation to the center is achieved by using vectors.

Usage

  • ‘m’ to toggle if entities are moving
  • ‘f’ to toggle if the screen gets refilled

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
#    version  II  1st of April, 2015

# modified version of 'Circle Walk II'
#       modified 17th of April, 2015

# easy vector functions
def convertVec(p1, p2):
	return [p2[0] - p1[0], p2[1] - p1[1]]
def getLength(vec):
	return math.sqrt( (vec[0]**2) + (vec[1]**2) )
def multiplyVec(vec, n):
	return [vec[0] * n, vec[1] * n]
def getPoint(vec, point):
	return [point[0] + vec[0], point[1] + vec[1]]

# 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, _number):
		self.startPos = _startPos
		self.pos = self.startPos[:]
		
		self.number = _number
		self.speed = 1
	
	# tick function
	def tick(self):
		#self.pos[0] += random.randint(-1, 1)
		#self.pos[1] += random.randint(-1, 1)
		
		# makes sure the point goes away from the center (using vectors)
		vec = convertVec(self.pos, main.CENTER)
		vecL = getLength(vec)
		if vecL != 0:
			vec0 = multiplyVec(vec, 1. / vecL)
			vecN = multiplyVec(vec0, vecL + random.randint(-1, 1) * self.speed)
			self.pos = getPoint(vecN, main.CENTER)

# tick function
def tick():
	# handle events
	for event in pygame.event.get():
		# quit program
		if event.type == pygame.QUIT:
				sys.exit()
		
		# key handle
		if event.type == pygame.KEYDOWN:
			# entities moving
			if event.key == pygame.K_m:
				if main.MOVING:
					main.MOVING = False
				else:
					main.MOVING = True
			
			# screen refilling
			if event.key == pygame.K_f:
				if main.FILL:
					main.FILL = False
				else:
					main.FILL = True
	
	if main.MOVING:
		for _ in main.ENTITIES:
			_.tick()
		
# render function
def render():
	# fill
	main.SCREEN.fill([0, 0, 0])
	if main.FILL:
		main.SURF.fill([0, 0, 0])
	
	# render entities
	l = None
	for _ in main.ENTITIES:
		if l != None:
			pygame.draw.line(main.SURF, [255, 0, 0], l, _.pos, main.THICKNESS)
		l = _.pos[:]
	
	if len(main.ENTITIES) > 1:
		pygame.draw.line(main.SURF, [255, 0, 0], l, main.ENTITIES[0].pos, main.THICKNESS)
	
	# scale and flip
	main.SCREEN.blit(pygame.transform.scale(main.SURF, [int(main.WIDTH * main.SCALE), int(main.HEIGHT * main.SCALE)]), [0, 0])
	pygame.display.flip()

# run function (uses 'tick()' and 'render()')
def run():
	ticksPerSecond = 60
	lastTime = time.time() * 1000000000
	nsPerTick =  1000000000.0 / float(ticksPerSecond)
	
	ticks = 0
	frames = 0
	
	lastTimer = time.time() * 1000
	delta = 0.0
	
	while True:
		now = time.time() * 1000000000
		delta += float(now - lastTime) / float(nsPerTick)
		lastTime = now
		shouldRender = False
				
		while delta >= 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
pygame.font.init()

main = dummy()

main.TICKS = 0
main.WIDTH, main.HEIGHT = 1080, 720
main.CENTER = [main.WIDTH / 2.0, main.HEIGHT / 2.0]
main.CENTERINT = [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 Crawler")

main.FILL = False

# entity init
main.THICKNESS = 1
main.MOVING = False
main.ENTITIES = []
n = 100
for _ in range(0, n):
	p = getCirclePos(main.CENTER, 100, 360. / n * _)
	main.ENTITIES.append(entity(p, _))

# start program
run()
Advertisements

One thought on “Circle Crawler

  1. Pingback: Circle Splatter | 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