Moving

‘Moving’ is an older program I made. Back then (november 2014) I was experimenting with collision detection. In this simulation there are randomly spawned in entities. Those entities bounce off each other and can also – sometimes – randomly change their direction.
The First ExampleThe Second ExampleThe Third Example


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

# entity class
class entity():
	# init
	def __init__(self):
		# unique ID
		game.lastID += 1
		self.id = game.lastID
		
		# image and rect
		self.image = pygame.Surface([50, 50])
		self.image.fill([random.randint(50 - 20, 50 + 20), random.randint(150 - 20, 150 + 20), random.randint(200 - 20, 200 + 20)])
		self.rect = self.image.get_rect()
		
		# position and direction
		self.pos = [random.randint(0, game.width - self.rect.right), random.randint(0, game.height - self.rect.bottom)]
		self.dir = random.randint(0, 3)
		
		# extra variables
		self.canThink = True
		self.canMove = True
	
	# render function
	def render(self):
		game.screen.blit(self.image, self.pos)
	
	# tick function
	def tick(self):
	# move if allowed
		if self.canMove:
			
			# calculate space to any other entity
			spaceTop =    maxOn(5, minOn(0, self.pos[1])                                   )
			spaceBottom = maxOn(5, minOn(0, game.height - (self.pos[1] + self.rect.bottom)))
			spaceLeft =   maxOn(5, minOn(0, self.pos[0])                                   )
			spaceRight =  maxOn(5, minOn(0, game.width - (self.pos[0] + self.rect.right))  )
			
			# entity collision
			for e in game.entities:
				# top collision
				if (self.rect.right + self.pos[0] > e.rect.left + e.pos[0] and self.rect.right + self.pos[0]  e.rect.left + e.pos[0] and self.rect.left + self.pos[0]  math.fabs((self.rect.top + self.pos[1]) - (e.rect.bottom + e.pos[1])):
						spaceTop = math.fabs((self.rect.top + self.pos[1]) - (e.rect.bottom + e.pos[1]))
				
				# bottom collision
				if (self.rect.right + self.pos[0] > e.rect.left + e.pos[0] and self.rect.right + self.pos[0]  e.rect.left + e.pos[0] and self.rect.left + self.pos[0]  math.fabs((self.rect.bottom + self.pos[1]) - (e.rect.top + e.pos[1])):
						spaceBottom = math.fabs((self.rect.bottom + self.pos[1]) - (e.rect.top + e.pos[1]))
				
				# left collision
				if (self.rect.bottom + self.pos[1] > e.rect.top + e.pos[1] and self.rect.bottom + self.pos[1]  e.rect.top + e.pos[1] and self.rect.top + self.pos[1]  math.fabs((self.rect.left + self.pos[0]) - (e.rect.right + e.pos[0])):
						spaceLeft = math.fabs((self.rect.left + self.pos[0]) - (e.rect.right + e.pos[0]))
				
				# right collision
				if (self.rect.bottom + self.pos[1] > e.rect.top + e.pos[1] and self.rect.bottom + self.pos[1]  e.rect.top + e.pos[1] and self.rect.top + self.pos[1]  math.fabs((e.rect.left + e.pos[0]) - (self.rect.right + self.pos[0])):
						spaceRight = math.fabs((e.rect.left + e.pos[0]) - (self.rect.right + self.pos[0]))
			
			# move in direction ('self.dir')
			# and maybe change direction
			
			# 0 -> up
			if self.dir == 0:
				self.pos[1] -= spaceTop
				# bounce off
				if spaceTop  down
			elif self.dir == 1:
				self.pos[1] += spaceBottom
				# bounce off
				if spaceBottom  left
			elif self.dir == 2:
				self.pos[0] -= spaceLeft
				# bounce off
				if spaceLeft  right
			elif self.dir == 3:
				self.pos[0] += spaceRight
				# bounce off
				if spaceRight  2 or 3
					self.dir = random.randint(2, 3)
					
				elif self.dir == 2 or self.dir == 3:
					# 'self.dir' -> 0 or 1
					self.dir = random.randint(0, 1)

# makes sure 'num' is not smaller than 'min'
def minOn(min, num):
	if num  max:
		return max
	return num

# render function
def render():
	# fill
	game.screen.fill([100, 100, 100])
	
	# render entities
	for e in game.entities:
		e.render()
	
	# flip
	pygame.display.flip()

# tick function
def tick():
	# handle events
	for event in pygame.event.get():
		# quit
		if event.type == pygame.QUIT:
			sys.exit()
	
	# tick entities
	for e in game.entities:
		e.tick()

# 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
			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 time, sys, pygame, random, math

game = dummy()
game.lastID = 0
game.width = 600
game.height = 400
game.size = [game.width, game.height]
game.screen = pygame.display.set_mode(game.size)
pygame.display.set_caption("Moving")
game.entities = []

# spawn in entities
for i in range(0, 10):
	game.entities.append(entity())

# main loop
run()
Advertisements

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