From: Skullheadx <704277@pdsb.net> Date: Mon, 16 Jan 2023 23:18:09 +0000 (-0500) Subject: Discrete Collision Detection X-Git-Url: http://git.skullheadx.com/blog/index.html?a=commitdiff_plain;h=1e6fe2a7d5dbcdd5d55e1add03f8761a43691bd2;p=Collision-Simulation.git Discrete Collision Detection --- diff --git a/box.py b/box.py new file mode 100644 index 0000000..cd0bf5b --- /dev/null +++ b/box.py @@ -0,0 +1,22 @@ +from colours import * +import pygame + + +class Box: + line_thickness = 5 + + def __init__(self, position, width, height): + self.position = pygame.Vector2(position) + self.width = width + self.height = height + + self.left = self.position.x + self.right = self.position.x + self.width + self.top = self.position.y + self.bottom = self.position.y + self.height + + def update(self, delta): + pass + + def draw(self, surf): + pygame.draw.rect(surf, BLACK, pygame.Rect(self.left, self.top, self.width, self.height), self.line_thickness) diff --git a/collision.py b/collision.py new file mode 100644 index 0000000..2ad00d2 --- /dev/null +++ b/collision.py @@ -0,0 +1,5 @@ +def handleBoxCollision(particle, box): + if particle.left <= box.left or particle.right >= box.right: + particle.velocity.x *= -1 + if particle.bottom >= box.bottom or particle.top <= box.top: + particle.velocity.y *= -1 diff --git a/display.py b/display.py index 2bf647a..e5fd63e 100644 --- a/display.py +++ b/display.py @@ -1,24 +1,33 @@ from colours import * +from particle import Particle +from box import Box import pygame - pygame.init() class Display: WIDTH, HEIGHT = 640, 640 - DIMENSIONS = pygame.Vector2(WIDTH, HEIGHT) - CENTER = pygame.Vector2(WIDTH / 2, HEIGHT / 2) + DIMENSIONS = (WIDTH, HEIGHT) + CENTER = (WIDTH / 2, HEIGHT / 2) FPS = 60 + COLLISION_LAYERS = 4 def __init__(self, window_name="Pygame"): self.is_running = False + pygame.display.set_caption(window_name) + self.collision_objects = {layer: [] for layer in range(self.COLLISION_LAYERS)} + + self.particles = [Particle(self.CENTER, (0, 0.5), (0, 0), 15, self.collision_objects[0])] + self.collision_objects[0] += self.particles + self.box = Box((0, 0), self.WIDTH, self.HEIGHT) + self.collision_objects[0].append(self.box) + def show(self): screen = pygame.display.set_mode(self.DIMENSIONS) - clock = pygame.time.Clock() delta = 0 self.is_running = True @@ -34,5 +43,15 @@ class Display: if event.type == pygame.QUIT: self.is_running = False + self.box.update(delta) + + for particle in self.particles: + particle.update(delta) + def draw(self, surf): surf.fill(WHITE) + + self.box.draw(surf) + + for particle in self.particles: + particle.draw(surf) diff --git a/main.py b/main.py index ee74ed5..dc3360a 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ from display import Display def main(): - d = Display() + d = Display("Collision Simulation") d.show() diff --git a/particle.py b/particle.py new file mode 100644 index 0000000..0f71de8 --- /dev/null +++ b/particle.py @@ -0,0 +1,43 @@ +import pygame +from math import copysign +from colours import * +from box import Box +from collision import handleBoxCollision + + +class Particle: + speed_limit = 3 + + def __init__(self, initial_position, initial_velocity, initial_acceleration, radius, collision_layer): + self.position = pygame.Vector2(initial_position) + self.velocity = pygame.Vector2(initial_velocity) + self.acceleration = pygame.Vector2(initial_acceleration) + self.radius = radius + + self.left = self.position.x - self.radius + self.right = self.position.x + self.radius + self.top = self.position.y - self.radius + self.bottom = self.position.y + self.radius + + self.collision_layer = collision_layer + + def update(self, delta): + self.velocity.x = min(self.speed_limit, abs(self.velocity.x + self.acceleration.x * delta))\ + * copysign(1, self.velocity.x + self.acceleration.x * delta) + self.velocity.y = min(self.speed_limit, abs(self.velocity.y + self.acceleration.y * delta))\ + * copysign(1, self.velocity.y + self.acceleration.y * delta) + + self.position.x += self.velocity.x * delta + self.position.y += self.velocity.y * delta + + self.left = self.position.x - self.radius + self.right = self.position.x + self.radius + self.top = self.position.y - self.radius + self.bottom = self.position.y + self.radius + + for thing in self.collision_layer: + if isinstance(thing, Box): + handleBoxCollision(self, thing) + + def draw(self, surf): + pygame.draw.circle(surf, RED, self.position, self.radius)