GameBox 0.3.0__tar.gz → 0.9.1__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.
Files changed (32) hide show
  1. {gamebox-0.3.0 → gamebox-0.9.1}/PKG-INFO +1 -1
  2. {gamebox-0.3.0 → gamebox-0.9.1}/pyproject.toml +1 -1
  3. gamebox-0.9.1/src/GameBox/GameLevel_ui/_Animations.py +39 -0
  4. gamebox-0.9.1/src/GameBox/GameLevel_ui/_sprites.py +185 -0
  5. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/__init__.py +10 -0
  6. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/_game.py +27 -0
  7. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/basics/_net.py +4 -0
  8. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/basics/_shapes.py +12 -1
  9. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/basics/cammera.py +1 -1
  10. gamebox-0.9.1/src/GameBox/helpers/_Conditions.py +56 -0
  11. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/helpers/_collisions.py +16 -12
  12. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/player/_player.py +14 -5
  13. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/player/_playerPhysics.py +2 -2
  14. gamebox-0.9.1/src/GameBox/player/_playerSprite.py +86 -0
  15. gamebox-0.9.1/src/GameBox/ui/_basicUI.py +36 -0
  16. gamebox-0.9.1/tests/GettingStarted.py +54 -0
  17. gamebox-0.9.1/tests/Player.png +0 -0
  18. {gamebox-0.3.0 → gamebox-0.9.1}/tests/basicScreen.py +4 -3
  19. gamebox-0.9.1/tests/testMap.json +1 -0
  20. gamebox-0.3.0/tests/testMap.json +0 -1
  21. {gamebox-0.3.0 → gamebox-0.9.1}/.gitignore +0 -0
  22. {gamebox-0.3.0 → gamebox-0.9.1}/LICENSE +0 -0
  23. {gamebox-0.3.0 → gamebox-0.9.1}/README.md +0 -0
  24. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/basics/__init__.py +0 -0
  25. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/basics/utils.py +0 -0
  26. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/helpers/_input.py +0 -0
  27. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/player/_playerControler.py +0 -0
  28. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/tilemap/_Editor.py +0 -0
  29. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/tilemap/_collisionDef.py +0 -0
  30. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/tilemap/_editorBrushes.py +0 -0
  31. {gamebox-0.3.0 → gamebox-0.9.1}/src/GameBox/tilemap/_tilemap.py +0 -0
  32. {gamebox-0.3.0 → gamebox-0.9.1}/tests/levelTiles.png +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GameBox
3
- Version: 0.3.0
3
+ Version: 0.9.1
4
4
  Summary: GameBox is a beginner-friendly Python package built on top of pygame, designed to make 2D game development faster and easier. It provides ready-to-use modules, utilities, and abstractions that let new developers create polished games without needing advanced coding knowledge—while still offering the flexibility for experienced coders to customize and extend.
5
5
  Author-email: Sam Fertig <sfertig007@gmail.com>
6
6
  License-Expression: MIT
@@ -3,7 +3,7 @@ requires = ["hatchling >= 1.26"]
3
3
  build-backend = "hatchling.build"
4
4
  [project]
5
5
  name = "GameBox"
6
- version = "0.3.0"
6
+ version = "0.9.1"
7
7
  authors = [
8
8
  { name="Sam Fertig", email="sfertig007@gmail.com" },
9
9
  ]
@@ -0,0 +1,39 @@
1
+ import pygame
2
+ import numpy as np
3
+
4
+ from ..basics._net import Global
5
+
6
+ class Animation:
7
+ def __init__(self, image, tileDim, startPos, frames, dur):
8
+ if type(image) == str:
9
+ image = pygame.image.load(image)
10
+
11
+ #others
12
+ self.dur = dur
13
+ self.currentFrame = 0
14
+ self.currentDur = 0
15
+
16
+ #get frames from image
17
+ self.frames = []
18
+ x, y = startPos
19
+ x *= tileDim[0]
20
+ y *= tileDim[1]
21
+ for i in range(frames):
22
+ self.frames.append(image.subsurface(x, y, tileDim[0], tileDim[1]))
23
+ x += tileDim[0]
24
+ if x >= image.get_width():
25
+ x = 0
26
+ y += tileDim[1]
27
+
28
+ def update(self, dt):
29
+ self.currentDur += dt
30
+ if self.currentDur >= self.dur:
31
+ self.currentDur = 0
32
+ self.currentFrame += 1
33
+ if self.currentFrame >= len(self.frames):
34
+ self.currentFrame = 0
35
+
36
+ def getFrame(self):
37
+ return self.frames[self.currentFrame]
38
+
39
+
@@ -0,0 +1,185 @@
1
+ import pygame
2
+ import numpy as np
3
+
4
+ from ..basics._net import Global
5
+ from ._Animations import Animation
6
+
7
+ class Sprite_2d:
8
+ def __init__(self, pos: tuple, image, scale: float = 1.0, collision = True, dirrection: int = 1):
9
+ """
10
+ Initialize a 2D sprite.
11
+
12
+ Args:
13
+ pos: Tuple (x, y) for the sprite position
14
+ image: Either a file path (str) or pygame.Surface object
15
+ scale: Scale factor for the sprite (default: 1.0)
16
+ """
17
+ #add to game
18
+ Global.game.objs.append(self)
19
+ self.collision = collision
20
+ self.__worldPos__ = True
21
+ self.dir = dirrection
22
+
23
+ self.pos = pos
24
+ if type(image) == str:
25
+ self.image = pygame.image.load(image)
26
+ else:
27
+ self.image = image
28
+
29
+ #scale image
30
+ print(self.image)
31
+ self.image = pygame.transform.scale_by(self.image, scale)
32
+ #flip image
33
+ if self.dir == -1:
34
+ self.image = pygame.transform.flip(self.image, True, False)
35
+
36
+ def update(self):
37
+ #world space
38
+ x, y = self.pos
39
+ if self.__worldPos__:
40
+ x = x - Global.cam.x
41
+ y = y - Global.cam.y
42
+ Global.screen.blit(self.image, (x, y))
43
+ if self.collision:
44
+ rect = self.image.get_rect()
45
+ rect.x = x
46
+ rect.y = y
47
+ Global.collisions.append(rect)
48
+
49
+ def switch_dirrection(self):
50
+ self.image = pygame.transform.flip(self.image, True, False)
51
+
52
+
53
+ def move_by(self, x: int, y: int):
54
+ self.pos = (self.pos[0] + x, self.pos[1] + y)
55
+
56
+ def move_to(self, x: int, y: int):
57
+ self.pos = (x, y)
58
+
59
+ def get_pos(self):
60
+ return self.pos
61
+
62
+ def rescale(self, scale: float):
63
+ self.image = pygame.transform.scale_by(self.image, scale)
64
+
65
+ def __remove__(self):
66
+ Global.game.objs.remove(self)
67
+
68
+ def split_image(image, tileDim, startPos):
69
+ if type(image) == str:
70
+ image = pygame.image.load(image)
71
+ else:
72
+ image = image
73
+
74
+ #return image split
75
+ x = startPos[0] * tileDim[0]
76
+ y = startPos[1] * tileDim[1]
77
+ return image.subsurface((x, y, tileDim[0], tileDim[1]))
78
+
79
+ class Animated_Sprite2D:
80
+ def __init__(self, pos, image, imageDim, tileDim, frames, speed, scale = 1.0, collision = True, dirrection = 1):
81
+ self.animation = Animation(image, tileDim, (0, 0), frames, speed)
82
+ self.collision = collision
83
+ self.dir = dirrection
84
+ self.pos = pos
85
+
86
+ self.scale = scale
87
+ self.image = pygame.transform.scale_by(self.animation.getFrame(), scale)
88
+ if self.dir == -1:
89
+ self.image = pygame.transform.flip(self.image, True, False)
90
+
91
+ self.__worldPos__ = True
92
+
93
+ #add to game
94
+ Global.game.objs.append(self)
95
+
96
+ def update(self):
97
+ self.animation.update(Global.dt)
98
+ self.image = pygame.transform.scale_by(self.animation.getFrame(), self.scale)
99
+ if self.dir == -1:
100
+ self.image = pygame.transform.flip(self.image, True, False)
101
+
102
+ #world space
103
+ x, y = self.pos
104
+ if self.__worldPos__:
105
+ x = x - Global.cam.x
106
+ y = y - Global.cam.y
107
+ Global.screen.blit(self.image, (x, y))
108
+ if self.collision:
109
+ rect = self.image.get_rect()
110
+ rect.x = x
111
+ rect.y = y
112
+ Global.collisions.append(rect)
113
+
114
+ def __remove__(self):
115
+ Global.game.objs.remove(self)
116
+
117
+ def switch_dirrection(self):
118
+ self.image = pygame.transform.flip(self.image, True, False)
119
+
120
+ def move_by(self, x: int, y: int):
121
+ self.pos = (self.pos[0] + x, self.pos[1] + y)
122
+
123
+ def move_to(self, x: int, y: int):
124
+ self.pos = (x, y)
125
+
126
+ def get_pos(self):
127
+ return self.pos
128
+
129
+ def rescale(self, scale: float):
130
+ self.image = pygame.transform.scale_by(self.image, scale)
131
+
132
+ class AnimationPlayer2D:
133
+ def __init__(self, pos, scale):
134
+ self.pos = pos
135
+ self.scale = scale
136
+ self.anims = {}
137
+ self.currentAnim = None
138
+
139
+ self.__worldPos__ = True
140
+
141
+ #add to game
142
+ Global.game.objs.append(self)
143
+
144
+ def update(self):
145
+ if self.currentAnim is not None:
146
+ self.anims[self.currentAnim].update()
147
+
148
+ def add_animation(self, name, image, imageDim, tileDim, frames, speed, scale = 1.0, collision = True, dirrection = 1):
149
+ self.anims[name] = Animated_Sprite2D(self.pos, image, imageDim, tileDim, frames, speed, scale, collision, dirrection)
150
+ self.currentAnim = name
151
+ self.anims[self.currentAnim].__remove__()
152
+
153
+ def remove_animation(self, name: str):
154
+ self.anims[name].__remove__()
155
+ del self.anims[name]
156
+
157
+ def set_worldPos(self, worldPos: bool):
158
+ for anim in self.anims:
159
+ self.anims[anim].__worldPos__ = worldPos
160
+
161
+ def __remove__(self):
162
+ if self in Global.game.objs:
163
+ Global.game.objs.remove(self)\
164
+
165
+ def set_scale(self, scale: float):
166
+ for anim in self.anims:
167
+ self.anims[anim].rescale(scale)
168
+
169
+ def set_animation(self, anim: str):
170
+ self.currentAnim = anim
171
+
172
+ def move_by(self, x: int, y: int):
173
+ self.pos = (self.pos[0] + x, self.pos[1] + y)
174
+ for anim in self.anims:
175
+ self.anims[anim].move_by(x, y)
176
+
177
+ def move_to(self, x: int, y: int):
178
+ self.pos = (x, y)
179
+ for anim in self.anims:
180
+ self.anims[anim].move_to(x, y)
181
+
182
+ def get_pos(self):
183
+ return self.pos
184
+
185
+
@@ -16,6 +16,10 @@ from .player._player import Player
16
16
  from .basics.utils import clamp, moveTward, zeroOut
17
17
  from .tilemap._tilemap import TileMap
18
18
  from.helpers._input import Keys
19
+ from .ui._basicUI import Image
20
+
21
+ from .GameLevel_ui._sprites import Sprite_2d, Animated_Sprite2D, AnimationPlayer2D, split_image
22
+ from.helpers._Conditions import Conditions
19
23
 
20
24
 
21
25
  __all__ = [
@@ -28,5 +32,11 @@ __all__ = [
28
32
  "zeroOut",
29
33
  "TileMap",
30
34
  "Keys",
35
+ "Image",
36
+ "Sprite_2d",
37
+ "Animated_Sprite2D",
38
+ "AnimationPlayer2D",
39
+ "split_image",
40
+ "Conditions",
31
41
  ]
32
42
 
@@ -26,6 +26,7 @@ class Game:
26
26
  Global.clock = pygame.time.Clock()
27
27
  Global.game = self
28
28
  self.objs = []
29
+ self.ui_objs = []
29
30
 
30
31
 
31
32
  def update(self, event: pygame.event,frame_rate=60):
@@ -40,6 +41,11 @@ class Game:
40
41
  if type(obj) == Player: player = obj
41
42
  else: obj.update()
42
43
  if player != None: player.update()
44
+
45
+ #update ui
46
+ for obj in self.ui_objs:
47
+ obj.update()
48
+
43
49
  pygame.display.update()
44
50
 
45
51
  def get_screen(self):
@@ -51,4 +57,25 @@ class Game:
51
57
  if hasattr(obj, "_quit") and callable(obj._quit):
52
58
  obj._quit()
53
59
 
60
+ def _set_debug(self, debug: bool):
61
+ """
62
+ Set the debug mode for the game. This will show / hide debuging information
63
+ like collisions. Note: This feture is for development and testing purposes only.
64
+
65
+ Parameters:
66
+ debug (bool): The debug mode.
67
+
68
+ Returns:
69
+ None
70
+ """
71
+ Global._debug = debug
72
+ def _get_debug_state(self):
73
+ """
74
+ Get the debug mode for the game.
75
+
76
+ Returns:
77
+ bool: The debug mode.
78
+ """
79
+ return Global._debug
80
+
54
81
 
@@ -18,6 +18,10 @@ class _global_:
18
18
  #-collisions
19
19
  self.collisions: list[pygame.Rect] = []
20
20
 
21
+ self.cond: object = None
22
+
23
+ self._debug: bool = False
24
+
21
25
  #objects
22
26
  self.player = self._player()
23
27
  self.tilemap = []
@@ -30,4 +30,15 @@ class Rect:
30
30
  self.x += x
31
31
  self.y += y
32
32
  else:
33
- Global.cam.move(x, y)
33
+ Global.cam._move(x, y)
34
+
35
+ def move_to(self, x, y):
36
+ if (Global.cam.follow) != (self):
37
+ self.x = x
38
+ self.y = y
39
+ else:
40
+ Global.cam.x = x
41
+ Global.cam.y = y
42
+
43
+ def __remove__(self):
44
+ Global.game.objs.remove(self)
@@ -15,7 +15,7 @@ class Cammera:
15
15
  self.diff = (0, 0)
16
16
  self.scale = scale
17
17
 
18
- def move(self, x, y):
18
+ def _move(self, x: int, y: int):
19
19
  self.x += x
20
20
  self.y += y
21
21
 
@@ -0,0 +1,56 @@
1
+ import pygame
2
+ import numpy as np
3
+
4
+ from ..basics.utils import zeroOut
5
+ from ..basics._net import Global
6
+
7
+ class _Conditions:
8
+ def __init__(self):
9
+ #conditions start with 'C' and then command ('v' for velocity), and dir (^ up, _ down, < left, > right, # none, ~ any)
10
+ self.velocity_up = 'CV^'
11
+ self.velocity_down = 'CV_'
12
+ self.velocity_left = 'CV<'
13
+ self.velocity_right = 'CV>'
14
+ self.velocity_none = 'CV#'
15
+ self.velocity_any = 'CV~'
16
+
17
+ Conditions = _Conditions()
18
+ Global.cond = Conditions
19
+
20
+ class Condition_check:
21
+ def __init__(self, stateTree: dict[str, dict[_Conditions, str]], currentState: str):
22
+ self.stateTree = stateTree
23
+ self.currentState = currentState
24
+
25
+ def check(self, velocity: tuple, pos: tuple):
26
+ state = self.stateTree[self.currentState]
27
+ for cond, next in state.items():
28
+ #velocities
29
+ if cond[1] == 'V':
30
+ if self._resolve_velocities(velocity, cond):
31
+ self.currentState = next
32
+ return next
33
+ return self.currentState
34
+
35
+
36
+ def _resolve_velocities(self, velocities, cond):
37
+ vx, vy = velocities
38
+ vx = zeroOut(vx, 0.1)
39
+ vy = zeroOut(vy, 0.1)
40
+ dir = cond[2]
41
+ print(vx, vy, dir)
42
+ #resolve in order up, down, left, right, none, any
43
+ if dir == "^" and vy < 0: return True
44
+ if dir == "_" and vy > 0: return True
45
+ if dir == "<" and vx < 0: return True
46
+ if dir == ">" and vx > 0: return True
47
+ if dir == "#" and vx == 0 and vy == 0: return True
48
+ if dir == "~" and (vx != 0 or vy != 0): return True
49
+ return False
50
+
51
+ def updateState(self, state: str):
52
+ self.currentState = state
53
+ def updateStateTree(self, stateTree: dict[str, dict[_Conditions, str]]):
54
+ self.stateTree = stateTree
55
+
56
+
@@ -7,7 +7,6 @@ from ..basics._net import Global
7
7
  def CheckCollisions(x, y, vx, vy, dim, sample, obj):
8
8
  x, y = x + vx, y + vy
9
9
 
10
-
11
10
  #basic object collisions
12
11
  x, y, vx, vy = _mainCollisionLogic(Global.collisions, x, y, vx, vy, dim)
13
12
  x, y, vx, vy = _checkTilemapCollisions(x, y, vx, vy, dim, sample, obj)
@@ -15,20 +14,14 @@ def CheckCollisions(x, y, vx, vy, dim, sample, obj):
15
14
  return x, y, vx, vy
16
15
 
17
16
  def _mainCollisionLogic(collisions, x, y, vx, vy, dim):
18
- new_rect = pygame.Rect((x, y), dim)
19
- for collision in collisions:
20
- #pygame.draw.rect(Global.screen, (255, 0, 0), collision, 1)
21
- if collision.colliderect(new_rect):
22
- if vx > 0:
23
- x = collision.left - dim[0]
24
- elif vx < 0:
25
- x = collision.right
26
- vx = 0
27
-
28
17
  # Y-axis collisions
18
+ py = y
29
19
  new_rect = pygame.Rect((x, y), dim)
20
+ if Global._debug:
21
+ pygame.draw.rect(Global.screen, "green", new_rect, 5)
30
22
  for collision in collisions:
31
- #pygame.draw.rect(Global.screen, (255, 0, 0), collision, 1)
23
+ if Global._debug:
24
+ pygame.draw.rect(Global.screen, "yellow", collision, 5)
32
25
  if collision.colliderect(new_rect):
33
26
  if vy > 0: # falling
34
27
  y = collision.top - dim[1]
@@ -36,6 +29,17 @@ def _mainCollisionLogic(collisions, x, y, vx, vy, dim):
36
29
  elif vy < 0: # jumping
37
30
  y = collision.bottom
38
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
39
43
 
40
44
  return x, y, vx, vy
41
45
 
@@ -4,6 +4,9 @@ import numpy as np
4
4
  from ..basics._net import Global
5
5
 
6
6
  from ..player._playerPhysics import _playerPhysics
7
+ from ..player._playerSprite import _playerSprite
8
+
9
+ from ..GameLevel_ui._sprites import Sprite_2d
7
10
 
8
11
  class Player:
9
12
  def __init__(self, pos: tuple, size: tuple, color: tuple = (0, 0, 0), gravity: bool = False):
@@ -11,30 +14,34 @@ class Player:
11
14
  self.screenPos = pos
12
15
  self.dim = size
13
16
  self.color = color
17
+ self.width, self.height = size
14
18
 
15
19
  self.gravity = gravity
20
+
21
+ self.state = ""
16
22
 
17
23
  Global.game.objs.append(self)
18
24
  Global.player.pos = pos
19
25
  Global.player.player = self
20
26
 
27
+ self.sprite = _playerSprite(self)
28
+
21
29
 
22
30
  def add_physics(self, speed: float = 1.0, gravity: float = 0.0, jump: float = 10.0, maxV: float = 10.0, airRes: float = 0.2):
23
31
  self.physics = _playerPhysics(self, speed, gravity, jump, maxV, airRes)
24
32
 
25
33
  def update(self):
26
34
  self.physics.update()
27
- #debug rect
28
- width = self.dim[0] * Global.cam.scale
29
- height = self.dim[1] * Global.cam.scale
35
+ #ui
36
+
30
37
  if (Global.cam.follow) != (self):
31
38
  x = self.x - Global.cam.x
32
39
  y = self.y - Global.cam.y
33
40
  elif (Global.cam.follow) == (self):
34
41
  x = self.x
35
42
  y = self.y
36
- rect = pygame.Rect(x, y, width, height)
37
- pygame.draw.rect(Global.screen, self.color, rect)
43
+ velocity = (self.physics.vx, self.physics.vy)
44
+ self.sprite.update(x, y, velocity)
38
45
 
39
46
  #movement
40
47
  def top_down_movement(self):
@@ -50,3 +57,5 @@ class Player:
50
57
  The larger the sample size the longer it may take to calculate collisions per frame.
51
58
  """
52
59
  self.physics.sample = sample
60
+
61
+
@@ -19,7 +19,7 @@ class _playerPhysics:
19
19
  self.onGround = False
20
20
  self.canJump = False
21
21
 
22
- self.sample = 10
22
+ self.sample = 25
23
23
 
24
24
  self.vx, self.vy = 0, 0
25
25
 
@@ -34,7 +34,7 @@ class _playerPhysics:
34
34
  elif (Global.cam.follow) == (self.player):
35
35
  dx = -(self.player.x - x)
36
36
  dy = -(self.player.y - y)
37
- Global.cam.move(self.vx, self.vy)
37
+ Global.cam._move(self.vx, self.vy)
38
38
 
39
39
 
40
40
 
@@ -0,0 +1,86 @@
1
+ import pygame
2
+ import numpy as np
3
+
4
+ from ..basics._net import Global
5
+
6
+ from ..GameLevel_ui._sprites import Sprite_2d, Animated_Sprite2D, AnimationPlayer2D
7
+ from ..helpers._Conditions import Condition_check, _Conditions
8
+
9
+ class _playerSprite:
10
+ def __init__(self, player):
11
+ self.player = player
12
+
13
+ self.state = player.state
14
+ self.statetree = {}
15
+ self.condition_check = None
16
+
17
+ self.sprite = None
18
+
19
+
20
+ def update(self, x, y, velocity):
21
+ #state updates
22
+ if self.condition_check is not None:
23
+ self.state = self.condition_check.check(velocity, self.player.screenPos)
24
+ #set animation if possible
25
+ if type(self.sprite) == AnimationPlayer2D:
26
+ if self.state in self.sprite.anims:
27
+ self.sprite.set_animation(self.state)
28
+ #any changes to follow target
29
+ if Global.cam.follow == self.player and self.sprite is not None:
30
+ self.sprite.__worldPos__ = False
31
+ self.sprite.move_to(self.player.screenPos[0], self.player.screenPos[1])
32
+ elif Global.cam.follow != self.player and self.sprite is not None:
33
+ self.sprite.__worldPos__ = True
34
+ self.sprite.move_to(self.player.x, self.player.y)
35
+
36
+ if self.sprite is None:
37
+ #rect (x, y) is top left corner
38
+ rect = pygame.Rect((x, y), self.player.dim)
39
+ pygame.draw.rect(Global.screen, self.player.color, rect)
40
+ if type(self.sprite) == Sprite_2d:
41
+ self.sprite.update()
42
+ elif type(self.sprite) == Animated_Sprite2D:
43
+ self.sprite.update()
44
+ elif type(self.sprite) == AnimationPlayer2D:
45
+ self.sprite.update()
46
+
47
+ def add_sprite_2d(self, image, scale=1.0, dirrection=1):
48
+ self.sprite = Sprite_2d((self.player.x, self.player.y), image, scale, False, dirrection)
49
+ if Global.cam.follow == self.player:
50
+ self.sprite.__worldPos__ = False
51
+ self.sprite.__remove__()
52
+
53
+ def add_animated_sprite_2d(self, image, imageDim, tileDim, frames, speed, scale = 1.0, collision = True, dirrection = 1):
54
+ self.sprite = Animated_Sprite2D((self.player.x, self.player.y), image, imageDim, tileDim, frames, speed, scale, collision, dirrection)
55
+ if Global.cam.follow == self.player:
56
+ self.sprite.__worldPos__ = False
57
+ self.sprite.__remove__()
58
+
59
+ def remove_sprite(self):
60
+ if self.sprite is not None:
61
+ self.sprite = None
62
+
63
+ def add_animation_player(self, scale = 1.0):
64
+ self.sprite = AnimationPlayer2D((self.player.x, self.player.y), scale)
65
+ if Global.cam.follow == self.player:
66
+ self.sprite.set_worldPos(False)
67
+ self.sprite.__remove__()
68
+
69
+ def add_animation(self, name, image, imageDim, tileDim, frames, speed, scale = 1.0, dirrection = 1):
70
+ self.sprite.add_animation(name, image, imageDim, tileDim, frames, speed, scale, False, dirrection)
71
+ self.sprite.__remove__()
72
+ self.sprite.set_worldPos(False)
73
+
74
+ def remove_animation(self, name: str):
75
+ self.sprite.remove_animation(name)
76
+
77
+ def set_animation(self, anim: str):
78
+ self.sprite.set_animation(anim)
79
+
80
+ def set_states(self, stateTree: dict[str, dict[_Conditions, str]], currentState: str):
81
+ self.statetree = stateTree
82
+ self.state = currentState
83
+ self.condition_check = Condition_check(self.statetree, self.state)
84
+
85
+
86
+
@@ -0,0 +1,36 @@
1
+ import pygame
2
+ import numpy as np
3
+
4
+ from ..basics._net import Global
5
+
6
+ from ..GameLevel_ui._sprites import Sprite_2d
7
+
8
+ class Image:
9
+ def __init__(self, pos: tuple, image, scale: float = 1.0):
10
+ """
11
+ Initialize an Image UI element.
12
+
13
+ Args:
14
+ pos: Tuple (x, y) for the image position
15
+ image: Either a file path (str) or pygame.Surface object
16
+ scale: Scale factor for the image (default: 1.0)
17
+ """
18
+ #add to game
19
+ self.image = Sprite_2d(pos, image, scale)
20
+ self.image.__remove__()
21
+ Global.game.ui_objs.append(self)
22
+
23
+ def move_by(self, x: int, y: int):
24
+ self.image.move_by(x, y)
25
+
26
+ def move_to(self, x: int, y: int):
27
+ self.image.move_to(x, y)
28
+
29
+ def get_pos(self):
30
+ return self.image.get_pos()
31
+
32
+ def rescale(self, scale: float):
33
+ self.image.rescale(scale)
34
+
35
+ def update(self):
36
+ Global.screen.blit(self.image.image, self.image.pos)
@@ -0,0 +1,54 @@
1
+ import pygame
2
+ import os
3
+ from src.GameBox import *
4
+
5
+ width, height = 800, 600
6
+
7
+ game = Game(width, height, "blue", "First Game!")
8
+ screen = game.get_screen()
9
+
10
+ cam = Cammera()
11
+
12
+ Keys.init()
13
+
14
+ player = Player((width / 2, height / 2), (64, 64), "green", False)
15
+ player.add_physics(1.0, 3.0, 16, 7.0, 0.5)
16
+
17
+ player.sprite.add_animation_player(2.0)
18
+ player.sprite.add_animation("Walk", "tests/Player.png", (5, 1), (32, 32), 5, 0.075, 2.0, 1)
19
+ player.sprite.add_animation("Idle", "tests/Player.png", (5, 1), (32, 32), 1, 0.075, 2.0, 1)
20
+
21
+ player.sprite.set_animation("Idle")
22
+
23
+
24
+ stateTree = {
25
+ "Idle": {Conditions.velocity_any: "Walk"},
26
+ "Walk": {Conditions.velocity_none: "Idle"}
27
+ }
28
+ player.sprite.set_states(stateTree, "Walk")
29
+
30
+ rect = Rect((width / 2, height / 4), (64, 64), "red", True)
31
+
32
+
33
+ cam.set_follow_target(player)
34
+ running = True
35
+ while running:
36
+ events = pygame.event.get()
37
+ for event in events:
38
+ if event.type == pygame.QUIT:
39
+ running = False
40
+
41
+ player.top_down_movement()
42
+ game.update(events, 60)
43
+
44
+ #print player state
45
+ os.system("cls")
46
+ print(player.sprite.state)
47
+
48
+ if Keys.is_pressed(pygame.K_i):
49
+ game._set_debug(not game._get_debug_state())
50
+
51
+
52
+ game.quit()
53
+ pygame.quit()
54
+ os.system("cls")
Binary file
@@ -10,16 +10,16 @@ Keys.init()
10
10
 
11
11
  cam = Cammera()
12
12
 
13
- player = Player((width / 2, height / 4), (50, 50), "green", False)
13
+ player = Player((width / 2, height / 4), (64, 64), "green", False)
14
14
  player.add_physics(1.0, 3.0, 16, 7.0, 0.5)
15
15
 
16
16
  map = TileMap("tests/levelTiles.png", (16, 16), 5, (25, 25), 0)
17
17
  map.load_map_from_json("tests/testMap.json")
18
18
  map.activate_editor(Keys.tab)
19
19
 
20
+ player.sprite.add_animated_sprite_2d("tests/Player.png", (5, 1), (32, 32), 5, 0.075, 2.0, True, 1)
20
21
 
21
-
22
- player.set_tilemap_sample(50)
22
+ #player.set_dim_as_sprite()
23
23
 
24
24
  cam.set_follow_target(player)
25
25
  #cam.move(-50, -50)
@@ -33,6 +33,7 @@ while running:
33
33
 
34
34
  player.top_down_movement()
35
35
 
36
+
36
37
  game.update(events, 60)
37
38
 
38
39
 
@@ -0,0 +1 @@
1
+ {"map": [[11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8], [8, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8], [11, 11, 11, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8], [16, 17, 18, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 16, 17, 17, 17, 17, 17, 17, 17, 18, 8, 8], [8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]], "collisions": {"1": "full", "2": "halfTop", "7": "halfLeft", "3": "full", "13": "full", "15": "full", "9": "halfRight", "14": "halfBottom", "8": "none", "6": "bottomLeft", "5": "halfBottom", "4": "bottomRight", "10": "halfRight", "16": "topRight", "12": "halfLeft", "11": "none", "18": "topLeft", "17": "halfTop"}}
@@ -1 +0,0 @@
1
- {"map": [[11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 1, 2, 3, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 7, 8, 9, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 13, 14, 15, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 4, 5, 6, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 10, 11, 12, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 16, 17, 18, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]], "collisions": {"1": "full", "2": "halfTop", "7": "halfLeft", "3": "full", "13": "full", "15": "full", "9": "halfRight", "14": "halfBottom", "8": "none", "6": "bottomLeft", "5": "halfBottom", "4": "bottomRight", "10": "halfRight", "16": "topRight", "12": "halfLeft", "11": "none", "18": "topLeft", "17": "halfTop"}}
File without changes
File without changes
File without changes
File without changes