def test_remove_aspect_from_entity(world): aspect = Aspect([Component_A]) entity = world.create_entity(*aspect()) world._flush_component_updates() assert aspect.in_entity(entity) components = aspect.remove(entity) world._flush_component_updates() assert not aspect.in_entity(entity) assert Component_A not in entity assert len(components) == 1 assert isinstance(components[0], Component_A)
def test_create_with_override_for_missing_component(): with pytest.raises(ValueError): Aspect( [Component_A], overrides={ Component_B: dict(i=1), }, )
def test_create_with_overrides_on_aspect(): aspect = Aspect( [Component_A], overrides={ Component_A: dict(i=1), }, ) [component] = aspect() assert component.i == 1
def test_create_aspect_with_factory_function_defaults(world): class Foo: pass aspect = Aspect( [Component_A], overrides={ Component_A: dict(i=factory(lambda: 1)), }, ) [a] = aspect() assert a.i == 1
def test_aspect_from_multiple_components_different_dicts(): aspect = Aspect([Component_A, Component_B]) assert Component_A in aspect assert Component_B in aspect
panda3d.Floating, # Scale by speed for floating panda3d.Walking, # Scale by speed for walk / run / crouch / sprint panda3d.Inertiing, # Clamp movement speed delta by inertia panda3d.Bumping, # Bump into things (and out again). panda3d.Falling, # Fall, or stand on the ground. panda3d.Jumping, # Impart upward impulse. panda3d.ExecuteMovement, # Turn intention into actual movement # We're done with character movement, now adjust the cameras. panda3d.UpdateCameras, panda3d.CollideCamerasWithTerrain, ] game_map = Aspect( [panda3d.Position, panda3d.Model, panda3d.Scene, Map], overrides={ panda3d.Position: dict(value=factory(lambda: Point3(0, 0, 0))), panda3d.Model: dict(model_name='roadE.bam'), panda3d.Scene: dict(node=base.render), }, ) # Populate the world with the map, the player character, and a few NPCs # Map game_map.add(base.ecs_world.create_entity()) # Player player_avatar = Aspect([aspects.player_character, mechanics.Stamina]) player_avatar.add( base.ecs_world.create_entity(), overrides={panda3d.Position: dict(value=Point3(50, 290, 0))}, )
def test_aspect_from_multiple_aspects(): aspect_1 = Aspect([Component_A]) aspect_2 = Aspect([Component_B]) aspect_3 = Aspect([aspect_1, aspect_2]) assert Component_A in aspect_3 assert Component_B in aspect_3
wecs.panda3d.animation.AnimateCharacter, wecs.panda3d.animation.Animate, # Camera wecs.panda3d.camera.ReorientObjectCentricCamera, wecs.panda3d.camera.CollideCamerasWithTerrain, # Debug keys (`escape` to close, etc.) wecs.panda3d.debug.DebugTools, ] game_map = Aspect( [ wecs.panda3d.prototype.Model, wecs.panda3d.prototype.Geometry, wecs.panda3d.prototype.CollidableGeometry, wecs.panda3d.mouseover.MouseOverableGeometry, wecs.panda3d.mouseover.Pointable, wecs.panda3d.spawnpoints.SpawnMap, ], overrides={ wecs.panda3d.prototype.CollidableGeometry: dict(mask=FALLING_MASK | BUMPING_MASK | CAMERA_MASK, ), }, ) # There are characters, which are points in space that can be moved # around using the `CharacterController`, using either player input or # AI control. # They are spawned at one of the map's spawn points. character = Aspect( [ wecs.mechanics.clock.Clock,
wecs.panda3d.character.Walking, wecs.panda3d.character.Bumping(proxies=cn_proxy), wecs.panda3d.character.Falling(proxies=cn_proxy), wecs.panda3d.character.ExecuteMovement(proxies=cn_proxy), wecs.panda3d.camera.ReorientObjectCentricCamera, ] # Map game_map = Aspect( [ wecs.panda3d.prototype.Model, wecs.panda3d.prototype.Geometry, wecs.panda3d.prototype.CollidableGeometry, wecs.panda3d.prototype.FlattenStrong, ], overrides={ wecs.panda3d.prototype.Geometry: dict(file='roadE.bam'), wecs.panda3d.prototype.CollidableGeometry: dict(mask=FALLING_MASK | BUMPING_MASK, ), }, ) map_entity = base.ecs_world.create_entity(name="Level geometry") game_map.add(map_entity) # Player character = Aspect( [ wecs.mechanics.clock.Clock,
panda3d.ExecuteMovement, # Turn intention into actual movement. panda3d.AnimateCharacter, panda3d.Animate, # We're done with character movement, now update the cameras and console. panda3d.UpdateCameras, # panda3d.CollideCamerasWithTerrain, cefconsole.UpdateWecsSubconsole, cefconsole.WatchEntitiesInSubconsole, ] # Aspects are basically classes for entities. Here are two that we will use. game_map = Aspect( [ panda3d.Position, panda3d.Model, panda3d.Scene, panda3d.CollidableGeometry, panda3d.FlattenStrong, cefconsole.WatchedEntity, ], overrides={ panda3d.Model: dict(model_name='grid.bam'), panda3d.Scene: dict(node=base.render), }, ) lab_character = Aspect([aspects.player_character, cefconsole.WatchedEntity]) # Create entities game_map.add(base.ecs_world.create_entity()) lab_character.add(base.ecs_world.create_entity(name="Rebecca"))
from wecs.panda3d.constants import CAMERA_MASK import behaviors from avatar_ui import Embodiable # Map game_map = Aspect( [ wecs.panda3d.prototype.Model, wecs.panda3d.prototype.Geometry, wecs.panda3d.prototype.CollidableGeometry, wecs.panda3d.prototype.FlattenStrong, wecs.panda3d.mouseover.MouseOverableGeometry, wecs.panda3d.mouseover.Pointable, ], overrides={ wecs.panda3d.prototype.Geometry: dict(file='../../assets/roadE.bam', ), wecs.panda3d.prototype.CollidableGeometry: dict(mask=FALLING_MASK | BUMPING_MASK | CAMERA_MASK, ), }, ) map_entity = base.ecs_world.create_entity(name="Level geometry") game_map.add(map_entity) # There are characters, which are points in space that can be moved # around using the `CharacterController`, using either player input or # AI control.
def test_aspect_from_mixed_args(): aspect_1 = Aspect([Component_A]) aspect_2 = Aspect([Component_B, aspect_1]) assert Component_A in aspect_2 assert Component_B in aspect_2
def test_clashing_aspects(): aspect_1 = Aspect([Component_A, Component_B]) aspect_2 = Aspect([Component_B]) with pytest.raises(ValueError): aspect_3 = Aspect([aspect_1, aspect_2])
def test_aspect_not_in_entity(world): entity = world.create_entity() aspect = Aspect([Component_A]) assert not aspect.in_entity(entity)
def test_aspect_in_entity(world): aspect = Aspect([Component_A]) entity = world.create_entity() aspect.add(entity) world._flush_component_updates() assert aspect.in_entity(entity)
def test_adding_clashing_aspect_to_entity(world): aspect = Aspect([Component_A]) entity = world.create_entity(Component_A()) with pytest.raises(KeyError): aspect.add(entity)
def test_adding_aspect_to_entity(world): aspect = Aspect([Component_A]) entity = world.create_entity() aspect.add(entity) world._flush_component_updates() assert Component_A in entity
def test_create_with_overrides_on_creation(): aspect = Aspect([Component_A]) [component] = aspect(overrides={Component_A: dict(i=1)}) assert component.i == 1
def test_clashing_args(): with pytest.raises(ValueError): aspect = Aspect([Component_A, Component_A])
def test_remove_aspect_from_entity_that_does_not_have_it(world): aspect = Aspect([Component_A]) entity = world.create_entity() with pytest.raises(ValueError): aspect.remove(entity)
def test_create_components(): aspect = Aspect([Component_A]) [components_a] = aspect() [components_b] = [Component_A()] assert components_a.i == components_b.i
def test_name(): aspect = Aspect([], name="foo") assert repr(aspect) == "foo"
# `npc_mind` is a mind that executes a constant movement # * Things that see the world # `first_person` is a first person camera # `third_person` is, unsurprisingly, a third person camera (with a few features). # * Abstractions that are actually useful # The `player_character` is an `avatar` controlled by a `pc_mind` and seen through # the `third_person` camera. # A `non_player_character` is an `avatar` controlled by an `npc_mind` # A `game_map` is a model that you can bump / fall into. character = Aspect( [ mechanics.Clock, panda3d.Position, panda3d.Scene, panda3d.CharacterController, panda3d.Model, ], overrides={ mechanics.Clock: dict(clock=panda3d.panda_clock), }, ) def rebecca_bumper(): return { 'bumper': dict( shape=CollisionSphere, center=Vec3(0.0, 0.0, 1.0), radius=0.7, ),
def test_no_name(): aspect = Aspect([]) assert repr(aspect).startswith("<")
class Cursoring(System): entity_filters = { 'cursor': and_filter([CursorMovement, CharacterController, Model]), } def update(self, entities_by_filter): for entity in entities_by_filter['cursor']: cursor = entity[CursorMovement] model = entity[Model] char = entity[CharacterController] char.translation *= cursor.move_speed char.rotation *= cursor.rot_speed char.rotation[1] = 0 if cursor.snapping: if char.move.x == 0 and char.move.y == 0 and char.move.z == 0: if char.heading == 0: np = model.node np.set_pos(snap_vector(np.get_pos(), cursor.move_snap)) np.set_hpr(snap_vector(np.get_hpr(), cursor.rot_snap)) cursor = Aspect( [ aspects.character, wp3d.Input, CursorMovement, #wp3d.camera.ThirdPersonCamera, #wp3d.camera.TurntableCamera, Creator, ], )
def test_aspect_from_components(): aspect = Aspect([Component_A]) assert Component_A in aspect
# An `avatar` is a character that can walk. # A `spectator` is a character that floats and bumps into the map. # * Things that control beings # `pc_mind` represents the input from the neural network between the player's ears. # `npc_mind` is a mind that executes a constant movement # * Things that see the world # `first_person` is a first person camera # `third_person` is, unsurprisingly, a third person camera (with a few features). # * Abstractions that are actually useful # The `player_character` is an `avatar` controlled by a `pc_mind` and seen through # the `third_person` camera. # A `non_player_character` is an `avatar` controlled by an `npc_mind` # A `game_map` is a model that you can bump / fall into. character = Aspect([ panda3d.Clock, panda3d.Position, panda3d.Scene, panda3d.CharacterController, panda3d.Model ]) def rebecca_bumper(): return { 'bumper': dict( shape=CollisionSphere, center=Vec3(0.0, 0.0, 1.0), radius=0.7, ), } def rebecca_lifter():
def test_aspect_from_aspect(): aspect_1 = Aspect([Component_A]) aspect_2 = Aspect([aspect_1]) assert Component_A in aspect_2
panda3d.UpdateBillboards, cefconsole.UpdateWecsSubconsole, cefconsole.WatchEntitiesInSubconsole, debug.DebugTools, ] # Aspects are basically classes for entities. Here are two that we will use. game_map = Aspect( [mechanics.Clock, panda3d.Position, panda3d.Model, panda3d.Geometry, panda3d.Scene, panda3d.CollidableGeometry, panda3d.FlattenStrong, ], overrides={ mechanics.Clock: dict(clock=panda3d.panda_clock), panda3d.Geometry: dict(file='roadE.bam'), panda3d.Scene: dict(node=base.render), }, ) # Populate the world with the map, the player character, and a few NPCs # Map map_entity = base.ecs_world.create_entity(name="Level geometry") game_map.add(map_entity)
wecs.panda3d.camera.PrepareCameras, # Interface interactions wecs.panda3d.mouseover.MouseOverOnEntity, wecs.panda3d.mouseover.UpdateMouseOverUI, Take, DisplayInventory, # Debug keys (`escape` to close, etc.) wecs.panda3d.debug.DebugTools, ] scenery = Aspect( [ wecs.panda3d.prototype.Model, wecs.panda3d.prototype.Geometry, wecs.panda3d.mouseover.MouseOverableGeometry, wecs.panda3d.mouseover.Targetable, Takeable, ], ) scenery.add( base.ecs_world.create_entity(name="Ball 1"), overrides={ wecs.panda3d.prototype.Model: dict( post_attach=lambda: wecs.panda3d.prototype.transform( pos=Vec3(-1, 0, 1), ), ), wecs.panda3d.prototype.Geometry: dict(file='models/smiley'),