Shadow

Thinking about vectors and polygons a bit more, I came up with an idea to mimic shadows. In this program you can create colorful polygons with no limited quantity of individual points anywhere on the screen. Furthermore you then can move a light source (represented as a yellow circle) to change the polygon’s pitch black shadow.

A few polygons A few polygons, light source moved

The shadow can also be modified in that its distance to the polygon can be changed. To understand the shadow’s creation, there is also an option to visualize the path the light would – in reality – go.

A few polygons, light lines shown Jblog text and triangles, light source in center

Due to the shadow not changing in size (only in distance to its polygon) but rather in distance, I implemented the option to get a grid as the background. That way you more have the impression that the shadow is casted onto another surface beneath the surface containing all the polygons and not floating on the same surface.

A few polygons, light lines and grid shown A few polygons, grid shown Jblog text and triangles, grid shown

To have a nice contrast from the polygons to their shadow, I decided to give every polygon a randomly assigned color by creation.

Jblog text and triangles

Lastly the program will save every polygon that has been drawn in a file called ’tiles.txt’. It will be saved in the current working directory (in short ‘cwd’). If you create a new polygon or change the color of an existing one, it will automatically be saved.

Usage

  • right-clicking moves the light source
  • left-clicking adds one new point (for polygon creation)
  • left-clicking in flowdraw-mode adds points while holding the button
  • middle-clicking will connect the new points and create another polygon
  • scrolling (mouse wheel) changes the shadow-polygon distance
  • scrolling while holding ‘space’ changes the distance ten times as rapid
  • ‘l’ toggles if the path of the light is shown
  • ‘b’ toggles if the background grid is shown
  • ‘f’ toggles flowdraw-mode
  • ‘r’ removes the polygon containing a point nearest to the mouse courser
  • ‘c’ changes the polygon’s color containing a point nearest to the mouse courser
  • ‘s’ lets you manually save your progress
  • all the key bindings can be changed by linking – in the code posted below – ‘main.keys.X’ to another ‘pygame.K_X’.

Jblog text and triangles, grid shown
An example how ’tiles.txt’ can look (here for drawing ‘Jblog’ and some triangles).

main.TILES.append( tile([[266, 194], [267, 194], [268, 194], [269, 194], [270, 194], [274, 194], [276, 195], [278, 195], [280, 195], [282, 195], [284, 195], [287, 195], [289, 195], [292, 195], [295, 195], [299, 196], [303, 196], [307, 196], [310, 197], [313, 197], [315, 197], [316, 197], [318, 197], [319, 197], [321, 197], [323, 197], [324, 197], [326, 197], [326, 198], [326, 199], [326, 207], [326, 208], [326, 209], [326, 211], [325, 213], [325, 215], [325, 217], [325, 219], [325, 221], [325, 224], [325, 227], [325, 230], [324, 236], [323, 242], [322, 249], [322, 256], [322, 263], [320, 270], [320, 276], [320, 281], [320, 285], [320, 289], [320, 293], [320, 297], [320, 300], [320, 303], [320, 306], [320, 309], [320, 312], [320, 313], [321, 315], [321, 316], [321, 317], [321, 318], [321, 319], [321, 320], [321, 321], [321, 322], [321, 323], [321, 324], [321, 325], [321, 326], [321, 327], [321, 328], [321, 329], [321, 330], [321, 331], [321, 332], [321, 333], [321, 334], [317, 334], [317, 335], [316, 336], [312, 336], [311, 336], [310, 337], [310, 339], [309, 339], [308, 339], [307, 340], [306, 340], [305, 340], [304, 341], [303, 341], [302, 341], [301, 341], [299, 341], [298, 341], [298, 339], [296, 339], [294, 338], [292, 337], [290, 336], [287, 335], [284, 333], [282, 331], [280, 330], [277, 328], [276, 326], [276, 325], [275, 323], [274, 321], [273, 320], [273, 318], [273, 317], [273, 316], [273, 315], [273, 313], [273, 312], [273, 311], [273, 310], [273, 309], [275, 307], [275, 306], [275, 305], [277, 304], [278, 303], [278, 302], [280, 302], [281, 302], [282, 302], [283, 302], [284, 302], [285, 301], [286, 301], [287, 301], [288, 301], [289, 301], [289, 302], [297, 302], [298, 303], [298, 305], [298, 306], [298, 307], [299, 307], [299, 308], [299, 309], [300, 310], [300, 311], [300, 312], [301, 313], [302, 314], [303, 316], [305, 316], [306, 316], [306, 315], [306, 313], [307, 311], [307, 308], [307, 305], [307, 302], [307, 299], [307, 297], [307, 295], [307, 293], [307, 291], [307, 289], [307, 284], [307, 281], [307, 278], [307, 275], [307, 272], [307, 268], [307, 264], [307, 260], [307, 253], [308, 250], [308, 247], [308, 244], [308, 241], [308, 238], [308, 236], [308, 234], [308, 233], [308, 232], [308, 231], [307, 231], [306, 231], [305, 231], [303, 231], [302, 231], [301, 231], [299, 231], [297, 231], [293, 231], [291, 231], [290, 231], [286, 231], [283, 231], [281, 231], [279, 231], [277, 231], [276, 231], [274, 230], [273, 229], [272, 229], [272, 227], [272, 225], [272, 222], [272, 219], [271, 216], [271, 213], [271, 210], [271, 207], [271, 204], [271, 202], [271, 201], [271, 200]], [184, 216, 171]) )
main.TILES.append( tile([[355, 205], [355, 207], [355, 208], [355, 210], [355, 211], [355, 213], [355, 216], [355, 223], [355, 230], [355, 237], [354, 244], [354, 249], [353, 253], [353, 257], [353, 262], [353, 266], [352, 270], [352, 274], [351, 278], [351, 281], [351, 285], [351, 288], [351, 291], [351, 294], [351, 296], [351, 298], [351, 300], [351, 302], [351, 304], [351, 306], [350, 308], [350, 310], [350, 312], [349, 314], [348, 315], [348, 317], [347, 317], [347, 318], [347, 319], [347, 320], [347, 321], [347, 322], [347, 323], [347, 324], [347, 325], [347, 326], [347, 327], [347, 328], [347, 329], [347, 330], [348, 331], [348, 332], [349, 333], [351, 334], [352, 334], [353, 335], [355, 336], [357, 337], [359, 337], [361, 337], [364, 337], [367, 337], [370, 337], [373, 337], [376, 337], [378, 337], [379, 337], [381, 337], [383, 335], [384, 334], [385, 333], [387, 333], [388, 332], [389, 329], [391, 328], [392, 326], [393, 323], [394, 321], [395, 319], [395, 317], [395, 315], [396, 313], [396, 311], [396, 309], [396, 307], [396, 306], [396, 303], [395, 301], [393, 299], [393, 298], [391, 297], [390, 296], [388, 294], [380, 294], [377, 293], [375, 293], [373, 292], [371, 291], [369, 290], [368, 290], [367, 288], [366, 287], [365, 287], [365, 285], [365, 283], [365, 282], [365, 280], [365, 279], [366, 278], [366, 276], [367, 274], [368, 272], [369, 270], [371, 268], [371, 266], [372, 264], [372, 262], [372, 260], [373, 257], [373, 255], [374, 253], [376, 250], [377, 247], [378, 244], [379, 241], [381, 238], [382, 234], [383, 230], [383, 227], [384, 224], [385, 221], [385, 218], [385, 216], [385, 215], [385, 214], [385, 212], [383, 212], [382, 211], [380, 211], [379, 211], [377, 210], [375, 209], [373, 208], [371, 208], [369, 208], [368, 208], [364, 208], [362, 208], [362, 207], [361, 207], [360, 207], [360, 206], [359, 206]], [240, 120, 26]) )
main.TILES.append( tile([[423, 206], [423, 207], [423, 208], [423, 209], [423, 210], [423, 211], [423, 212], [422, 215], [422, 218], [421, 221], [420, 224], [420, 228], [419, 234], [419, 236], [419, 238], [418, 241], [418, 246], [418, 248], [418, 250], [417, 254], [417, 256], [417, 258], [417, 263], [417, 266], [416, 272], [416, 276], [416, 284], [416, 287], [416, 294], [415, 297], [415, 303], [415, 306], [415, 311], [415, 314], [415, 318], [415, 320], [416, 322], [417, 323], [417, 325], [419, 326], [421, 328], [426, 330], [429, 332], [432, 333], [435, 333], [437, 333], [441, 333], [443, 333], [444, 333], [446, 331], [446, 330], [447, 328], [447, 327], [448, 325], [448, 318], [448, 316], [448, 314], [448, 313], [447, 312], [446, 309], [444, 307], [441, 306], [440, 305], [438, 304], [436, 304], [435, 303], [434, 303], [434, 302], [433, 301], [431, 300], [431, 298], [431, 297], [431, 296], [431, 294], [431, 291], [431, 290], [431, 286], [432, 284], [433, 278], [433, 276], [433, 271], [433, 268], [433, 265], [433, 262], [434, 260], [434, 255], [435, 253], [435, 250], [435, 248], [437, 243], [437, 241], [438, 236], [439, 233], [439, 231], [439, 228], [439, 223], [439, 221], [439, 218], [439, 217], [439, 215], [439, 214], [438, 214], [438, 213], [437, 212], [436, 211], [436, 209], [435, 209], [435, 208], [433, 208], [431, 207], [430, 207], [429, 206], [428, 206], [428, 205], [426, 205]], [47, 219, 39]) )
main.TILES.append( tile([[485, 282], [486, 281], [489, 281], [490, 279], [492, 279], [493, 279], [495, 278], [497, 277], [498, 277], [500, 277], [504, 276], [506, 276], [508, 276], [512, 275], [514, 275], [516, 275], [517, 275], [519, 277], [521, 278], [523, 279], [525, 281], [526, 283], [527, 284], [528, 285], [529, 288], [529, 289], [529, 293], [529, 295], [529, 298], [528, 300], [528, 303], [527, 305], [526, 307], [526, 309], [525, 310], [525, 311], [523, 312], [522, 313], [521, 313], [513, 313], [511, 313], [510, 313], [508, 314], [507, 314], [505, 314], [502, 314], [498, 314], [496, 314], [493, 314], [490, 313], [481, 313], [479, 312], [478, 310], [477, 308], [477, 305], [477, 303], [477, 302], [477, 301], [477, 299], [477, 298], [477, 296], [477, 295], [478, 293], [479, 292], [481, 290], [481, 288], [482, 288], [483, 286], [484, 286], [484, 284], [484, 283], [484, 281], [484, 280]], [154, 123, 153]) )
main.TILES.append( tile([[575, 280], [573, 280], [571, 280], [567, 280], [564, 280], [562, 280], [554, 281], [552, 282], [552, 283], [550, 285], [549, 286], [548, 288], [548, 290], [548, 291], [547, 293], [547, 294], [547, 296], [547, 297], [547, 298], [547, 299], [548, 301], [549, 301], [549, 303], [550, 304], [552, 305], [553, 307], [554, 308], [557, 308], [558, 308], [560, 308], [561, 308], [563, 308], [563, 307], [566, 307], [567, 306], [571, 304], [573, 303], [574, 300], [576, 299], [576, 297], [577, 296], [577, 295], [577, 294], [578, 292], [578, 291], [578, 289], [578, 288], [578, 286], [578, 285], [578, 296], [578, 298], [578, 301], [578, 303], [578, 306], [577, 310], [577, 314], [577, 318], [577, 322], [577, 326], [577, 330], [577, 332], [577, 334], [577, 338], [577, 339], [577, 344], [577, 347], [577, 352], [577, 354], [576, 358], [576, 360], [576, 361], [575, 362], [575, 363], [574, 364], [573, 365], [565, 366], [564, 367], [561, 368], [560, 369], [558, 369], [556, 369], [555, 369], [553, 369], [552, 369], [550, 369], [549, 369], [549, 368], [549, 366], [547, 365], [547, 362], [547, 360], [547, 358], [547, 356], [548, 355], [549, 355], [550, 353], [551, 352], [551, 350], [552, 349], [553, 347], [554, 347], [555, 344], [556, 343], [557, 340], [558, 340], [558, 339], [559, 339], [560, 336], [561, 334], [562, 333], [562, 332], [563, 332], [563, 330], [565, 328], [565, 326], [566, 324], [566, 323], [567, 321], [568, 319], [568, 318], [570, 317], [570, 315], [570, 313], [570, 312], [570, 311], [571, 310], [571, 308]], [73, 14, 43]) )
main.TILES.append( tile([[280, 353], [281, 353], [281, 352], [283, 352], [285, 352], [286, 352], [287, 352], [287, 351], [290, 351], [293, 351], [294, 351], [296, 351], [297, 351], [299, 350], [301, 350], [303, 350], [307, 350], [311, 349], [314, 349], [316, 349], [319, 349], [325, 348], [331, 348], [333, 348], [337, 348], [339, 348], [343, 348], [345, 348], [350, 348], [353, 348], [359, 348], [362, 348], [369, 348], [372, 348], [375, 348], [383, 348], [387, 348], [390, 348], [393, 348], [403, 348], [407, 348], [417, 348], [422, 348], [436, 348], [441, 348], [450, 347], [460, 347], [467, 346], [477, 346], [484, 345], [490, 345], [496, 345], [503, 344], [510, 344], [513, 344], [514, 344], [516, 343], [518, 343], [519, 343], [519, 342], [521, 342], [522, 342], [524, 342], [525, 342], [525, 343], [526, 343], [528, 344], [528, 345], [528, 347], [528, 348], [528, 350], [528, 352], [529, 356], [529, 360], [530, 363], [531, 366], [531, 370], [532, 373], [535, 377], [538, 380], [540, 380], [545, 380], [549, 381], [559, 381], [563, 381], [572, 381], [581, 380], [584, 380], [587, 380], [589, 379], [597, 379], [597, 378], [597, 377], [598, 376], [598, 375], [600, 371], [600, 369], [601, 365], [602, 363], [602, 358], [602, 353], [602, 351], [602, 347], [602, 343], [603, 340], [603, 337], [603, 329], [605, 328], [606, 327], [608, 327], [612, 325], [614, 325], [618, 325], [620, 325], [624, 325], [626, 325], [627, 325], [629, 325], [631, 325], [633, 325], [634, 325], [637, 325], [637, 326], [639, 326], [639, 327], [639, 328], [639, 329], [639, 330], [639, 333], [639, 335], [639, 339], [639, 344], [638, 349], [638, 354], [638, 358], [638, 363], [638, 369], [638, 376], [638, 382], [638, 387], [638, 391], [637, 394], [636, 397], [636, 398], [633, 399], [632, 399], [630, 400], [629, 400], [625, 401], [623, 401], [617, 401], [614, 401], [609, 401], [606, 401], [602, 401], [598, 401], [592, 401], [590, 401], [585, 401], [583, 402], [577, 402], [574, 402], [572, 402], [566, 402], [561, 403], [555, 403], [550, 403], [546, 403], [542, 403], [538, 403], [534, 403], [531, 403], [529, 403], [525, 403], [519, 403], [517, 403], [511, 403], [508, 403], [504, 403], [501, 403], [496, 403], [494, 403], [491, 403], [489, 403], [485, 403], [483, 403], [481, 403], [480, 403], [478, 403], [476, 403], [472, 403], [470, 403], [464, 403], [459, 403], [449, 402], [439, 402], [431, 402], [427, 402], [417, 402], [407, 402], [400, 402], [392, 402], [378, 401], [366, 399], [356, 398], [340, 393], [336, 392], [331, 390], [328, 389], [325, 389], [324, 389], [322, 388], [321, 388], [316, 388], [315, 387], [313, 387], [312, 387], [311, 387], [309, 387], [305, 387], [303, 387], [302, 386], [294, 386], [292, 385], [289, 385], [287, 384], [285, 382], [282, 380], [280, 379], [279, 376], [279, 374], [279, 372], [278, 369], [278, 367], [278, 363], [278, 359], [278, 355], [278, 354], [278, 349], [278, 348], [278, 346]], [114, 236, 243]) )
main.TILES.append( tile([[904, 115], [957, 132], [903, 188], [815, 282]], [38, 109, 45]) )
main.TILES.append( tile([[990, 482], [1021, 539], [804, 472]], [182, 147, 233]) )
main.TILES.append( tile([[802, 683], [726, 695], [706, 571]], [3, 69, 112]) )
main.TILES.append( tile([[922, 626], [1012, 581], [751, 524]], [25, 120, 138]) )
main.TILES.append( tile([[1011, 348], [1035, 429], [818, 391]], [156, 162, 83]) )
main.TILES.append( tile([[988, 176], [1034, 269], [862, 324]], [216, 76, 87]) )
main.TILES.append( tile([[640, 179], [614, 47], [684, 49]], [207, 124, 3]) )
main.TILES.append( tile([[723, 216], [747, 69], [838, 84]], [85, 35, 17]) )
main.TILES.append( tile([[311, 61], [421, 84], [419, 86], [304, 102], [302, 103], [316, 119], [319, 119], [331, 119], [347, 120], [354, 121], [356, 124], [354, 137], [352, 142], [347, 142], [338, 136], [326, 123], [325, 118], [340, 104], [373, 102], [382, 102], [396, 105], [405, 106], [413, 103], [413, 97]], [205, 172, 248]) )

# Python 2.7.7 Code
# Pygame 1.9.1 (for Python 2.7.7)
# Jonathan Frech 12th of May, 2015
#         edited 13th of May, 2015

Version_Number = 1.1
Version_Name = "Shadow"
Version_Author = "Jonathan Frech"

Version_Caption = Version_Name + " V. " + str(Version_Number)

# 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]]
def addVec(vec1, vec2):
	return [vec1[0] + vec2[0], vec1[1] + vec2[1]]

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

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

# 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)))
			]

# swaps a boolean
def boolSwap(_bool):
	if _bool:
		return False
	else:
		return True

# returns an position which does not contain floats
# ('pygame.draw.cirlce()'!)
def intPos(_pos):
	return [
		int(_pos[0]),
		int(_pos[1])
	]

# returns the nearest tile (nearest to one of its points) to given position
def getNearestTileTo(_pos):
	minDistance = None
	nearest = None
	for _ in main.TILES:
		for __ in _.points:
			distance = getDistance(_pos, __)
			if minDistance == None or distance < minDistance:
				minDistance = distance
				nearest = _
	
	return nearest

# save the tiles
def saveTiles():
	try:
		doc = open(main.TILEFILE, "w")
		for _ in main.TILES:
			doc.write(str(_) + "\n")
		doc.close()
	except:
		pass

# load the tiles
def loadTiles():
	content = None
	try:
		doc = open(main.TILEFILE, "r")
		content = doc.read().splitlines()
		doc.close()
	except:
		pass
	
	if content != None:
		for _ in content:
			try:
				exec _
			except:
				pass

# tile class
class tile():
	# init
	def __init__(self, _points, _color = None):
		self.points = _points
		self.color = _color
		
		self.shadowPoints = []
		
		if self.color == None:
			self.changeColor()
	
	# str function
	def __str__(self):
		msg = "main.TILES.append( tile(" + str(self.points) + ", " + str(self.color) + ") )"
		
		return msg
	
	# random color (for fun)
	def changeColor(self):
		self.color = [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]
	
	# render the tile
	def render(self, _surface):
		pygame.draw.polygon(_surface, self.color, self.points)

	# render its shadow (using vectors, from light source)
	def renderShadow(self, _surface):
		self.shadowPoints = []
		for _ in self.points:
			vec = convertVec(main.LIGHTPOS, _)
			vecL = getLength(vec)
			if vecL != 0:
				vec0 = multiplyVec(vec, 1. / vecL)
				vecN = multiplyVec(vec0, main.SHADOWDISTANCE)
				self.shadowPoints.append(
					getPoint(vecN, _)
				)
			
		pygame.draw.polygon(_surface, [0, 0, 0], self.shadowPoints)

# tick function
def tick():
	# handle events
	for event in pygame.event.get():
		# quit
		if event.type == pygame.QUIT:
				sys.exit()
		
		# keyup
		if event.type == pygame.KEYUP:
			# handle 'main.KEYSDOWN'
			if event.key in main.KEYSDOWN:
				main.KEYSDOWN.remove(event.key)
		
		# keydown
		if event.type == pygame.KEYDOWN:
			# handle 'main.KEYSDOWN'
			if event.key not in main.KEYSDOWN:
				main.KEYSDOWN.append(event.key)
			
			# toggle if the light lines are shown
			if event.key == main.keys.lightLines:
				main.SHOWLIGHTLINES = boolSwap(main.SHOWLIGHTLINES)
			
			# remove the tile nearest to mouse position
			if event.key == main.keys.remove:
				nearest = getNearestTileTo(getMousePos())
				if nearest != None:
					main.TILES.remove(nearest)
			
			# change the tile's color nearest to mouse position
			if event.key == main.keys.colorChange:
				nearest = getNearestTileTo(getMousePos())
				if nearest != None:
					nearest.changeColor()
					
					# save
					saveTiles()
			
			# save
			if event.key == main.keys.save:
				saveTiles()
			
			# backlines (toggle)
			if event.key == main.keys.backlines:
				main.BACKLINES = boolSwap(main.BACKLINES)
			
			# flowdraw (toggle)
			if event.key == main.keys.flowdraw:
				main.FLOWDRAWMODE = boolSwap(main.FLOWDRAWMODE)
		
		# mousebuttondown
		if event.type == pygame.MOUSEBUTTONDOWN:
			# add a point (single click)
			if event.button == 3:
				if not main.FLOWDRAWMODE:
					p = getMousePos()
					if [p[0], p[1]] not in main.NEWPOINTS:
						main.NEWPOINTS.append(p)
			
			# create the tile from 'main.NEWPOINTS'
			elif event.button == 2:
				if len(main.NEWPOINTS) > 2:
					main.TILES.append(
						tile(main.NEWPOINTS)
					)
				main.NEWPOINTS = []
				
				# save
				saveTiles()
			
			# shadow distance +
			elif event.button == 4:
				if main.keys.stepUp in main.KEYSDOWN:
					main.SHADOWDISTANCE += 10
				else:
					main.SHADOWDISTANCE += 1
			
			# shadow distance -
			elif event.button == 5:
				if main.keys.stepUp in main.KEYSDOWN:
					main.SHADOWDISTANCE -= 10
				else:
					main.SHADOWDISTANCE -= 1
				
				if main.SHADOWDISTANCE < 1:
					main.SHADOWDISTANCE = 1
	
	# move light pos
	if pygame.mouse.get_pressed()[0]:
		main.LIGHTDEST = getMousePos()
	
	# add a point (hold click)
	if main.FLOWDRAWMODE:
		if pygame.mouse.get_pressed()[2]:
			p = getMousePos()
			if [p[0], p[1]] not in main.NEWPOINTS:
				main.NEWPOINTS.append(p)
	
	# calculate distance to destination (for smooth movement)
	dist = [
		main.LIGHTDEST[0] - main.LIGHTPOS[0],
		main.LIGHTDEST[1] - main.LIGHTPOS[1]
	]
	# move to destination (/ 5.0 defines the speed)
	main.LIGHTPOS[0] += dist[0] / 20.0
	main.LIGHTPOS[1] += dist[1] / 20.0

# render function
def render():
	# fill
	main.SCREEN.fill(main.BACKGROUNDCOLOR)
	if main.FILL:
		main.SURF.fill(main.COLOR)
	
	# render background lines (if turned on)
	if main.BACKLINES:
		n = 10
		for _ in range(0, main.WIDTH / n):
			pygame.draw.line(main.SURF, [180, 0, 0], [_*n, 0], [_*n, main.HEIGHT])
		for _ in range(0, main.HEIGHT / n):
			pygame.draw.line(main.SURF, [180, 0, 0], [0, _*n], [main.WIDTH, _*n])
	
	# render tile shadows
	for _ in main.TILES:
		_.renderShadow(main.SURF)
	
	# render tiles (and light lines if turned on)
	for _ in main.TILES:
		_.render(main.SURF)
	pygame.draw.circle(main.SURF, [200, 200, 0], intPos(main.LIGHTPOS), 10)
	if main.SHOWLIGHTLINES:
		for _ in main.TILES:
			for __ in range(0, len(_.points)):
				pygame.draw.line(main.SURF, [200, 200, 0], main.LIGHTPOS, _.points[__])
				pygame.draw.line(main.SURF, [100, 100, 0], _.points[__], _.shadowPoints[__])
	
	# draw 'main.NEWPOINTS' (used to create a new tile)
	for _ in main.NEWPOINTS:
		pygame.draw.circle(main.SURF, [0, 255, 0], _, 3)
	
	# blit 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

# importing needed modules
import pygame, sys, time, math, os, random

# main dummy
main = dummy()
main.TICKS = 0

main.RES = 1
main.WIDTH = 1080 / main.RES
main.HEIGHT = 720 / main.RES
main.SIZE = [main.WIDTH, main.HEIGHT]
main.CENTER = [main.WIDTH / 2, main.HEIGHT / 2]
main.CENTERFLOAT = [main.WIDTH / 2.0, main.HEIGHT / 2.0]

main.SCALE = 1 * main.RES
main.SCALEDSIZE = [int(main.WIDTH * main.SCALE), int(main.HEIGHT * main.SCALE)]
main.SCALEDSIZEFLOAT = [main.WIDTH * main.SCALE, main.HEIGHT * main.SCALE]

main.SURF = pygame.Surface(main.SIZE)

main.SCREEN = pygame.display.set_mode(main.SCALEDSIZE)
pygame.display.set_caption(Version_Caption)

main.BACKGROUNDCOLOR = [0, 0, 0]
main.COLOR = [150, 0, 0]
main.FILL = True

main.KEYSDOWN = []

# precreated tiles
main.TILES = []
main.TILEFILE = os.getcwd() + "/tiles.txt"
loadTiles()

main.NEWPOINTS = []

main.LIGHTPOS = main.CENTERFLOAT[:]
main.LIGHTDEST = main.LIGHTPOS[:]
main.SHADOWDISTANCE = 30
main.SHOWLIGHTLINES = False
main.BACKLINES = False
main.FLOWDRAWMODE = False

main.keys = dummy()
main.keys.remove = pygame.K_r
main.keys.colorChange = pygame.K_c
main.keys.save = pygame.K_s
main.keys.lightLines = pygame.K_l
main.keys.stepUp = pygame.K_SPACE
main.keys.backlines = pygame.K_b
main.keys.flowdraw = pygame.K_f

# start program
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