Przechodząc przez ściany po kolizji Pygame

głosy
2

Hey guys Potrzebuję pomocy z publikacji na temat kolizji w pygame. Mam mapę granicy utworzenia piksela idealny kolizji z wykorzystaniem nakładania maski. Zderzenie jest wykrywany bez żadnych problemów, ale jeśli chodzi o zatrzymanie odtwarzacza od przechodzenia przez ściany, zawsze znajdzie się jakiś sposób są wysyłane przez nią. Zrobiłem kilka prób (a wiele z nich naprawdę), w tym nawet zamrożenie gracza po naciśnięciu trzech przycisków na raz, aby uniknąć go z spazzing się, ale bezskutecznie.

Teraz, mogę sprawdzić, który użytkownik naciśnie przycisk, aby ustawić kierunek:

while True:
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        pygame.quit()
        sys.exit()
    key = pygame.key.get_pressed()
    if key[pygame.K_w]:
        COLLISION_DIRECTION = UP
    if key[pygame.K_s]:
        COLLISION_DIRECTION = DOWN
    if key[pygame.K_d]:
        COLLISION_DIRECTION = RIGHT
    if key[pygame.K_a]:
        COLLISION_DIRECTION = LEFT

A następnie wykonaj test zderzenia na podstawie kierunku. W mojej ostatniej desperackiej próbie, I uciekają się do oszczędzania ostatnią pozycję braku kolizji na tablicy, tłumacząc świat (ruszam świat, a nie gracz) do tej pozycji i odjęcie lub dodanie prędkość ruchu:

if boundariesMap_mask.overlap(player.mask, (offset_x, offset_y)) is None:
        lastPos = [world.x, world.y]
    else:
        while COLLISION_DIRECTION == UP:
            world.y = (lastPos[1]-DIST_WORLD)
            break
        while COLLISION_DIRECTION == DOWN:
            world.y = (lastPos[1]+DIST_WORLD)
            break
        while COLLISION_DIRECTION == LEFT:
            world.x = (lastPos[0]-DIST_WORLD)
            break
        while COLLISION_DIRECTION == RIGHT:
            world.x = (lastPos[0]+DIST_WORLD)
            break

Mój najlepszy przypuszczenie jest, że należy zablokować wszystkie dodatkowe wejście podczas ruchu z powrotem do bezpiecznej pozycji, aby uniknąć zmiany COLLISION_DIRECTION. Można faceci dają mi żadnej pomocy?

world.x i world.y są zmienne współrzędne świata

Edit: zapomniałem dodać klasę konstruktora świat

class World(pygame.sprite.Sprite):
def __init__(self):
    self.sprite = pygame.image.load('bin\\assets\\test.png')
    self.x = 220
    self.y = 45

def draw(self, surface):
    surface.blit(self.sprite, (self.x, self.y))

def handle_keys(self):

    key = pygame.key.get_pressed()
    if pygame.joystick.get_count():
        joystick_x = round(my_joystick.get_axis(0))
        joystick_y = round(my_joystick.get_axis(1))

        if joystick_x < 0:
            self.x += DIST_WORLD
        if joystick_x > 0:
            self.x -= DIST_WORLD
        if joystick_y < 0:
            self.y += DIST_WORLD
        if joystick_y > 0:
            self.y -= DIST_WORLD

    if key[pygame.K_w]:
        self.y += DIST_WORLD
    if key[pygame.K_s]:
        self.y -= DIST_WORLD
    if key[pygame.K_a]:
        self.x += DIST_WORLD
    if key[pygame.K_d]:
        self.x -= DIST_WORLD
Utwórz 22/05/2015 o 00:41
użytkownik
W innych językach...                            


1 odpowiedzi

głosy
1

Sądząc pytanie i odpowiedź w komentarzach, wydaje się, że usterka jest wyzwalany, gdy trzy lub więcej naciśnięcie klawisza są rejestrowane, powodując COLLISION_DIRECTIONa World.yi World.xbyć aktualizowany niewłaściwie.

Wziąć pod uwagę fakt, że jeśli gracz porusza się wzdłuż pewnego kierunku w osi X lub Y, nie mogą się poruszać w przeciwnym kierunku w tym samym czasie. Zastanów się również fakt, że kod w pętli głównej gra pozwala wartość COLLISION_DIRECTIONmają być nadpisywane czy gracz jest naciśnięcie klawiszy na raz wielu; Na przykład, gdy W, A i S przytrzymywany równocześnie końcowe COLLISION_DIRECTIONbyłoby "LEFT".

Zakładam, że jesteś pozwalając ruchu po przekątnej, więc to, co chcemy zrobić tutaj to zrobić COLLISION_DETECTIONsensowne dla osi x i y-osi jednocześnie. Następnie musimy ograniczyć liczbę kontroli wciśnięcia klawisza, aby dokładnie dwa (raz na osi x, a raz na osi y), tak, że problem z trzema przyciskami nie dzieje.

W głównej pętli gry:

## Instead of one COLLISION_DIRECTION, we now have two separate variables:
## COLLISION_DIRECTION_X and COLLISION_DIRECTION_Y

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        key = pygame.key.get_pressed()

        ## Using elif so we don't mess up COLLISION_DIRECTION_Y
        if key[pygame.K_w]:
            COLLISION_DIRECTION_Y = "UP"
        elif key[pygame.K_s]:
            COLLISION_DIRECTION_Y = "DOWN"

        ## Using elif so we don't mess up COLLISION_DIRECTION_X
        if key[pygame.K_d]:
            COLLISION_DIRECTION_X = "RIGHT"
        elif key[pygame.K_a]:
            COLLISION_DIRECTION_X = "LEFT"

Aktualizacja wykrywania kolizji odpowiednio:

 if boundariesMap_mask.overlap(player.mask, (offset_x, offset_y)) is None:
    lastPos = [world.x, world.y]
 else:
    ## Redundant while-break replaced with simple if-statements;
    ## Using while is not exactly necessary because we carry out
    ## these statements each frame

    if COLLISION_DIRECTION_Y == "UP":
        world.y = (lastPos[1]-DIST_WORLD)
    elif COLLISION_DIRECTION_Y == "DOWN":
        world.y = (lastPos[1]+DIST_WORLD)

    if COLLISION_DIRECTION_X == "LEFT":
        world.x = (lastPos[0]-DIST_WORLD)
    elif COLLISION_DIRECTION_X == "RIGHT":
        world.x = (lastPos[0]+DIST_WORLD)

A potem, w swojej handle_keysfunkcji:

 def handle_keys(self):

    key = pygame.key.get_pressed()
    if pygame.joystick.get_count():
        joystick_x = round(my_joystick.get_axis(0))
        joystick_y = round(my_joystick.get_axis(1))

        ## Restrict joystick x-input checking, because we logically
        ## cannot be both greater and less than zero

        if joystick_x < 0:
            self.x += DIST_WORLD
        elif joystick_x > 0:
            self.x -= DIST_WORLD

        ## Restrict joystick y-input checking, because we logically
        ## cannot be both greater and less than zero

        if joystick_y < 0:
            self.y += DIST_WORLD
        elif joystick_y > 0:
            self.y -= DIST_WORLD

    ## Restrict keypress vertical axis checking for the same reason
    if key[pygame.K_w]:
        self.y += DIST_WORLD
    elif key[pygame.K_s]:
        self.y -= DIST_WORLD

    ## Restrict keypress horizontal axis checking for same reason
    if key[pygame.K_a]:
        self.x += DIST_WORLD
    elif key[pygame.K_d]:
        self.x -= DIST_WORLD

Mam nadzieję, że to pomogło! Jeżeli kod nie zrobić, to przepraszam, ale w każdym razie, mam nadzieję, że moje komentarze przed kodem zapewnić pewien wgląd.

Odpowiedział 14/06/2015 o 05:15
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more