Beispiel #1
0
 def __init__(self, pos, level):
     self.size = Vector(0.8, 1.2)
     self.pos = Vector(pos[0], pos[1]) - (self.size - Vector(1, 1))
     self.level = level
     self.hp = 100
     self.image = player_image
     self.velocity = Vector(0, 0)
    def test_zero(self):
        v = Vector(0.0, 0.0)

        self.assertEqual(v.x, 0.0)
        self.assertEqual(v.y, 0.0)
        self.assertEqual(v.get_magnitude(), 0.0)
        self.assertEqual(v.get_angle(), None)
Beispiel #3
0
 def __init__(self, location , mass , velocity = None):
     if velocity == None: self.velocity = Vector(0,0)
     else: self.velocity = velocity
     self.applied_force = Vector(0,0)
     self._location = location
     self._mass = mass
     self._object_type = ObjectType.DEFAULT
Beispiel #4
0
 def __init__(self, wall_type, relevant_coord):
     if(wall_type == WallType.LEFT or wall_type == WallType.RIGHT):
         super().__init__(Vector(relevant_coord, 0), None)
     else:
         super().__init__(Vector(0, relevant_coord), None)
     self._object_type = ObjectType.WALL
     self.__wall_type = wall_type
Beispiel #5
0
 def shoot(self):
     if World.main_character is not None:
         if KeyLogger.bindings['shoot'].check():
             v = Vector(Mouse.get_real_coordinates() -
                        World.main_character.get_firing_coordinates())
             World.main_character.fire_normal_bullet(v.normalize())
             return True
     return False
    def test_init(self):
        v = Vector(1, 1)

        self.assertEqual(v.x, 1.0)
        self.assertEqual(v.y, 1.0)

        # Type check
        self.assertIsInstance(v.x, float)
        self.assertIsInstance(v.y, float)
        self.assertIsInstance(v.get_magnitude(), float)
        self.assertIsInstance(v.get_angle(), float)
 def get_safe_distance(self, v, k=0):
     if k > 2:
         return Coordinates(0, 0)
     o = self.check_collision(v, type_exceptions=['walkable'])
     if o is not None:
         k += 1
         d = Vector(v).normalize() * (Vector(self.distance(o, v)) *
                                      Vector(v).normalize())
         return self.get_safe_distance(
             (Coordinates(d) * Coordinates(0.99, 0.99)).int(), k)
     else:
         return v
Beispiel #8
0
def resolve_ball_wall_collision(ball: PoolBall, wall: Direction):
    """
    Sets the new velocity for this ball after it has collided with a wall.
    *Assumes wall is in one of 4 directions: N, E, S, or W*

    :param ball: pool ball
    :param wall: which wall (N, E, S, W)
    """

    if wall == Direction.NORTH or wall == Direction.SOUTH:
        ball.vel = Vector(ball.vel.x, -ball.vel.y)  # Reverse y-direction
    else:  # EAST or WEST
        ball.vel = Vector(-ball.vel.x, ball.vel.y)  # Reverse x-direction
    def test_resolve_ball_ball_collision_2d_two_moving(self):
        # Initialize ball objects
        ball_a = PoolBall(ball_type=BallType.CUE, pos=Coordinates(0.0, 0.0), mass=1.0, radius=0.5)
        ball_b = PoolBall(ball_type=BallType.CUE, pos=Coordinates(0.0, 0.0), mass=1.0, radius=0.5)

        # A enters from W (270 degrees), contacts B on its left (180 degrees)
        # A enters from E (0 degrees), contacts A on its right (0 degrees)
        # A and B should both reverse their direction
        ball_a.pos, ball_a.vel, ball_a.mass = Coordinates(-0.5, 0.0), Vector(1.0, 0.0), 3.0
        ball_b.pos, ball_b.vel, ball_b.mass = Coordinates(0.5, 0.0), Vector(-1.0, 0.0), 3.0

        resolve_ball_ball_collision(ball_a, ball_b)

        a_vel_new = Vector(-1.0, 0.0)
        b_vel_new = Vector(1.0, 0.0)

        self.assertVectorAlmostEqual(ball_a.vel, a_vel_new)
        self.assertVectorAlmostEqual(ball_b.vel, b_vel_new)

        # A enters from W (270 degrees), contacts B on its left (180 degrees)
        # A enters from E (0 degrees), contacts A on its right (0 degrees)
        # A and B should both reverse their direction
        ball_a.pos, ball_a.vel, ball_a.mass = Coordinates(-0.5, 0.0), Vector(1.0, 0.0), 3.0
        ball_b.pos, ball_b.vel, ball_b.mass = Coordinates(0.5, 0.0), Vector(-1.0, 0.0), 3.0

        resolve_ball_ball_collision(ball_a, ball_b)

        a_vel_new = Vector(-1.0, 0.0)
        b_vel_new = Vector(1.0, 0.0)

        self.assertVectorAlmostEqual(ball_a.vel, a_vel_new)
        self.assertVectorAlmostEqual(ball_b.vel, b_vel_new)

        """
    def test_resolve_ball_ball_collision_1d_diagonal(self):
        # Initialize ball objects
        ball_a = PoolBall(ball_type=BallType.CUE, pos=Coordinates(0.0, 0.0), mass=1.0, radius=0.5)
        ball_b = PoolBall(ball_type=BallType.CUE, pos=Coordinates(0.0, 0.0), mass=1.0, radius=0.5)

        # 2-D, stationary target ball
        ball_a.pos, ball_a.vel, ball_a.mass = Coordinates(-1.0, -1.0), Vector(2.0, 2.0), 3.0
        ball_b.pos, ball_b.vel, ball_b.mass = Coordinates(0.0, 0.0), Vector(0.0, 0.0), 3.0

        resolve_ball_ball_collision(ball_a, ball_b)

        a_vel_new = Vector(0.0, 0.0)
        b_vel_new = Vector(2.0, 2.0)

        self.assertVectorAlmostEqual(ball_a.vel, a_vel_new)
        self.assertVectorAlmostEqual(ball_b.vel, b_vel_new)

        # 2-D, head-on collision, same speeds
        ball_a.pos, ball_a.vel, ball_a.mass = Coordinates(-1.0, -1.0), Vector(2.0, 2.0), 3.0
        ball_b.pos, ball_b.vel, ball_b.mass = Coordinates(0.0, 0.0), Vector(-2.0, -2.0), 3.0

        resolve_ball_ball_collision(ball_a, ball_b)

        a_vel_new = Vector(-2.0, -2.0)
        b_vel_new = Vector(2.0, 2.0)

        self.assertVectorAlmostEqual(ball_a.vel, a_vel_new)
        self.assertVectorAlmostEqual(ball_b.vel, b_vel_new)
Beispiel #11
0
 def collides_line(self, other, additional_coordinates):
     a = Vector(other.get_coordinates() - self.get_coordinates() -
                additional_coordinates)
     e1 = self.e
     e2 = other.e
     if e1**e2 == 0:
         if a**e1 != 0:
             return False
         else:
             if a.x == 0:
                 if a.y == 0:
                     return True
                 else:
                     lam1 = a.y / e1.y
                     lam2 = (a.y + e2.y) / e1.y
                     if 0 <= lam1 <= 1 or 0 <= lam2 <= 1:
                         return lam1 * lam2 < 0
                     else:
                         return True
             else:
                 lam1 = a.x / e1.x
                 lam2 = (a.x + e2.x) / e1.x
                 if not 0 <= lam1 <= 1 or 0 <= lam2 <= 1:
                     return lam1 * lam2 < 0
                 else:
                     return True
     else:
         lam1 = (a**e2) / (e1**e2)
         lam2 = (a**e1) / (e1**e2)
         return 0 <= lam1 <= 1 and 0 <= lam2 <= 1
Beispiel #12
0
 def future_shape(self, additional_coordinates):
     circle2 = Circle(self.gameobject,
                      self.get_coordinates() + additional_coordinates,
                      self.radius)
     v = Vector(additional_coordinates).normalize().right_angled()
     line1 = Line(self.gameobject,
                  self.get_coordinates() + v * self.radius,
                  self.get_coordinates() - v * self.radius)
     line2 = Line(
         self.gameobject,
         self.get_coordinates() - v * self.radius,
         self.get_coordinates() - v * self.radius + additional_coordinates)
     line3 = Line(
         self.gameobject,
         self.get_coordinates() - v * self.radius + additional_coordinates,
         self.get_coordinates() + v * self.radius + additional_coordinates)
     line4 = Line(
         self.gameobject,
         self.get_coordinates() + v * self.radius + additional_coordinates,
         self.get_coordinates() + v * self.radius)
     return [
         self, circle2,
         MultilineObject(self.gameobject, self.coordinates,
                         [line1, line2, line3, line4])
     ]
 def __init__(self, animations, velocity=Vector(0, 0), center_of_gravity=Coordinates(0, 0), mass=0.02):
     GameObject.__init__(self, animations)
     self.velocity = velocity
     self.mass = mass
     self.hit_exceptions = []
     self.type_exceptions = ['shootable']
     self.center_of_gravity = center_of_gravity
     self.thread = Thread(self.run, (), 'projectile thread')
 def move(self, direction):
     v = self.walking_distance / target_fps * direction
     try:
         d = self.get_safe_distance(v)
     except RecursionError:
         print('Maximum recursion depth exceeded.')
         d = Vector(0, 0)
     self.reposition(self.coordinates + d)
Beispiel #15
0
class PhysicsObject():
    __global_forces = vector.get_inert_vector(2)
    def __init__(self, location , mass , velocity = None):
        if velocity == None: self.velocity = Vector(0,0)
        else: self.velocity = velocity
        self.applied_force = Vector(0,0)
        self._location = location
        self._mass = mass
        self._object_type = ObjectType.DEFAULT

    def exert_force(self , force: Sequence):
        self.applied_force+=force
    def move(self):
        self.velocity.update( Vector.sum(self.applied_force,self.__global_forces, self.velocity))
        self._location.update(self._location+self.velocity)

    
    @staticmethod
    def get_global_force()->Vector:
        return PhysicsObject.__global_forces.copy()
    @staticmethod
    def set_global_force(value: Sequence):
        if(not isinstance(value, Sequence) and len(value)!=2): raise ValueError
        PhysicsObject.__global_forces = Vector(*value)

    @staticmethod
    def check_collision(obj_a:'PhysicsObject', obj_b: 'PhysicsObject')->bool:
        x_distance = obj_a._location[0] - obj_b._location[0]
        y_distance = obj_a._location[0] - obj_b._location[0]

        if(obj_a._object_type==ObjectType.CIRCLE and obj_b._object_type==ObjectType.CIRCLE):
            radii_sum = obj_a._radius + obj_b._radius
            return radii_sum**2 < (x_distance**2) + (y_distance**2)
        
        if(
            obj_a._object_type == ObjectType.WALL   and obj_b._object_type == ObjectType.CIRCLE or
            obj_a._object_type == ObjectType.CIRCLE and obj_b._object_type == ObjectType.WALL):
            if(obj_a._object_type== ObjectType.WALL): wall = obj_a
            else: wall = obj_b

            if(wall.wall_type == WallType.LEFT or wall.wall_type == WallType.RIGHT):
                return x_distance**2<=0
            else:
                return y_distance**2<=0

        return False
Beispiel #16
0
def check_ray_circle_intersection(p1: Coordinates, p2: Coordinates,
                                  c_mid: Coordinates, c_radius: float):
    """
    Check whether a ray intersects a circle.

    :param p1: starting point of ray
    :param p2: end point of ray
    :param c_mid: coordinates for the center of the circle
    :param c_radius: radius of the circle
    :return: True if intersection; False otherwise
    """

    # Source: https://stackoverflow.com/a/1084899

    # d is direction vector of ray, from start to end
    # f is direction Vector from center sphere to ray start
    d = Vector(p2.y - p1.y, p2.x - p1.x)
    f = Vector(p1.y - c_mid.y, p1.x - c_mid.x)

    a = d.dot_product(d)
    b = 2 * f.dot_product(d)
    c = f.dot_product(f) - c_radius**2

    discriminant = b * b - 4 * a * c

    if discriminant < 0:
        return False
    else:
        discriminant = np.sqrt(discriminant)

        t1 = (-b - discriminant) / (2 * a)
        t2 = (-b + discriminant) / (2 * a)

        return (0 <= t1 <= 1) or (0 <= t2 <= 1)
Beispiel #17
0
    def on_frame(self):
        self.ball.body.add_force(Vector(0, 0.5))
        self.ball.body.integrate_force()

        for rock in self.rocks:
            if self.collision.try_collide_polygon(rock.body, preserve=0.3):
                break

        self.draw_entity(self.ball)
Beispiel #18
0
 def __init__(self, game_states):
     GameState.__init__(self)
     self.game_states = game_states
     self.add(self.move, 1 / target_fps)
     self.add(self.delete_gf, 1 / 10)
     self.add(self.shoot, 1 / 2)
     self.add(self.create_gravity_field, 1 / 2)
     self.add(self.back, 1 / 20)
     self.add(self.zoom_out, 1 / target_fps)
     self.add(self.zoom_in, 1 / target_fps)
     self.add(self.recenter, 1 / 3)
     self.add(self.change_perspective, 1 / 1)
     self.word_to_vector = {
         'up': Vector(0, -1),
         'down': Vector(0, 1),
         'left': Vector(-1, 0),
         'right': Vector(1, 0)
     }
Beispiel #19
0
 def distance_line(self, other):
     c = Vector(self - other.get_coordinates())
     lam = (c * other.e) / (other.e * other.e)
     if lam <= 0:
         return c * (-1)
     elif lam >= 1:
         return other.e - c
     else:
         eps = (c ** other.e) / (other.e * other.e)
         return other.e.right_angled() * eps * (-1)
Beispiel #20
0
 def __init__(self,
              ball_type: BallType,
              pos: Coordinates,
              mass: float,
              radius: float,
              vel=None):
     self.ball_type = ball_type
     self.pos = pos
     self.mass = mass
     self.radius = radius
     if vel is None:
         self.vel = Vector(0, 0)
    def test_init(self):
        name = '1'
        pos = Coordinates(0, 0)
        mass = 1.0
        radius = 1.0

        p = PoolBall(name, pos, mass, radius)

        self.assertEqual(p.type, name)
        self.assertEqual(p.pos, pos)
        self.assertEqual(p.mass, mass)
        self.assertEqual(p.radius, radius)
        self.assertEqual(p.vel, Vector(0, 0))  # Default should be 0
Beispiel #22
0
 def distance_rectangle(self, other):
     c = other.get_coordinates()
     if self.x < c.x:
         if self.y < c.y:
             return Vector(c - self)
         elif self.y > c.y + other.b:
             return Vector(c + Coordinates(0, other.b) - self)
         else:
             return self.distance(other.get_lines()[0])
     elif self.x > c.x + other.a:
         if self.y < c.y:
             return Vector(c + Coordinates(other.a, 0) - self)
         elif self.y > c.y + other.b:
             return Vector(c + Coordinates(other.a, other.b) - self)
         else:
             return self.distance(other.get_lines()[2])
     else:
         if self.y < c.y:
             return self.distance(other.get_lines()[3])
         elif self.y > c.y + other.b:
             return self.distance(other.get_lines()[1])
         else:
             return Vector(0, 0)
    def test_resolve_ball_ball_collision_2d_one_moving(self):
        # Initialize ball objects
        ball_a = PoolBall(ball_type=BallType.CUE, pos=Coordinates(0.0, 0.0), mass=1.0, radius=0.5)
        ball_b = PoolBall(ball_type=BallType.CUE, pos=Coordinates(0.0, 0.0), mass=1.0, radius=0.5)

        # A enters from NW (135 degrees), contacts B on its left (180 degrees)
        # B is stationary, located at origin
        # A should exit S (270 degrees)
        # B should exit E (0 degrees)
        ball_a.pos, ball_a.vel, ball_a.mass = Coordinates(-1.0, 0.0), Vector(1.0, -1.0), 3.0
        ball_b.pos, ball_b.vel, ball_b.mass = Coordinates(0.0, 0.0), Vector(0.0, 0.0), 3.0

        resolve_ball_ball_collision(ball_a, ball_b)

        a_vel_new = Vector(0.0, -1.0)
        b_vel_new = Vector(1.0, 0.0)

        self.assertVectorAlmostEqual(ball_a.vel, a_vel_new)
        self.assertVectorAlmostEqual(ball_b.vel, b_vel_new)

        # A enters from 122.3 degrees, contacts B on its left (180 degrees)
        # B is stationary, located at origin
        # A should exit S (270 degrees), with y-component of initial magnitude
        # B should exit E (0 degrees), with x-component of initial magnitude
        mag = 7.14
        ang = 32.3
        ball_a.pos, ball_a.vel, ball_a.mass = Coordinates(-1.0, 0.0), Vector(mag * np.cos(ang), -mag * np.sin(ang)), 3.0
        ball_b.pos, ball_b.vel, ball_b.mass = Coordinates(0.0, 0.0), Vector(0.0, 0.0), 3.0

        resolve_ball_ball_collision(ball_a, ball_b)

        a_vel_new = Vector(0.0, -mag * np.sin(ang))
        b_vel_new = Vector(mag * np.cos(ang), 0.0)

        self.assertVectorAlmostEqual(ball_a.vel, a_vel_new)
        self.assertVectorAlmostEqual(ball_b.vel, b_vel_new)
Beispiel #24
0
def get_point_on_line_distance_from_point(line_start, line_end, point,
                                          distance) -> Coordinates:
    a_side = distance
    c_side = get_distance(line_start, point)

    v_point = Vector(point.x - line_start.x, point.y - line_start.y)
    v_line = Vector(line_end.x - line_start.x, line_end.y - line_start.y)
    dot = v_point.dot_product(v_line)

    a_angle = np.arccos(dot / v_point.get_magnitude() / v_line.get_magnitude())

    from physics.trianglesolver import solve
    (a_side, b_side, c_side, a_angle, b_angle,
     c_angle) = solve(a=a_side, c=c_side, A=a_angle, ssa_flag='obtuse')
    assert a_angle + b_angle + c_angle == np.radians(
        180), 'a_angle: {} \nb_angle: {}\nc_angle: {}\n'.format(
            a_angle, b_angle, c_angle)
    # Compute exact point
    angle = np.radians(get_angle(line_end, line_start))
    x = line_start.x + b_side * np.cos(angle)
    y = line_start.y + b_side * np.sin(angle)

    return Coordinates(x, y)
Beispiel #25
0
    def __init__(self, mass=1, position=Vector(0, 0), velocity=Vector(0, 0)):
        self.mass = mass
        self.position = position
        self.velocity = velocity

        self.acceleration = Vector(0, 0)
Beispiel #26
0
 def __init__(self, actor):
     Thread.__init__(self, actor)
     self.gravity = 9.8
     self.acceleration = Vector(0, self.gravity / 10)
     self.actor = actor
     self.force = actor.mass * self.gravity
Beispiel #27
0
import time
import threading, multiprocessing

import pygame

from graphics.graphics_objects import Circle, PrimarySurface
from graphics.graphics_engine import Renderer
from physics.physics_objects import CirclePhysicsObject
from physics.physics_engine import Engine
from physics.vector import Vector



screen_size = [800,800]
base_surface = PrimarySurface(screen_size)
my_location = Vector(500, 500)

phys_obj = CirclePhysicsObject(my_location, 1, 5)
graph_obj = Circle(base_surface, my_location, 5)

phys_engine = Engine()
phys_engine.register_object(phys_obj)

renderer = Renderer(screen_size, base_surface)
renderer.register_object(graph_obj, 1)

# thread_lock = threading.Lock()

# renderer.run(thread_lock)
# phys_engine.run(thread_lock)
 def newton_g(self, field):
     r = Vector(field.get_center_of_gravity() - self.get_center_of_gravity())
     return r * (self.mass * field.mass / abs(r) ** 3 * constants.G)
# then calculates the shortest distance to move `object1` out of
# `object2`, and returns a vector representing that movement.  If
# there is no collision, a vector (0, 0) will be returned.
from physics.collision import get_exit_direction
from physics.vector import Vector


window = Window()

paddle_image = load_image('paddle.png')
paddle_image.anchor_x = paddle_image.width / 2
paddle_sprite = Sprite(paddle_image, 0, 10)

ball_image = load_image('ball.png')
ball_sprite = Sprite(ball_image, 10, 300)
ball_velocity = Vector()
ball_velocity.x = 50
ball_velocity.y = -50

@window.event
def on_draw():
    window.clear()
    paddle_sprite.draw()
    ball_sprite.draw()

@window.event
def on_mouse_motion(mouse_x, mouse_y, dx, dy):
    right_side = window.width - paddle_sprite.width / 2
    left_side = paddle_sprite.width / 2

    if mouse_x > right_side:
Beispiel #30
0
 def set_global_force(value: Sequence):
     if(not isinstance(value, Sequence) and len(value)!=2): raise ValueError
     PhysicsObject.__global_forces = Vector(*value)
 def gravity(self):
     v = Vector(0, 0)
     for field in World.gravity_fields:
         v += self.newton_g(field)
     return v
from pyglet.clock import schedule_interval
from pyglet.app import run

from physics.collision import get_exit_direction
from physics.vector import Vector
from physics.rect import Rect


window = Window()

paddle_image = load_image('paddle.png')
paddle_sprite = Sprite(paddle_image, 0, 10)

ball_image = load_image('ball.png')
ball_sprite = Sprite(ball_image, 10, 300)
ball_velocity = Vector.new(50, -50)

left_wall = Rect.new(0, 0, 0, window.height)
top_wall = Rect.new(0, window.height, window.width, 0)
right_wall = Rect.new(window.width, 0, 0, window.height)

walls = [left_wall, top_wall, right_wall, paddle_sprite]

@window.event
def on_draw():
    window.clear()
    paddle_sprite.draw()
    ball_sprite.draw()

@window.event
def on_mouse_motion(mouse_x, mouse_y, dx, dy):