Bobbles

In this program you can spawn in circular entities. Their color is defined by their position and they will move randomly across the screen. You can also toggle if their spawn time (in ticks) is shown or not and if the screen gets refilled.

Usage

  • Left-clicking spawns in a new entity (at current mouse position)
  • ‘f’ toggles if the screen gets refilled (view example number 3 for reference)
  • ‘n’ toggles if numbers are shown

The First Example The Second Example (numbers shown) The Third Example (not refilling the screen)


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

# 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

# returns 1 or -1
def getAOne():
	if random.randint(0, 1) == 0:
		return 1
	return -1

# entity class
class newEntity():
	def __init__(self, _pos, _num):
		self.pos = _pos
		self.num = _num
		self.radius = 10
		self.destination = self.pos[:]
		
		self.Ttext = main.FONT.render(str(self.num), 1, [255, 0, 0])
		self.Trect = self.Ttext.get_rect()
		#self.Tpos = 
	
	# render
	def render(self, _surf):
		pygame.draw.circle(_surf, [
			colorValid(self.pos[0]*self.pos[1] / 300),
			colorValid(self.pos[0]),
			colorValid(self.pos[1])
		], [int(self.pos[0]), int(self.pos[1])], self.radius)
		
		if main.SHOWNUMBERS:
			pos = [
				1 + (self.radius / 2) + self.pos[0],
				1 + (self.radius / 2) + self.pos[1]
			]
			_surf.blit(self.Ttext, pos)
	
	# tick
	def tick(self):
		# destination bounds
		if self.destination[0]  main.WIDTH:
			self.destination[0] = main.WIDTH
		if self.destination[1]  main.HEIGHT:
			self.destination[1] = main.HEIGHT
		
		# calculate distance
		dist = [
			self.destination[0] - self.pos[0],
			self.destination[1] - self.pos[1]
		]
		
		# move entity
		self.pos[0] += dist[0] * .1
		self.pos[1] += dist[1] * .1
		
		# re-calculate destination if entity is nearly at current destination
		# (.5 is half a pixel)
		if dist[0] <= .5 and dist[1] <= .5:
			# random movement
			self.destination[0] += getAOne() * 50
			self.destination[1] += getAOne() * 50
			
			# random destination
			"""
			self.destination[0] = random.randint(0, main.WIDTH)
			self.destination[1] = random.randint(0, main.HEIGHT)
			#"""
		
		# position bounds
		if self.pos[0]  main.WIDTH:
			self.pos[0] = main.WIDTH
		if self.pos[1]  main.HEIGHT:
			self.pos[1] = main.HEIGHT

# tick function
def tick():
	# handle events
	for event in pygame.event.get():
		# quit
		if event.type == pygame.QUIT:
				sys.exit()
		
		# key
		if event.type == pygame.KEYDOWN:
			
			# toggle 'main.SHOWNUMBERS'
			if event.key == pygame.K_n:
				if main.SHOWNUMBERS:
					main.SHOWNUMBERS = False
				else:
					main.SHOWNUMBERS = True
			
			# toggle 'main.FILL'
			if event.key == pygame.K_f:
				if main.FILL:
					main.FILL = False
				else:
					main.FILL = True
		
		# mouse
		if event.type == pygame.MOUSEBUTTONDOWN:
			# spawn in new entity
			if event.button == 1:
				main.ENTITIES.append(newEntity(
					getMousePos(), main.TICKS
				))
	
	# tick entities
	for _ in main.ENTITIES:
		_.tick()
	
# render function
def render():
	# fill
	main.SCREEN.fill([0, 0, 0])
	if main.FILL:
		main.SURF.fill([50, 50, 100])
	
	# render entities
	for _ in main.ENTITIES:
		_.render(main.SURF)
	
	# blit and flip
	main.SCREEN.blit(pygame.transform.scale(main.SURF, main.SCALEDSIZE), [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

import pygame, sys, time, math, os, random
pygame.font.init()

main = dummy()
main.TICKS = 0

main.WIDTH = 1080
main.HEIGHT = 720
main.SIZE = [main.WIDTH, main.HEIGHT]
main.SCALE = 1
main.SCALEDSIZE = [int(main.WIDTH * main.SCALE), int(main.HEIGHT * main.SCALE)]

main.SURF = pygame.Surface(main.SIZE)
main.SCREEN = pygame.display.set_mode(main.SCALEDSIZE)
pygame.display.set_caption("Bobbles")

main.ENTITIES = []
main.SHOWNUMBERS = False
main.FILL = True

main.FONT = pygame.font.Font(None, 20)

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