Download entity.py from Minecraft3193092-organization/minecraft-python: direct link, hf CLI and curl.
- Browser
- Download file 3.9 kB
-
https://huggingface.co/Minecraft3193092-organization/minecraft-python/resolve/8ebbcd63745b2e1364c50841ebcdff05c2323a8f/entity.py
- Command line
-
hf download hf://Minecraft3193092-organization/minecraft-python@8ebbcd63745b2e1364c50841ebcdff05c2323a8f/entity.py
-
curl -L -o entity.py https://huggingface.co/Minecraft3193092-organization/minecraft-python/resolve/8ebbcd63745b2e1364c50841ebcdff05c2323a8f/entity.py
3.9 kB
| import math | |
| import collider | |
| FLYING_ACCEL = (0, 0, 0) | |
| GRAVITY_ACCEL = (0, -32, 0) | |
| # these values all come (losely) from Minecraft, but are multiplied by 20 (since Minecraft runs at 20 TPS) | |
| FRICTION = ( 20, 20, 20) | |
| DRAG_FLY = ( 5, 5, 5) | |
| DRAG_JUMP = (1.8, 0, 1.8) | |
| DRAG_FALL = (1.8, 0.4, 1.8) | |
| class Entity: | |
| def __init__(self, world): | |
| self.world = world | |
| # physical variables | |
| self.jump_height = 1.25 | |
| self.flying = False | |
| self.position = [0, 80, 0] | |
| self.rotation = [-math.tau / 4, 0] | |
| self.velocity = [0, 0, 0] | |
| self.accel = [0, 0, 0] | |
| # collision variables | |
| self.width = 0.6 | |
| self.height = 1.8 | |
| self.collider = collider.Collider() | |
| self.grounded = False | |
| def update_collider(self): | |
| x, y, z = self.position | |
| self.collider.x1 = x - self.width / 2 | |
| self.collider.x2 = x + self.width / 2 | |
| self.collider.y1 = y | |
| self.collider.y2 = y + self.height | |
| self.collider.z1 = z - self.width / 2 | |
| self.collider.z2 = z + self.width / 2 | |
| def teleport(self, pos): | |
| self.position = list(pos) | |
| self.velocity = [0, 0, 0] # to prevent collisions | |
| def jump(self, height = None): | |
| # obviously, we can't initiate a jump while in mid-air | |
| if not self.grounded: | |
| return | |
| if height is None: | |
| height = self.jump_height | |
| self.velocity[1] = math.sqrt(-2 * GRAVITY_ACCEL[1] * height) | |
| def friction(self): | |
| if self.flying: | |
| return DRAG_FLY | |
| elif self.grounded: | |
| return FRICTION | |
| elif self.velocity[1] > 0: | |
| return DRAG_JUMP | |
| return DRAG_FALL | |
| def update(self, delta_time): | |
| # apply input acceleration, and adjust for friction/drag | |
| self.velocity = [v + a * f * delta_time for v, a, f in zip(self.velocity, self.accel, self.friction)] | |
| self.accel = [0, 0, 0] | |
| # compute collisions | |
| self.update_collider() | |
| self.grounded = False | |
| for _ in range(3): | |
| adjusted_velocity = [v * delta_time for v in self.velocity] | |
| vx, vy, vz = adjusted_velocity | |
| # find all the blocks we could potentially be colliding with | |
| # this step is known as "broad-phasing" | |
| step_x = 1 if vx > 0 else -1 | |
| step_y = 1 if vy > 0 else -1 | |
| step_z = 1 if vz > 0 else -1 | |
| steps_xz = int(self.width / 2) | |
| steps_y = int(self.height) | |
| x, y, z = map(int, self.position) | |
| cx, cy, cz = [int(x + v) for x, v in zip(self.position, adjusted_velocity)] | |
| potential_collisions = [] | |
| for i in range(x - step_x * (steps_xz + 1), cx + step_x * (steps_xz + 2), step_x): | |
| for j in range(y - step_y * (steps_y + 2), cy + step_y * (steps_y + 3), step_y): | |
| for k in range(z - step_z * (steps_xz + 1), cz + step_z * (steps_xz + 2), step_z): | |
| pos = (i, j, k) | |
| num = self.world.get_block_number(pos) | |
| if not num: | |
| continue | |
| for _collider in self.world.block_types[num].colliders: | |
| entry_time, normal = self.collider.collide(_collider + pos, adjusted_velocity) | |
| if normal is None: | |
| continue | |
| potential_collisions.append((entry_time, normal)) | |
| # get first collision | |
| if not potential_collisions: | |
| break | |
| entry_time, normal = min(potential_collisions, key = lambda x: x[0]) | |
| entry_time -= 0.001 | |
| if normal[0]: | |
| self.velocity[0] = 0 | |
| self.position[0] += vx * entry_time | |
| if normal[1]: | |
| self.velocity[1] = 0 | |
| self.position[1] += vy * entry_time | |
| if normal[2]: | |
| self.velocity[2] = 0 | |
| self.position[2] += vz * entry_time | |
| if normal[1] == 1: | |
| self.grounded = True | |
| self.position = [x + v * delta_time for x, v in zip(self.position, self.velocity)] | |
| # apply gravity acceleration | |
| gravity = FLYING_ACCEL if self.flying else GRAVITY_ACCEL | |
| self.velocity = [v + a * delta_time for v, a in zip(self.velocity, gravity)] | |
| # apply friction/drag | |
| self.velocity = [v - min(v * f * delta_time, v, key = abs) for v, f in zip(self.velocity, self.friction)] | |
| # make sure we can rely on the entity's collider outside of this function | |
| self.update_collider() |