forked from bedohswe/p3he
		
	Compare commits
	
		
			16 Commits
		
	
	
		
			dfb6594ec5
			...
			eb6b4b987c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| eb6b4b987c | |||
| f93dfb1fb2 | |||
| 00f930e151 | |||
| e62f985e73 | |||
| 08347cdc3f | |||
| 1c342f163c | |||
| 3448684363 | |||
| b29fc7d929 | |||
| de6a555c94 | |||
| db3ea32c75 | |||
| f3f9f31a05 | |||
| 2d28957eaa | |||
| 13aefdde9a | |||
| c3858c548e | |||
| d9ce3fd3ab | |||
| d28d1d10ed | 
							
								
								
									
										20
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								README.md
									
									
									
									
									
								
							| @ -2,25 +2,29 @@ | ||||
| 
 | ||||
| My school project | ||||
| 
 | ||||
| ## Load levels | ||||
| ## Loading games | ||||
| 
 | ||||
| You can load a level by pass the path to the level as an argument, see example: | ||||
| You can load a game by passing the name of the game as an argument: | ||||
| 
 | ||||
| ```sh | ||||
| python3 main.py maps/triangle.json | ||||
| python3 main.py triangle | ||||
| ``` | ||||
| 
 | ||||
| ## Controls | ||||
| Game can be loaded only if it is located in the games/ directory. | ||||
| If no game is specified then "squareroom" will be loaded. | ||||
| 
 | ||||
| 
 | ||||
| ## Controls (might be overriden by games) | ||||
| 
 | ||||
| | Descripton                             | Key | | ||||
| |------------------------------------|:---:| | ||||
| | Move forwards                      |  W  | | ||||
| |----------------------------------------|:---:| | ||||
| | Move forward                           |  W  | | ||||
| | Move backwards                         |  D  | | ||||
| | Strafe left                            |  Q  | | ||||
| | Strafe right                           |  E  | | ||||
| | Turn exactly 180 degrees           |  R  | | ||||
| | Turn 180 degrees                       |  R  | | ||||
| | Toggle FPS cap                         | F1  | | ||||
| | Create a wall                          | F2  | | ||||
| | Toggle debug info                      | F3  | | ||||
| | Print to terminal current position | F4  | | ||||
| | Print current position to the terminal | F4  | | ||||
| | Save level to `./levels` folder        | F5  | | ||||
|  | ||||
							
								
								
									
										57
									
								
								defaultcontrols.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								defaultcontrols.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| import pygame | ||||
| from engineevents import EngineEvent | ||||
| from constants import ROT, IROT, OFFSET, I | ||||
| from gyro import GyroVector | ||||
| from levels import open_level, save_level, make_wall | ||||
| from alert import Alert | ||||
| 
 | ||||
| def defaultcontrols(): | ||||
|     aoEngineEvents = list() | ||||
|     for event in pygame.event.get(): | ||||
|         if event.type == pygame.QUIT: | ||||
|             aoEngineEvents.append(EngineEvent("bCont", lambda _: False)) | ||||
|         if event.type == pygame.KEYDOWN: | ||||
|             if event.key == pygame.K_r: | ||||
|                 aoEngineEvents.append(EngineEvent(None, lambda args: args[0].rotate(-1), tsArguments=("gPlayer",))) | ||||
|             if event.key == pygame.K_F3: | ||||
|                 aoEngineEvents.append(EngineEvent("debugInfo", lambda args: not args[0])) | ||||
|             if event.key == pygame.K_F1: | ||||
|                 aoEngineEvents.append(EngineEvent("bCap", lambda args: not args[0])) | ||||
|             if event.key == pygame.K_F2: | ||||
|                 def fX(args): | ||||
|                     #0: wall_buffer | ||||
|                     #1: gPlayer | ||||
|                     #2: level | ||||
|                     if (len(args[0]) == 1): | ||||
|                         args[0].append(args[1].cPos) | ||||
|                         make_wall(args[0], args[2]) | ||||
|                         args[0].clear() | ||||
|                     else: | ||||
|                         args[0].append(args[1].cPos) | ||||
|                 aoEngineEvents.append(EngineEvent(None, fX, tsArguments=("wall_buffer", "gPlayer", "level") )) | ||||
|             if event.key == pygame.K_F5: | ||||
|                 #0: level | ||||
|                 #1: alert_append | ||||
|                 #2: display | ||||
|                 def fX(args): | ||||
|                     filename = save_level(args[0]) | ||||
|                     alert = Alert(f"File saved as {filename}", args[2]) | ||||
| 
 | ||||
|                     args[1](alert, 5) | ||||
|                 aoEngineEvents.append(EngineEvent(None, fX, tsArguments=("level", "alert_append", "display") )) | ||||
|             if event.key == pygame.K_F4: | ||||
|                 aoEngineEvents.append(EngineEvent(None, lambda args: print(args[0].cPos), tsArguments=("gPlayer",)))  | ||||
|     keys = pygame.key.get_pressed() | ||||
|     if keys[pygame.K_d]: | ||||
|         aoEngineEvents.append(EngineEvent(None, lambda args: args[0].rotate( ROT), tsArguments=("gPlayer",))) | ||||
|     if keys[pygame.K_a]: | ||||
|         aoEngineEvents.append(EngineEvent(None, lambda args: args[0].rotate(IROT), tsArguments=("gPlayer",))) | ||||
|     if keys[pygame.K_q]: | ||||
|         aoEngineEvents.append(EngineEvent(None, lambda args: args[0].__iadd__(GyroVector(OFFSET * args[0].cRot*I, 1)), tsArguments=("gPlayer",))) | ||||
|     if keys[pygame.K_e]: | ||||
|         aoEngineEvents.append(EngineEvent(None, lambda args: args[0].__isub__(GyroVector(OFFSET * args[0].cRot*I, 1)), tsArguments=("gPlayer",))) | ||||
|     if keys[pygame.K_w]: | ||||
|         aoEngineEvents.append(EngineEvent(None, lambda args: args[0].__isub__(GyroVector(OFFSET * args[0].cRot  , 1)), tsArguments=("gPlayer",))) | ||||
|     if keys[pygame.K_s]: | ||||
|         aoEngineEvents.append(EngineEvent(None, lambda args: args[0].__iadd__(GyroVector(OFFSET * args[0].cRot  , 1)), tsArguments=("gPlayer",))) | ||||
|     return aoEngineEvents | ||||
							
								
								
									
										4
									
								
								draw.py
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								draw.py
									
									
									
									
									
								
							| @ -22,7 +22,7 @@ class DrawnSegment: | ||||
|         self.color = color | ||||
| 
 | ||||
| @jit#(cache=True,parallel=True) | ||||
| def draw(level,gPlayer,fov,res): | ||||
| def draw(level,gPlayer,fov,res,dscale): | ||||
|     EMPTYDRAWN = DrawnSegment(0, BLACK) | ||||
|     drawn = [EMPTYDRAWN] * res | ||||
|     irot = exp(fov/res*I) | ||||
| @ -37,7 +37,7 @@ def draw(level,gPlayer,fov,res): | ||||
|                 continue | ||||
|             if cDot(rot,MobiusAdd(cInt,-gPlayer.cPos)) > 0: | ||||
|                 continue | ||||
|             rDist = MobiusDist(cInt,gPlayer.cPos)*1.1 | ||||
|             rDist = MobiusDist(cInt,gPlayer.cPos) * dscale | ||||
|             if j.isFinite and not cBetween(Poincare2Klein(j.pointA),Poincare2Klein(j.pointB),Poincare2Klein(cInt)): | ||||
|                 continue | ||||
|             if m is None: | ||||
|  | ||||
							
								
								
									
										11
									
								
								engineevents.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								engineevents.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| class EngineEvent: | ||||
|     def __init__(self, sVariableToModify, fLambda, tsArguments=None): | ||||
|         self.sVariableToModify = sVariableToModify | ||||
|         self.fLambda = fLambda | ||||
|         if tsArguments is not None: | ||||
|             self.tsArguments = tsArguments | ||||
|         else: | ||||
|             self.tsArguments = (sVariableToModify,) | ||||
| 
 | ||||
| class EngineEventProcessingError(Exception): | ||||
|     pass | ||||
							
								
								
									
										4
									
								
								games/empty/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								games/empty/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| from engineevents import EngineEvent | ||||
| 
 | ||||
| def init(aoEngineEvents): | ||||
|     aoEngineEvents.append(EngineEvent('level', lambda _: [])) | ||||
							
								
								
									
										17
									
								
								games/squareroom/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								games/squareroom/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| import importlib.resources as impr | ||||
| import sys | ||||
| import json | ||||
| import serialize | ||||
| from engineevents import EngineEvent | ||||
| 
 | ||||
| def init(aoEngineEvents): | ||||
|     curm = sys.modules[__name__] | ||||
|     files = impr.files(curm) | ||||
|     level = None | ||||
|     with files.joinpath("squareroom.json").open('r') as leveldir: | ||||
|         level = json.loads(leveldir.read(), object_hook=serialize.object_hook) | ||||
|     aoEngineEvents.append(EngineEvent( | ||||
|             'level', | ||||
|             lambda _: level, | ||||
|             tsArguments=() | ||||
|             )) | ||||
							
								
								
									
										1
									
								
								games/squareroom/squareroom.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								games/squareroom/squareroom.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| [{"__type__": "objSegment", "isFinite": true, "pointA": {"__type__": "complex", "real": 0.6, "imag": 0.0}, "pointB": {"__type__": "complex", "real": 0.0, "imag": 0.6}, "color": [255, 0, 0]}, {"__type__": "objSegment", "isFinite": true, "pointA": {"__type__": "complex", "real": 0.6, "imag": 0.0}, "pointB": {"__type__": "complex", "real": 0.0, "imag": -0.6}, "color": [0, 255, 0]}, {"__type__": "objSegment", "isFinite": true, "pointA": {"__type__": "complex", "real": -0.6, "imag": 0.0}, "pointB": {"__type__": "complex", "real": 0.0, "imag": -0.6}, "color": [0, 0, 255]}, {"__type__": "objSegment", "isFinite": true, "pointA": {"__type__": "complex", "real": -0.6, "imag": 0.0}, "pointB": {"__type__": "complex", "real": 0.0, "imag": 0.6}, "color": [255, 255, 0]}] | ||||
							
								
								
									
										17
									
								
								games/triangleroom/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								games/triangleroom/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| import importlib.resources as impr | ||||
| import sys | ||||
| import json | ||||
| import serialize | ||||
| from engineevents import EngineEvent | ||||
| 
 | ||||
| def init(aoEngineEvents): | ||||
|     curm = sys.modules[__name__] | ||||
|     files = impr.files(curm) | ||||
|     level = None | ||||
|     with files.joinpath("triangle.json").open('r') as leveldir: | ||||
|         level = json.loads(leveldir.read(), object_hook=serialize.object_hook) | ||||
|     aoEngineEvents.append(EngineEvent( | ||||
|             'level', | ||||
|             lambda _: level, | ||||
|             tsArguments=() | ||||
|             )) | ||||
							
								
								
									
										1
									
								
								games/triangleroom/triangle.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								games/triangleroom/triangle.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| [{"__type__": "objSegment", "isFinite": true, "pointA": {"__type__": "complex", "real": 0.38529100476842437, "imag": 0.0}, "pointB": {"__type__": "complex", "real": -0.2372040619364459, "imag": 0.36629343026935063}, "color": [255, 0, 0]}, {"__type__": "objSegment", "isFinite": true, "pointA": {"__type__": "complex", "real": -0.2372040619364459, "imag": 0.36629343026935063}, "pointB": {"__type__": "complex", "real": -0.22354939429564802, "imag": -0.26820653903460523}, "color": [0, 255, 0]}, {"__type__": "objSegment", "isFinite": true, "pointA": {"__type__": "complex", "real": -0.22354939429564802, "imag": -0.26820653903460523}, "pointB": {"__type__": "complex", "real": 0.39868528559672944, "imag": 0.017873216691274733}, "color": [0, 0, 255]}] | ||||
							
								
								
									
										137
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								main.py
									
									
									
									
									
								
							| @ -2,20 +2,21 @@ | ||||
| 
 | ||||
| from math import copysign, pi, acos | ||||
| import sys | ||||
| import os | ||||
| from importlib import import_module | ||||
| 
 | ||||
| import pygame | ||||
| import pygame.freetype | ||||
| 
 | ||||
| from gyro import GyroVector, Poincare2Klein | ||||
| from levels import open_level, save_level, make_wall | ||||
| from constants import I, WHITE, BLACK, IROT, ROT, OFFSET | ||||
| from draw import draw | ||||
| from draw import draw, DrawnSegment | ||||
| from alert import Alert | ||||
| from engineevents import EngineEvent, EngineEventProcessingError | ||||
| from defaultcontrols import defaultcontrols | ||||
| 
 | ||||
| gOrigin = GyroVector(0,1) | ||||
| 
 | ||||
| SKY = (127,127,255) | ||||
| GROUND = (102, 51, 0) | ||||
| 
 | ||||
| def renderDebugInfo(gPlayer, clock, fontSize = 18): | ||||
|     font = pygame.freetype.Font(None, fontSize) | ||||
| @ -32,7 +33,11 @@ def nonzerocap(n): | ||||
|     if n <= 0: return 1 | ||||
|     return n | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def mainLoop(): | ||||
|     sky = (127,127,255) | ||||
|     ground = (102, 51, 0) | ||||
|     bCap = True | ||||
|     bCont = True | ||||
|     gPlayer = GyroVector(0,1) | ||||
| @ -42,6 +47,10 @@ def mainLoop(): | ||||
|     debugInfo = True | ||||
|     wall_buffer = [] | ||||
|     alerts = [] | ||||
|     aoEngineEvents = [] | ||||
|     fvControl_ao = defaultcontrols | ||||
|     level = [] | ||||
|     iDistScale = 1.1 | ||||
| 
 | ||||
|     def alert_append(alert, delay): | ||||
|         if len(alerts) >= 1: | ||||
| @ -50,58 +59,87 @@ def mainLoop(): | ||||
|         alerts.append(alert) | ||||
|         alert.start_hide_thread(alerts, delay) | ||||
| 
 | ||||
|     def processevents(): | ||||
|         nonlocal bCap | ||||
|         nonlocal bCont | ||||
|         nonlocal gPlayer | ||||
|         nonlocal display | ||||
|         nonlocal fontSize | ||||
|         nonlocal debugInfo | ||||
|         nonlocal wall_buffer | ||||
|         nonlocal alerts | ||||
|         nonlocal alert_append | ||||
|         nonlocal aoEngineEvents | ||||
|         nonlocal level | ||||
|         nonlocal sky | ||||
|         nonlocal ground | ||||
|         nonlocal iDistScale | ||||
|         state = { | ||||
|             'bCap': bCap, | ||||
|             'bCont': bCont, | ||||
|             'gPlayer': gPlayer, | ||||
|             'display': display, | ||||
|             'fontSize': fontSize, | ||||
|             'debugInfo': debugInfo, | ||||
|             'wall_buffer': wall_buffer, | ||||
|             'alerts': alerts, | ||||
|             'alert_append': alert_append, | ||||
|             'aoEngineEvents': aoEngineEvents, | ||||
|             'level': level, | ||||
|             'sky': sky, | ||||
|             'ground': ground, | ||||
|             'iDistScale': iDistScale | ||||
|         } | ||||
|         for i in aoEngineEvents: | ||||
|             if i.sVariableToModify == "bCap": | ||||
|                 bCap        = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify == "bCont": | ||||
|                 bCont       = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify == "gPlayer": | ||||
|                 gPlayer     = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify == "fontSize": | ||||
|                 fontSize    = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify == "wall_buffer": | ||||
|                 wall_buffer = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify == "alerts": | ||||
|                 alerts      = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify == "sky": | ||||
|                 sky         = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify == "ground": | ||||
|                 ground      = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify == "debugInfo": | ||||
|                 debugInfo   = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify == "level": | ||||
|                 level       = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify == "iDistScale": | ||||
|                 iDistScale  = i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             elif i.sVariableToModify is None: | ||||
|                               i.fLambda(list(map(lambda oX: state[oX], i.tsArguments))) | ||||
|             else: | ||||
|                 raise EngineEventProcessingError('Unknown variable: ' + i.sVariableToModify) | ||||
| 
 | ||||
|         aoEngineEvents.clear() | ||||
|     try: | ||||
|         level = open_level(sys.argv[1]) | ||||
|         game = import_module('games.' +  sys.argv[1]) | ||||
|     except IndexError: | ||||
|         level = open_level("maps/squareroom.json") | ||||
|         game = import_module("games.squareroom") | ||||
| 
 | ||||
|     game.init(aoEngineEvents) | ||||
|     processevents() | ||||
| 
 | ||||
|     while bCont: | ||||
|         for event in pygame.event.get(): | ||||
|             if event.type == pygame.QUIT: | ||||
|                 bCont = False | ||||
|             if event.type == pygame.KEYDOWN: | ||||
|                 if event.key == pygame.K_r: | ||||
|                     gPlayer.cRot *= -1 | ||||
|                 if event.key == pygame.K_F3: | ||||
|                     debugInfo = not debugInfo | ||||
|                 if event.key == pygame.K_F1: | ||||
|                     bCap = not bCap | ||||
|                 if event.key == pygame.K_F2: | ||||
|                     if (len(wall_buffer) == 1): | ||||
|                         wall_buffer.append(gPlayer.cPos) | ||||
|                         make_wall(wall_buffer, level) | ||||
|                         wall_buffer.clear() | ||||
|                     else: | ||||
|                         wall_buffer.append(gPlayer.cPos) | ||||
|                 if event.key == pygame.K_F5: | ||||
|                     filename = save_level(level) | ||||
|                     alert = Alert(f"File saved as {filename}", display) | ||||
| 
 | ||||
|                     alert_append(alert, 5) | ||||
|                 if event.key == pygame.K_F4: | ||||
|                     print(gPlayer.cPos) | ||||
| 
 | ||||
|         keys = pygame.key.get_pressed() | ||||
|         if keys[pygame.K_d]: | ||||
|             gPlayer.rotate(ROT) | ||||
|         if keys[pygame.K_a]: | ||||
|             gPlayer.rotate(IROT) | ||||
|         if keys[pygame.K_q]: | ||||
|             gPlayer += GyroVector(OFFSET * gPlayer.cRot*I, 1) | ||||
|         if keys[pygame.K_e]: | ||||
|             gPlayer -= GyroVector(OFFSET * gPlayer.cRot*I, 1) | ||||
|         if keys[pygame.K_w]: | ||||
|             gPlayer -= GyroVector(OFFSET * gPlayer.cRot, 1) | ||||
|         if keys[pygame.K_s]: | ||||
|             gPlayer += GyroVector(OFFSET * gPlayer.cRot, 1) | ||||
| 
 | ||||
|         aoEngineEvents = fvControl_ao() | ||||
|         processevents() | ||||
|         display.fill(WHITE) | ||||
|         drawn = draw(level,gPlayer,pi/4,320) | ||||
|         pygame.draw.rect(display,SKY,    (0,0,1280,360)) | ||||
|         pygame.draw.rect(display,GROUND, (0,360,1280,360)) | ||||
|         if len(level) != 0: | ||||
|             drawn = draw(level,gPlayer,pi/4,320,iDistScale) | ||||
|         else: | ||||
|             drawn = [DrawnSegment(0, BLACK)] * 320 | ||||
|         pygame.draw.rect(display,sky,    (0,0,1280,360)) | ||||
|         pygame.draw.rect(display,ground, (0,360,1280,360)) | ||||
|         n = 0 | ||||
|         for i in drawn: | ||||
|             pygame.draw.rect(display,i.color, (n,int((nonzerocap(i.dist)) * 360),8,int((1 -nonzerocap(i.dist)) * 1280))) | ||||
|             pygame.draw.rect(display,i.color, (n,int((nonzerocap(i.dist)) * 360),4,int((1 -nonzerocap(i.dist)) * 1280))) | ||||
|             n += 4 | ||||
|         gPlayer.normalize() | ||||
|         if debugInfo: | ||||
| @ -137,5 +175,6 @@ def main(): | ||||
|     return retstatus | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     sys.path.append(os.path.realpath(__file__)) | ||||
|     if not main(): | ||||
|         print("An error occured") | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user