def initialize(): # noinspection PyProtectedMember from api.sax_engine._examples.example_tile_grid import tile_map # tile_map = list(zip(*tile_map)) # t_wall = Tile("Wall", {"color": C_L_GRAY}) # t_air = Tile("Air", {}) scene0 = scene_system.SceneObject(name="scene0", tile_grid=tile_map) # import and create debug related stuff from prefabs.debug import FpsOverlay scene_system.add_content_to_scene(scene0, FpsOverlay(Vector2(5, 5), (255, 0, 0))) from prefabs.debug import CameraMarker scene_system.add_content_to_scene(scene0, CameraMarker()) from prefabs.background import TileGridRenderer tgr = TileGridRenderer() scene_system.add_content_to_scene(scene0, tgr) map_mid = v_mul(grid_size(tile_map), (0.5, 0.5)) # import and create player from game.actors.player.player import Player from game.actors.pre_alpha_tier.pre_alpha_tier import PreAlphaTier for _ in range(0, 20, 4): pos = Point(*v_add(map_mid, (_, 0))) tier = PreAlphaTier(position=pos) scene_system.add_content_to_scene(scene0, tier) from api.sax_engine.core.systems.graphics.camera import Camera render_targets = list(graphics_system.get_camera_setup(0)) player0 = Player(position=Point(*v_add(map_mid, (0, 0))), n=0) scene_system.add_content_to_scene(scene0, player0) camera0 = Camera(Point(*map_mid), "camera 0", render_targets[0], pixels_per_tile=32, follow_target=player0, grid_locks_view=True) scene_system.add_content_to_scene(scene0, camera0) # player1 = Player(position=Point(*v_add(map_mid, (0, 0))), n=1) # scene_system.add_content_to_scene(scene0, player1) # camera1 = Camera(Point(*map_mid), "camera 1", render_targets[1], # pixels_per_tile=32, # follow_target=player1, # grid_locks_view=True) # scene_system.add_content_to_scene(scene0, camera1) # from prefabs.utilities import TextContent # scene_system.add_content_to_scene(scene0, TextContent(Point(*map_mid), "Fun with physics!")) # scene_system.add_content_to_scene(scene0, TextContent(Point(55, 0), "Rock bottom!")) scene_system.change_active_scene(scene0)
def update(self, g: Vector2 = Vector2(-1, -1)) -> None: self.target.contact_points.clear() bounding_box = Rectangle(self.target.position, self.target.size) self.velocity = Vector2(*v_add(self.velocity, v_mul(g, self.target.scene.delta_time))) h_trans, v_trans = translation = v_mul(self.velocity, self.target.scene.delta_time) h_rays, v_rays = bounding_box.directional_projection(v_norm(translation), v_len(translation)) all_hits = static_ray_hits(self.target.scene.tile_grid, *h_rays) closest_hit = next(sorted(all_hits, key=lambda h: h.distance), default=None) h_absorb = bool(closest_hit) if h_absorb: # select closest hit distance and correct it to align with tile h_trans = closest_hit.ray.dir.x * closest_hit.distance + alignment_correction(closest_hit.point.x, closest_hit.ray.dir.x) all_hits = static_ray_hits(self.target.scene.tile_grid, *v_rays) closest_hit = next(list(sorted(all_hits, key=lambda h: h.distance)), default=None) v_absorb = bool(closest_hit) if v_absorb: self.target.contact_points.extend((hit.ray.pos for hit in closest_hit)) v_trans = closest_hit.ray.dir.y * closest_hit.distance + alignment_correction(closest_hit.point.y, closest_hit.ray.dir.y) self.target.position = Point(*v_add(self.target.position, (h_trans, v_trans))) # todo observer for absorbing velocity h_vel, v_vel = self.velocity if h_absorb: h_vel = -h_vel if v_absorb: v_vel = -v_vel self.velocity = Vector2(h_vel, v_vel)
def __init__(self, offset: Vector2 = Vector2(5, 5), color: RGB = C_SOMETHING, size: int = 16) -> None: super().__init__(Point(0, 0)) self.size = size self.offset = offset self.color = color
def project(self, point: Point, view_offset: Vector2 = Vector2(0, 0)) -> Point: view_origin = self.view_origin(view_offset) x, y = v_mul(v_sub(point, view_origin), self.pixels_per_tile) if self.inverse_h: x = self.dimension[0] - x if self.inverse_v: y = self.dimension[1] - y return Point(x, y)
def test_rect2ray(self): b = Rectangle(Point(0, 0), Vector2(2, 2)) r1 = create_ray(Point(-1, -1), Vector2(1, 1)) self.assertTrue(b.intersect(r1)) r2 = create_ray(Point(1, 1), Vector2(3, 3)) self.assertTrue(b.intersect(r2)) r3 = create_ray(Point(0, 0), Vector2(2, 2)) self.assertTrue(b.intersect(r3)) r4 = create_ray(Point(-1, -1), Vector2(3, 3)) self.assertTrue(b.intersect(r4)) r5 = create_ray(Point(-1, 0), Vector2(1, 0), 0.99) self.assertFalse(b.intersect(r5)) r6 = create_ray(Point(3, 0), Vector2(-1, 0), 0.99) self.assertFalse(b.intersect(r6)) r7 = create_ray(Point(-1, 1), Vector2(0, -1)) self.assertFalse(b.intersect(r7)) r8 = create_ray(Point(-1, 1), Vector2(1, -1)) self.assertTrue(b.intersect(r8)) r9 = create_ray(Point(-1, 1), Vector2(2, -1)) self.assertTrue(b.intersect(r9))
def __init__(self, n=0, position=Point(0, 0)): super().__init__(position) self.number = n # data self.physics_data: PhysicsData = PhysicsData() self.shared_data: SharedData = SharedData() self.graphics_data: GraphicsData = GraphicsData() # events self.event_stream = EventStream(verbose=False) # state from .components.state.states import create_states self.state_machine = StateMachine(*create_states(self))
def test_rect2circle(self): b = Rectangle(Point(0, 0), Vector2(2, 2)) c1 = Circle(Point(1, 1), 1) self.assertTrue(b.intersect(c1)) c2 = Circle(Point(1, 1), 5) self.assertTrue(b.intersect(c2)) c3 = Circle(Point(0, 0), 1) self.assertTrue(b.intersect(c3)) c4 = Circle(Point(-1, 1), 1) self.assertTrue(b.intersect(c4)) c5 = Circle(Point(-1, 1), 0.99) self.assertFalse(b.intersect(c5)) c6 = Circle(Point(3, 3), math.sqrt(2)) self.assertTrue(b.intersect(c6)) c7 = Circle(Point(3.01, 3.01), math.sqrt(2)) self.assertFalse(b.intersect(c7))
def test_rect2rect(self): b = Rectangle(Point(0, 0), Vector2(2, 2)) self.assertTrue(b.intersect(b)) b1 = Rectangle(Point(1, 1), Vector2(2, 2)) self.assertTrue(b.intersect(b1)) b2 = Rectangle(Point(2, 2), Vector2(2, 2)) self.assertTrue(b.intersect(b2)) b3 = Rectangle(Point(2.1, 2.1), Vector2(2, 2)) self.assertFalse(b.intersect(b3)) b4 = Rectangle(Point(1, 1), Vector2(-2, -2)) self.assertTrue(b.intersect(b4)) b5 = Rectangle(Point(2, 2), Vector2(-2, -2)) self.assertTrue(b.intersect(b5)) b6 = Rectangle(Point(0, 0), Vector2(-2, -2)) self.assertTrue(b.intersect(b6)) b7 = Rectangle(Point(-.1, -.1), Vector2(-2, -2)) self.assertFalse(b.intersect(b7))
def on_enter(id_: StateId): from api.sax_engine.vector import Vector2 x, _ = player.physics_data.velocity player.physics_data.velocity = Vector2(x, player.physics_data.JUMP_VELOCITY) player.shared_data.jumps_left -= 1 if id_ == StateId.on_ground: from api.sax_engine.core import add_content_to_scene from prefabs.debug import PointMarker from api.sax_engine.geometry import Point if player.physics_data.absorb.x < 0: p = player.position else: x, y = player.position p = Point(x + player.physics_data.size, y) add_content_to_scene(player.scene, PointMarker(p, (255, 0, 0), 5))
def test_rect2point(self): b = Rectangle(Point(0, 0), Vector2(2, 2)) p1 = Point(1, 1) self.assertTrue(b.intersect(p1)) p2 = Point(0, 0) self.assertTrue(b.intersect(p2)) p3 = Point(2, 2) self.assertTrue(b.intersect(p3)) p4 = Point(-.1, 1) self.assertFalse(b.intersect(p4)) p5 = Point(3, 1) self.assertFalse(b.intersect(p5))
def __init__(self, color: RGB = (0, 0, 0)) -> None: super().__init__(Point(0, 0)) self.color = color
def setUp(self): self.scene0 = core.SceneObject() self.scene1 = core.SceneObject() self.content0 = TestContentEntity(Point(0, 0)) self.content1 = TestContentEntity(Point(0, 0))
from .example_tile_grid import tile_map scene0 = scene_system.SceneObject(name="scene0", tile_grid=tile_map) from prefabs.debug import FpsOverlay scene_system.add_content_to_scene(scene0, FpsOverlay(Vector2(5, 5), (255, 0, 0))) from prefabs.debug import CameraMarker scene_system.add_content_to_scene(scene0, CameraMarker()) from prefabs.background import TileGridRenderer tgr = TileGridRenderer() scene_system.add_content_to_scene(scene0, tgr) map_mid = v_mul(grid_size(tile_map), (0.5, 0.5)) from .example_content import ExampleContentEntity content0 = ExampleContentEntity(position=Point(*v_add(map_mid, (0, 0)))) scene_system.add_content_to_scene(scene0, content0) from api.sax_engine.core.systems.graphics.camera import Camera camera0 = Camera(Point(*map_mid), "camera 0", next(graphics_system.get_camera_setup()), pixels_per_tile=16, follow_target=content0, grid_locks_view=True) scene_system.add_content_to_scene(scene0, camera0) from prefabs.utilities import Text scene_system.add_content_to_scene(scene0, Text(Point(*map_mid), "Fun with physics!")) scene_system.add_content_to_scene(scene0, Text(Point(55, 0), "Rock bottom!")) scene_system.change_active_scene(scene0)
def __init__(self, position=Point(0, 0)): self.scene: SceneObject = None self._tags: Set[str] = set() self.position: Point = position
def __init__(self, position=Point(0, 0)): super().__init__(position)
def view_rectangle(self, view_offset: Vector2 = (0, 0)) -> Rectangle: return Rectangle(Point(*v_add(self.anchor, view_offset)), Vector2(*self.view_dimension()))
def view_origin(self, view_offset: Vector2 = Vector2(0, 0)) -> Point: return Point(*v_add(self.anchor, view_offset))
def update(self) -> None: g: Vector2 = Vector2( *v_mul((0, -1), self.target.physics_data.GRAVITY_MODIFIER)) tile_grid = self.target.scene.tile_grid physics_data = self.target.physics_data delta_time = self.target.scene.delta_time bounding_box = Rectangle(self.target.position, physics_data.size) # calculate new velocity from acceleration physics_data.velocity = Vector2( *v_add(physics_data.velocity, v_mul(g, delta_time))) # calculate position change from velocity h_trans, v_trans = v_mul(physics_data.velocity, delta_time) # prepare static collision with bounding_box h_rays = bounding_box.directional_projection(h_trans, horizontal=True) # get all ray hits all_hits = (multi_ray_cast(tile_grid, blocked_tiles, *h_rays, only_hits=True)) # try to select closest hit closest_hit = next(iter(sorted(all_hits, key=lambda h: h.distance)), None) # if there is any hit h_absorb = bool(closest_hit) if h_absorb: # correct horizontal translation and align it with tile correction = alignment_correction(closest_hit.point.x, closest_hit.ray.dir.x) h_trans = closest_hit.ray.dir.x * closest_hit.distance + correction v_rays = tuple( bounding_box.directional_projection(v_trans, horizontal=False)) all_hits = tuple( multi_ray_cast(tile_grid, blocked_tiles, *v_rays, only_hits=True)) closest_hit = next(iter(sorted(all_hits, key=lambda h: h.distance)), None) v_absorb = bool(closest_hit) if v_absorb: correction = alignment_correction(closest_hit.point.y, closest_hit.ray.dir.y) v_trans = closest_hit.ray.dir.y * closest_hit.distance + correction if v_trans < 0 and all_hits and (all_hits[0].ray != v_rays[0] or all_hits[-1].ray != v_rays[-1]): self.target.push_event(EventId.watch_out) # grid debugging # ---------------------------------------------------- # from api.sax_engine.core import add_content_to_scene # from prefabs.debug import PointMarker # min_x, min_y = bounding_box.min().to_int() # max_x, max_y = bounding_box.max().to_int() # for x in range(min_x, max_x + 1): # for y in range(min_y, max_y + 1): # p = Point(*v_add((x, y), (0.5, 0.5))) # add_content_to_scene(self.target.scene, PointMarker(p, (255, 0, 0), self.target.scene.delta_time)) # ---------------------------------------------------- # set new position remove_shape_from_grid(tile_grid, bounding_box, self.target) self.target.position = Point( *v_add(self.target.position, (h_trans, v_trans))) register_shape_on_grid(tile_grid, bounding_box, self.target) # adjust velocity based on collision data h_vel, v_vel = physics_data.velocity if h_absorb: self.target.push_event(EventId.touch_wall, orientation=h_absorb) h_vel = 0 if v_absorb: if v_vel < 0: self.target.push_event(EventId.touch_floor) else: self.target.push_event(EventId.touch_ceiling) v_vel = 0 physics_data.velocity = Vector2(h_vel, v_vel)
def in_view(self, point: Point, view_offset: Vector2 = (0, 0)) -> bool: return Rectangle(Point(0, 0), Vector2(*self.dimension)).intersect(self.project(point, view_offset))
from api.sax_engine.events import yield_api_events from .example_content import * from time import sleep # create a screen and some render targets for the cameras graphics.init_display(full_screen=True) render_target = next(graphics.get_camera_setup(n_split=0)) # create scenes scene0: scene.SceneObject = scene.SceneObject() scene1: scene.SceneObject = scene.SceneObject() # create content test_content0 = ExampleContentEntity(position=Point(0, 0)) test_content1 = ExampleContentEntity(position=Point(1, 1)) # add a camera to scene0 from api.sax_engine.core.systems.graphics.camera import Camera scene.add_content_to_scene(scene0, Camera(Point(0, 0), "Main camera", render_target)) # add a background clear to scene1 from prefabs.background import PlainBackground scene.add_content_to_scene(scene1, PlainBackground((0, 0, 0))) # add camera markers to both scenes from prefabs.debug import CameraMarker scene.add_content_to_scene(scene0, CameraMarker()) scene.add_content_to_scene(scene1, CameraMarker())
def __init__(self) -> None: super().__init__(Point(0, 0)) self.size = 16 self.offset_row1 = (5, -(5 + self.size) * 2) self.offset_row2 = (5, -(5 + self.size)) self.colors = [C_RED, C_YELLOW, C_GREEN, C_BLUE]
graphics.init_display(full_screen=True) from .example_tile_grid import tile_map scene0 = core.SceneObject(name="scene0", tile_grid=tile_map) from prefabs.debug import FpsOverlay core.add_content_to_scene(scene0, FpsOverlay(Vector2(5, 5), (255, 0, 0))) from prefabs.debug import CameraMarker core.add_content_to_scene(scene0, CameraMarker()) tgr = TileGridRenderer() core.add_content_to_scene(scene0, tgr) map_mid = Point(*v_mul(tgr.grid_size(), (0.5, 0.5))) content0 = ExampleContentEntity(position=Point(*v_add(map_mid, (0, 0)))) content1 = ExampleContentEntity(position=Point(*v_add(map_mid, (1, 1)))) content2 = ExampleContentEntity(position=Point(*v_add(map_mid, (1, 0)))) content3 = ExampleContentEntity(position=Point(*v_add(map_mid, (0, 1)))) core.change_active_scene(scene0) core.add_content_to_scene(scene0, content0) core.add_content_to_scene(scene0, content1) test_ppt = (32, 16) for n, r in enumerate(graphics.get_camera_setup(1)): c = Camera(map_mid, "camera {}".format(n), r, pixels_per_tile=test_ppt[n]) core.add_content_to_scene(scene0, c)