GameBox 0.9.1__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 +70 -106
- 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.1.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.1.dist-info/RECORD +0 -25
- {gamebox-0.9.1.dist-info → gamebox-0.10.0.dev1.dist-info}/WHEEL +0 -0
- {gamebox-0.9.1.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,114 +1,78 @@
|
|
|
1
1
|
import pygame
|
|
2
|
-
import numpy as np
|
|
3
|
-
|
|
4
|
-
from ..basics._net import Global
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def CheckCollisions(x, y, vx, vy, dim, sample, obj):
|
|
8
|
-
x, y = x + vx, y + vy
|
|
9
|
-
|
|
10
|
-
#basic object collisions
|
|
11
|
-
x, y, vx, vy = _mainCollisionLogic(Global.collisions, x, y, vx, vy, dim)
|
|
12
|
-
x, y, vx, vy = _checkTilemapCollisions(x, y, vx, vy, dim, sample, obj)
|
|
13
|
-
|
|
14
|
-
return x, y, vx, vy
|
|
15
|
-
|
|
16
|
-
def _mainCollisionLogic(collisions, x, y, vx, vy, dim):
|
|
17
|
-
# Y-axis collisions
|
|
18
|
-
py = y
|
|
19
|
-
new_rect = pygame.Rect((x, y), dim)
|
|
20
|
-
if Global._debug:
|
|
21
|
-
pygame.draw.rect(Global.screen, "green", new_rect, 5)
|
|
22
|
-
for collision in collisions:
|
|
23
|
-
if Global._debug:
|
|
24
|
-
pygame.draw.rect(Global.screen, "yellow", collision, 5)
|
|
25
|
-
if collision.colliderect(new_rect):
|
|
26
|
-
if vy > 0: # falling
|
|
27
|
-
y = collision.top - dim[1]
|
|
28
|
-
vy = 0
|
|
29
|
-
elif vy < 0: # jumping
|
|
30
|
-
y = collision.bottom
|
|
31
|
-
vy = 0
|
|
32
|
-
|
|
33
|
-
new_rect = pygame.Rect((x, py), dim)
|
|
34
|
-
for collision in collisions:
|
|
35
|
-
if Global._debug:
|
|
36
|
-
pygame.draw.rect(Global.screen, "yellow", collision, 5)
|
|
37
|
-
if collision.colliderect(new_rect):
|
|
38
|
-
if vx > 0:
|
|
39
|
-
x = collision.left - dim[0]
|
|
40
|
-
elif vx < 0:
|
|
41
|
-
x = collision.right
|
|
42
|
-
vx = 0
|
|
43
2
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
3
|
+
from ..basics.Net import Global
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def CollisionLogic(vel, pos, dim, sample):
|
|
7
|
+
x, y = pos
|
|
8
|
+
vx, vy = vel
|
|
9
|
+
|
|
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)
|
|
12
|
+
|
|
13
|
+
pos = pygame.Vector2(x, y)
|
|
14
|
+
vel = pygame.Vector2(vx, vy)
|
|
15
|
+
|
|
16
|
+
return pos, vel
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _Collisions(x, y, vx, vy, dim, shapes):
|
|
20
|
+
# Apply movement
|
|
21
|
+
x += vx
|
|
22
|
+
y += vy
|
|
23
|
+
|
|
24
|
+
rect = pygame.Rect(x, y, dim.x, dim.y)
|
|
25
|
+
|
|
26
|
+
for collision in shapes:
|
|
27
|
+
if not rect.colliderect(collision):
|
|
28
|
+
continue
|
|
29
|
+
|
|
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
|
|
35
|
+
|
|
36
|
+
# Find smallest overlap
|
|
37
|
+
min_x = min(overlap_left, overlap_right)
|
|
38
|
+
min_y = min(overlap_top, overlap_bottom)
|
|
39
|
+
|
|
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
|
|
61
44
|
else:
|
|
62
|
-
|
|
63
|
-
|
|
45
|
+
rect.left = collision.right
|
|
46
|
+
vx = 0
|
|
64
47
|
else:
|
|
65
|
-
if
|
|
66
|
-
|
|
67
|
-
py = int(((pry + Global.cam.y)) // tilemap.tileDim[1])
|
|
48
|
+
if overlap_top < overlap_bottom:
|
|
49
|
+
rect.bottom = collision.top
|
|
68
50
|
else:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
#check if player is on tilemap
|
|
74
|
-
if px < 0 or px >= tilemap.mapDim[0] or py < 0 or py >= tilemap.mapDim[1]:
|
|
75
|
-
return x, y, vx, vy
|
|
76
|
-
#get collision rects around player
|
|
77
|
-
collisions: list[pygame.Rect] = []
|
|
78
|
-
for tx in range(px - sample, px + sample):
|
|
79
|
-
for ty in range(py - sample, py + sample):
|
|
80
|
-
nx = int(px + tx)
|
|
81
|
-
ny = int(py + ty)
|
|
82
|
-
#if tile is on map
|
|
83
|
-
if nx < 0 or nx >= tilemap.mapDim[0] or ny < 0 or ny >= tilemap.mapDim[1]:
|
|
84
|
-
continue
|
|
85
|
-
#if tile has defined collision shape
|
|
86
|
-
tile = str(tilemap.map[ny][nx])
|
|
87
|
-
if tile not in tilemap.collisionDict: continue
|
|
88
|
-
|
|
89
|
-
#get collision shape
|
|
90
|
-
rectshape = tilemap.collisionDict[str(tile)]
|
|
91
|
-
rect = getattr(tilemap.collisionShapes, rectshape).copy()
|
|
92
|
-
|
|
93
|
-
# Position rect correctly in the world
|
|
94
|
-
if Global.cam.follow != obj:
|
|
95
|
-
if Global.cam.x != 0 or Global.cam.y != 0:
|
|
96
|
-
rect.x = ((nx * tilemap.tileDim[0])) - Global.cam.x
|
|
97
|
-
rect.y = ((ny * tilemap.tileDim[1])) - Global.cam.y
|
|
98
|
-
else:
|
|
99
|
-
rect.x += (nx * tilemap.tileDim[0]) - Global.cam.x
|
|
100
|
-
rect.y += (ny * tilemap.tileDim[1]) - Global.cam.y
|
|
101
|
-
else:
|
|
102
|
-
if Global.cam.x != 0 or Global.cam.y != 0:
|
|
103
|
-
rect.x += ((nx * tilemap.tileDim[0])) - Global.cam.x
|
|
104
|
-
rect.y += ((ny * tilemap.tileDim[1])) - Global.cam.y
|
|
105
|
-
else:
|
|
106
|
-
rect.x += (nx * tilemap.tileDim[0]) - Global.cam.x
|
|
107
|
-
rect.y += (ny * tilemap.tileDim[1]) - Global.cam.y
|
|
108
|
-
collisions.append(rect)
|
|
51
|
+
rect.top = collision.bottom
|
|
52
|
+
vy = 0
|
|
109
53
|
|
|
110
|
-
|
|
111
|
-
x, y, vx, vy = _mainCollisionLogic(collisions, x, y, vx, vy, dim)
|
|
54
|
+
return rect.x, rect.y, vx, vy
|
|
112
55
|
|
|
113
|
-
return x, y, vx, vy
|
|
114
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]
|
|
75
|
+
collisions.append(rect)
|
|
76
|
+
#collision math
|
|
77
|
+
x, y, vx, vy = _Collisions(x, y, vx, vy, dim, collisions)
|
|
78
|
+
return x, y, vx, vy
|
GameBox/player/Player.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
|
|
3
|
+
from ..basics.Net import Global
|
|
4
|
+
from ._playerPhysics import playerPhysics
|
|
5
|
+
from ._playerControler import playerController
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Player:
|
|
9
|
+
def __init__(self, pos, dim, color, show=True, layer=3):
|
|
10
|
+
self.pos = pygame.Vector2(pos)
|
|
11
|
+
self.dim = pygame.Vector2(dim)
|
|
12
|
+
self.vel = pygame.Vector2(0, 0)
|
|
13
|
+
self.color = color
|
|
14
|
+
|
|
15
|
+
self.physics = None
|
|
16
|
+
self.move = playerController(self)
|
|
17
|
+
self.show = show
|
|
18
|
+
|
|
19
|
+
self.sampleSize = 5
|
|
20
|
+
self.layer = layer
|
|
21
|
+
|
|
22
|
+
Global.objs[str(layer)].append(self)
|
|
23
|
+
#Global.player = self
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def copy(self):
|
|
27
|
+
p = Player(self.pos, self.dim, self.color, self.show, self.layer)
|
|
28
|
+
p.add_physics(self.physics.speed, self.physics.gravity, self.physics.jumpForce, self.physics.maxV, self.physics.friction)
|
|
29
|
+
return p
|
|
30
|
+
|
|
31
|
+
def add_physics(self, speed: float = 7.0, gravity: float = 5.5, jumpForce: float = 10.0, maxV: tuple = (25, 25), friction: tuple = (0.8, 0.8)):
|
|
32
|
+
self.physics = playerPhysics(self, speed, gravity, jumpForce, pygame.Vector2(maxV), pygame.Vector2(friction))
|
|
33
|
+
|
|
34
|
+
def update(self):
|
|
35
|
+
if self.physics: self.physics.update()
|
|
36
|
+
if self.show: self.draw()
|
|
37
|
+
|
|
38
|
+
#--debug func--
|
|
39
|
+
def draw(self):
|
|
40
|
+
sp = (self.pos - Global.cam.pos) * Global.cam.zoom
|
|
41
|
+
ss = self.dim * Global.cam.zoom
|
|
42
|
+
pygame.draw.rect(Global.screen, self.color, [sp, ss])
|
|
43
|
+
|
|
44
|
+
def set_sample_size(self, size):
|
|
45
|
+
self.sampleSize = size
|