Commits

Anonymous committed 5893575

Initial commit

  • Participants

Comments (0)

Files changed (16)

+syntax: glob
+.metadata/*

File roguelike/.project

+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>MonsterSlayers</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>

File roguelike/.pydevproject

+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?><pydev_project>
+<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+<path>/roguelike</path>
+</pydev_pathproperty>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 3.0</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+</pydev_project>

File roguelike/Brown Block.png

Added
New image

File roguelike/Character Cat Girl.png

Added
New image

File roguelike/Enemy Bug.png

Added
New image

File roguelike/Gem Blue.png

Added
New image

File roguelike/Grass Block.png

Added
New image

File roguelike/Key.png

Added
New image

File roguelike/Plain Block.png

Added
New image

File roguelike/Rock.png

Added
New image

File roguelike/Tree Short.png

Added
New image

File roguelike/Tree Tall.png

Added
New image

File roguelike/Water Block.png

Added
New image

File roguelike/Wood Block.png

Added
New image

File roguelike/main.py

+'''
+Created: Aug 4, 2013
+Last modified: Aug 7, 2013 
+'''
+
+import pygame
+import math
+import sys
+
+
+
+######################################################################## engine
+
+def get_stick(joy, axisX, axisY):
+	state = ( joy.get_axis(axisX), joy.get_axis(axisY) )
+	
+	magSq = magnitudeSq2d(state)
+	
+	### The MadCatz controller reports a vector magnitude of >1 when the sticks
+	### are tilted towards the corners, which seems to be because of a dead
+	### zone around the outside. Negating this by normalizing the vector
+	### whenever its magnitude is >1.
+	if magSq > 1:
+		return normalize2d(state)
+	
+	dead_zone_radius = .2
+	
+	### Circular dead zone
+	if magSq < dead_zone_radius ** 2:
+		return (0, 0)
+	
+	### Scale usable input space so it goes from 0->1 instead of abruptly
+	### jumping to the hardware's representation of the edge of the dead zone.
+	mag = math.sqrt(magSq)
+	max_mag = 1 - dead_zone_radius
+	#new_mag = max_mag / mag
+	new_mag = (mag - dead_zone_radius) / max_mag
+	
+	return mag_scale_to_2d(state, new_mag)
+
+def sum2d(a, b):
+	return (a[0] + b[0], a[1] + b[1])
+def dif2d(a, b):
+	return (a[0] - b[0], a[1] - b[1])
+
+def magnitudeSq2d(vec):
+	return vec[0] ** 2 + vec[1] ** 2
+def magnitude2d(vec):
+	return math.sqrt(magnitudeSq2d(vec))
+
+def normalize2d(vec):
+	return mag_scale_2d(vec, 1 / magnitude2d(vec))
+
+def int2d(vec):
+	return (int(vec[0]), int(vec[1]))
+
+def mag_scale_2d(vec, scalar):
+	return (vec[0] * scalar, vec[1] * scalar)
+def mag_scale_to_2d(vec, scalar):
+	if not math.isfinite(scalar):
+		raise Exception() # because this was probably not intended
+	#try:
+	return mag_scale_2d(vec, scalar / magnitude2d(vec))
+	#except:
+	#	return (NaN, NaN)
+	### Just let it throw when the vector has a magnitude of zero; there's no
+	### real way to klodge that into a usable number because it would require
+	### a direction.
+	### A real programming language would allow this function to have
+	### preconditions.
+
+def flipY2d(vec):
+	return (vec[0], -vec[1])
+def flip2d(vec):
+	return (-vec[0], -vec[1])
+
+def scale2d(vec, scalar):
+	return (vec[0] * scalar, vec[1] * scalar)
+
+
+EVENT_DRAW = 100
+
+event_handlers = [] # contains: (predicate:function, callback:function)
+def proc_event(event):
+	for handler in event_handlers:
+		if handler[0](event):
+			handler[1]()
+			
+def proc_events():
+	for event in pygame.event.get():
+		proc_event(event)
+		
+def event_loop():
+	while True:
+		proc_events()
+		
+		surfaceScreen.fill(colorBG)
+		proc_event(pygame.event.Event(EVENT_DRAW))
+		pygame.display.update()
+
+def on_event(predicate, callback):
+	### TODO: take priorty as parameter so screen flip and hud drawing can be
+	### registered in any order
+	
+	### TODO: what about attaching events to other events?
+	def remove():
+		raise Exception('on_event()~~>remove() not implemented')
+		### This requires a linked list or something similar
+		
+	event_handlers.append((predicate, callback))
+	return remove
+
+
+
+
+
+
+
+
+
+########################################################################### app
+
+on_event(lambda a: a.type == pygame.QUIT, lambda: sys.exit())
+
+def draw_joy_input():
+	#for joy in range(len(joysticks)):
+	for joyIndex, joy in enumerate(joysticks):
+		for button in range(joy.get_numbuttons()):
+			pygame.draw.rect(
+				surfaceScreen,
+				(colorDebugToggleOn if joy.get_button(button) else colorDebugToggleOff),
+				pygame.Rect(button * 40 + 5, joyIndex * 50 + 10, 30, 30)
+			)
+		#print(str(joy) + ': ' + str(joysticks[joy].get_axis(0)))
+		
+		sticks = [ (0, 1), (4, 3) ]
+		for i in range(len(sticks)):
+			axes = sticks[i]
+			stick_center = ((joy.get_numbuttons() + i) * 40 + 5 + 15, joyIndex * 50 + 10 + 15)
+			pygame.draw.circle(surfaceScreen, colorDebug0, stick_center, 15)
+			pygame.draw.line(
+				surfaceScreen, colorDebug1, stick_center,
+				int2d(sum2d(stick_center, mag_scale_2d(get_stick(joy, axes[0], axes[1]), 15))),
+				3
+			)
+		
+		trigger_height = 30 * joy.get_axis(2)
+		pygame.draw.rect(
+			surfaceScreen,
+			colorDebug0,
+			pygame.Rect((joy.get_numbuttons() + i) * 40 + 5 + 40, joyIndex * 50 + 10, 30, 30)
+		)
+		if trigger_height > 0:
+			pygame.draw.rect(
+				surfaceScreen,
+				colorDebugToggleOn,
+				pygame.Rect((joy.get_numbuttons() + i) * 40 + 5 + 40, joyIndex * 50 + 10 + (30 - trigger_height), 30, trigger_height)
+			)
+		
+		### so... pygame won't detect the right-side trigger?
+		pygame.draw.rect(
+			surfaceScreen,
+			colorDebug0,
+			pygame.Rect((joy.get_numbuttons() + i) * 40 + 5 + 80, joyIndex * 50 + 10, 30, 30)
+		)
+		
+		for hat in range(joy.get_numhats()):
+			hat_center = ((joy.get_numbuttons() + i) * 40 + 5 + 40 + 80 + 15, joyIndex * 50 + 10 + 15)
+			pygame.draw.rect(
+				surfaceScreen,
+				colorDebug0,
+				pygame.Rect((joy.get_numbuttons() + i) * 40 + 5 + 40 + 80, joyIndex * 50 + 10, 30, 30),
+				3
+			)
+			pygame.draw.line(
+				surfaceScreen, colorDebug1, hat_center,
+				int2d(sum2d(hat_center, flipY2d(mag_scale_2d(joy.get_hat(hat), 15)))),
+				3
+			)
+on_event(lambda a: a.type == EVENT_DRAW, draw_joy_input)
+
+colorBG = pygame.Color(255, 220, 255)
+colorDebug0 = pygame.Color(190, 170, 170)
+colorDebug1 = pygame.Color(150, 0, 0)
+colorDebugToggleOn = pygame.Color(20, 170, 20)
+colorDebugToggleOff = pygame.Color(160, 0, 0)
+colorHud = pygame.Color(255, 255, 255)
+colorHudOutline = pygame.Color(0, 0, 0)
+
+pygame.init()
+surfaceScreen = pygame.display.set_mode((600, 400)) # TODO: flags and depth
+# what about fullscreen?
+
+joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())]
+for joy in joysticks:
+	joy.init()
+
+
+
+TILE_W = 1
+TILE_D = .85
+TILE_H = .4
+
+
+# tile: (surface, (reg_x, reg_y), reg_diameter_horizontal)
+tile_ground = [pygame.image.load('Plain Block.png').convert_alpha(), (50, 85), 101]
+tile_ground_double = [pygame.image.load('Plain Block.png').convert_alpha(), (50, 85), 50]
+tile_ground_brown = [pygame.image.load('Brown Block.png').convert_alpha(), (50, 85), 101]
+tile_grass = [pygame.image.load('Grass Block.png').convert_alpha(), (50, 85), 101]
+
+camera = (0, 0, 6, 4) # (left, top, width, height)
+blocks = [] # contains: ((x, y, z), tile)
+def draw_environment():
+	global blocks
+	blocks = sorted(blocks, key=lambda a: a[0][2] + a[0][1] * 1000000)#cmp=lambda a, b: a[0][2] - b[0][2])
+	for block in blocks:
+		block_pos = block[0]
+		tile = block[1]
+		tile_surface = tile[0]
+		tile_reg_diameter = tile[2]
+		
+		scale_world2screen = 101
+		scale_image2tile = tile_surface.get_width() / tile_reg_diameter
+		
+		#dest_size = int2d(scale2d(tile_surface.get_size(), scale_image2tile))
+		dest_w = scale_world2screen * scale_image2tile
+		dest_h = dest_w * tile_surface.get_height() / tile_surface.get_width()
+		
+		surfaceScreen.blit(
+			pygame.transform.smoothscale(tile_surface, int2d((dest_w, dest_h))),
+			#dif2d(
+			#	(block[0][0] * 100, block[0][2] * 85 - block[0][1] * 40),
+			#	scale2d(tile[1], scale_image2tile)
+			#)
+			dif2d(
+				scale2d(
+					(
+						block_pos[0] * TILE_W,# - tile[1][0] * scale_world2screen / tile_reg_diameter,#  - tile[1][0] * scale_image2tile / scale_world2screen,
+						block_pos[2] * TILE_D - block_pos[1] * TILE_H
+					),
+					scale_world2screen
+				),
+				#scale2d(tile[1], scale_image2tile / scale_world2screen)
+				scale2d(tile[1], scale_world2screen / tile_reg_diameter)
+			)
+		)
+on_event(lambda a: a.type == EVENT_DRAW, draw_environment)
+
+
+
+
+blocks.append([(1, 1, 2), tile_ground])
+blocks.append([(1, 1, 1), tile_ground])
+blocks.append([(1, 0, 1), tile_ground])
+blocks.append([(1, 0, 2), tile_ground])
+blocks.append([(0, 0, 0), tile_ground])
+blocks.append([(1, 0, 0), tile_ground])
+blocks.append([(3, -1, 2), tile_ground_double])
+blocks.append([(3, 0, 2), tile_ground])
+blocks.append([(2, 0, 1), tile_ground_brown])
+blocks.append([(2, 0, 2), tile_ground_brown])
+blocks.append([(2, 1, 1), tile_grass])
+blocks.append([(2, 1, 2), tile_grass])
+blocks.append([(1, 0, 3), tile_grass])
+
+fps_clock = pygame.time.Clock()
+gui_font = pygame.font.SysFont('Verdana', 18)
+def draw_fps():
+	fps_clock.tick()
+	
+	fps_string = 'FPS: ' + str(int(fps_clock.get_fps()))
+	
+	fps_surface = gui_font.render(fps_string, True, colorHudOutline)
+	surfaceScreen.blit(fps_surface, (-2, 0))
+	surfaceScreen.blit(fps_surface, (2, 0))
+	surfaceScreen.blit(fps_surface, (0, 2))
+	surfaceScreen.blit(fps_surface, (0, -2))
+	
+	fps_surface = gui_font.render(fps_string, True, colorHud)
+	surfaceScreen.blit(fps_surface, (0, 0))
+on_event(lambda a: a.type == EVENT_DRAW, draw_fps)
+
+
+#################################################################### unit tests
+
+assert mag_scale_to_2d((1, 0), 2) == (2, 0)
+assert mag_scale_to_2d((-2, 0), .5) == (-.5, 0)
+
+#print(mag_scale_to_2d((1, 1), 1))
+#print((math.sqrt(2), math.sqrt(2)))
+assert mag_scale_to_2d((1, 1), 1) == (1 / math.sqrt(2), 1 / math.sqrt(2))
+
+
+
+
+
+
+
+
+
+
+
+
+
+event_loop()
+