예제 #1
0
 def handle_orientation_update(self, delta_angle: float):
     orientation = self.transform.viewing_direction
     rorientation = orientation.to_angle() % (pi * 2.0)
     aorientation = elisa.linalg.rad_to_angle(rorientation)
     s_angle = 1.0 if delta_angle >= 0 else -1.0
     aorientation = aorientation + s_angle * elisa.linalg.rad_to_angle(
         abs(delta_angle)
     )
     aorientation = aorientation % 360.0
     orientation = elisa.linalg.angle_to_rad(aorientation)
     self.transform.viewing_direction = Vec2.from_angle(orientation)
예제 #2
0
    def update(self, time_delta, entities):
        if len(entities) < 1:
            return None

        pvis = [e for e in entities if e.has_component_type("Collidable")]

        # for now we just render everyone having a position component
        # and do not care about the projection from world space coordinates to camera space
        renderables = [
            e
            for e in entities
            if e.has_component_type("Renderable") and e.has_component_type("Transform2")
        ]

        # clear the backbuffer
        self.clear_back_buffer()

        for e in renderables:
            # get the position of the renderable and draw it - for now we assume that there is only one
            pos = e.get_of_type("Transform2").position
            rx = e.get_of_type("Renderable")
            col = rx.color

            if rx.shape == Shape.Point:
                pygame.draw.circle(
                    self.back_buffer, col, (int(pos.x), int(pos.y)), 5, 0
                )
            elif rx.shape == Shape.Square:
                pygame.draw.rect(
                    self.back_buffer,
                    SRender.C_DARK_GRAY,
                    (pos.x, pos.y, rx.width, rx.width),
                    1,
                )
            else:
                pass

        fov_entity = [
            e
            for e in entities
            if e.has_component_type("FieldOfView")
            and e.has_component_type("Transform2")
        ]

        if fov_entity:
            for e in fov_entity:
                transform = e.get_of_type("Transform2")
                fov = e.get_of_type("FieldOfView")

                pos, dvec = transform.position, transform.viewing_direction
                view_dist = fov.distance
                dvec_alpha = dvec.to_angle()
                fov_angle = fov.angle
                falpha1, falpha2 = (dvec_alpha - fov_angle / 2.0) % (
                    2.0 * pi
                ), dvec_alpha + fov_angle / 2.0 % (2.0 * pi)
                N_sample = int(elisa.linalg.rad_to_angle(fov_angle))
                v1 = Vec2.from_angle(falpha1) * view_dist
                v2 = Vec2.from_angle(falpha2) * view_dist
                dv = (v2 - v1) / N_sample
                pdvi = v1

                pv1, pv2 = pos + v1, pos + v2
                pygame.draw.polygon(
                    self.back_buffer,
                    SRender.C_VDARK_GRAY,
                    [(pos.x, pos.y), (pv1.x, pv1.y), (pv2.x, pv2.y)],
                    0,
                )

                for i in range(N_sample):
                    # perform the collision test
                    ppvi = pos + pdvi
                    pdvi = pdvi + dv
                    rayi = Ray2(origin=pos, direction=pdvi)
                    for vis in pvis:
                        visplanes = vis.get_of_type("Collidable").planes
                        vpos = vis.get_of_type("Transform2").position
                        vrx = vis.get_of_type("Renderable")

                        intersects = False
                        for planei in visplanes:
                            r, t, _ip = elisa.linalg.intersection2(rayi, planei)
                            if (
                                r
                                and 0 <= t <= pdvi.length
                                and elisa.linalg.inside_square2(
                                    vpos.x, vpos.y, vrx.width, _ip
                                )
                            ):
                                intersects = True
                                break

                        if intersects:
                            pygame.draw.line(
                                self.back_buffer,
                                SRender.C_GRAY,
                                (pos.x, pos.y),
                                (ppvi.x, ppvi.y),
                                1,
                            )
                            pygame.draw.rect(
                                self.back_buffer,
                                SRender.C_WHITE,
                                (vpos.x, vpos.y, vrx.width, vrx.width),
                                1,
                            )

                pygame.draw.circle(
                    self.back_buffer,
                    SRender.C_DARK_GRAY,
                    (int(pos.x), int(pos.y)),
                    int(view_dist),
                    1,
                )

        self.screen_buffer.blit(self.back_buffer, (0, 0))
        pygame.display.flip()

        return None