Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ss20:neg_sourcecode [2020/08/26 18:13] srather |
ss20:neg_sourcecode [2020/09/11 14:25] (aktuell) srather [main] |
||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | |||
+ | [[nichteuklidische_geometrie|← Back to project page]] | ||
+ | |||
====== Sourcecode ====== | ====== Sourcecode ====== | ||
- | Download sourcecode from Git repository: | + | Download the release version here:\\ |
+ | {{:ss20:neg-world-engine.zip}} | ||
- | [[https://gitlab.tubit.tu-berlin.de/srather/NEG-World-Engine.git|https://gitlab.tubit.tu-berlin.de/srather/NEG-World-Engine.git]] | + | Or download the newest version from the Git repository:\\ |
+ | [[https://gitlab.tubit.tu-berlin.de/srather/NEG-World-Engine.git]] | ||
- | **[[neg_sourcecode#sourcecode|Sourcecode]]:** | + | ==== Folder Structure: ==== |
- | * **[[neg_sourcecode#root|Root]]:** [[neg_sourcecode#readme|README]], [[neg_sourcecode#main|main]] | ||
- | * **[[neg_datatypes#datatypes|Datatypes]]:** [[neg_datatypes#vector|Vector]], [[neg_datatypes#matrix|Matrix]] | + | **[[neg_sourcecode|Root]]:** [[neg_sourcecode#readme|README]], [[neg_sourcecode#main|main]] |
- | * **[[neg_objects#objects|Objects]]:** [[neg_objects#drawable|drawable]], [[neg_objects#ray|Ray]], [[neg_objects#polygon|Polygon]], [[neg_objects#floor|Floor]], [[neg_objects#portal|Portal]] | + | * **[[neg_datatypes|Datatypes]]:** [[neg_datatypes#vector|Vector]], [[neg_datatypes#matrix|Matrix]] |
- | * **[[neg_misc#misc|Misc]]:** [[neg_misc#colors|colors]], [[neg_misc#generate|generate]], [[neg_misc#draw|draw]] | + | * **[[neg_drawables|Drawables]]:** [[neg_drawables#drawable|drawable]], [[neg_drawables#ray|Ray]], [[neg_drawables#polygon|Polygon]], [[neg_drawables#floor|Floor]], [[neg_drawables#portal|Portal]] |
+ | * **[[neg_utility|Utility]]:** [[neg_utility#colors|colors]], [[neg_utility#generate|generate]], [[neg_utility#draw|draw]] | ||
===== Root ===== | ===== Root ===== | ||
Zeile 24: | Zeile 29: | ||
<file markdown README.md> | <file markdown README.md> | ||
- | <img src="https://gitlab.tubit.tu-berlin.de/srather/NEG-World-Engine/raw/master/icon.png"> | ||
- | |||
# NEG-World-Engine | # NEG-World-Engine | ||
> A 2D Non-Euclidean Engine bases on portals | > A 2D Non-Euclidean Engine bases on portals | ||
+ | |||
+ |  | ||
**Dependencies:** | **Dependencies:** | ||
Zeile 46: | Zeile 51: | ||
- Move with WASD, the arrow keys or by clicking with your mouse | - Move with WASD, the arrow keys or by clicking with your mouse | ||
- Press the number keys 0-9 to explore different worlds | - Press the number keys 0-9 to explore different worlds | ||
- | - Have fun with your 7-40 fps | + | |
</file> | </file> | ||
- | |||
- | |||
- | {{:ss20:icon.png?nolink|}} | ||
====== NEG-World-Engine ====== | ====== NEG-World-Engine ====== | ||
> A 2D Non-Euclidean Engine bases on portals | > A 2D Non-Euclidean Engine bases on portals | ||
+ | |||
+ | {{:ss20:icon.png?nolink|}} | ||
**Dependencies:** | **Dependencies:** | ||
Zeile 73: | Zeile 77: | ||
* Move with WASD, the arrow keys or by clicking with your mouse | * Move with WASD, the arrow keys or by clicking with your mouse | ||
* Press the number keys 0-9 to explore different worlds | * Press the number keys 0-9 to explore different worlds | ||
- | * Have fun with your 7-40 fps | ||
- | [[neg_sourcecode#sourcecode|Back to top]] | + | [[#top|↑ Back to top]] |
---- | ---- | ||
+ | |||
===== main ===== | ===== main ===== | ||
Zeile 85: | Zeile 89: | ||
import pygame | import pygame | ||
import math | import math | ||
+ | |||
+ | import sys | ||
+ | sys.path.append(".\\datatypes") | ||
+ | sys.path.append(".\\drawables") | ||
+ | sys.path.append(".\\utility") | ||
+ | |||
import generate | import generate | ||
+ | import draw | ||
+ | from vector import * | ||
from polygon import * | from polygon import * | ||
from portal import * | from portal import * | ||
- | from draw import * | ||
from floor import * | from floor import * | ||
Zeile 101: | Zeile 112: | ||
current_fps = FPS | current_fps = FPS | ||
- | current_speed = Vector(0.0, 0.0) | + | current_speed = Vector(0, 0) |
+ | |||
+ | # generate worlds | ||
def gen4(): | def gen4(): | ||
+ | """ | ||
+ | Generate world 4 (and 8). | ||
+ | Return a big polygon with sides as mirrors and a | ||
+ | slightly smaller one with polygons on its vertices. | ||
+ | """ | ||
+ | |||
def mirror(m, v): | def mirror(m, v): | ||
v=Vector(*v) | v=Vector(*v) | ||
return 2 * v.dot(m) / m.dot(m) * m - v | return 2 * v.dot(m) / m.dot(m) * m - v | ||
- | |||
w = [] | w = [] | ||
pol = generate.polygon(4, (0, 0), 500) | pol = generate.polygon(4, (0, 0), 500) | ||
Zeile 117: | Zeile 135: | ||
def gen6(): | def gen6(): | ||
+ | """ | ||
+ | Generate additional objects for world 6. | ||
+ | Return the 2 houses with their doors. | ||
+ | """ | ||
+ | |||
w = [] | w = [] | ||
w += generate.border(generate.polygon(4, (0, 0), 200, phase=-0.5))[:-1] | w += generate.border(generate.polygon(4, (0, 0), 200, phase=-0.5))[:-1] | ||
Zeile 158: | Zeile 181: | ||
# 4: 4 mirrors | # 4: 4 mirrors | ||
[ | [ | ||
+ | |||
] | ] | ||
+ gen4(), | + gen4(), | ||
Zeile 168: | Zeile 192: | ||
Portal((2000, -50), (3000, -50), offset=(-2000, 0), offset2=(-2000, 0)), | Portal((2000, -50), (3000, -50), offset=(-2000, 0), offset2=(-2000, 0)), | ||
], | ], | ||
- | # + generate.border(generate.polygon(4, (0, -100), 400, phase=0.5)) | ||
- | # + generate.border(generate.polygon(4, (2000, -100), 400, phase=0.5)), | ||
# 6: big room | # 6: big room | ||
Zeile 231: | Zeile 253: | ||
- | world = [] | + | def bake_physics(wrld): |
+ | """ | ||
+ | Return a list of all lines an points in 'wrld' which have a collision. | ||
+ | """ | ||
- | |||
- | def bake_physics(wrld): | ||
lns = [] | lns = [] | ||
- | |||
for object in wrld: | for object in wrld: | ||
+ | # ignore floor tiles | ||
if type(object) is Floor: | if type(object) is Floor: | ||
continue | continue | ||
+ | # dissasample polygons into lines | ||
if isinstance(object, Polygon): | if isinstance(object, Polygon): | ||
if len(object) <= 2: | if len(object) <= 2: | ||
Zeile 246: | Zeile 270: | ||
for i, _ in enumerate(object): | for i, _ in enumerate(object): | ||
lns.append(object.__class__(object[i-1], object[i])) | lns.append(object.__class__(object[i-1], object[i])) | ||
- | |||
return lns | return lns | ||
- | |||
- | lines = bake_physics(world) | ||
Zeile 256: | Zeile 277: | ||
window = pygame.display.set_mode(WINDOW) | window = pygame.display.set_mode(WINDOW) | ||
pygame.display.set_caption("NEG World Engine") | pygame.display.set_caption("NEG World Engine") | ||
+ | pygame.display.set_icon(pygame.image.load('icon_small.png')) | ||
clock = pygame.time.Clock() | clock = pygame.time.Clock() | ||
+ | world = [] # empty starting world | ||
+ | lines = bake_physics(world) | ||
Zeile 269: | Zeile 293: | ||
# draw frame | # draw frame | ||
window.fill(colors.GRAY) | window.fill(colors.GRAY) | ||
- | draw_world(window, world, POSITION, DEPTH) | + | draw.world(window, world, POSITION, DEPTH) |
- | draw_player(window, POSITION, ZOOM) | + | draw.player(window, POSITION, ZOOM) |
- | draw_debug(window, 0, f"{current_fps:.0f} FPS", colors.BRIGHT_GREEN) | + | draw.debug(window, 0, f"{current_fps:.0f} FPS", colors.BRIGHT_GREEN) |
- | draw_debug(window, 1, f"{POSITION.x:.0f} X {POSITION.y:.0f} y", colors.BRIGHT_GREEN) | + | draw.debug(window, 1, f"{POSITION.x:.0f} X {POSITION.y:.0f} y", colors.BRIGHT_GREEN) |
# check inputs | # check inputs | ||
- | force = Vector(0, 0) | + | keys = pygame.key.get_pressed() |
- | keys = pygame.key.get_pressed() # keyboard | + | # change world if numbers are pressed |
if keys[pygame.K_1]: world = worlds[0]; lines = bake_physics(world); POSITION *= 0; current_speed *= 0; DEPTH = 2 | if keys[pygame.K_1]: world = worlds[0]; lines = bake_physics(world); POSITION *= 0; current_speed *= 0; DEPTH = 2 | ||
if keys[pygame.K_2]: world = worlds[1]; lines = bake_physics(world); POSITION *= 0; current_speed *= 0; DEPTH = 2 | if keys[pygame.K_2]: world = worlds[1]; lines = bake_physics(world); POSITION *= 0; current_speed *= 0; DEPTH = 2 | ||
Zeile 288: | Zeile 312: | ||
if keys[pygame.K_9]: world = worlds[8]; lines = bake_physics(world); POSITION *= 0; current_speed *= 0; DEPTH = 0 | if keys[pygame.K_9]: world = worlds[8]; lines = bake_physics(world); POSITION *= 0; current_speed *= 0; DEPTH = 0 | ||
if keys[pygame.K_0]: world = worlds[9]; lines = bake_physics(world); POSITION *= 0; current_speed *= 0; DEPTH = 1 | if keys[pygame.K_0]: world = worlds[9]; lines = bake_physics(world); POSITION *= 0; current_speed *= 0; DEPTH = 1 | ||
+ | |||
+ | # change speed if arrows are pressed | ||
+ | force = Vector(0, 0) | ||
if keys[pygame.K_LEFT ] or keys[pygame.K_a]: force += Vector(-1, 0) | if keys[pygame.K_LEFT ] or keys[pygame.K_a]: force += Vector(-1, 0) | ||
if keys[pygame.K_RIGHT] or keys[pygame.K_d]: force += Vector( 1, 0) | if keys[pygame.K_RIGHT] or keys[pygame.K_d]: force += Vector( 1, 0) | ||
Zeile 294: | Zeile 321: | ||
force = force.normalised() | force = force.normalised() | ||
- | if pygame.mouse.get_focused(): # mouse | + | # change speed if left mouse button is pressed |
- | if pygame.mouse.get_pressed()[0]: # left button pressed | + | if pygame.mouse.get_focused(): |
+ | if pygame.mouse.get_pressed()[0]: | ||
force += (Vector(*pygame.mouse.get_pos()) - WINDOW / 2).normalised() | force += (Vector(*pygame.mouse.get_pos()) - WINDOW / 2).normalised() | ||
+ | # apply changes (not opimal, movement should be independant of framerate) | ||
current_speed += force.normalised() * SPEED / max(current_fps, 0.1) | current_speed += force.normalised() * SPEED / max(current_fps, 0.1) | ||
current_speed *= SPEED ** -(1 / max(current_fps, 60)) | current_speed *= SPEED ** -(1 / max(current_fps, 60)) | ||
- | |||
- | # a = force.normalised() * SPEED | ||
- | # v0 = current_speed | ||
- | # dt = 1 / max(30, current_fps) | ||
- | # f = 3 | ||
- | # current_speed = a - (a - v0) * math.exp(-f * dt) | ||
POSITION += current_speed | POSITION += current_speed | ||
- | # check physics | + | # check physics (not optimal, player can glitch into things) |
for line in lines: | for line in lines: | ||
if line.dist_to(POSITION) < ZOOM/2: | if line.dist_to(POSITION) < ZOOM/2: | ||
Zeile 321: | Zeile 344: | ||
continue | continue | ||
+ | # removes the part of the speed vector which causes collision | ||
POSITION -= current_speed | POSITION -= current_speed | ||
current_speed = b_a * (b_a.dot(current_speed) / b_a.dot(b_a)) | current_speed = b_a * (b_a.dot(current_speed) / b_a.dot(b_a)) | ||
POSITION += current_speed | POSITION += current_speed | ||
- | #check if gone through portal | + | # check if gone through portal |
move = Ray(POSITION - current_speed, current_speed) | move = Ray(POSITION - current_speed, current_speed) | ||
for object in world: | for object in world: | ||
if type(object) is Portal: | if type(object) is Portal: | ||
+ | # intersect portal with movement ray | ||
port = Ray(object[0], object[1] - object[0]) | port = Ray(object[0], object[1] - object[0]) | ||
point = move.intersect(port) | point = move.intersect(port) | ||
if point: # not empty | if point: # not empty | ||
if move.value_at(*point) <= 1 and port.value_at(*point) <= 1: | if move.value_at(*point) <= 1 and port.value_at(*point) <= 1: | ||
+ | # change world to portal world | ||
world = object.go_through(move.dir, world) | world = object.go_through(move.dir, world) | ||
lines = bake_physics(world) | lines = bake_physics(world) | ||
Zeile 344: | Zeile 370: | ||
# exit routine | # exit routine | ||
pygame.quit() | pygame.quit() | ||
+ | |||
</file> | </file> | ||
- | [[neg_sourcecode#sourcecode|Back to top]] | + | [[#top|↑ Back to top]] |