def _move_sprite(moving_sprite: arcade.Sprite, platforms: arcade.SpriteList, dt): if moving_sprite.bottom <= 0 and moving_sprite.change_y < 0: moving_sprite.change_y = 0 moving_sprite.bottom = 0 moving_sprite.center_y += moving_sprite.change_y * moving_sprite.speed_multiplier * ( dt / (1 / 60)) hit_list_y = arcade.check_for_collision_with_list(moving_sprite, platforms) for platform in hit_list_y: if platform.color != moving_sprite.current_background: if moving_sprite.change_y > 0: if not platform.change_y: moving_sprite.top = platform.bottom moving_sprite.change_y = 0 elif moving_sprite.change_y < 0: moving_sprite.bottom = platform.top if platform.change_y: if platform.change_y < 0: moving_sprite.center_y -= 2 moving_sprite.change_y = -3 else: moving_sprite.change_y = 0 else: moving_sprite.change_y = 0 if platform.change_x: moving_sprite.momentum = platform.change_x moving_sprite.center_x += (moving_sprite.change_x + moving_sprite.momentum ) * moving_sprite.speed_multiplier * (dt / (1 / 60)) hit_list_x = arcade.check_for_collision_with_list(moving_sprite, platforms) for platform in hit_list_x: if platform.color != moving_sprite.current_background and platform not in hit_list_y: if moving_sprite.change_x > 0 and not platform.change_x: moving_sprite.right = platform.left elif moving_sprite.change_x < 0 and not platform.change_x: moving_sprite.left = platform.right if platform.change_y: if platform.change_y >= 0: moving_sprite.change_x = 0 else: moving_sprite.change_x = 0 if len(hit_list_y) <= 0 and moving_sprite.momentum != 0: moving_sprite.change_x += moving_sprite.momentum moving_sprite.momentum = 0
def on_key_press(self, key, key_modifiers): """ Called when a key is pressed. Sets the state of holding an arrow key. :param key: The key that was pressed :param key_modifiers: Things like shift, ctrl, etc """ if key == arcade.key.LEFT or key == arcade.key.DOWN: self.player.change_x = -3 if key == arcade.key.RIGHT or key == arcade.key.UP: self.player.change_x = 3 if key == arcade.key.W or key == arcade.key.D: pass if key == arcade.key.S or key == arcade.key.A: pass if key == arcade.key.SPACE: bullet = Sprite(filename="game_piece_red.png", \ center_x=self.player.center_x, center_y=self.player.center_y) bullet.change_y = 30 bullet.scale = .25 self.bullets.append(bullet)
def _move_sprite(moving_sprite: arcade.Sprite, walls: arcade.SpriteList): # Rotate moving_sprite.angle += moving_sprite.change_angle hit_list = check_for_collision_with_list(moving_sprite, walls) if len(hit_list) > 0: # Resolve any collisions by this weird kludge _circular_check(moving_sprite, walls) # --- Move in the y direction moving_sprite.center_y += moving_sprite.change_y # Check for wall hit hit_list_x = check_for_collision_with_list(moving_sprite, walls) # print(f"Post-y move {hit_list_x}") # If we hit a wall, move so the edges are at the same point if len(hit_list_x) > 0: if moving_sprite.change_y > 0: while check_for_collision_with_list(moving_sprite, walls): moving_sprite.center_y -= 1 elif moving_sprite.change_y < 0: while check_for_collision_with_list(moving_sprite, walls): moving_sprite.center_y += 1 was_falling = (abs(moving_sprite.change_y) > abs( moving_sprite.engine.gravity_constant)) if was_falling: # they have been moving for more than one frame play_sound_effect('impact') moving_sprite.change_y = min(0.0, hit_list_x[0].change_y) moving_sprite.center_y = round(moving_sprite.center_y, 2) # --- Move in the x direction moving_sprite.center_x += moving_sprite.change_x check_again = True while check_again: check_again = False # Check for wall hit hit_list_y = check_for_collision_with_list(moving_sprite, walls) # If we hit a wall, move so the edges are at the same point if len(hit_list_y) > 0: change_x = moving_sprite.change_x if change_x > 0: while check_for_collision_with_list(moving_sprite, walls): moving_sprite.center_x -= 1 elif change_x < 0: while check_for_collision_with_list(moving_sprite, walls): moving_sprite.center_x += 1 else: raise AssertionError( "Error, x collision while player wasn't moving.\n" "Make sure you aren't calling multiple updates, like " "a physics engine update and an all sprites list update.")
def _move_sprite(moving_sprite: Sprite, walls: SpriteList, ramp_up: bool): # Rotate moving_sprite.angle += moving_sprite.change_angle hit_list = check_for_collision_with_list(moving_sprite, walls) if len(hit_list) > 0: # Resolve any collisions by this weird kludge _circular_check(moving_sprite, walls) # --- Move in the y direction moving_sprite.center_y += moving_sprite.change_y # Check for wall hit hit_list_x = check_for_collision_with_list(moving_sprite, walls) # print(f"Post-y move {hit_list_x}") complete_hit_list = hit_list_x # If we hit a wall, move so the edges are at the same point if len(hit_list_x) > 0: if moving_sprite.change_y > 0: while len(check_for_collision_with_list(moving_sprite, walls)) > 0: moving_sprite.center_y -= 1 # print(f"Spot X ({self.player_sprite.center_x}, {self.player_sprite.center_y})" # f" {self.player_sprite.change_y}") elif moving_sprite.change_y < 0: # Reset number of jumps for item in hit_list_x: while check_for_collision(moving_sprite, item): # self.player_sprite.bottom = item.top <- Doesn't work for ramps moving_sprite.center_y += 0.25 if item.change_x != 0: moving_sprite.center_x += item.change_x # print(f"Spot Y ({self.player_sprite.center_x}, {self.player_sprite.center_y})") else: pass # TODO: The code below can't execute, as "item" doesn't # exist. In theory, this condition should never be arrived at. # Collision while player wasn't moving, most likely # moving platform. # if self.player_sprite.center_y >= item.center_y: # self.player_sprite.bottom = item.top # else: # self.player_sprite.top = item.bottom moving_sprite.change_y = min(0.0, hit_list_x[0].change_y) # print(f"Spot D ({self.player_sprite.center_x}, {self.player_sprite.center_y})") moving_sprite.center_y = round(moving_sprite.center_y, 2) # print(f"Spot Q ({self.player_sprite.center_x}, {self.player_sprite.center_y})") # --- Move in the x direction moving_sprite.center_x += moving_sprite.change_x check_again = True while check_again: check_again = False # Check for wall hit hit_list_y = check_for_collision_with_list(moving_sprite, walls) complete_hit_list = hit_list_x for sprite in hit_list_y: if sprite not in complete_hit_list: complete_hit_list.append(sprite) # If we hit a wall, move so the edges are at the same point if len(hit_list_y) > 0: change_x = moving_sprite.change_x if change_x > 0: if ramp_up: for _ in hit_list_y: # print(f"Spot 1 ({self.player_sprite.center_x}, {self.player_sprite.center_y})") # See if we can "run up" a ramp moving_sprite.center_y += change_x if len( check_for_collision_with_list( moving_sprite, walls)) > 0: # No, ramp run-up doesn't work. moving_sprite.center_y -= change_x moving_sprite.center_x -= 1 # print(f"Spot R ({self.player_sprite.center_x}, {self.player_sprite.center_y})") check_again = True break # else: # print("Run up ok 1") # print(f"Spot 2 ({self.player_sprite.center_x}, {self.player_sprite.center_y})") else: while len( check_for_collision_with_list( moving_sprite, walls)) > 0: moving_sprite.center_x -= 1 elif change_x < 0: if ramp_up: for item in hit_list_y: # See if we can "run up" a ramp moving_sprite.center_y -= change_x if len( check_for_collision_with_list( moving_sprite, walls)) > 0: # Can't run up the ramp, reverse moving_sprite.center_y += change_x moving_sprite.left = max(item.right, moving_sprite.left) # print(f"Reverse 1 {item.right}, {self.player_sprite.left}") # Ok, if we were shoved back to the right, we need to check this whole thing again. check_again = True break # print(f"Spot 4 ({self.player_sprite.center_x}, {self.player_sprite.center_y})") else: while len( check_for_collision_with_list( moving_sprite, walls)) > 0: moving_sprite.center_x += 1 else: print( "Error, x collision while player wasn't moving.\n" "Make sure you aren't calling multiple updates, like " "a physics engine update and an all sprites list update.") # print(f"Spot E ({self.player_sprite.center_x}, {self.player_sprite.center_y})") return complete_hit_list
def _move_sprite(moving_sprite: Sprite, walls: SpriteList, ramp_up: bool): # start_time = time.time() # See if we are starting this turn with a sprite already colliding with us. if len(check_for_collision_with_list(moving_sprite, walls)) > 0: _circular_check(moving_sprite, walls) original_x = moving_sprite.center_x original_y = moving_sprite.center_y original_angle = moving_sprite.angle # --- Rotate rotating_hit_list = [] if moving_sprite.change_angle: # Rotate moving_sprite.angle += moving_sprite.change_angle # Resolve collisions caused by rotating rotating_hit_list = check_for_collision_with_list(moving_sprite, walls) if len(rotating_hit_list) > 0: max_distance = (moving_sprite.width + moving_sprite.height) / 2 # Resolve any collisions by this weird kludge _circular_check(moving_sprite, walls) if get_distance(original_x, original_y, moving_sprite.center_x, moving_sprite.center_y) > max_distance: # Ok, glitched trying to rotate. Reset. moving_sprite.center_x = original_x moving_sprite.center_y = original_y moving_sprite.angle = original_angle # --- Move in the y direction moving_sprite.center_y += moving_sprite.change_y # Check for wall hit hit_list_x = check_for_collision_with_list(moving_sprite, walls) # print(f"Post-y move {hit_list_x}") complete_hit_list = hit_list_x # If we hit a wall, move so the edges are at the same point if len(hit_list_x) > 0: if moving_sprite.change_y > 0: while len(check_for_collision_with_list(moving_sprite, walls)) > 0: moving_sprite.center_y -= 1 # print(f"Spot X ({self.player_sprite.center_x}, {self.player_sprite.center_y})" # f" {self.player_sprite.change_y}") elif moving_sprite.change_y < 0: # Reset number of jumps for item in hit_list_x: while check_for_collision(moving_sprite, item): # self.player_sprite.bottom = item.top <- Doesn't work for ramps moving_sprite.center_y += 0.25 if item.change_x != 0: moving_sprite.center_x += item.change_x # print(f"Spot Y ({self.player_sprite.center_x}, {self.player_sprite.center_y})") else: pass # TODO: The code below can't execute, as "item" doesn't # exist. In theory, this condition should never be arrived at. # Collision while player wasn't moving, most likely # moving platform. # if self.player_sprite.center_y >= item.center_y: # self.player_sprite.bottom = item.top # else: # self.player_sprite.top = item.bottom moving_sprite.change_y = min(0.0, hit_list_x[0].change_y) # print(f"Spot D ({self.player_sprite.center_x}, {self.player_sprite.center_y})") moving_sprite.center_y = round(moving_sprite.center_y, 2) # print(f"Spot Q ({self.player_sprite.center_x}, {self.player_sprite.center_y})") # end_time = time.time() # print(f"Move 1 - {end_time - start_time:7.4f}") # start_time = time.time() loop_count = 0 # --- Move in the x direction if moving_sprite.change_x: # Keep track of our current y, used in ramping up almost_original_y = moving_sprite.center_y # Strip off sign so we only have to write one version of this for # both directions direction = math.copysign(1, moving_sprite.change_x) cur_x_change = abs(moving_sprite.change_x) upper_bound = cur_x_change lower_bound = 0 cur_y_change = 0 exit_loop = False while not exit_loop: loop_count += 1 # print(f"{cur_x_change=}, {upper_bound=}, {lower_bound=}, {loop_count=}") # Move sprite and check for collisions moving_sprite.center_x = original_x + cur_x_change * direction collision_check = check_for_collision_with_list( moving_sprite, walls) # Update collision list for sprite in collision_check: if sprite not in complete_hit_list: complete_hit_list.append(sprite) # Did we collide? if len(collision_check) > 0: # We did collide. Can we ramp up and not collide? if ramp_up: cur_y_change = cur_x_change moving_sprite.center_y = original_y + cur_y_change collision_check = check_for_collision_with_list( moving_sprite, walls) if len(collision_check) > 0: cur_y_change -= cur_x_change else: while (len(collision_check) == 0) and cur_y_change > 0: # print("Ramp up check") cur_y_change -= 1 moving_sprite.center_y = almost_original_y + cur_y_change collision_check = check_for_collision_with_list( moving_sprite, walls) cur_y_change += 1 collision_check = [] if len(collision_check) > 0: # print(f"Yes @ {cur_x_change}") upper_bound = cur_x_change - 1 if upper_bound - lower_bound <= 1: cur_x_change = lower_bound exit_loop = True # print(f"Exit 2 @ {cur_x_change}") else: cur_x_change = (upper_bound + lower_bound) / 2 else: exit_loop = True # print(f"Exit 1 @ {cur_x_change}") else: # No collision. Keep this new position and exit lower_bound = cur_x_change if upper_bound - lower_bound <= 1: # print(f"Exit 3 @ {cur_x_change}") exit_loop = True else: # print(f"No @ {cur_x_change}") cur_x_change = (upper_bound + lower_bound) / 2 # print(cur_x_change * direction, cur_y_change) moving_sprite.center_x = original_x + cur_x_change * direction moving_sprite.center_y = almost_original_y + cur_y_change # print(f"({moving_sprite.center_x}, {moving_sprite.center_y}) {cur_x_change * direction}, {cur_y_change}") # Add in rotating hit list for sprite in rotating_hit_list: if sprite not in complete_hit_list: complete_hit_list.append(sprite) # end_time = time.time() # print(f"Move 2 - {end_time - start_time:7.4f} {loop_count}") return complete_hit_list