如何在迷宫墙中添加碰撞以防止物体穿过迷宫墙?
问题描述
所以我做一个重复的Pac-Man游戏项目已经有一段时间了,我一直试图在我的圆形对象和迷宫的墙壁之间添加碰撞,但遇到了困难--here is an imaged example.
我曾尝试将Player类中的冲突检测放在与Main不同的文件中,方法是将网格的位置设置为等于迷宫的墙,然后返回语句FALSE以指示对象撞到了墙,否则返回TRUE以指示不同的情况。
我做错了什么或丢失了什么?以下是我的主文件和播放器文件的内容:
请注意,我的网格的单元格宽度和高度为:
宽度=448-60/19,其中19是单元格的列周长 高度=576-60/21,其中21是单元格的行长我存储在文本文件中的迷宫墙壁坐标是:
1111111111111111111
1000000001000000001
1011011101011101101
1000000000000000001
1011011111111101101
1000010001000100001
1111011101011101111
0001010000000101000
1111010110110101111
0000000100010000000
1111010111110101111
0001010000000101000
1111010111110101111
1000000001000000001
1011011101011101101
1001000000000001001
1101010111110101011
1000010001000100001
1011111101011111101
1000000000000000001
1111111111111111111
我的主.py文件:
from pygame.locals import (KEYDOWN, K_UP, K_DOWN, K_LEFT, K_RIGHT,
K_RETURN, K_BACKSPACE, K_ESCAPE, QUIT)
from Pac_Mans_Main_Menu_State_Machine import *
from the_players_class import *
class ItsElements:
pygame.init()
pygame.display.set_caption("Pac-Man")
self.the_screens_width, self.the_screens_height = 448, 576
self.the_screens_perimeter = pygame.Surface((self.the_screens_width, self.the_screens_height))
self.the_screens_perimeter_window = pygame.display.set_mode(size=(self.the_screens_width, self.the_screens_height))
self.the_maze_image_surface = pygame.image.load("Maze_Background.png")
self.the_maze_image_surface = pygame.transform.scale(self.the_maze_image_surface, size=(448 - 60, 576 - 60))
self.the_mazes_walls = []
with open("The_Mazes_Walls_Coordinates.txt", 'r') as the_maze_images_surface:
for the_maze_image_surfaces_y_index, the_maze_image_surfaces_walls_coordinates in enumerate(the_maze_images_surface):
for the_maze_image_surfaces_x_index, the_characters_type in enumerate(the_maze_image_surfaces_walls_coordinates):
if the_characters_type == "1":
self.the_mazes_walls.append(The_Vector(the_maze_image_surfaces_x_index, the_maze_image_surfaces_y_index))
self.THE_UP_KEY, self.THE_DOWN_KEY, self.THE_LEFT_KEY, self.THE_RIGHT_KEY, self.THE_START_KEY, self.THE_BACK_KEY =
False, False, False, False, False, False
self.the_player = ThePlayer(self, The_Vector(9, 9))
def display_the_maze_background(self):
self.the_screens_perimeter.blit(self.the_maze_image_surface, (30, 30))
def draw_the_maze_backgrounds_pre_defined_walls_coordinates_using_the_screens_grid(self):
for the_walls in self.the_mazes_walls:
pygame.draw.rect(self.the_maze_image_surface, "Purple", (the_walls.x * ((448 - 60) / 19) + 1,
the_walls.y * ((576 - 60) / 21) + 1,
((448 - 60) / 19), ((576 - 60) / 21)))
def draw_the_screens_grid(self):
for x in range(self.the_screens_width // 2):
pygame.draw.line(self.the_maze_image_surface, "Gray", (x * ((448 - 60) / 19), 0),
(x * ((448 - 60) / 19), 576))
for y in range(self.the_screens_height // 2):
pygame.draw.line(self.the_maze_image_surface, "Gray", (0, y * ((576 - 60) / 21)),
(448, y * ((576 - 60) / 21)))
def check_the_events(self):
for the_event in pygame.event.get():
if the_event.type == KEYDOWN:
if the_event.key == K_UP:
self.THE_UP_KEY = True
if self.the_programs_playing_status is True:
self.the_player.move_the_circular_surfaces_position(The_Vector(0, -1))
if the_event.key == K_DOWN:
self.THE_DOWN_KEY = True
if self.the_programs_playing_status is True:
self.the_player.move_the_circular_surfaces_position(The_Vector(0, 1))
if the_event.key == K_LEFT:
self.THE_LEFT_KEY = True
if self.the_programs_playing_status is True:
self.the_player.move_the_circular_surfaces_position(The_Vector(-1, 0))
if the_event.key == K_RIGHT:
self.THE_RIGHT_KEY = True
if self.the_programs_playing_status is True:
self.the_player.move_the_circular_surfaces_position(The_Vector(1, 0))
if the_event.key == K_RETURN:
self.THE_START_KEY = True
if the_event.key == K_BACKSPACE:
self.THE_BACK_KEY = True
if the_event.key == K_ESCAPE:
self.the_programs_running_status, self.the_programs_playing_status = False, False
self.the_current_menu.run_the_display = False
elif the_event.type == QUIT:
self.the_programs_running_status, self.the_programs_playing_status = False, False
self.the_current_menu.run_the_display = False
def reset_the_pressed_keys(self):
self.THE_UP_KEY, self.THE_DOWN_KEY, self.THE_LEFT_KEY, self.THE_RIGHT_KEY, self.THE_START_KEY, self.THE_BACK_KEY =
False, False, False, False, False, False
def the_programs_main_loop(self):
while self.the_programs_playing_status:
# "'Check' the ''player's 'inputs'' 'in the 'events:''"
self.check_the_events()
# Did the "'player' 'hit' the ''Enter' key' on their 'keyboard?'" "If so," then "'Stop' 'playing' the program but
# 'continue' 'running' it:"
if self.THE_START_KEY:
self.the_programs_playing_status = False
# "'Fill' the screen's 'surface' 'black:'"
self.the_screens_perimeter.fill("Black")
# "'Display' the 'game's 'background:''"
self.display_the_maze_background()
# "'Display' the ''manually' drawn' ''maze background' image:'"
self.draw_the_maze_backgrounds_pre_defined_walls_coordinates_using_the_screens_grid()
# "'Display' the 'screen's 'grid:''"
self.draw_the_screens_grid()
# "'Display' the 'player's ''current' score:''"
self.display_the_current_score_text()
# "'Display' the 'player's ''high' score:''"
self.display_the_high_score_text()
self.the_screens_perimeter_window.blit(self.the_screens_perimeter, (0, 0))
self.the_player.draw_the_players_circles_surface()
self.the_player.update()
# "'Calling' 'flip()' will 'update the 'screen's 'display'' 'with the 'newly drawn surface''' or else 'nothing will
# change:'"
pygame.display.flip()
self.reset_the_pressed_keys()
我的player.py文件包含我的播放器的类:
import pygame
from pygame.math import Vector2 as The_Vector
class ThePlayer(pygame.sprite.Sprite):
def __init__(self, pac_man, the_grids_position):
super(ThePlayer, self).__init__()
self.pac_man = pac_man
self.the_grids_position = the_grids_position
self.the_pixels_position =
The_Vector((self.the_grids_position.x * (448 - 60) / 19) + ((60 / 2) + ((448 - 60) / 19) / 1.9),
(self.the_grids_position.y * (576 - 60) / 21) + ((60 / 2) + ((576 - 60) / 21) / 1.9))
self.the_circular_surfaces_direction = The_Vector(0, 0)
# print(self.the_grids_position, self.the_pixels_position)
def draw_the_players_circles_surface(self):
pygame.draw.circle(self.pac_man.the_screens_perimeter_window, "Yellow",
(int(self.the_pixels_position.x), int(self.the_pixels_position.y)), 7)
# This block will be used to "'track' the ''player's 'position:''"
# pygame.draw.rect(self.pac_man.the_screens_perimeter_window, "Red",
# (self.the_pixels_position.x - (448 - 60) / 19 + (60 / 5.7),
# self.the_pixels_position.y - (576 - 60) / 21 + (60 / 4.7),
# (448 - 60) / 19, (576 - 60) / 21), 1)
# OR:
pygame.draw.rect(self.pac_man.the_screens_perimeter_window, "Red",
(self.the_grids_position.x * (448 - 60) / 19 + (60 / 1.95),
self.the_grids_position.y * (576 - 60) / 21 + (60 / 1.95),
(448 - 60) / 19, (576 - 60) / 21), 1)
def move_the_circular_surfaces_position(self, the_circular_surfaces_direction):
self.the_circular_surfaces_direction = the_circular_surfaces_direction
def the_circular_surface_collides_with_a_wall(self):
for the_walls in self.pac_man.the_mazes_walls:
if The_Vector(self.the_grids_position + self.the_circular_surfaces_direction) == the_walls:
return False
else:
return True
def update(self):
# "'Move' the 'circular surface' 'relative to' the 'pixel's 'x's' and 'y's' positions' ''on' the 'screen:''"
self.the_pixels_position += self.the_circular_surfaces_direction
# "'Set' the 'grid's 'position'' 'relative to' the 'pixel's 'x:'"
self.the_grids_position.x = (self.the_pixels_position.x - 60 + ((448 - 60) / 19) // 2) // ((448 - 60) / 19) + 1
# "'Set' the 'grid's 'position'' 'relative to' the 'pixel's 'y:'"
self.the_grids_position.y = (self.the_pixels_position.y - 60 + ((576 - 60) / 21) // 2) // ((576 - 60) / 21) + 1
请原谅我的问题太长了,非常感谢您的时间和对相关人员的帮助。我希望这个问题可以正确重现。
解决方案
正如另一个用户所指出的,我不确定您移动的逻辑在哪里。然而,这是我通常编程冲突的方式:
# Suppose you know what direction you want the player to move in
currentPosition = # (row, column) tuple of current position
newPosition = # (row, column) tuple of new position
# e.g. (currentPosition[0] + rowDelta, currentPosition[1] + rowDelta)
if ("""newPosition collides with a wall in your maze"""):
# Player's position remains the same
else:
# Move the player's current position to newPosition
# and call whatever code you need to render it.
相关文章