pgfe 0.1.0__tar.gz
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.
- pgfe-0.1.0/PKG-INFO +5 -0
- pgfe-0.1.0/pyproject.toml +9 -0
- pgfe-0.1.0/pyproject.toml.orig +11 -0
- pgfe-0.1.0/src/pgfe/Enum.py +6 -0
- pgfe-0.1.0/src/pgfe/__init__.py +6 -0
- pgfe-0.1.0/src/pgfe/entity/AbstractEntity.py +29 -0
- pgfe-0.1.0/src/pgfe/entity/__init__.py +0 -0
- pgfe-0.1.0/src/pgfe/entity/entity_components/AbstractComponent.py +9 -0
- pgfe-0.1.0/src/pgfe/entity/entity_components/CollisionExceptions.py +37 -0
- pgfe-0.1.0/src/pgfe/entity/entity_components/__init__.py +0 -0
- pgfe-0.1.0/src/pgfe/entity/entity_components/colliders/AABBCollider.py +37 -0
- pgfe-0.1.0/src/pgfe/entity/entity_components/colliders/AbstractCollider.py +57 -0
- pgfe-0.1.0/src/pgfe/entity/entity_components/colliders/__init__.py +0 -0
- pgfe-0.1.0/src/pgfe/entity/entity_controllers/AbstractController.py +11 -0
- pgfe-0.1.0/src/pgfe/entity/entity_controllers/WASDController.py +38 -0
- pgfe-0.1.0/src/pgfe/entity/entity_controllers/__init__.py +0 -0
- pgfe-0.1.0/src/pgfe/events_manager.py +33 -0
- pgfe-0.1.0/src/pgfe/game/AbstractGame.py +53 -0
- pgfe-0.1.0/src/pgfe/game/__init__.py +0 -0
- pgfe-0.1.0/src/pgfe/scene/AbstractScene.py +54 -0
- pgfe-0.1.0/src/pgfe/scene/__init__.py +0 -0
pgfe-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
import abc
|
|
3
|
+
import pygame as pg
|
|
4
|
+
|
|
5
|
+
from pgfe.entity.entity_controllers.AbstractController import AbstractController
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AbstractEntity(pg.sprite.Sprite, abc.ABC):
|
|
9
|
+
|
|
10
|
+
def __init__(self, *groups, x: int, y: int, image: pg.Surface) -> None:
|
|
11
|
+
pg.sprite.Sprite.__init__(self, *groups)
|
|
12
|
+
self.controller: AbstractController|None = None
|
|
13
|
+
|
|
14
|
+
self.image = image
|
|
15
|
+
self.rect = self.image.get_rect()
|
|
16
|
+
self.rect.x = x
|
|
17
|
+
self.rect.y = y
|
|
18
|
+
|
|
19
|
+
self.velocity: pg.Vector2 = pg.Vector2()
|
|
20
|
+
|
|
21
|
+
def update_velocity(self, x: float = 0.0, y: float = 0.0) -> None:
|
|
22
|
+
self.velocity.x += x
|
|
23
|
+
self.velocity.y += y
|
|
24
|
+
|
|
25
|
+
def move_x(self):
|
|
26
|
+
self.rect.x += self.velocity.x
|
|
27
|
+
|
|
28
|
+
def move_y(self):
|
|
29
|
+
self.rect.y += self.velocity.y
|
|
File without changes
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import dataclasses, typing
|
|
5
|
+
|
|
6
|
+
from pgfe.entity.entity_components.AbstractComponent import AbstractComponent
|
|
7
|
+
|
|
8
|
+
if typing.TYPE_CHECKING:
|
|
9
|
+
from rampant.world.tiles.Tile import Tile
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclasses.dataclass
|
|
13
|
+
class CollisionExceptions(AbstractComponent):
|
|
14
|
+
def __init__(self):
|
|
15
|
+
super().__init__()
|
|
16
|
+
self.unconditional: CollisionRules.Unconditional = self.Unconditional()
|
|
17
|
+
self.conditional: CollisionRules.Conditional = self.Conditional()
|
|
18
|
+
|
|
19
|
+
class Unconditional(list):
|
|
20
|
+
def add(self, tile: "type[Tile]"):
|
|
21
|
+
self.append(tile)
|
|
22
|
+
|
|
23
|
+
def remove(self, tile: "type[Tile]"):
|
|
24
|
+
super().remove(tile)
|
|
25
|
+
|
|
26
|
+
def get_rules(self):
|
|
27
|
+
return [i for i in self]
|
|
28
|
+
|
|
29
|
+
class Conditional(dict):
|
|
30
|
+
def add(self, tile: "type[Tile]", condition: "typing.Callable[[Tile], Tile|None]"):
|
|
31
|
+
self[tile] = condition
|
|
32
|
+
|
|
33
|
+
def remove(self, tile: "type[Tile]"):
|
|
34
|
+
super().pop(self, tile)
|
|
35
|
+
|
|
36
|
+
def get_rules(self):
|
|
37
|
+
return {(t, c) for t, c in self.items()}
|
|
File without changes
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
import abc
|
|
3
|
+
|
|
4
|
+
from pgfe import Enum
|
|
5
|
+
from pgfe.entity.entity_components.colliders.AbstractCollider import AbstractCollider
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AABBCollider(AbstractCollider, abc.ABC):
|
|
9
|
+
def __init__(self):
|
|
10
|
+
super().__init__()
|
|
11
|
+
|
|
12
|
+
def collide(self, sprite, axis) -> tuple[bool, bool]:
|
|
13
|
+
if axis == Enum.Axis.X:
|
|
14
|
+
to_return = [False, False]
|
|
15
|
+
if self.velocity.x > 0:
|
|
16
|
+
self.rect.right = sprite.rect.left
|
|
17
|
+
self.velocity.x = 0
|
|
18
|
+
to_return[0] = True
|
|
19
|
+
if self.velocity.x < 0:
|
|
20
|
+
self.rect.left = sprite.rect.right
|
|
21
|
+
self.velocity.x = 0
|
|
22
|
+
to_return[1] = True
|
|
23
|
+
return tuple(to_return)
|
|
24
|
+
|
|
25
|
+
if axis == Enum.Axis.Y:
|
|
26
|
+
to_return = [False, False]
|
|
27
|
+
if self.velocity.y > 0:
|
|
28
|
+
self.rect.bottom = sprite.rect.top
|
|
29
|
+
self.velocity.y = 0
|
|
30
|
+
to_return[1] = True
|
|
31
|
+
if self.velocity.y < 0:
|
|
32
|
+
self.rect.top = sprite.rect.bottom
|
|
33
|
+
self.velocity.y = 0
|
|
34
|
+
to_return[0] = True
|
|
35
|
+
return tuple(to_return)
|
|
36
|
+
|
|
37
|
+
return False, False
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
|
|
2
|
+
import abc
|
|
3
|
+
import pygame as pg
|
|
4
|
+
|
|
5
|
+
from pgfe import Enum
|
|
6
|
+
from pgfe.entity.entity_components.AbstractComponent import AbstractComponent
|
|
7
|
+
from pgfe.entity.entity_components.CollisionExceptions import CollisionExceptions
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AbstractCollider(AbstractComponent, abc.ABC):
|
|
11
|
+
def __init__(self):
|
|
12
|
+
super().__init__()
|
|
13
|
+
|
|
14
|
+
self.collision_exceptions = CollisionExceptions()
|
|
15
|
+
|
|
16
|
+
def get_collides(self, sprite_group):
|
|
17
|
+
for sprite in sprite_group.sprites():
|
|
18
|
+
if sprite != self and self.rect.colliderect(sprite.rect):
|
|
19
|
+
yield sprite
|
|
20
|
+
|
|
21
|
+
@abc.abstractmethod
|
|
22
|
+
def collide(self, sprite: pg.sprite.Sprite, axis: Enum.Axis) -> tuple[bool, bool]:
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
def collides(self, sprite_group):
|
|
26
|
+
directions = {"top": False, "left": False, "bottom": False, "right": False}
|
|
27
|
+
|
|
28
|
+
# Remove unwanted sprites
|
|
29
|
+
for sprite in sprite_group.sprites():
|
|
30
|
+
if sprite != self and type(sprite) in self.collision_exceptions.unconditional:
|
|
31
|
+
sprite_group.remove(sprite)
|
|
32
|
+
|
|
33
|
+
self.move_x()
|
|
34
|
+
for sprite in self.get_collides(sprite_group):
|
|
35
|
+
right, left = self.collide(sprite, Enum.Axis.X)
|
|
36
|
+
directions.update({
|
|
37
|
+
"left": left,
|
|
38
|
+
"right": right
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
self.move_y()
|
|
42
|
+
for sprite in self.get_collides(sprite_group):
|
|
43
|
+
top, bottom = self.collide(sprite, Enum.Axis.Y)
|
|
44
|
+
directions.update({
|
|
45
|
+
"top": top,
|
|
46
|
+
"bottom": bottom
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
return directions
|
|
50
|
+
|
|
51
|
+
@abc.abstractmethod
|
|
52
|
+
def move_x(self):
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
@abc.abstractmethod
|
|
56
|
+
def move_y(self):
|
|
57
|
+
pass
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
import pygame as pg
|
|
3
|
+
|
|
4
|
+
from pgfe.entity.entity_controllers.AbstractController import AbstractController
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class WASDController(AbstractController):
|
|
8
|
+
def __init__(self):
|
|
9
|
+
super().__init__()
|
|
10
|
+
|
|
11
|
+
def return_wasd(self) -> dict[str, float]:
|
|
12
|
+
pressed = pg.key.get_pressed()
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
"w": pressed[pg.K_w],
|
|
16
|
+
"a": pressed[pg.K_a],
|
|
17
|
+
"s": pressed[pg.K_s],
|
|
18
|
+
"d": pressed[pg.K_d]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
def return_movement(self) -> pg.Vector2:
|
|
22
|
+
vector = pg.math.Vector2()
|
|
23
|
+
wasd = self.return_wasd()
|
|
24
|
+
|
|
25
|
+
if wasd["w"]:
|
|
26
|
+
vector.x = 0
|
|
27
|
+
vector.y -= 1
|
|
28
|
+
if wasd["a"]:
|
|
29
|
+
vector.y = 0
|
|
30
|
+
vector.x -= 1
|
|
31
|
+
if wasd["s"]:
|
|
32
|
+
vector.x = 0
|
|
33
|
+
vector.y += 1
|
|
34
|
+
if wasd["d"]:
|
|
35
|
+
vector.y = 0
|
|
36
|
+
vector.x += 1
|
|
37
|
+
|
|
38
|
+
return vector
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
import pygame as pg
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
events: dict[int, list[typing.Callable]] = {}
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def add(hook: int, event: typing.Callable[[int], None]):
|
|
10
|
+
global events
|
|
11
|
+
|
|
12
|
+
event_list = events.get(hook)
|
|
13
|
+
if event_list:
|
|
14
|
+
events[hook].append(event)
|
|
15
|
+
else:
|
|
16
|
+
events[hook] = [event]
|
|
17
|
+
|
|
18
|
+
def remove(hook: int, event: typing.Callable):
|
|
19
|
+
global events
|
|
20
|
+
events[hook].remove(event)
|
|
21
|
+
|
|
22
|
+
def clear(hook: int):
|
|
23
|
+
global events
|
|
24
|
+
events[hook] = []
|
|
25
|
+
|
|
26
|
+
def update_events():
|
|
27
|
+
global events
|
|
28
|
+
|
|
29
|
+
for event in pg.event.get():
|
|
30
|
+
if event.type in events:
|
|
31
|
+
for called in events[event.type]:
|
|
32
|
+
called(event)
|
|
33
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
|
|
2
|
+
import abc
|
|
3
|
+
import pygame as pg
|
|
4
|
+
|
|
5
|
+
from pgfe.scene.AbstractScene import AbstractScene
|
|
6
|
+
from pgfe import events_manager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def quit(event: int):
|
|
10
|
+
pg.quit()
|
|
11
|
+
raise SystemExit
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AbstractGame(abc.ABC):
|
|
15
|
+
|
|
16
|
+
def __init__(self, framerate: int = 60, tickrate: int = 60, **window_args):
|
|
17
|
+
self.window: pg.Window = pg.Window(**window_args)
|
|
18
|
+
self.window.get_surface()
|
|
19
|
+
|
|
20
|
+
self.clock: pg.time.Clock = pg.time.Clock()
|
|
21
|
+
|
|
22
|
+
self.framerate: int = framerate
|
|
23
|
+
self.tickrate: int = tickrate
|
|
24
|
+
|
|
25
|
+
self.dt: float = 0
|
|
26
|
+
self.frame_dt: float = 0
|
|
27
|
+
|
|
28
|
+
self.scene: AbstractScene|None = None
|
|
29
|
+
|
|
30
|
+
events_manager.add(pg.QUIT, quit)
|
|
31
|
+
|
|
32
|
+
def set_scene(self, scene: AbstractScene):
|
|
33
|
+
self.scene = scene
|
|
34
|
+
self.scene.load()
|
|
35
|
+
|
|
36
|
+
def tick(self):
|
|
37
|
+
self.dt = self.clock.tick(self.tickrate) / 1000
|
|
38
|
+
self.frame_dt = self.dt * self.framerate
|
|
39
|
+
|
|
40
|
+
def update_idle_tasks(self):
|
|
41
|
+
self.scene.render(self.window.get_surface())
|
|
42
|
+
events_manager.update_events()
|
|
43
|
+
self.window.flip()
|
|
44
|
+
|
|
45
|
+
def play(self):
|
|
46
|
+
while True:
|
|
47
|
+
self.tick()
|
|
48
|
+
|
|
49
|
+
self.window.get_surface().fill(self.scene.colors.BG)
|
|
50
|
+
|
|
51
|
+
self.scene.update()
|
|
52
|
+
|
|
53
|
+
self.update_idle_tasks()
|
|
File without changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import abc
|
|
5
|
+
import typing
|
|
6
|
+
import dataclasses
|
|
7
|
+
import pygame as pg
|
|
8
|
+
|
|
9
|
+
if typing.TYPE_CHECKING:
|
|
10
|
+
from pgfe.game.AbstractGame import AbstractGame
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclasses.dataclass
|
|
14
|
+
class SceneColors:
|
|
15
|
+
|
|
16
|
+
BG: pg.Color = dataclasses.field(
|
|
17
|
+
default_factory=lambda: pg.Color("black")
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
FG: pg.Color = dataclasses.field(
|
|
21
|
+
default_factory=lambda: pg.Color("grey")
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
extra: dict[str, pg.Color] = dataclasses.field(default_factory=dict)
|
|
25
|
+
|
|
26
|
+
def add_color(self, name: str, color: pg.Color):
|
|
27
|
+
self.extra[name] = color
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AbstractScene(abc.ABC):
|
|
31
|
+
|
|
32
|
+
def __init__(self, game: AbstractGame, colors: SceneColors = SceneColors(), **groups: pg.sprite.Group):
|
|
33
|
+
|
|
34
|
+
self.game: AbstractGame = game
|
|
35
|
+
|
|
36
|
+
self.colors: SceneColors = colors
|
|
37
|
+
|
|
38
|
+
self.groups: dict[str, pg.sprite.Group] = groups
|
|
39
|
+
|
|
40
|
+
@abc.abstractmethod
|
|
41
|
+
def load(self):
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
def reset(self):
|
|
45
|
+
for group in self.groups.values():
|
|
46
|
+
group.empty()
|
|
47
|
+
|
|
48
|
+
def update(self, *args, **kwargs):
|
|
49
|
+
for group in self.groups.values():
|
|
50
|
+
group.update(*args, **kwargs)
|
|
51
|
+
|
|
52
|
+
def render(self, surface: pg.Surface):
|
|
53
|
+
for group in self.groups.values():
|
|
54
|
+
group.draw(surface)
|
|
File without changes
|