def __init__(self):
super().__init__()
# background
self.background = pygame.sprite.Sprite()
self.background.rect = pygame.Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)
self.background.image = pygame.image.load(os.path.join('img', 'menu.png'))
self.background.rect = self.background.image.get_rect()
self.spritesBackGround.add(self.background)
boxWidth = 0.55 * SCREEN_WIDTH
self.createControlBox(SCREEN_WIDTH/2-boxWidth/2, 3*SCREEN_HEIGHT / 7, boxWidth,3 * SCREEN_HEIGHT / 7)
buttonWidth = 0.55 * SCREEN_WIDTH-100
self.backToTitleScreenButton = Button((SCREEN_WIDTH/2-buttonWidth/2, 17 * SCREEN_HEIGHT / 20+20), (buttonWidth, 50), 'Back to main menu',
self.goToTitleScreen)
self.spritesHUD.add(self.backToTitleScreenButton)
self.notifyGroup.add(self.backToTitleScreenButton)
self.chargePad = ColaCan(150, 40, self)
self.spritesHUD.add(self.chargePad)
self.musicName = "TitleScreen.wav"
python类Rect()的实例源码
def __init__(self, shooter):
"""
:param Sprite shooter: the shooter that shoots this Arrow object
"""
# init our recyclable SpriteSheet
if not self.sprite_sheet:
self.sprite_sheet = spyg.SpriteSheet("data/baleog.tsx")
super().__init__(16, 16, self.sprite_sheet, {
"default": "fly", # the default animation to play
"fly": {"frames": [158, 159, 160, 161], "rate": 1 / 10},
}, shooter, anim_settings_name="arrow", width_height=(16, 5), image_rect=pygame.Rect(-8, -13, 32, 32))
self.type = spyg.Sprite.get_type("arrow,particle")
self.collision_mask = spyg.Sprite.get_type("default,enemy,friendly,coconut")
# simple physics, no extra component needed for that
self.ax = -10
self.ay = 40
self.vx = 300
self.vy = -5
def __init__(self, layer, pytmx_tiled_map, id_, tile_props, rect):
"""
:param TiledTileLayer layer: the TiledTileLayer object to which this tile belongs
:param pytmx.pytmx.TiledMap pytmx_tiled_map: the tmx tiled-map object to which this tile belongs
(useful to have to look up certain map-side properties, e.g. tilewidth/height)
:param int id_: tthe ID of the tile in the layer
:param dict tile_props: the properties dict of this tile (values already translated into python types)
:param Union[pygame.Rect,None] rect: the pygame.Rect representing the position and size of the tile
"""
super().__init__(rect.x, rect.y, width_height=(rect.width, rect.height))
self.tiled_tile_layer = layer
self.pytmx_tiled_map = pytmx_tiled_map
self.tile = id_
self.tile_x = self.rect.x // self.pytmx_tiled_map.tilewidth
self.tile_y = self.rect.y // self.pytmx_tiled_map.tileheight
self.tile_props = tile_props
# add the `dockable` type to all tiles
self.type |= Sprite.get_type("dockable")
def __init__(self, layer, pytmx_tiled_map, id_, tile_props, rect):
"""
:param TiledTileLayer layer: the TiledTileLayer object to which this tile belongs
:param pytmx.pytmx.TiledMap pytmx_tiled_map: the tmx tiled-map object to which this tile belongs
(useful to have to look up certain map-side properties, e.g. tilewidth/height)
:param int id_: tthe ID of the tile in the layer
:param dict tile_props: the properties dict of this tile (values already translated into python types)
:param Union[pygame.Rect,None] rect: the pygame.Rect representing the position and size of the tile
"""
super().__init__(layer, pytmx_tiled_map, id_, tile_props, rect)
# slope properties of the tile
self.slope = tile_props.get("slope", None) # the slope property of the tile in the tmx file (inverse steepness (1/m in y=mx+b) of the line that defines the slope)
self.offset = tile_props.get("offset", None) # the offset property of the tile in the tmx file (in px (b in y=mx+b))
self.is_full = (self.slope == 0.0 and self.offset == 1.0) # is this a full collision tile?
self.max_x = self.pytmx_tiled_map.tilewidth
self.max_y = max(self.get_y(0), self.get_y(self.rect.width)) # store our highest y-value (height of this tile)
def updateGeneralScreen( self ):
gui.draw.rect(self.screen, self.lg, gui.rect.Rect( 480, 420, 300, 10 ), 1 )
self.progress = self.time.getIntvProgress( )
gui.draw.rect( self.screen, self.lg, gui.rect.Rect( 480, 420, min( 300, 300*self.progress ), 10 ) )
label = self.fontRegular.render( 'Speed', 2, self.lg )
self.screen.blit( label, ( 480, 450 ) )
label = self.fontRegular.render( str( self.time.getSpeed( ) )+'x', 2, self.lg )
size = self.fontRegular.size( str( self.time.getSpeed( ) )+'x' )[ 0 ]
self.screen.blit( label, ( 780-size, 450 ) )
label = self.fontRegular.render( 'Generation', 2, self.lg )
self.screen.blit( label, ( 480, 480 ) )
label = self.fontRegular.render( str( self.ai.currentGeneration ), 2, self.lg )
size = self.fontRegular.size( str( self.ai.currentGeneration ) )[ 0 ]
self.screen.blit( label, ( 780-size, 480 ) )
label = self.fontRegular.render( 'Genom', 2, self.lg )
self.screen.blit( label, ( 480, 510 ) )
label = self.fontRegular.render( str( self.ai.currentGenome ), 2, self.lg )
size = self.fontRegular.size( str( self.ai.currentGenome ) )[ 0 ]
self.screen.blit( label, ( 780-size, 510 ) )
def updateGenomeScreen( self ):
gui.draw.rect( self.screen, self.lg, gui.Rect( 630, 405, 39, 30 ), 1 )
gui.draw.rect( self.screen, self.lg, gui.Rect( 668, 405, 39, 30 ), 1 )
gui.draw.rect( self.screen, self.lg, gui.Rect( 706, 405, 39, 30 ), 1 )
gui.draw.rect( self.screen, self.lg, gui.Rect( 744, 405, 39, 30 ), 1 )
label = self.fontSmall.render( str( self.genomeScreen[ 0 ] ) + '/' + str( len( self.ai.population.generations )-1 ) + ': ' + str( self.genomeScreen[ 1 ] ), 2, self.lg )
self.screen.blit( label, ( 480, 400 ) )
if self.genomeScreen[ 1 ] == -1:
for i in range( 10 ):
label = self.fontSmall.render( '%d:' % i, 2, self.lg )
self.screen.blit( label, ( 445, 450+15*i ) )
for i in range( 40 ):
score = self.ai.population.generations[ self.genomeScreen[ 0 ] ].genomes[ i ].score
label = self.fontSmall.render( str( score ), 2, self.lg )
self.screen.blit( label, ( 480+75*int(i/10), 450+15*(i%10) ) )
else:
genome = str( self.ai.population.generations[ self.genomeScreen[ 0 ] ].genomes[ self.genomeScreen[ 1 ] ] ).split( '\n' )
i = 0
for line in genome:
if line != '':
label = self.fontSmall.render( str( line ), 2, self.lg )
self.screen.blit( label, ( 480, 450+15*i ) )
i += 1
def __init__(self, screen):
self.screen = screen
quadrants = [None] * 7
w = screen.get_width()
h = screen.get_height()
quadrant_size = (w / 2, h / 2)
vertical_half_size = (w / 2, h)
quadrants[0] = self.screen.subsurface(pygame.Rect((0, 0), quadrant_size))
quadrants[1] = self.screen.subsurface(pygame.Rect((w / 2, 0), quadrant_size))
quadrants[2] = self.screen.subsurface(pygame.Rect((0, h / 2), quadrant_size))
quadrants[3] = self.screen.subsurface(pygame.Rect((w / 2, h / 2), quadrant_size))
quadrants[4] = self.screen.subsurface(pygame.Rect((0, 0), vertical_half_size))
quadrants[5] = self.screen.subsurface(pygame.Rect((w / 2, 0), vertical_half_size))
quadrants[6] = self.screen.subsurface(pygame.Rect((0, 0), (w, h)))
self.quadrants = quadrants
#self.identify()
def __init__(self, x, y, color, direction, speed, container, brain = None):
pygame.sprite.Sprite.__init__(self, container)
self.image = pygame.Surface((16,16), flags=pygame.SRCALPHA)
self.rect = self.image.get_rect()
basex = 423
if color==RED:
basex += 96
## Generate the sprite image from spritesheet
ssrect = pygame.Rect((basex,710,16,16))
global spritesheet
self.image.blit(spritesheet,(0,0),ssrect)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.direction = direction
self.speed = speed
self.brain = brain
def __init__(self,bulletgroup):
super(Player, self).__init__()
global spritesheet
spritesheet.convert_alpha()
self.cooldown = 0.5
self.canfire = True
self.bulcount = 0
self.x = 320
self.y = 500
self.velx = 0
self.vely = 0 # wish there was a vector class
self.deadcb = self.amdead
self.bullets = bulletgroup
self.image = pygame.Surface((96,96))
self.rect = self.image.get_rect()
## Generate the sprite image from spritesheet
ssrect = pygame.Rect((96,96,96,96))
self.image.blit(spritesheet,(0,0),ssrect)
self.image.convert()
self.image.set_colorkey(self.image.get_at((0, 0)))
self.hitAnim = SpriteSequence("hit",spritesheet,pygame.Rect(96,480,96,96),8,1,0,0.1,False,None)
self.blowAnim = SpriteSequence("blow",spritesheet,pygame.Rect(96,384,96,96),8,1,0,0.1,False,self.onAnimComplete)
self.idleAnim = SpriteSequence("idle",spritesheet,pygame.Rect(96,576,96,192),8,1,0,0.1,True,None)
self.idleAnim.play()
def check_collisions(self, jeff, level_select):
for j in range(len(self.level_data["DATA"])):
# if self.y - 50 * (j + 1) < jeff.get_pos()[1]:
# break
for i in range(int(self.level_cursor), int(self.level_cursor) + int(Constant.WIN_WIDTH / 50) + 1):
if i >= len(self.level_data["DATA"][j]) or (i - self.level_cursor) * 50 > jeff.get_pos()[0] + 50:
break
if self.level_data["TILES"][self.level_data["DATA"][j][i]]["NAME"] == "End":
self.lvl_end = True
level_select.unlock_next_level(self.last_level)
if pygame.Rect([jeff.get_pos()[0] + 2, jeff.get_pos()[1] - 2],
[46, 46]).colliderect(pygame.Rect([(i - self.level_cursor) * 50, self.y - 50 * (j + 1)], [50, 50])) and \
self.level_data["TILES"][self.level_data["DATA"][j][i]]["NAME"] == "Bloc":
print(self.level_data["TILES"][self.level_data["DATA"][j][i]]["NAME"])
jeff.die()
elif pygame.Rect([jeff.get_pos()[0] + 10, jeff.get_pos()[1] - 10],
[30, 30]).colliderect(pygame.Rect([(i - self.level_cursor) * 50, self.y - 50 * (j + 1)], [50, 50])):
if self.level_data["TILES"][self.level_data["DATA"][j][i]]["NAME"] == "Pic":
print(self.level_data["TILES"][self.level_data["DATA"][j][i]]["NAME"])
jeff.die()
elif self.level_data["TILES"][self.level_data["DATA"][j][i]]["NAME"] == "Energy":
self.level_data["DATA"][j][i] = 0
jeff.obtain_energy()
def game():
resources = os.path.join(os.getcwd(), '../')
controller = wargame.engine.init(resources)
# this time, we want 1 node to control 2 other nodes
# we need 2 images to display mouse over and mouse not over
red = Resources.colour_surface(128, 128, (255, 0, 0))
blue = Resources.colour_surface(128, 128, (0, 0, 255))
green = Resources.colour_surface(128, 128, (0, 255, 0))
# we need a node
sender = NodeTransmit(green, blue, pygame.Rect(256, 173, 128, 128))
receive1 = NodeReceive(blue, red, pygame.Rect(64, 176, 128, 128), sender.message_id)
receive2 = NodeReceive(blue, red, pygame.Rect(448, 176, 128, 128), sender.message_id)
# add the nodes to a SCENE
scene = Scene([sender, receive1, receive2])
# I add the scene to the ENGINE
controller.add_scene('start', scene)
# I tell the engine what scene to start and run the controller
controller.run('start')
def game():
resources = os.path.join(os.getcwd(), '../')
controller = wargame.engine.init(resources)
# add a sprite from an image
sprite = ImageNode.from_image(100, 100, 'sprites.soldier')
# we want the unit to move, so add a tween
# all times are in milliseconds for the engine
# this move rect is a VECTOR, so we move by this amount
move = pygame.Rect(300, 0, 0, 0)
sprite.tween = MoveTween(4000, sprite.rect, move)
# I add the node to a SCENE
scene = Scene([sprite])
# I add the scene to the ENGINE
controller.add_scene('start', scene)
# I tell the engine what scene to start and run the controller
controller.run('start')
def game():
resources = os.path.join(os.getcwd(), '../')
controller = wargame.engine.init(resources)
# we need 2 images to display mouse over and mouse not over
red = Resources.colour_surface(200, 200, (255, 0, 0))
blue = Resources.colour_surface(200, 200, (0, 0, 255))
# we need a node
node = MouseOverNode(blue, red, pygame.Rect(220, 140, 200, 200))
# I add the node to a SCENE
scene = Scene([node])
# I add the scene to the ENGINE
controller.add_scene('start', scene)
# I tell the engine what scene to start and run the controller
controller.run('start')
def display_number( self, number, pos, segment=SEGMENT_BOTH ):
img = self.number_surfaces[ number ]
area = img.get_clip()
offs = [0,0]
if segment == self.SEGMENT_UPPER:
area.height /=2
elif segment == self.SEGMENT_LOWER:
hh = area.height /2
area.top = hh
area.height = hh
offs[1] = hh
p = (pos[0]+offs[0],pos[1]+offs[1])
self.window.blit( img, p, area=area )
# draw a translucent black rect over *most* of a changing segement
# cheap, hacky transition effect!
if segment == self.SEGMENT_UPPER:
yo = 10
r = pygame.Rect( (p[0],p[1]+yo), (area.width,area.height-yo) )
brightness = 128 + 64
self.window.fill( (brightness,brightness,brightness), rect=r, special_flags=pygame.BLEND_MULT )
def displayBars():
for l in xrange(4):
for bar in xrange(len(ntscRGB)):
surface.fill(ntscRGB[bar][l], pygame.Rect(bar * 20, l * 50, 20, 50))
pygame.display.flip()
def displayBars():
for bar in xrange(32):
for lum in xrange(4):
surface.fill(ntscRGB[bar][lum], pygame.Rect(bar * 5, lum*50, 5, 50))
pygame.display.flip()
def displayBars():
for l in xrange(4):
for bar in xrange(len(ntscRGB)):
surface.fill(ntscRGB[bar][l], pygame.Rect(bar * 20, l * 50, 20, 50))
pygame.display.flip()
def displayBars():
for bar in xrange(32):
for lum in xrange(4):
surface.fill(ntscRGB[bar][lum], pygame.Rect(bar*4.57, lum*50, 5, 50))
pygame.display.flip()
def test_movement(self):
# Create a test surface with a red square at (0, 0) and a blue
# square at (1, 1), both being 2x2.
test_surface = pygame.surface.Surface((3, 3))
test_surface.fill((255, 0, 0), pygame.Rect(0, 0, 2, 2))
test_surface.fill((0, 255, 0), pygame.Rect(1, 1, 2, 2))
# Create our camera
camera = Camera((3, 3), (2, 2), (2, 2),
behavior=CameraBehavior())
# Blit our test surface
camera.source_surface.blit(test_surface, (0, 0))
camera.update_state(["this", "seriously", 323423, "works"])
# Set focus to the top left pixel and check that we have a 2x2
# view into the test surface in the top left (that is, (0, 0)
# to (1, 1) should be visible)
camera.scroll_to(pygame.Rect(0, 0, 1, 1))
camera.update_state("HAHA LIES THIS IS LIES AHAHAHA")
focal_subsurface = test_surface.subsurface(pygame.Rect(0, 0, 2, 2))
assert(compare_surfaces(focal_subsurface, camera))
# Set focus to the pixel in the center of the test surface (1, 1)
# and check that (1, 1) to (2, 2) is displayed on the camera
camera.scroll_to(pygame.Rect(1, 1, 1, 1))
camera.update_state("lialskdjflasjflksadjf")
focal_subsurface = test_surface.subsurface(pygame.Rect(1, 1, 2, 2))
assert(compare_surfaces(focal_subsurface, camera))
def test_scroll(self):
# Create surface to render to
output_surface = pygame.surface.Surface((1, 1))
# Create fixtures
red_surface = pygame.surface.Surface((1, 1))
blue_surface = pygame.surface.Surface((1, 1))
red_surface.fill((255, 0, 0))
blue_surface.fill((0, 255, 0))
# Create the camera and blit colors to it
camera = Camera((2, 1), (1, 1), (1, 1))
camera.source_surface.blit(red_surface, (0, 0))
camera.source_surface.blit(blue_surface, (1, 0))
camera.update_state("so many of these")
# We should be at (0, 0) so blitting should get us a red pixel
output_surface.blit(camera, (0, 0))
assert(compare_surfaces(red_surface, output_surface))
# Scroll one pixel to the left, and we should get a blue pixel
# when blitting
focal_rect = pygame.Rect((1, 0), (1, 1))
camera.scroll_to(focal_rect) # updates for us
camera.update_state("just a lot")
output_surface.blit(camera, (0, 0))
assert(compare_surfaces(blue_surface, output_surface))
# FIXME: This is messy!
def _draw_agent(center_point, screen, base_size=30):
'''
Args:
center_point (tuple): (x,y)
screen (pygame.Surface)
Returns:
(pygame.rect)
'''
# taxi_image = pygame.image.load("taxi.png")
# image_rect = taxi_image.get_rect()
tri_bot_left = center_point[0] - base_size, center_point[1] + base_size
tri_bot_right = center_point[0] + base_size, center_point[1] + base_size
tri_top = center_point[0], center_point[1] - base_size
tri = [tri_bot_left, tri_top, tri_bot_right]
tri_color = (98, 140, 190)
# screen.blit(taxi_image, image_rect)
# return image_rect
return pygame.draw.polygon(screen, tri_color, tri)
def added_to_stage(self, stage):
"""
adjusts our max positions based on the stage's level's dimensions - only if it's a Level (not a simple Screen)
:param Stage stage: the Stage we were added to
"""
# TODO: make this independent on Level or simple Screen (even a Screen should have dimensions)
if isinstance(stage.screen, Level):
if self.x_min == "auto":
self.x_min = 0
if self.x_max == "auto":
self.x_max = stage.screen.width - self.rect.width
if self.y_min == "auto":
self.y_min = 0
if self.y_max == "auto":
self.y_max = stage.screen.height - self.rect.height
def collide_simple_with_sprite(self, sprite, collision_detector):
"""
Collides a Sprite (that only obeys simple physics rules) with a TiledTileLayer and solves all detected collisions.
The Sprite needs to have the properties vx and vy, which are interpreted as the Sprite's velocity.
Ignores slopes.
:param Sprite sprite: the Sprite to test for collisions against a TiledTileLayer
:param callable collision_detector: the collision detector method to use (this is set in the Sprite's Stage's options)
"""
tile_start_x, tile_end_x, tile_start_y, tile_end_y = self.get_overlapping_tiles(sprite)
xy, v = Stage.estimate_sprite_direction(sprite)
# very simple algo: look through tile list (in no particular order) and return first tile that collides
# None if no colliding tile found
for tile_x in range(tile_start_x, tile_end_x + 1):
for tile_y in range(tile_start_y, tile_end_y + 1):
tile_sprite = self.tile_sprites[tile_x, tile_y]
if not tile_sprite:
continue
col = collision_detector(sprite, tile_sprite, collision_objects=None,
direction=xy, direction_veloc=v, original_pos=(sprite.rect.x, sprite.rect.y))
if col:
return col
return None
def __init__(self, layer, pytmx_tiled_map, id_, tile_props, rect):
"""
:param TiledTileLayer layer: the TiledTileLayer object to which this tile belongs
:param pytmx.pytmx.TiledMap pytmx_tiled_map: the tmx tiled-map object to which this tile belongs
(useful to have to look up certain map-side properties, e.g. tilewidth/height)
:param int id_: tthe ID of the tile in the layer
:param dict tile_props: the properties dict of this tile (values already translated into python types)
:param Union[pygame.Rect,None] rect: the pygame.Rect representing the position and size of the tile
"""
super().__init__(rect.x, rect.y, width_height=(rect.width, rect.height))
self.tiled_tile_layer = layer
self.pytmx_tiled_map = pytmx_tiled_map
self.tile = id_
self.tile_x = self.rect.x // self.pytmx_tiled_map.tilewidth
self.tile_y = self.rect.y // self.pytmx_tiled_map.tileheight
self.tile_props = tile_props
# add the `dockable` type to all tiles
self.type |= Sprite.get_type("dockable")
def __init__(self, layer, pytmx_tiled_map, id_, tile_props, rect):
"""
:param TiledTileLayer layer: the TiledTileLayer object to which this tile belongs
:param pytmx.pytmx.TiledMap pytmx_tiled_map: the tmx tiled-map object to which this tile belongs
(useful to have to look up certain map-side properties, e.g. tilewidth/height)
:param int id_: tthe ID of the tile in the layer
:param dict tile_props: the properties dict of this tile (values already translated into python types)
:param Union[pygame.Rect,None] rect: the pygame.Rect representing the position and size of the tile
"""
super().__init__(layer, pytmx_tiled_map, id_, tile_props, rect)
# slope properties of the tile
self.slope = tile_props.get("slope", None) # the slope property of the tile in the tmx file (inverse steepness (1/m in y=mx+b) of the line that defines the slope)
self.offset = tile_props.get("offset", None) # the offset property of the tile in the tmx file (in px (b in y=mx+b))
self.is_full = (self.slope == 0.0 and self.offset == 1.0) # is this a full collision tile?
self.max_x = self.pytmx_tiled_map.tilewidth
self.max_y = max(self.get_y(0), self.get_y(self.rect.width)) # store our highest y-value (height of this tile)
def tick(self, game_loop):
"""
Needs to be called by the GameObject at some point during the GameObject's `tick` method.
:param GameLoop game_loop: the currently playing GameLoop object
"""
obj = self.game_object
self.reset()
if self.game_obj_cmp_anim and self.game_obj_cmp_anim.flags & Animation.get_flag("paralyzes"):
return
# look for edges ahead -> then change direction if one is detected
# - makes sure an enemy character does not fall off a cliff
if (not (game_loop.frame % 3) and self.check_cliff_ahead()) or obj.rect.x <= 0 or obj.rect.x >= obj.x_max:
self.toggle_direction()
self.commands["left" if self.flipped else "right"] = True
def check_cliff_ahead(self):
"""
Checks whether there is a cliff ahead (returns true if yes).
"""
obj = self.game_object
tile_w = obj.stage.screen.tmx_obj.tilewidth
tile_h = obj.stage.screen.tmx_obj.tileheight
# check below character (c=character sprite, _=locateObject (a stripe with x=x width=w-6 and height=3))
# ccc -> walking direction
# ccc
# _
w = max(tile_w * 1.5, obj.rect.width - 6)
col = obj.stage.locate((obj.rect.right - tile_w - w) if self.flipped else (obj.rect.left + tile_w),
obj.rect.bottom - tile_h * 0.5,
w,
tile_h * 1.75,
Sprite.get_type("default"))
if not col or isinstance(col.sprite2, LiquidBody):
return True
return False
# checks whether an enemy is in sight
def move(self, sprite, x, y, absolute=False):
"""
This will 'overwrite' the normal Sprite's `move` method by Component's extend.
:param Sprite sprite: the GameObject that this Component belongs to (the Sprite to move around)
:param Union[int,None] x: the amount in pixels to move in x-direction
:param Union[int,None] y: the amount in pixels to move in y-direction
:param bool absolute: whether x and y are given as absolute coordinates (default: False): in this case x/y=None means do not move in this dimension
"""
orig_x = sprite.rect.x
orig_y = sprite.rect.y
# first call the original Sprite's move method
sprite._super_move(x, y, absolute)
# move all our docked Sprites along with us
if not absolute:
for docked_sprite in self.docked_sprites:
docked_sprite.move(x, y, absolute=False)
else:
# translate into relative movement: we don't want the docked components to move to the given mothership's absolute values
x_move = x - orig_x if x is not None else 0
y_move = y - orig_y if y is not None else 0
for docked_sprite in self.docked_sprites:
docked_sprite.move(x_move, y_move)
def tick(self, game_loop):
"""
Moving elevator up and down OR left and right.
"""
dt = game_loop.dt
self.move(self.vx * dt, self.vy * dt)
if self.direction == "x":
if self.rect.x < self.min_pos:
self.vx = abs(self.vx)
self.move(self.min_pos, None, absolute=True)
elif self.rect.x > self.max_pos:
self.vx = -abs(self.vx)
self.move(self.max_pos, None, absolute=True)
else:
if self.rect.y < self.min_pos:
self.vy = abs(self.vy)
self.move(None, self.min_pos, absolute=True)
elif self.rect.y > self.max_pos:
self.vy = -abs(self.vy)
self.move(None, self.max_pos, absolute=True)
def lock_ladder(self):
"""
Locks the GameObject into a ladder.
Makes sure that there is nothing in the x-way (to move to the center of the ladder if standing a little bit aside). Otherwise, will not lock.
"""
obj = self.game_object
# test x-direction after corrective x-move to center of ladder (if there is something, don't lock)
#obj.stage.locate()
self.on_ladder = self.touched_ladder
# switch off gravity
self.gravity = False
# lock obj to center of ladder (touched_ladder is always set to the one we are touching right now)
obj.rect.centerx = self.touched_ladder.rect.centerx
self.vx = 0 # stop x-movement
# undock all objects currently docked to us (if any)
self.game_obj_cmp_dockable.undock_all_docked_objects()
# store the type before it locked to the ladder and remove the dockable/one-way-platform types (if set)
self.type_before_ladder = obj.type
obj.type &= ~Sprite.get_type("one_way_platform,dockable")