GameBox 0.9.2__py3-none-any.whl → 0.10.0.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- GameBox/Game.py +68 -0
- GameBox/__init__.py +21 -24
- GameBox/basics/Cammera.py +43 -0
- GameBox/basics/Net.py +28 -0
- GameBox/basics/Shapes.py +80 -0
- GameBox/basics/sound.py +16 -0
- GameBox/basics/ui.py +70 -0
- GameBox/basics/utils.py +2 -1
- GameBox/helpers/{_input.py → Input.py} +8 -3
- GameBox/helpers/_collisions.py +60 -147
- GameBox/player/Player.py +45 -0
- GameBox/player/_playerControler.py +27 -52
- GameBox/player/_playerPhysics.py +27 -76
- GameBox/tilemap/Tilemap.py +46 -0
- {gamebox-0.9.2.dist-info → gamebox-0.10.0.dev1.dist-info}/METADATA +1 -1
- gamebox-0.10.0.dev1.dist-info/RECORD +18 -0
- GameBox/GameLevel_ui/_Animations.py +0 -39
- GameBox/GameLevel_ui/_sprites.py +0 -185
- GameBox/_game.py +0 -81
- GameBox/basics/__init__.py +0 -0
- GameBox/basics/_net.py +0 -36
- GameBox/basics/_shapes.py +0 -44
- GameBox/basics/cammera.py +0 -36
- GameBox/helpers/_Conditions.py +0 -56
- GameBox/player/_player.py +0 -61
- GameBox/player/_playerSprite.py +0 -86
- GameBox/tilemap/_Editor.py +0 -36
- GameBox/tilemap/_collisionDef.py +0 -41
- GameBox/tilemap/_editorBrushes.py +0 -166
- GameBox/tilemap/_tilemap.py +0 -94
- GameBox/ui/_basicUI.py +0 -36
- gamebox-0.9.2.dist-info/RECORD +0 -25
- {gamebox-0.9.2.dist-info → gamebox-0.10.0.dev1.dist-info}/WHEEL +0 -0
- {gamebox-0.9.2.dist-info → gamebox-0.10.0.dev1.dist-info}/licenses/LICENSE +0 -0
GameBox/Game.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
|
|
3
|
+
from .basics.Net import Global
|
|
4
|
+
from .basics.Shapes import Rect
|
|
5
|
+
|
|
6
|
+
class Game:
|
|
7
|
+
def __init__(self, width: int, height: int, bg_color = "black", title = "Game", resizable: bool = False):
|
|
8
|
+
pygame.init()
|
|
9
|
+
flags = pygame.RESIZABLE if resizable else 0
|
|
10
|
+
self.flags = flags
|
|
11
|
+
self.screen = pygame.Surface((width, height))
|
|
12
|
+
self.width, self.height = width, height
|
|
13
|
+
self.display = pygame.display.set_mode((width, height), flags)
|
|
14
|
+
self.clock = pygame.time.Clock()
|
|
15
|
+
self.running = True
|
|
16
|
+
self.bg_color = bg_color
|
|
17
|
+
self.title = title
|
|
18
|
+
|
|
19
|
+
#set global
|
|
20
|
+
Global.screen = self.screen
|
|
21
|
+
Global.screenDim = pygame.Vector2(width, height)
|
|
22
|
+
Global.bg_color = bg_color
|
|
23
|
+
Global.winTitle = title
|
|
24
|
+
Global.clock = self.clock
|
|
25
|
+
|
|
26
|
+
def update(self, events, render = True, fps=60):
|
|
27
|
+
Global.collision = []
|
|
28
|
+
#update cam
|
|
29
|
+
Global.cam.update()
|
|
30
|
+
|
|
31
|
+
self.screen.fill(Global.bg_color)
|
|
32
|
+
Global.events = events
|
|
33
|
+
Global.dt = self.clock.tick(fps)/1000.0
|
|
34
|
+
|
|
35
|
+
#collect all collision rects first
|
|
36
|
+
for key in range(5, -1, -1):
|
|
37
|
+
for obj in Global.objs[str(key)]:
|
|
38
|
+
if hasattr(obj, '_addCollision'):
|
|
39
|
+
obj._addCollision()
|
|
40
|
+
|
|
41
|
+
#then update all objects
|
|
42
|
+
for key in range(5, -1, -1):
|
|
43
|
+
for obj in Global.objs[str(key)]:
|
|
44
|
+
if hasattr(obj, 'update'):
|
|
45
|
+
obj.update()
|
|
46
|
+
|
|
47
|
+
if render:
|
|
48
|
+
self.display.blit(pygame.transform.scale(self.screen, (self.width, self.height)), (0, 0))
|
|
49
|
+
pygame.display.update()
|
|
50
|
+
|
|
51
|
+
def get_screen(self): return self.screen
|
|
52
|
+
|
|
53
|
+
def rescale(self, event):
|
|
54
|
+
self.width = event.w
|
|
55
|
+
self.height = event.h
|
|
56
|
+
self.display = pygame.display.set_mode((self.width, self.height), self.flags)
|
|
57
|
+
|
|
58
|
+
def quit(self):
|
|
59
|
+
return
|
|
60
|
+
#for tilemap in Global.tilemaps:
|
|
61
|
+
# tilemap._quit()
|
|
62
|
+
|
|
63
|
+
def generate_bounds(self, width, height, color="black", show=False):
|
|
64
|
+
Rect(pygame.Vector2(0, -10), pygame.Vector2(width, 10), color, show)
|
|
65
|
+
Rect(pygame.Vector2(-10, 0), pygame.Vector2(10, height), color, show)
|
|
66
|
+
Rect(pygame.Vector2(width, 0), pygame.Vector2(10, height), color, show)
|
|
67
|
+
Rect(pygame.Vector2(0, height), pygame.Vector2(width, 10), color, show)
|
|
68
|
+
|
GameBox/__init__.py
CHANGED
|
@@ -5,38 +5,35 @@ GameBox makes it easy to build 2D games with graphics, sound, and UI in just a f
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
__version__ = "0.
|
|
8
|
+
__version__ = "0.10.0"
|
|
9
9
|
__author__ = "Sam Fertig"
|
|
10
10
|
|
|
11
11
|
#____imports____
|
|
12
|
-
from .
|
|
13
|
-
from .basics.
|
|
14
|
-
from .basics.
|
|
15
|
-
from .
|
|
16
|
-
from .
|
|
17
|
-
from .
|
|
18
|
-
from.
|
|
19
|
-
from .
|
|
20
|
-
|
|
21
|
-
from .GameLevel_ui._sprites import Sprite_2d, Animated_Sprite2D, AnimationPlayer2D, split_image
|
|
22
|
-
from.helpers._Conditions import Conditions
|
|
23
|
-
|
|
12
|
+
from .Game import Game
|
|
13
|
+
from .basics.Cammera import Cammera
|
|
14
|
+
from .basics.Shapes import Rect, Circle
|
|
15
|
+
from .helpers.Input import Keys
|
|
16
|
+
from .player.Player import Player
|
|
17
|
+
from .basics.utils import clamp
|
|
18
|
+
from .basics.ui import Image, Text
|
|
19
|
+
from .basics.sound import Sound
|
|
20
|
+
from .tilemap.Tilemap import Tilemap
|
|
24
21
|
|
|
25
22
|
__all__ = [
|
|
26
|
-
"Game",
|
|
23
|
+
"Game",
|
|
27
24
|
"Cammera",
|
|
28
25
|
"Rect",
|
|
26
|
+
"Circle",
|
|
27
|
+
"Keys",
|
|
29
28
|
"Player",
|
|
30
29
|
"clamp",
|
|
31
|
-
"moveTward",
|
|
32
|
-
"zeroOut",
|
|
33
|
-
"TileMap",
|
|
34
|
-
"Keys",
|
|
35
30
|
"Image",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
"Text",
|
|
32
|
+
"Sound",
|
|
33
|
+
"Tilemap"
|
|
34
|
+
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
42
39
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
from random import randint as Ri
|
|
3
|
+
|
|
4
|
+
from .Net import Global
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Cammera:
|
|
8
|
+
def __init__(self, scale: float = 1.0, smooth: float = 1.0):
|
|
9
|
+
|
|
10
|
+
Global.cam = self
|
|
11
|
+
|
|
12
|
+
self.pos = pygame.Vector2(0, 0)
|
|
13
|
+
self.smooth = smooth
|
|
14
|
+
self.zoom = scale
|
|
15
|
+
|
|
16
|
+
self.shakeinfo = [False, 0, 0, False] # [active, duration, power, returnPos]
|
|
17
|
+
|
|
18
|
+
#movement
|
|
19
|
+
self.target = None
|
|
20
|
+
self.offset = None
|
|
21
|
+
|
|
22
|
+
def update(self):
|
|
23
|
+
#addon
|
|
24
|
+
addon = pygame.Vector2(0, 0)
|
|
25
|
+
if self.shakeinfo[0]:
|
|
26
|
+
addon = pygame.Vector2(Ri(-1, 1), Ri(-1, 1)) * self.shakeinfo[2]
|
|
27
|
+
self.shakeinfo[1]-=1
|
|
28
|
+
if self.shakeinfo[1]<=0:
|
|
29
|
+
self.shakeinfo[0] = False
|
|
30
|
+
if self.shakeinfo[3]: self.pos = pygame.Vector2(self.shakeinfo[3])
|
|
31
|
+
|
|
32
|
+
if self.target and hasattr(self.target, "pos"):
|
|
33
|
+
target_pos = self.target.pos
|
|
34
|
+
self.pos = (self.pos + (target_pos + self.offset - self.pos) * self.smooth)
|
|
35
|
+
|
|
36
|
+
self.pos+=addon
|
|
37
|
+
|
|
38
|
+
def set_target(self, target):
|
|
39
|
+
self.target = target
|
|
40
|
+
self.offset = self.pos - target.pos
|
|
41
|
+
|
|
42
|
+
def shake(self, dur, power, returnPos=False):
|
|
43
|
+
self.shakeinfo = [True, dur, power, returnPos]
|
GameBox/basics/Net.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class _global_:
|
|
6
|
+
def __init__(self):
|
|
7
|
+
#screen info
|
|
8
|
+
self.screen: pygame.Surface
|
|
9
|
+
self.screenDim: np.array
|
|
10
|
+
self.bg_color: np.array
|
|
11
|
+
self.winTitle: str
|
|
12
|
+
|
|
13
|
+
self.player = None
|
|
14
|
+
|
|
15
|
+
#time info
|
|
16
|
+
self.clock: pygame.time.Clock
|
|
17
|
+
self.dt: float
|
|
18
|
+
|
|
19
|
+
#game info and data
|
|
20
|
+
#objs in layers 1-5
|
|
21
|
+
self.objs = {"0":[], "1":[], "2":[], "3":[], "4":[], "5":[]}
|
|
22
|
+
self.collision = []
|
|
23
|
+
self.events = None
|
|
24
|
+
self.cam = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Global = _global_()
|
|
28
|
+
|
GameBox/basics/Shapes.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
|
|
3
|
+
from .Net import Global
|
|
4
|
+
|
|
5
|
+
class shape:
|
|
6
|
+
def __init__(self, pos, dim, color, show):
|
|
7
|
+
self.pos = pygame.Vector2(pos)
|
|
8
|
+
self.dim = pygame.Vector2(dim)
|
|
9
|
+
self.color = color
|
|
10
|
+
self.show = show
|
|
11
|
+
|
|
12
|
+
def move_to(self, x, y):
|
|
13
|
+
self.pos = pygame.Vector2(x, y)
|
|
14
|
+
def move_by(self, x, y):
|
|
15
|
+
self.pos += pygame.Vector2(x, y)
|
|
16
|
+
|
|
17
|
+
def scale(self, factor):
|
|
18
|
+
self.dim *= factor
|
|
19
|
+
def set_dim(self, width, height):
|
|
20
|
+
self.dim = pygame.Vector2(width, height)
|
|
21
|
+
def change_dim(self, width, height):
|
|
22
|
+
self.dim += pygame.Vector2(width, height)
|
|
23
|
+
def set_color(self, color):
|
|
24
|
+
self.color = color
|
|
25
|
+
|
|
26
|
+
def collide(self, obj):
|
|
27
|
+
rect = pygame.Rect(self.pos, self.dim)
|
|
28
|
+
if hasattr(obj, 'pos') and hasattr(obj, 'dim'):
|
|
29
|
+
obj_rect = pygame.Rect(obj.pos, obj.dim)
|
|
30
|
+
return rect.colliderect(obj_rect)
|
|
31
|
+
print(f"<GameBox> Error: Object {obj} does not have pos and dim attributes and can't be collided with")
|
|
32
|
+
return False
|
|
33
|
+
|
|
34
|
+
class Rect(shape):
|
|
35
|
+
def __init__(self, pos, dim, color, show=True, collision=True, layer=3):
|
|
36
|
+
super().__init__(pos, dim, color, show)
|
|
37
|
+
self.collision = collision
|
|
38
|
+
self.layer = layer
|
|
39
|
+
|
|
40
|
+
Global.objs[str(layer)].append(self)
|
|
41
|
+
|
|
42
|
+
def update(self):
|
|
43
|
+
if self.show: self.draw()
|
|
44
|
+
|
|
45
|
+
def _addCollision(self):
|
|
46
|
+
if self.collision:
|
|
47
|
+
rect = pygame.Rect(self.pos, self.dim)
|
|
48
|
+
Global.collision.append(rect)
|
|
49
|
+
|
|
50
|
+
def draw(self):
|
|
51
|
+
sp = (self.pos - Global.cam.pos) * Global.cam.zoom
|
|
52
|
+
ss = self.dim * Global.cam.zoom
|
|
53
|
+
pygame.draw.rect(Global.screen, self.color, (sp, ss))
|
|
54
|
+
|
|
55
|
+
def delete(self):
|
|
56
|
+
Global.objs[str(self.layer)].remove(self)
|
|
57
|
+
|
|
58
|
+
class Circle(shape):
|
|
59
|
+
def __init__(self, pos, radius, color, show=True, layer=3):
|
|
60
|
+
super().__init__(pos, pygame.Vector2(radius, radius), color)
|
|
61
|
+
self.collision = False
|
|
62
|
+
self.layer = layer
|
|
63
|
+
Global.objs[str(layer)].append(self)
|
|
64
|
+
|
|
65
|
+
def update(self):
|
|
66
|
+
if self.show: self.draw()
|
|
67
|
+
|
|
68
|
+
def _addCollision(self):
|
|
69
|
+
if self.collision:
|
|
70
|
+
rect = pygame.Rect(self.pos, self.dim)
|
|
71
|
+
Global.collision.append(rect)
|
|
72
|
+
|
|
73
|
+
def draw(self):
|
|
74
|
+
sp = (self.pos - Global.cam.pos) * Global.cam.zoom
|
|
75
|
+
ss = self.dim * Global.cam.zoom
|
|
76
|
+
pygame.draw.circle(Global.screen, self.color, (sp), ss[0]//2)
|
|
77
|
+
|
|
78
|
+
def delete(self):
|
|
79
|
+
Global.objs[str(self.layer)].remove(self)
|
|
80
|
+
|
GameBox/basics/sound.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
|
|
3
|
+
class Sound:
|
|
4
|
+
def __init__(self, path: str, volume: float = 1.0):
|
|
5
|
+
self.sound = pygame.mixer.Sound(path)
|
|
6
|
+
self.volume = volume
|
|
7
|
+
|
|
8
|
+
def play(self, loops: int = 0, maxtime: int = 0, fade_ms: int = 0):
|
|
9
|
+
self.sound.play(loops, maxtime, fade_ms)
|
|
10
|
+
|
|
11
|
+
def stop(self):
|
|
12
|
+
self.sound.stop()
|
|
13
|
+
|
|
14
|
+
def set_volume(self, volume: float):
|
|
15
|
+
self.volume = volume
|
|
16
|
+
self.sound.set_volume(volume)
|
GameBox/basics/ui.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
|
|
3
|
+
from .Net import Global
|
|
4
|
+
|
|
5
|
+
class _image:
|
|
6
|
+
def __init__(self, pos, image, scale, show):
|
|
7
|
+
self.pos = pygame.Vector2(pos)
|
|
8
|
+
self.image = pygame.transform.scale(image, (int(image.get_width() * scale), int(image.get_height() * scale)))
|
|
9
|
+
self.scale = scale
|
|
10
|
+
self.show=show
|
|
11
|
+
|
|
12
|
+
def move_to(self, pos):
|
|
13
|
+
self.pos = pygame.Vector2(pos)
|
|
14
|
+
def move_by(self, x, y):
|
|
15
|
+
self.pos.x += x
|
|
16
|
+
self.pos.y += y
|
|
17
|
+
|
|
18
|
+
def change_scale(self, amount):
|
|
19
|
+
self.scale += amount
|
|
20
|
+
self.image = pygame.transform.scale(self.image, (int(self.image.get_width() * self.scale), int(self.image.get_height() * self.scale)))
|
|
21
|
+
|
|
22
|
+
def load_image(image) -> pygame.Surface:
|
|
23
|
+
if type(image) == str:
|
|
24
|
+
return pygame.image.load(image)
|
|
25
|
+
return image
|
|
26
|
+
|
|
27
|
+
class Image(_image):
|
|
28
|
+
def __init__(self, pos, image, scale, show=True, layer=0):
|
|
29
|
+
super().__init__(pos, load_image(image), scale, show)
|
|
30
|
+
self.layer = layer
|
|
31
|
+
Global.objs[str(self.layer)].append(self)
|
|
32
|
+
|
|
33
|
+
def update(self):
|
|
34
|
+
if self.show: self.draw()
|
|
35
|
+
|
|
36
|
+
def draw(self):
|
|
37
|
+
if Global.cam.zoom != 0:
|
|
38
|
+
image = pygame.transform.scale(self.image, (int(self.image.get_width() * Global.cam.zoom), int(self.image.get_height() * Global.cam.zoom)))
|
|
39
|
+
Global.screen.blit(image, self.pos - Global.cam.pos)
|
|
40
|
+
else:
|
|
41
|
+
Global.screen.blit(self.image, self.pos)
|
|
42
|
+
|
|
43
|
+
class Text:
|
|
44
|
+
def __init__(self, pos, text, font, color, show=True, ui=True, layer=0):
|
|
45
|
+
self.pos = pygame.Vector2(pos)
|
|
46
|
+
self.text = text
|
|
47
|
+
self.font = font
|
|
48
|
+
self.color = color
|
|
49
|
+
self.layer = layer
|
|
50
|
+
self.ui = ui
|
|
51
|
+
Global.objs[str(self.layer)].append(self)
|
|
52
|
+
self.show = show
|
|
53
|
+
|
|
54
|
+
def change(self, text):
|
|
55
|
+
self.text = text
|
|
56
|
+
|
|
57
|
+
def update(self):
|
|
58
|
+
if self.show: self.draw()
|
|
59
|
+
|
|
60
|
+
def draw(self):
|
|
61
|
+
text = self.font.render(self.text, True, self.color)
|
|
62
|
+
#scale if needed
|
|
63
|
+
if Global.cam.zoom != 1.0: text = pygame.transform.scale_by(text, Global.cam.zoom)
|
|
64
|
+
|
|
65
|
+
if self.ui: Global.screen.blit(text, self.pos)
|
|
66
|
+
else:
|
|
67
|
+
sp = self.pos - Global.cam.pos
|
|
68
|
+
Global.screen.blit(text, sp)
|
|
69
|
+
|
|
70
|
+
|
GameBox/basics/utils.py
CHANGED
|
@@ -4,6 +4,7 @@ import numpy as np
|
|
|
4
4
|
|
|
5
5
|
def clamp(value, min_value, max_value):
|
|
6
6
|
return max(min(value, max_value), min_value)
|
|
7
|
+
|
|
7
8
|
def moveTward(value, target, speed):
|
|
8
9
|
if value < target:
|
|
9
10
|
value += speed
|
|
@@ -14,4 +15,4 @@ def moveTward(value, target, speed):
|
|
|
14
15
|
def zeroOut(value, max):
|
|
15
16
|
if value < 0 and value > -max: value = 0
|
|
16
17
|
if value > 0 and value < max: value = 0
|
|
17
|
-
return value
|
|
18
|
+
return value
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pygame
|
|
2
2
|
|
|
3
|
-
from ..basics.
|
|
3
|
+
from ..basics.Net import Global
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class _keys:
|
|
@@ -61,14 +61,19 @@ class _keys:
|
|
|
61
61
|
|
|
62
62
|
#mouse
|
|
63
63
|
self.mouse_x, self.mouse_y = 0, 0
|
|
64
|
-
def init(self): Global.
|
|
64
|
+
def init(self): Global.objs[str(5)].append(self)
|
|
65
65
|
|
|
66
66
|
def is_pressed(self, key):
|
|
67
|
-
|
|
67
|
+
if Global.events is None: return False
|
|
68
|
+
for event in Global.events:
|
|
68
69
|
if event.type == pygame.KEYDOWN:
|
|
69
70
|
if event.key == key: return True
|
|
70
71
|
return False
|
|
71
72
|
|
|
73
|
+
def is_held(self, key):
|
|
74
|
+
keys = pygame.key.get_pressed()
|
|
75
|
+
return keys[key]
|
|
76
|
+
|
|
72
77
|
def update(self): self.mouse_x, self.mouse_y = pygame.mouse.get_pos()
|
|
73
78
|
|
|
74
79
|
|
GameBox/helpers/_collisions.py
CHANGED
|
@@ -1,165 +1,78 @@
|
|
|
1
1
|
import pygame
|
|
2
|
-
import numpy as np
|
|
3
2
|
|
|
4
|
-
from ..basics.
|
|
3
|
+
from ..basics.Net import Global
|
|
5
4
|
|
|
6
5
|
|
|
7
|
-
def
|
|
8
|
-
|
|
6
|
+
def CollisionLogic(vel, pos, dim, sample):
|
|
7
|
+
x, y = pos
|
|
8
|
+
vx, vy = vel
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
x, y, vx, vy = _checkTilemapCollisions(x, y, vx, vy, dim, sample, obj)
|
|
10
|
+
x, y, vx, vy = _Collisions(x, y, vx, vy, dim, Global.collision)
|
|
11
|
+
#x, y, vx, vy = _tilemapCollisions(x, y, vx, vy, dim, sample)
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def _mainCollisionLogic(collisions, x, y, vx, vy, dim):
|
|
17
|
-
offset = 0
|
|
13
|
+
pos = pygame.Vector2(x, y)
|
|
14
|
+
vel = pygame.Vector2(vx, vy)
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
rect = pygame.Rect(x, y, dim[0], dim[1])
|
|
16
|
+
return pos, vel
|
|
21
17
|
|
|
22
|
-
# =====================
|
|
23
|
-
# Y AXIS COLLISION
|
|
24
|
-
# =====================
|
|
25
|
-
y_hit = None
|
|
26
18
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
def _Collisions(x, y, vx, vy, dim, shapes):
|
|
20
|
+
# Apply movement
|
|
21
|
+
x += vx
|
|
22
|
+
y += vy
|
|
30
23
|
|
|
31
|
-
|
|
32
|
-
if vy > 0 and prev_rect.bottom <= collision.top:
|
|
33
|
-
if y_hit is None or collision.top < y_hit.top:
|
|
34
|
-
y_hit = collision
|
|
35
|
-
elif vy < 0 and prev_rect.top >= collision.bottom:
|
|
36
|
-
if y_hit is None or collision.bottom > y_hit.bottom:
|
|
37
|
-
y_hit = collision
|
|
24
|
+
rect = pygame.Rect(x, y, dim.x, dim.y)
|
|
38
25
|
|
|
39
|
-
|
|
40
|
-
if
|
|
41
|
-
|
|
42
|
-
else:
|
|
43
|
-
y = y_hit.bottom + offset
|
|
44
|
-
vy = 0
|
|
45
|
-
|
|
46
|
-
# update rect after Y resolution
|
|
47
|
-
rect.y = y
|
|
48
|
-
|
|
49
|
-
# =====================
|
|
50
|
-
# X AXIS COLLISION
|
|
51
|
-
# =====================
|
|
52
|
-
x_hit = None
|
|
53
|
-
|
|
54
|
-
for collision in collisions:
|
|
55
|
-
if collision.colliderect(rect):
|
|
26
|
+
for collision in shapes:
|
|
27
|
+
if not rect.colliderect(collision):
|
|
28
|
+
continue
|
|
56
29
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
30
|
+
# Calculate overlap on each side
|
|
31
|
+
overlap_left = rect.right - collision.left
|
|
32
|
+
overlap_right = collision.right - rect.left
|
|
33
|
+
overlap_top = rect.bottom - collision.top
|
|
34
|
+
overlap_bottom = collision.bottom - rect.top
|
|
61
35
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
36
|
+
# Find smallest overlap
|
|
37
|
+
min_x = min(overlap_left, overlap_right)
|
|
38
|
+
min_y = min(overlap_top, overlap_bottom)
|
|
65
39
|
|
|
66
|
-
|
|
67
|
-
if
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
x = x_hit.right + offset
|
|
71
|
-
vx = 0
|
|
72
|
-
|
|
73
|
-
if Global._debug:
|
|
74
|
-
pygame.draw.rect(
|
|
75
|
-
Global.screen,
|
|
76
|
-
"green",
|
|
77
|
-
rect,
|
|
78
|
-
2
|
|
79
|
-
)
|
|
80
|
-
pygame.draw.rect(
|
|
81
|
-
Global.screen,
|
|
82
|
-
"red",
|
|
83
|
-
prev_rect,
|
|
84
|
-
1
|
|
85
|
-
)
|
|
86
|
-
pygame.draw.rect(
|
|
87
|
-
Global.screen,
|
|
88
|
-
"blue",
|
|
89
|
-
(x, y, dim[0], dim[1]),
|
|
90
|
-
2
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
return x, y, vx, vy
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def _checkTilemapCollisions(x, y, vx, vy, dim, sample, obj):
|
|
98
|
-
if len(Global.tilemap) == 0:
|
|
99
|
-
return x, y, vx, vy
|
|
100
|
-
|
|
101
|
-
for tilemap in Global.tilemap:
|
|
102
|
-
|
|
103
|
-
#get player reletive tilemap pos
|
|
104
|
-
prect = pygame.Rect(x, y, dim[0], dim[1])
|
|
105
|
-
prx, pry = prect.center
|
|
106
|
-
if Global.cam.follow != obj:
|
|
107
|
-
if Global.cam.x != 0 or Global.cam.y != 0:
|
|
108
|
-
px = int((prx) - Global.cam.x)
|
|
109
|
-
py = int((pry) - Global.cam.y)
|
|
110
|
-
px = int(px // tilemap.tileDim[0])
|
|
111
|
-
py = int(py // tilemap.tileDim[1])
|
|
40
|
+
# Resolve on the axis with least penetration
|
|
41
|
+
if min_x < min_y:
|
|
42
|
+
if overlap_left < overlap_right:
|
|
43
|
+
rect.right = collision.left
|
|
112
44
|
else:
|
|
113
|
-
|
|
114
|
-
|
|
45
|
+
rect.left = collision.right
|
|
46
|
+
vx = 0
|
|
115
47
|
else:
|
|
116
|
-
if
|
|
117
|
-
|
|
118
|
-
py = int(((pry + Global.cam.y)) // tilemap.tileDim[1])
|
|
48
|
+
if overlap_top < overlap_bottom:
|
|
49
|
+
rect.bottom = collision.top
|
|
119
50
|
else:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
rect
|
|
143
|
-
|
|
144
|
-
# Position rect correctly in the world
|
|
145
|
-
if Global.cam.follow != obj:
|
|
146
|
-
if Global.cam.x != 0 or Global.cam.y != 0:
|
|
147
|
-
rect.x = ((nx * tilemap.tileDim[0])) - Global.cam.x
|
|
148
|
-
rect.y = ((ny * tilemap.tileDim[1])) - Global.cam.y
|
|
149
|
-
else:
|
|
150
|
-
rect.x += (nx * tilemap.tileDim[0]) - Global.cam.x
|
|
151
|
-
rect.y += (ny * tilemap.tileDim[1]) - Global.cam.y
|
|
152
|
-
else:
|
|
153
|
-
if Global.cam.x != 0 or Global.cam.y != 0:
|
|
154
|
-
rect.x += ((nx * tilemap.tileDim[0])) - Global.cam.x
|
|
155
|
-
rect.y += ((ny * tilemap.tileDim[1])) - Global.cam.y
|
|
156
|
-
else:
|
|
157
|
-
rect.x += (nx * tilemap.tileDim[0]) - Global.cam.x
|
|
158
|
-
rect.y += (ny * tilemap.tileDim[1]) - Global.cam.y
|
|
51
|
+
rect.top = collision.bottom
|
|
52
|
+
vy = 0
|
|
53
|
+
|
|
54
|
+
return rect.x, rect.y, vx, vy
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _tilemapCollisions(x, y, vx, vy, dim, sampleSize):
|
|
58
|
+
for map in Global.tilemaps:
|
|
59
|
+
#get player tilemap pos
|
|
60
|
+
tx = x//map.tileDim[0]
|
|
61
|
+
ty = y//map.tileDim[1]
|
|
62
|
+
#get tiles around player
|
|
63
|
+
collisions = []
|
|
64
|
+
for yIndex in range(-sampleSize, sampleSize):
|
|
65
|
+
for xIndex in range(-sampleSize, sampleSize):
|
|
66
|
+
#if point not on map, skip
|
|
67
|
+
if tx+xIndex < 0 or tx+xIndex >= map.mapDim[0] or ty+yIndex < 0 or ty+yIndex >= map.mapDim[1]: continue
|
|
68
|
+
#get shape
|
|
69
|
+
tile = str(map.map[int(ty+yIndex)][int(tx+xIndex)])
|
|
70
|
+
if tile not in map.collisionDict: continue
|
|
71
|
+
shape = map.collisionDict[str(tile)]
|
|
72
|
+
rect = getattr(map.collisionShapes, shape).copy()
|
|
73
|
+
rect.x += (tx+xIndex)*map.tileDim[0]
|
|
74
|
+
rect.y += (ty+yIndex)*map.tileDim[1]
|
|
159
75
|
collisions.append(rect)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return x, y, vx, vy
|
|
165
|
-
|
|
76
|
+
#collision math
|
|
77
|
+
x, y, vx, vy = _Collisions(x, y, vx, vy, dim, collisions)
|
|
78
|
+
return x, y, vx, vy
|