GameBox 0.1.2__tar.gz → 0.1.3__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.
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.pyc
3
+
4
+ .venv/
5
+ .env
6
+
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+
11
+ .vscode/
12
+ .idea/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GameBox
3
- Version: 0.1.2
3
+ Version: 0.1.3
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
@@ -14,6 +14,8 @@ GameBox is a lightweight 2D game framework built on pygame.
14
14
  This is an early technical preview of a full engine rewrite.
15
15
  APIs may change frequently.
16
16
 
17
+ github: {https://github.com/sfertig/GameBox}
18
+
17
19
  Versioning
18
20
  GameBox follows a modified semantic versioning scheme.
19
21
  Versions starting with 0.x.x are experimental and may change without notice.
@@ -2,6 +2,8 @@ GameBox is a lightweight 2D game framework built on pygame.
2
2
  This is an early technical preview of a full engine rewrite.
3
3
  APIs may change frequently.
4
4
 
5
+ github: {https://github.com/sfertig/GameBox}
6
+
5
7
  Versioning
6
8
  GameBox follows a modified semantic versioning scheme.
7
9
  Versions starting with 0.x.x are experimental and may change without notice.
@@ -3,7 +3,7 @@ requires = ["hatchling >= 1.26"]
3
3
  build-backend = "hatchling.build"
4
4
  [project]
5
5
  name = "GameBox"
6
- version = "0.1.2"
6
+ version = "0.1.3"
7
7
  authors = [
8
8
  { name="Sam Fertig", email="sfertig007@gmail.com" },
9
9
  ]
@@ -5,7 +5,7 @@ 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.0.3"
8
+ __version__ = "0.1.3"
9
9
  __author__ = "Sam Fertig"
10
10
 
11
11
  #____imports____
@@ -14,6 +14,8 @@ from .basics.cammera import Cammera
14
14
  from .basics._shapes import Rect
15
15
  from .player._player import Player
16
16
  from .basics.utils import clamp, moveTward, zeroOut
17
+ from .tilemap._tilemap import TileMap
18
+ from.helpers._input import Keys
17
19
 
18
20
 
19
21
  __all__ = [
@@ -23,6 +25,8 @@ __all__ = [
23
25
  "Player",
24
26
  "clamp",
25
27
  "moveTward",
26
- "zeroOut"
28
+ "zeroOut",
29
+ "TileMap",
30
+ "Keys",
27
31
  ]
28
32
 
@@ -1,6 +1,7 @@
1
1
  import pygame
2
2
  import numpy as np
3
3
 
4
+
4
5
  from .basics._net import Global
5
6
  from .player._player import Player
6
7
 
@@ -9,7 +10,7 @@ class Game:
9
10
  """
10
11
  Initialize the Game object.
11
12
 
12
- ParameArters:
13
+ Parameters:
13
14
  width (int): The width of the game window.
14
15
  height (int): The height of the game window.
15
16
  bg_color (tuple): The background color of the game window.
@@ -26,8 +27,11 @@ class Game:
26
27
  Global.game = self
27
28
  self.objs = []
28
29
 
30
+
29
31
  def update(self, frame_rate=60):
32
+ #clear collisions
30
33
  Global.collisions.clear()
34
+
31
35
  Global.dt = Global.clock.tick(frame_rate) / 1000.0
32
36
  Global.screen.fill(Global.bgColor)
33
37
  player = None
@@ -36,3 +40,14 @@ class Game:
36
40
  else: obj.update()
37
41
  if player != None: player.update()
38
42
  pygame.display.update()
43
+
44
+ def get_screen(self):
45
+ return Global.screen
46
+
47
+ def quit(self):
48
+ #will save files later
49
+ for obj in self.objs:
50
+ if hasattr(obj, "_quit") and callable(obj._quit):
51
+ obj._quit()
52
+
53
+
@@ -19,10 +19,12 @@ class _global_:
19
19
 
20
20
  #objects
21
21
  self.player = self._player()
22
+ self.tilemap: object = None
22
23
 
23
24
  class _player:
24
25
  def __init__(self):
25
26
  self.pos: tuple = None
27
+ self.player: object = None
26
28
 
27
29
 
28
30
 
@@ -12,6 +12,8 @@ class Rect:
12
12
  self.collision = collision
13
13
 
14
14
  def update(self):
15
+ width = self.width * Global.cam.scale
16
+ height = self.height * Global.cam.scale
15
17
  if (Global.cam.follow) != (self):
16
18
  x = self.x - Global.cam.x
17
19
  y = self.y - Global.cam.y
@@ -19,7 +21,7 @@ class Rect:
19
21
  x = self.x
20
22
  y = self.y
21
23
 
22
- rect = pygame.Rect(x, y, self.width, self.height)
24
+ rect = pygame.Rect(x, y, width ,height)
23
25
  if self.collision: Global.collisions.append(rect)
24
26
  pygame.draw.rect(Global.screen, self.color, rect)
25
27
 
@@ -6,13 +6,14 @@ from ._net import Global
6
6
  from ..basics.utils import moveTward
7
7
 
8
8
  class Cammera:
9
- def __init__(self):
9
+ def __init__(self, scale: float = 1.0):
10
10
  self.x = 0
11
11
  self.y = 0
12
12
  Global.game.objs.append(self)
13
13
  Global.cam = self
14
14
  self.follow = None
15
15
  self.diff = (0, 0)
16
+ self.scale = scale
16
17
 
17
18
  def move(self, x, y):
18
19
  self.x += x
@@ -28,3 +29,8 @@ class Cammera:
28
29
  self.follow = target
29
30
  print(target)
30
31
  self.diff = (target.x - self.x, target.y - self.y)
32
+
33
+ def set_scale(self, scale: float = 1.0):
34
+ self.scale = scale
35
+ def change_scale(self, scale: float = 1.0):
36
+ self.scale += scale
@@ -0,0 +1,70 @@
1
+ import pygame
2
+
3
+ from ..basics._net import Global
4
+
5
+
6
+ class _keys:
7
+ def __init__(self):
8
+
9
+ #alphabet
10
+ self.a = pygame.K_a
11
+ self.b = pygame.K_b
12
+ self.c = pygame.K_c
13
+ self.d = pygame.K_d
14
+ self.e = pygame.K_e
15
+ self.f = pygame.K_f
16
+ self.g = pygame.K_g
17
+ self.h = pygame.K_h
18
+ self.i = pygame.K_i
19
+ self.j = pygame.K_j
20
+ self.k = pygame.K_k
21
+ self.l = pygame.K_l
22
+ self.m = pygame.K_m
23
+ self.n = pygame.K_n
24
+ self.o = pygame.K_o
25
+ self.p = pygame.K_p
26
+ self.q = pygame.K_q
27
+ self.r = pygame.K_r
28
+ self.s = pygame.K_s
29
+ self.t = pygame.K_t
30
+ self.u = pygame.K_u
31
+ self.v = pygame.K_v
32
+ self.w = pygame.K_w
33
+ self.x = pygame.K_x
34
+ self.y = pygame.K_y
35
+ self.z = pygame.K_z
36
+
37
+ #numbers
38
+ self.n0 = pygame.K_0
39
+ self.n1 = pygame.K_1
40
+ self.n2 = pygame.K_2
41
+ self.n3 = pygame.K_3
42
+ self.n4 = pygame.K_4
43
+ self.n5 = pygame.K_5
44
+ self.n6 = pygame.K_6
45
+ self.n7 = pygame.K_7
46
+ self.n8 = pygame.K_8
47
+ self.n9 = pygame.K_9
48
+
49
+ #special keys
50
+ self.enter = pygame.K_RETURN
51
+ self.escape = pygame.K_ESCAPE
52
+ self.space = pygame.K_SPACE
53
+ self.backspace = pygame.K_BACKSPACE
54
+
55
+ #arrow keys
56
+ self.up = pygame.K_UP
57
+ self.down = pygame.K_DOWN
58
+ self.left = pygame.K_LEFT
59
+ self.right = pygame.K_RIGHT
60
+
61
+ #mouse
62
+ self.mouse_x, self.mouse_y = 0, 0
63
+ def init(self): Global.game.objs.append(self)
64
+
65
+ def is_pressed(self, key): return pygame.key.get_pressed()[key]
66
+
67
+ def update(self): self.mouse_x, self.mouse_y = pygame.mouse.get_pos()
68
+
69
+
70
+ Keys = _keys()
@@ -16,6 +16,7 @@ class Player:
16
16
 
17
17
  Global.game.objs.append(self)
18
18
  Global.player.pos = pos
19
+ Global.player.player = self
19
20
 
20
21
 
21
22
  def add_physics(self, speed: float = 1.0, gravity: float = 0.0, jump: float = 10.0, maxV: float = 10.0, airRes: float = 0.2):
@@ -24,7 +25,15 @@ class Player:
24
25
  def update(self):
25
26
  self.physics.update()
26
27
  #debug rect
27
- rect = pygame.Rect(self.x, self.y, self.dim[0], self.dim[1])
28
+ width = self.dim[0] * Global.cam.scale
29
+ height = self.dim[1] * Global.cam.scale
30
+ if (Global.cam.follow) != (self):
31
+ x = self.x - Global.cam.x
32
+ y = self.y - Global.cam.y
33
+ elif (Global.cam.follow) == (self):
34
+ x = self.x
35
+ y = self.y
36
+ rect = pygame.Rect(x, y, width, height)
28
37
  pygame.draw.rect(Global.screen, self.color, rect)
29
38
 
30
39
  #movement
@@ -33,3 +42,11 @@ class Player:
33
42
 
34
43
  def platforming_movement(self):
35
44
  self.physics.platforming_movement()
45
+
46
+ def set_tilemap_sample(self, sample: int = 10):
47
+ """
48
+ Sets the sample size for player physics collisions.
49
+ Is the radius of tiles that will be used to get tilemap collisions around player. Note:
50
+ The larger the sample size the longer it may take to calculate collisions per frame.
51
+ """
52
+ self.physics.sample = sample
@@ -0,0 +1,192 @@
1
+ import pygame
2
+ import numpy as np
3
+
4
+ from ..basics._net import Global
5
+ from ..basics.utils import clamp, moveTward, zeroOut
6
+
7
+ class _playerPhysics:
8
+ def __init__(self, player, speed: float = 1.0, gravity: float = 0.0, jump: float = 0.0, maxV: float = 10.0, airRes: float = 0.2):
9
+ self.player = player
10
+ self.rect = pygame.Rect(self.player.x, self.player.y, self.player.dim[0], self.player.dim[1])
11
+
12
+ self.speed = speed
13
+ self.gravity = gravity
14
+ self.jump = jump
15
+ self.player = player
16
+ self.maxV = maxV
17
+ self.airRes = airRes
18
+ self.onGround = False
19
+ self.canJump = False
20
+
21
+ self.sample = 10
22
+
23
+ self.vx, self.vy = 0, 0
24
+
25
+ def update(self):
26
+ self.ckeck_is_on_ground()
27
+ x, y = self.check_collisions()
28
+ if (Global.cam.follow) != (self.player):
29
+ self.player.x = x
30
+ self.player.y = y
31
+ elif (Global.cam.follow) == (self.player):
32
+ dx = -(self.player.x - x)
33
+ dy = -(self.player.y - y)
34
+ Global.cam.move(self.vx, self.vy)
35
+
36
+
37
+ def check_collisions(self):
38
+ x, y = self.player.x + self.vx, self.player.y + self.vy
39
+
40
+ #basic object collisions
41
+ x, y = self.collisionLogic(Global.collisions, x, y)
42
+ x, y = self.tilemap_collisions(x, y)
43
+
44
+ return x, y
45
+
46
+ def collisionLogic(self, collisions, x, y):
47
+ new_rect = pygame.Rect((x, self.player.y), self.player.dim)
48
+ for collision in collisions:
49
+ #pygame.draw.rect(Global.screen, (255, 0, 0), collision, 1)
50
+ if collision.colliderect(new_rect):
51
+ if self.vx > 0:
52
+ x = collision.left - self.player.dim[0]
53
+ elif self.vx < 0:
54
+ x = collision.right
55
+ self.vx = 0
56
+
57
+ # Y-axis collisions
58
+ new_rect = pygame.Rect((x, y), self.player.dim)
59
+ for collision in collisions:
60
+ #pygame.draw.rect(Global.screen, (255, 0, 0), collision, 1)
61
+ if collision.colliderect(new_rect):
62
+ if self.vy > 0: # falling
63
+ y = collision.top - self.player.dim[1]
64
+ self.vy = 0
65
+ elif self.vy < 0: # jumping
66
+ y = collision.bottom
67
+ self.vy = 0
68
+
69
+ return x, y
70
+
71
+ def tilemap_collisions(self, x, y):
72
+ sample = self.sample
73
+ if Global.tilemap is None:
74
+ return x, y
75
+
76
+ #get player reletive tilemap pos
77
+ prect = pygame.Rect(x, y, self.player.dim[0], self.player.dim[1])
78
+ prx, pry = prect.center
79
+ if Global.cam.follow != self.player:
80
+ if Global.cam.x != 0 or Global.cam.y != 0:
81
+ px = int((prx - Global.tilemap.offset[0]) - Global.cam.x)
82
+ py = int((pry - Global.tilemap.offset[1]) - Global.cam.y)
83
+ px = int(px // Global.tilemap.tileDim[0])
84
+ py = int(py // Global.tilemap.tileDim[1])
85
+ else:
86
+ px = int((x - Global.tilemap.offset[0]) / Global.tilemap.tileDim[0])
87
+ py = int((y - Global.tilemap.offset[1]) / Global.tilemap.tileDim[1])
88
+ else:
89
+ if Global.cam.x != 0 or Global.cam.y != 0:
90
+ px = int(((prx + Global.cam.x)-Global.tilemap.offset[0]) // Global.tilemap.tileDim[0])
91
+ py = int(((pry + Global.cam.y)-Global.tilemap.offset[1]) // Global.tilemap.tileDim[1])
92
+ else:
93
+ px = int((x - Global.tilemap.offset[0]) / Global.tilemap.tileDim[0])
94
+ py = int((y - Global.tilemap.offset[1]) / Global.tilemap.tileDim[1])
95
+
96
+ #draw collision rect
97
+ #print(f"px: {px}, py: {py} | cam.x: {Global.cam.x}, cam.y: {Global.cam.y} | x: {x}, y: {y}")
98
+ #rect = pygame.Rect(px , py, self.player.dim[0], self.player.dim[1])
99
+ #pygame.draw.rect(Global.screen, "red", rect)
100
+ #rect.x *= Global.tilemap.tileDim[0]
101
+ #rect.y *= Global.tilemap.tileDim[1]
102
+ #pygame.draw.rect(Global.screen, "yellow", rect, 1)
103
+ #pygame.display.update(rect)
104
+
105
+ #check if player is on tilemap
106
+ if px < 0 or px >= Global.tilemap.mapDim[0] or py < 0 or py >= Global.tilemap.mapDim[1]:
107
+ return x, y
108
+ #get collision rects around player
109
+ collisions: list[pygame.Rect] = []
110
+ for tx in range(px - sample, px + sample):
111
+ for ty in range(py - sample, py + sample):
112
+ nx = int(px + tx)
113
+ ny = int(py + ty)
114
+ #if tile is on map
115
+ if nx < 0 or nx >= Global.tilemap.mapDim[0] or ny < 0 or ny >= Global.tilemap.mapDim[1]:
116
+ continue
117
+ #if tile has defined collision shape
118
+ tile = str(Global.tilemap.map[ny][nx])
119
+ if tile not in Global.tilemap.collisionDict: continue
120
+
121
+ #get collision shape
122
+ rectshape = Global.tilemap.collisionDict[str(tile)]
123
+ rect = getattr(Global.tilemap.collisionShapes, rectshape).copy()
124
+
125
+ # Position rect correctly in the world
126
+ if Global.cam.follow != self.player:
127
+ if Global.cam.x != 0 or Global.cam.y != 0:
128
+ rect.x = ((nx * Global.tilemap.tileDim[0]) + Global.tilemap.offset[0]) - Global.cam.x
129
+ rect.y = ((ny * Global.tilemap.tileDim[1]) + Global.tilemap.offset[1]) - Global.cam.y
130
+ else:
131
+ rect.x += (nx * Global.tilemap.tileDim[0] + Global.tilemap.offset[0]) - Global.cam.x
132
+ rect.y += (ny * Global.tilemap.tileDim[1] + Global.tilemap.offset[1]) - Global.cam.y
133
+ else:
134
+ if Global.cam.x != 0 or Global.cam.y != 0:
135
+ rect.x += ((nx * Global.tilemap.tileDim[0]) + Global.tilemap.offset[0]) - Global.cam.x
136
+ rect.y += ((ny * Global.tilemap.tileDim[1]) + Global.tilemap.offset[1]) - Global.cam.y
137
+ else:
138
+ rect.x += (nx * Global.tilemap.tileDim[0] + Global.tilemap.offset[0]) - Global.cam.x
139
+ rect.y += (ny * Global.tilemap.tileDim[1] + Global.tilemap.offset[1]) - Global.cam.y
140
+ collisions.append(rect)
141
+
142
+ #check collisions
143
+ x, y = self.collisionLogic(collisions, x, y)
144
+
145
+ return x, y
146
+
147
+
148
+
149
+
150
+ def ckeck_is_on_ground(self):
151
+ self.canJump = False
152
+ rect = pygame.Rect(self.player.x, self.player.y + self.player.dim[1], self.player.dim[0], 10)
153
+ for collision in Global.collisions:
154
+ if collision.colliderect(rect):
155
+ self.canJump = True
156
+
157
+
158
+ def move(self, x, y):
159
+ self.vx += x * self.speed
160
+ self.vy += y * self.speed
161
+
162
+ def top_down_movement(self):
163
+ keys = pygame.key.get_pressed()
164
+ if keys[pygame.K_a]:
165
+ self.move(-1, 0)
166
+ if keys[pygame.K_d]:
167
+ self.move(1, 0)
168
+ if keys[pygame.K_w]:
169
+ self.move(0, -1)
170
+ if keys[pygame.K_s]:
171
+ self.move(0, 1)
172
+ #limit velocity
173
+ self.vx = clamp(self.vx, -self.maxV, self.maxV)
174
+ self.vy = clamp(self.vy, -self.maxV, self.maxV)
175
+ self.vx = moveTward(self.vx, 0, self.airRes)
176
+ self.vy = moveTward(self.vy, 0, self.airRes)
177
+ self.vx = zeroOut(self.vx, 0.3)
178
+ self.vy = zeroOut(self.vy, 0.3)
179
+
180
+ def platforming_movement(self):
181
+ keys = pygame.key.get_pressed()
182
+ if keys[pygame.K_a]:
183
+ self.move(-1, 0)
184
+ if keys[pygame.K_d]:
185
+ self.move(1, 0)
186
+ if keys[pygame.K_w] and self.canJump:
187
+ self.vy -= self.jump
188
+ #limit velocity
189
+ self.vx = clamp(self.vx, -self.maxV, self.maxV)
190
+ self.vx = moveTward(self.vx, 0, self.airRes)
191
+ self.vx = zeroOut(self.vx, 0.3)
192
+ if self.player.gravity and not self.onGround: self.vy += self.gravity
@@ -0,0 +1,34 @@
1
+ import pygame
2
+
3
+ class _tileCollisionDefs:
4
+ def __init__(self, tileDim):
5
+ width, height = tileDim
6
+ self.full = pygame.Rect(0, 0, width, height)
7
+
8
+ self.halfLeft = pygame.Rect(0, 0, width / 2, height)
9
+ self.halfRight = pygame.Rect(width / 2, 0, width / 2, height)
10
+ self.halfTop = pygame.Rect(0, 0, width, height / 2)
11
+ self.halfBottom = pygame.Rect(0, height / 2, width, height / 2)
12
+
13
+ self.topRight = pygame.Rect(width / 2, 0, width / 2, height / 2)
14
+ self.topLeft = pygame.Rect(0, 0, width / 2, height / 2)
15
+ self.bottomRight = pygame.Rect(width / 2, height / 2, width / 2, height / 2)
16
+ self.bottomLeft = pygame.Rect(0, height / 2, width / 2, height / 2)
17
+
18
+ self.dot = pygame.Rect(0, 0, 3, 3)
19
+
20
+ self.center = pygame.Rect(width / 2, height / 2, width / 2, height / 2)
21
+
22
+ self.none = pygame.Rect(0, 0, 0, 0)
23
+
24
+ def regenerate(self, tileDim):
25
+ width, height = tileDim
26
+ self.full = pygame.Rect(0, 0, width, height)
27
+
28
+ self.halfLeft = pygame.Rect(0, 0, width / 2, height)
29
+ self.halfRight = pygame.Rect(width / 2, 0, width / 2, height)
30
+ self.halfTop = pygame.Rect(0, 0, width, height / 2)
31
+ self.halfBottom = pygame.Rect(0, height / 2, width, height / 2)
32
+
33
+ self.center = pygame.Rect(width / 2, height / 2, width / 2, height / 2)
34
+
@@ -0,0 +1,75 @@
1
+ import pygame
2
+ import numpy as np
3
+ import json
4
+
5
+ from ..basics._net import Global
6
+
7
+ from ._collisionDef import _tileCollisionDefs
8
+
9
+ class TileMap:
10
+ def __init__(self, tileSet: str, tileDim: tuple, tileScale: float, mapDim: tuple, mapFill: int, offset: tuple):
11
+ self.tilesetFile = tileSet
12
+ self.mapFile = None
13
+ self.tileDim = (tileDim[0] * tileScale, tileDim[1] * tileScale)
14
+ self.tileDim = (self.tileDim[0] * Global.cam.scale, self.tileDim[1] * Global.cam.scale)
15
+ self.mapDim = mapDim
16
+ self.offset = offset
17
+ self.tilescale = tileScale
18
+ self.orginDim = tileDim
19
+
20
+ Global.game.objs.append(self)
21
+ Global.tilemap = self
22
+
23
+ self.collisionShapes = _tileCollisionDefs(self.tileDim)
24
+
25
+ self.collisionDict = {}
26
+
27
+ #map, tile splitting, ect
28
+ #--create map
29
+ self.map = np.full(self.mapDim, mapFill)
30
+ #--split map into tiles
31
+ self.tiles = {}
32
+ tileset = pygame.image.load(tileSet).convert_alpha()
33
+ tile_w, tile_h = tileDim
34
+ tile_id = 0
35
+ tileset_w, tileset_h = tileset.get_size()
36
+
37
+ for y in range(0, tileset_h, tile_h):
38
+ for x in range(0, tileset_w, tile_w):
39
+ tile = pygame.Surface(tileDim, pygame.SRCALPHA)
40
+ tile.blit(tileset, (0, 0), (x, y, tile_w, tile_h))
41
+ self.tiles[tile_id] = pygame.transform.scale(tile, self.tileDim)
42
+ tile_id += 1
43
+
44
+ print(f"tiles: {self.tiles}")
45
+ Global.tilmap = self
46
+
47
+ def load_map_from_json(self, filePath: str):
48
+ with open(filePath, "r") as f:
49
+ data = json.load(f)
50
+ self.__private_loadData(filePath, data)
51
+
52
+ def __private_loadData(self, path: str, data: dict):
53
+ self.map = np.array(data["map"])
54
+ self.mapFile = path
55
+ self.collisionDict = data["collisions"]
56
+
57
+ def update(self):
58
+ self.draw_tiles()
59
+
60
+
61
+ def draw_tiles(self):
62
+ for y in range(self.mapDim[1]):
63
+ for x in range(self.mapDim[0]):
64
+ tile = self.tiles[self.map[y][x]]
65
+ mx = (x * self.tileDim[0] + self.offset[0]) - Global.cam.x
66
+ my = (y * self.tileDim[1] + self.offset[1]) - Global.cam.y
67
+ if mx < -self.tileDim[0] or mx > Global.screenDim[0] or my < -self.tileDim[1] or my > Global.screenDim[1]: continue
68
+ Global.screen.blit(tile, (mx, my))
69
+
70
+ def _quit(self):
71
+ #save map
72
+ if self.mapFile is not None:
73
+ print('tilemap saved')
74
+ with open(self.mapFile, "w") as f:
75
+ json.dump(self.map.tolist(), f)
@@ -0,0 +1,36 @@
1
+ from src.GameBox import *
2
+ import pygame
3
+ import os
4
+
5
+ width, height = 800, 600
6
+ game = Game(width, height, "blue", "First Game!")
7
+ win = game.get_screen()
8
+
9
+ Keys.init()
10
+
11
+ cam = Cammera()
12
+
13
+ player = Player((width / 2, height / 4), (50, 50), "green", False)
14
+ player.add_physics(1.0, 3.0, 16, 7.0, 0.5)
15
+
16
+ map = TileMap("tests/levelTiles.png", (16, 16), 5, (25, 25), 10, (0, 0))
17
+ map.load_map_from_json("tests/testMap.json")
18
+
19
+ player.set_tilemap_sample(50)
20
+
21
+ cam.set_follow_target(player)
22
+ #cam.move(-50, -50)
23
+
24
+ running = True
25
+ while running:
26
+ for event in pygame.event.get():
27
+ if event.type == pygame.QUIT:
28
+ running = False
29
+
30
+ player.top_down_movement()
31
+
32
+ game.update(60)
33
+
34
+
35
+ #game.quit()
36
+ pygame.quit()
Binary file
@@ -0,0 +1,4 @@
1
+ {
2
+ "map": [[3, 3, 3, 3, 7, 7, 7, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7]],
3
+ "collisions": {"7": "none", "3": "halfBottom"}
4
+ }
@@ -1,104 +0,0 @@
1
- import pygame
2
- import numpy as np
3
-
4
- from ..basics._net import Global
5
- from ..basics.utils import clamp, moveTward, zeroOut
6
-
7
- class _playerPhysics:
8
- def __init__(self, player, speed: float = 1.0, gravity: float = 0.0, jump: float = 0.0, maxV: float = 10.0, airRes: float = 0.2):
9
- self.player = player
10
- self.rect = pygame.Rect(self.player.x, self.player.y, self.player.dim[0], self.player.dim[1])
11
-
12
- self.speed = speed
13
- self.gravity = gravity
14
- self.jump = jump
15
- self.player = player
16
- self.maxV = maxV
17
- self.airRes = airRes
18
- self.onGround = False
19
- self.canJump = False
20
-
21
- self.vx, self.vy = 0, 0
22
-
23
- def update(self):
24
- self.ckeck_is_on_ground()
25
- x, y = self.check_collisions()
26
- if (Global.cam.follow) != (self.player):
27
- self.player.x = x
28
- self.player.y = y
29
- elif (Global.cam.follow) == (self.player):
30
- dx = -(self.player.x - x)
31
- dy = -(self.player.y - y)
32
- Global.cam.move(self.vx, self.vy)
33
-
34
-
35
-
36
- def check_collisions(self):
37
- x, y = self.player.x + self.vx, self.player.y + self.vy
38
-
39
- # X-axis collisions
40
- new_rect = pygame.Rect((x, self.player.y), self.player.dim)
41
- for collision in Global.collisions:
42
- if collision.colliderect(new_rect):
43
- if self.vx > 0:
44
- x = collision.left - self.player.dim[0]
45
- elif self.vx < 0:
46
- x = collision.right
47
- self.vx = 0
48
-
49
- # Y-axis collisions
50
- new_rect = pygame.Rect((x, y), self.player.dim)
51
- for collision in Global.collisions:
52
- if collision.colliderect(new_rect):
53
- if self.vy > 0: # falling
54
- y = collision.top - self.player.dim[1]
55
- self.vy = 0
56
- elif self.vy < 0: # jumping
57
- y = collision.bottom
58
- self.vy = 0
59
-
60
- return x, y
61
-
62
- def ckeck_is_on_ground(self):
63
- self.canJump = False
64
- rect = pygame.Rect(self.player.x, self.player.y + self.player.dim[1], self.player.dim[0], 10)
65
- for collision in Global.collisions:
66
- if collision.colliderect(rect):
67
- self.canJump = True
68
-
69
-
70
- def move(self, x, y):
71
- self.vx += x * self.speed
72
- self.vy += y * self.speed
73
-
74
- def top_down_movement(self):
75
- keys = pygame.key.get_pressed()
76
- if keys[pygame.K_a]:
77
- self.move(-1, 0)
78
- if keys[pygame.K_d]:
79
- self.move(1, 0)
80
- if keys[pygame.K_w]:
81
- self.move(0, -1)
82
- if keys[pygame.K_s]:
83
- self.move(0, 1)
84
- #limit velocity
85
- self.vx = clamp(self.vx, -self.maxV, self.maxV)
86
- self.vy = clamp(self.vy, -self.maxV, self.maxV)
87
- self.vx = moveTward(self.vx, 0, self.airRes)
88
- self.vy = moveTward(self.vy, 0, self.airRes)
89
- self.vx = zeroOut(self.vx, 0.3)
90
- self.vy = zeroOut(self.vy, 0.3)
91
-
92
- def platforming_movement(self):
93
- keys = pygame.key.get_pressed()
94
- if keys[pygame.K_a]:
95
- self.move(-1, 0)
96
- if keys[pygame.K_d]:
97
- self.move(1, 0)
98
- if keys[pygame.K_w] and self.canJump:
99
- self.vy -= self.jump
100
- #limit velocity
101
- self.vx = clamp(self.vx, -self.maxV, self.maxV)
102
- self.vx = moveTward(self.vx, 0, self.airRes)
103
- self.vx = zeroOut(self.vx, 0.3)
104
- if self.player.gravity and not self.onGround: self.vy += self.gravity
@@ -1,29 +0,0 @@
1
- from src.GameBox import *
2
- import pygame
3
-
4
- width, height = 800, 600
5
- win = Game(width, height, "blue", "First Game!")
6
-
7
- cam = Cammera()
8
-
9
- player = Player((width / 2, 375), (50, 50), "green", True)
10
- player.add_physics(1.0, 3.0, 16, 7.0, 0.5)
11
-
12
- floor = Rect((0, height-50), (width, 50), "yellow", True)
13
-
14
- rect = Rect((0, 0), (50, 50), "red", True)
15
-
16
- cam.set_follow_target(floor)
17
-
18
- running = True
19
- while running:
20
- for event in pygame.event.get():
21
- if event.type == pygame.QUIT:
22
- running = False
23
-
24
- player.platforming_movement()
25
- floor.move(-0.5, -0.5)
26
-
27
- win.update(60)
28
-
29
- pygame.quit()
File without changes