Compare commits

..

No commits in common. "eb6b4b987c65c2d171578650d9fbd5867b4089af" and "dfb6594ec599e212c5d34fcc3cecbebe93a7b8f7" have entirely different histories.

10 changed files with 67 additions and 218 deletions

View File

@ -2,29 +2,25 @@
My school project
## Loading games
## Load levels
You can load a game by passing the name of the game as an argument:
You can load a level by pass the path to the level as an argument, see example:
```sh
python3 main.py triangle
python3 main.py maps/triangle.json
```
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)
## Controls
| Descripton | Key |
|----------------------------------------|:---:|
| Move forward | W |
|------------------------------------|:---:|
| Move forwards | W |
| Move backwards | D |
| Strafe left | Q |
| Strafe right | E |
| Turn 180 degrees | R |
| Turn exactly 180 degrees | R |
| Toggle FPS cap | F1 |
| Create a wall | F2 |
| Toggle debug info | F3 |
| Print current position to the terminal | F4 |
| Print to terminal current position | F4 |
| Save level to `./levels` folder | F5 |

View File

@ -1,57 +0,0 @@
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

View File

@ -22,7 +22,7 @@ class DrawnSegment:
self.color = color
@jit#(cache=True,parallel=True)
def draw(level,gPlayer,fov,res,dscale):
def draw(level,gPlayer,fov,res):
EMPTYDRAWN = DrawnSegment(0, BLACK)
drawn = [EMPTYDRAWN] * res
irot = exp(fov/res*I)
@ -37,7 +37,7 @@ def draw(level,gPlayer,fov,res,dscale):
continue
if cDot(rot,MobiusAdd(cInt,-gPlayer.cPos)) > 0:
continue
rDist = MobiusDist(cInt,gPlayer.cPos) * dscale
rDist = MobiusDist(cInt,gPlayer.cPos)*1.1
if j.isFinite and not cBetween(Poincare2Klein(j.pointA),Poincare2Klein(j.pointB),Poincare2Klein(cInt)):
continue
if m is None:

View File

@ -1,11 +0,0 @@
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

View File

@ -1,4 +0,0 @@
from engineevents import EngineEvent
def init(aoEngineEvents):
aoEngineEvents.append(EngineEvent('level', lambda _: []))

View File

@ -1,17 +0,0 @@
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=()
))

View File

@ -1 +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": [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]}]

View File

@ -1,17 +0,0 @@
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=()
))

View File

@ -1 +0,0 @@
[{"__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
View File

@ -2,21 +2,20 @@
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, DrawnSegment
from draw import draw
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)
@ -33,11 +32,7 @@ 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)
@ -47,10 +42,6 @@ def mainLoop():
debugInfo = True
wall_buffer = []
alerts = []
aoEngineEvents = []
fvControl_ao = defaultcontrols
level = []
iDistScale = 1.1
def alert_append(alert, delay):
if len(alerts) >= 1:
@ -59,87 +50,58 @@ 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:
game = import_module('games.' + sys.argv[1])
level = open_level(sys.argv[1])
except IndexError:
game = import_module("games.squareroom")
game.init(aoEngineEvents)
processevents()
level = open_level("maps/squareroom.json")
while bCont:
aoEngineEvents = fvControl_ao()
processevents()
display.fill(WHITE)
if len(level) != 0:
drawn = draw(level,gPlayer,pi/4,320,iDistScale)
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:
drawn = [DrawnSegment(0, BLACK)] * 320
pygame.draw.rect(display,sky, (0,0,1280,360))
pygame.draw.rect(display,ground, (0,360,1280,360))
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)
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))
n = 0
for i in drawn:
pygame.draw.rect(display,i.color, (n,int((nonzerocap(i.dist)) * 360),4,int((1 -nonzerocap(i.dist)) * 1280)))
pygame.draw.rect(display,i.color, (n,int((nonzerocap(i.dist)) * 360),8,int((1 -nonzerocap(i.dist)) * 1280)))
n += 4
gPlayer.normalize()
if debugInfo:
@ -175,6 +137,5 @@ def main():
return retstatus
if __name__ == "__main__":
sys.path.append(os.path.realpath(__file__))
if not main():
print("An error occured")