Exemple #1
0
    def test_union_requirements_multiplication(self):
        # arrange
        ur1 = UnionRequirements("a", [has("a"), has("b")])
        ur2 = UnionRequirements("b", [has("c"), has("b")])

        # act
        t = ur1 * ur1 * ur2

        # assert
        self.assertEqual(t.tuple, (ur1, ur1, ur2))
Exemple #2
0
    def test_has_and_has(self):
        # arrange
        h1 = has("a")
        h2 = has("b")
        h3 = has("c")
        h = h1 & h2 & h3

        # assert
        self.assertIs(h.name, None)
        self.assertListEqual(h.requirements, [h1, h2, h3])
Exemple #3
0
    def test_union_requirements_ror(self):
        # arrange
        h1 = has("a")
        h = "B" | h1

        # assert
        self.assertRaises(UnionRequirements.Error, lambda: "C" | h)
        self.assertEqual(h.name, "B")
        self.assertListEqual(h.requirements, [h1])
Exemple #4
0
    def test_union_requirement_match_works(self):
        # arrange
        class A:
            def a(self):
                pass

            def b(self):
                pass

        class B:
            def a(self):
                pass

        h1 = has("a")
        h2 = has("b")
        h = "u" | h1 & h2

        # assert
        self.assertTrue(h.match(A()))
        self.assertIsInstance(h.match(A())["u"], A)
        self.assertFalse(h.match(B()))
        self.assertRaises(UnionRequirements.Error, lambda:
                          (h1 & h2).match(A()))
Exemple #5
0
    def test_match_checks_attribute_existence(self):
        # arrange
        class A:
            def __init__(self):
                self.a = 1

            def t(self):
                pass

        class B:
            def a(self):
                pass

        h = has("t")

        # assert
        self.assertTrue(h.match(A()))
        self.assertFalse(h.match(B()))
Exemple #6
0
from src.ecs.clocks import delta_time
from src.ecs.requirements.has import has


def are_mounted(first, second):
    return (hasattr(first, 'mounting_object') and first.mounting_object is second) \
           or (hasattr(second, 'mounting_object') and second.mounting_object is first)


def mount(mounted):
    if not mounted.mounting_object:
        return

    parent = mounted.mounting_object

    # if mounted.mounting_force < abs(mounted.velocity - parent.velocity) * mounted.mass / delta_time():
    #     print('Mounting break with force', abs(mounted.velocity - parent.velocity) * mounted.mass / delta_time())
    #     mounted.mounting_object = None
    #     return

    if hasattr(parent, "velocity") and hasattr(mounted, "velocity"):
        mounted.velocity = parent.velocity

    rotation = parent.rotation if hasattr(parent, "rotation") else 0
    mounted.position = parent.position + mounted.mounting_offset.rotated(
        rotation)


mounting = (
    ("mounted" | has('mounting_object') & has('mounting_force')) >> mount, )
Exemple #7
0
            ending_loop_index / len(self.sprites) * length \
            if ending_loop_index else len(self.sprites)

        self.time = Limited(0, max_value=length, min_value=0)


def animate(animated):
    for condition, animation_ in animated._Animated__dict.items():
        if condition(animated):
            if animation_.time.value >= animation_.ending_loop_starts:
                animation_.time.min_value = animation_.ending_loop_starts
                animation_.time.cycled_step(delta_time())
                animation_.time.min_value = 0
            else:
                animation_.time.step(delta_time())
        else:
            animation_.time.min_value = 0
            animation_.time.step(-delta_time())

        animated.sprite = animation_.sprites[
            min(
                floor((animation_.time.to_proportion()) * len(animation_.sprites)),
                len(animation_.sprites) - 1
            )
        ]


animation = (
    ("animated" | has("_Animated__dict") & has("sprite")) >> animate,
)
Exemple #8
0
from src.ecs.requirements.has import has


def shoot_them_all(ai, enemy):
    if ai is enemy or enemy.radius <= 10:
        return

    delta = enemy.position - ai.position

    if delta and delta.squared_magnitude() <= ai.aggressive_range ** 2:
        ai.rotation = delta.angle()
        ai.shooting_enabled = True


ai = (
    ("ai" | has("flag_ai")) * ("enemy" | has("position", "solid")) >> shoot_them_all,
)
Exemple #9
0
from src.ecs.requirements.has import has
from src.ecs.union import Union

data_types = Union(
    vector="vector",
    text="text",
)


def display(container):
    if container.display_type == data_types.vector:
        container.size = container.display_func()
    elif container.display_type == data_types.text:
        container.text = container.display_func()
    else:
        raise NotImplementedError


ui = (("container" | has("display_func")) >> display, )
Exemple #10
0
from src.ecs.clocks import delta_time
from src.ecs.requirements.has import has


def clean(temporal, destructor):
    temporal.living_time.step(-delta_time())
    if temporal.living_time.value <= 0:
        destructor.clocks_destruction_list.append(temporal)


cleaning = (
    ("temporal" | has("living_time")) * ("destructor" | has("clocks_destruction_list")) >> clean,
)
Exemple #11
0
from _tkinter import TclError

import src.game
from src.ecs.clocks import Clocks
from src.ecs.requirements.has import has
from src.systems.graphics.animation import animation
from src.systems.graphics.ui import ui

displayable = ("displayable" | has("visible"))
display = ("display" | has("put"))


def clear(display):
    display.canvas.delete("all")
    display.camera.position = display.camera.target.position - display.size / 2


def put(displayable, display):
    if displayable.visible:
        display.put(displayable)


def update(display):
    display.canvas.update()
    try:
        display.canvas.update_idletasks()
    except TclError:
        raise Clocks.EndGameError


graphics = (
Exemple #12
0
    def test_execution_pair_subjects_addition(self):
        # arrange
        class A:
            def a(self):
                pass

        class B:
            def b(self):
                pass

        class C(A, B):
            pass

        pair = ExecutionPair(("f" | has("a")) * ("s" | has("b")),
                             lambda f, s: None)

        a1 = A()
        a2 = A()
        b1 = B()

        pair.subjects = [
            {
                "f": a1,
                "s": b1
            },
            {
                "f": a2,
                "s": b1
            },
        ]
        pair.subjects = (
            _Cache("f", [a1, a2]),
            _Cache("s", [b1]),
        )

        a3 = A()
        c = C()

        # act
        pair.try_add_subject(a3)
        pair.try_add_subject(c)

        # assert
        self.assertListEqual(pair.subjects, [
            {
                "f": a1,
                "s": b1
            },
            {
                "f": a2,
                "s": b1
            },
            {
                "f": a3,
                "s": b1
            },
            {
                "f": c,
                "s": b1
            },
            {
                "f": a1,
                "s": c
            },
            {
                "f": a2,
                "s": c
            },
            {
                "f": a3,
                "s": c
            },
            {
                "f": c,
                "s": c
            },
        ])
Exemple #13
0
from src.ecs.clocks import delta_time
from src.ecs.requirements.has import has


def apply_force(tractor):
    if tractor.traction_enabled:
        print('Traction enabled')
        tractor.velocity += \
            tractor.traction_direction.rotated(
                tractor.rotation
                if hasattr(tractor, "rotation") else 0) \
            * tractor.traction_force \
            * delta_time() \
            / tractor.mass


traction = (
    ("tractor" |
     has("velocity") &
     has("traction_force") &
     has("traction_direction") &
     has("mass")
     ) >> apply_force,
)
Exemple #14
0
from src.ecs.clocks import delta_time
from src.ecs.requirements.has import has


def precalculate(self, constants):
    self.squared_gravity_radius = self.mass / constants.g_min / constants.G


def accelerate(self, other, constants):
    if self is other:
        return

    assert self.position != other.position

    delta = other.position - self.position

    if delta.squared_magnitude() > self.squared_gravity_radius:
        return

    self.velocity += delta ** 0 * other.mass / delta.squared_magnitude() * constants.G * delta_time()


massive = has("mass") & has("position") & has("velocity")
gravity = (
    ("self" | massive) * ("constants" | has("g_min") & has("G")) >> precalculate,
    ("self" | massive) * ("other" | massive) * ("constants" | has("G")) >> accelerate,
)
Exemple #15
0
from src.ecs.requirements.has import has

solid = has("radius", "solid")
destructor_ = has("clocks_destruction_list")


def stop_collisions(self, other, destructor):
    if self is other or not self.solid or not other.solid:
        return

    delta = other.position - self.position
    d = self.radius + other.radius
    if delta.x <= d \
            and delta.y <= d \
            and delta.squared_magnitude() <= d ** 2 \
            and self.velocity.scalar_project(delta) > other.velocity.scalar_project(delta):
        m1 = self.system_mass if hasattr(self, "system_mass") else self.mass if hasattr(self, "mass") else 0
        m2 = other.system_mass if hasattr(other, "system_mass") else other.mass if hasattr(other, "mass") else 0
        k = (1 + (self.resilience_k + other.resilience_k) / 2) / (m1 + m2)

        v1 = self.velocity.project(delta)
        v2 = other.velocity.project(delta)

        # result_velocity = (m * self.velocity + M * other.velocity) / (m + M)
        # self.velocity ==
        #
        # e_before = self.mass * self.velocity ** 2 / 2 + other.mass * other.velocity ** 2 / 2
        # e_after = (self.mass + other.mass) * result_velocity ** 2 / 2
        #
        # de = (e_before - e_after) / 2
        # print(f'energy is {de}')
Exemple #16
0
from src.ecs.requirements.has import has
from src.tools import vector


def shoot(gun, creator):
    if gun.shooting_enabled:
        gun.shooting_enabled = False

        bullet = gun.bullet_constructor()
        dv = gun.shooting_velocity * vector.right.rotated(gun.rotation)
        creator.clocks_creation_list.append(bullet.set(
            position=gun.position + gun.shooting_offset.rotated(gun.rotation),
            velocity=gun.velocity + dv,
            rotation=gun.rotation,
        ))

        gun.velocity -= bullet.mass * dv / gun.mass


shooting = (
    ("gun" | has("shooting_enabled")) * ("creator" | has("clocks_creation_list")) >> shoot,
)
Exemple #17
0
from src.ecs.requirements.has import has

fps_monitor = (("label" | has("update_fps")) >>
               (lambda label: label.update_fps()), )
Exemple #18
0
from src.ecs.clocks import delta_time
from src.ecs.requirements.has import has

movable = "movable" | has("velocity") & has("position")


def apply_velocity(movable):
    movable.position += movable.velocity * delta_time()


inertia = (movable >> apply_velocity, )