From: Skullheadx <704277@pdsb.net> Date: Wed, 6 Jul 2022 19:23:11 +0000 (-0400) Subject: Added Ragdoll for enemy X-Git-Url: http://git.skullheadx.com/links.html?a=commitdiff_plain;h=35c5699b1f14d46f396ba5e60f8c97a4de78f535;p=Pygame-Jam.git Added Ragdoll for enemy --- diff --git a/Actors.py b/Actors.py index 141239c..091f72f 100644 --- a/Actors.py +++ b/Actors.py @@ -1,4 +1,5 @@ from Setup import * +from PhysicsBody import PhysicsBody class Actor: width, height = 50, 100 @@ -16,6 +17,7 @@ class Actor: self.on_ground = False collision_layer.add(self) # the layer the actor is on for collisions + self.collision_layer = collision_layer self.collision_mask = collision_mask # the layer the actor detects collisions against self.health = 100 @@ -23,6 +25,8 @@ class Actor: self.areas = dict() + self.movable = False + def update(self, delta): for area in self.areas.values(): @@ -48,8 +52,6 @@ class Actor: self.health += amount self.is_dead(reason) - - def follow_target(self, node, follow_range=None, stop_dist=None): if stop_dist is None: stop_dist = max(self.height, self.width) * 1.5 @@ -86,12 +88,16 @@ class Actor: if thing == self: continue if collision_rect.colliderect(thing.get_collision_rect()): + if thing.movable: + thing.velocity.x = vel.x if vel.x > 0: pos.x = thing.position.x - self.width vel.x = min(vel.x + thing.velocity.x, 0) elif vel.x < 0: pos.x = thing.position.x + thing.width vel.x = max(vel.x + thing.velocity.x, 0) + collision_rect = self.get_collision_rect(pos) + self.on_ground = False pos.y += vel.y * delta collision_rect = self.get_collision_rect(pos) @@ -103,6 +109,9 @@ class Actor: if area.is_colliding(thing): area.signal(thing) if collision_rect.colliderect(thing.get_collision_rect()): + if thing.movable: + thing.velocity.y += vel.y + if vel.y > 0: pos.y = thing.position.y - self.height vel.y = min(vel.y + thing.velocity.y, 0) @@ -110,6 +119,8 @@ class Actor: elif vel.y < 0: pos.y = thing.position.y + thing.height vel.y = max(vel.y + thing.velocity.y, 0) + collision_rect = self.get_collision_rect(pos) + return pos, vel def get_collision_rect(self, pos=None): diff --git a/Block.py b/Block.py index 6158ddf..a5dd3a2 100644 --- a/Block.py +++ b/Block.py @@ -10,6 +10,8 @@ class Block: self.velocity = pg.Vector2(0,0) # So that we may have moving blocks collision_layer.add(self) + self.movable = False + def update(self, delta): pass # when player "moves", it's actually the blocks diff --git a/Enemy.py b/Enemy.py index e7a5e8f..6793cf9 100644 --- a/Enemy.py +++ b/Enemy.py @@ -16,7 +16,7 @@ class Enemy(Actor): super().__init__(pos, collision_layer, collision_mask) self.areas = {"head":Area(self.position,pg.Vector2(self.width * 1/3 * 1/2,-5), self.width * 2/3, 25, Player, self.knockout)} - + self.movable = True self.dizzy_time = 0 def update(self, delta, target=None): @@ -31,7 +31,7 @@ class Enemy(Actor): def knockout(self, node): self.dizzy_time = 5000 - self.health -= 50 + self.health -= 10 node.on_ground = True node.jump() # self.crouch(1000) diff --git a/Game.py b/Game.py index 93adab0..689ca77 100644 --- a/Game.py +++ b/Game.py @@ -3,6 +3,7 @@ from Player import Player from Pet import Pet from Enemy import Enemy from Block import Block +from PhysicsBody import PhysicsBody class Game: @@ -19,17 +20,21 @@ class Game: def update(self, delta): - self.player.update(delta) - self.pet.update(delta, self.player) - for enemy in self.enemies: + + for i,enemy in enumerate(self.enemies): enemy.update(delta, self.player) if enemy.dead: - print('enemy died') + self.enemies[i] = PhysicsBody(enemy.position,enemy.velocity,enemy.width,enemy.height,enemy.colour,enemy.collision_layer,enemy.collision_mask) + self.collision_layer["enemy"].remove(enemy) + self.collision_layer["enemy"].add(self.enemies[i]) for block in self.blocks: block.update(delta) - + + self.player.update(delta) + self.pet.update(delta, self.player) + def draw(self, surf): screen.fill((255, 255, 255)) for enemy in self.enemies: diff --git a/PhysicsBody.py b/PhysicsBody.py new file mode 100644 index 0000000..2a73e13 --- /dev/null +++ b/PhysicsBody.py @@ -0,0 +1,81 @@ +from Setup import * +from Block import Block + +class PhysicsBody: + speed = 0.2 + jump_strength = 1 + gravity = 0.098 + friction = 0.9 + + def __init__(self, pos, vel, width, height, colour, collision_layer, collision_mask): + self.position = pg.Vector2(pos) + self.velocity = pg.Vector2(vel) + self.width, self.height = width, height + self.colour = colour + + self.on_ground = False + + self.dead = False + + self.movable =True + + collision_layer.add(self) # the layer the actor is on for collisions + self.collision_layer = collision_layer + self.collision_mask = collision_mask # the layer the actor detects collisions against + + def update(self, delta, test=None): + # Apply friction so the enemy isn't walking on ice + if self.on_ground: + self.velocity.x *= self.friction + + # Apply gravity + self.velocity.y += self.gravity + + self.position, self.velocity = self.move_and_collide(self.position, self.velocity, delta) + + def move_and_collide(self, pos, vel, delta): + pos.x += vel.x * delta + collision_rect = self.get_collision_rect(pos) + for mask in self.collision_mask: + for thing in mask: + if thing == self: + continue + if collision_rect.colliderect(thing.get_collision_rect()): + if thing.movable: + thing.velocity.x = vel.x + if vel.x > 0: + pos.x = thing.position.x - self.width + vel.x = min(vel.x + thing.velocity.x, 0) + elif vel.x < 0: + pos.x = thing.position.x + thing.width + vel.x = max(vel.x + thing.velocity.x, 0) + collision_rect = self.get_collision_rect(pos) + self.on_ground = False + pos.y += vel.y * delta + collision_rect = self.get_collision_rect(pos) + for mask in self.collision_mask: + for thing in mask: + if thing == self: + continue + if collision_rect.colliderect(thing.get_collision_rect()): + if thing.movable: + thing.velocity.y += vel.y + + if vel.y > 0: + pos.y = thing.position.y - self.height + vel.y = min(vel.y + thing.velocity.y, 0) + self.on_ground = True + elif vel.y < 0: + pos.y = thing.position.y + thing.height + vel.y = max(vel.y + thing.velocity.y, 0) + collision_rect = self.get_collision_rect(pos) + return pos, vel + + def get_collision_rect(self, pos=None): + if pos is None: + pos = self.position + return pg.Rect(pos, (self.width, self.height)) + + def draw(self, surf): + # print(self.position, self.velocity) + pg.draw.rect(surf, self.colour, self.get_collision_rect(), border_radius=8)