Nie dochodzi do kolizji

0

Mam problem nie działa mi kolizja. Ściany udało mi się dodać i je narysować ale postać może cały czas przez nie przechodzić.Próbuje na razie w jednym kierunku. Widać gdzieś tu błąd?

import pygame
from Settings import *
from game import *
class Player(object):
    def __init__(self,x,y,k,path):
        self.x = x
        self.y = y
        self.image = pygame.image.load(path)
        self.K =k
        self.myfont = pygame.font.SysFont("cosmicsansms", 30)
        self.label = self.myfont.render("Gracz!", 32, (255, 0, 255))
        self.rect = pygame.Rect(self.x,self.y,self.K,self.K)

    def draw(self,screen):
        screen.blit(self.image, (self.x * self.K, self.y * self.K))
        screen.blit(self.label, (self.x * self.K, self.y * self.K))
        self.rect = pygame.Rect(self.x * self.K, self.y * self.K, self.K, self.K)
        print(self.rect)
    def move_left(self):
        self.x =self.x -1
        self.move(self.x-1,self.y)
    def move_right(self):
        self.x = self.x +1
    def move_up(self):
        self.y =self.y -1
    def move_down(self):
        self.y = self.y+1

    def move(self, dx, dy):

        # 
        if dx != 0:
            self.move_single_axis(dx, 0)
        if dy != 0:
            self.move_single_axis(0, dy)

    def move_single_axis(self, dx, dy):

        # 
        self.rect.x += dx
        self.rect.y += dy

        #
        for wall in walls:
            if self.rect.colliderect(wall.rect):
                if dx > 0:  # 
                    self.rect.right = wall.rect.left
                if dx < 0:  # 
                    self.rect.left = wall.rect.right
                if dy > 0:  #l
                    self.rect.bottom = wall.rect.top
                if dy < 0:  # 
                    self.rect.top = wall.rect.bottom


class Wall(object):
    def __init__(self, pos):
        walls.append(self)
        self.rect = pygame.Rect(pos[0], pos[1], KRATKA, KRATKA)





1
def move_left(self):
        self.x =self.x -1
        self.move(self.x-1,self.y)

Czyli każdy krok to 2px? Jak aktualizujesz self.x, to nie musisz znowu odejmować 1 przekazując wartość do metody.

    def move_single_axis(self, dx, dy):

        # 
        self.rect.x += dx
        self.rect.y += dy

        #
        for wall in walls:
            if self.rect.colliderect(wall.rect):
                if dx > 0:  # 
                    self.rect.right = wall.rect.left
                if dx < 0:  # 
                    self.rect.left = wall.rect.right
                if dy > 0:  #l
                    self.rect.bottom = wall.rect.top
                if dy < 0:  # 
                    self.rect.top = wall.rect.bottom

Tego też w ogóle nie rozumiem. Załóżmy, że self.x = 100, robisz krok w lewo i self.rect.x += 98, co przy początkowej wartości x daje 198. dx i dy nigdy nie będą < 0, bo odejmujesz to od self.x, self.y , a koordynaty 0,0 to lewy górny róg ekranu.

0

Jak zrobie np cos takiego to poruszyc sie nie moge ```python

  def move_left(self):
       #self.x =self.x -1
       self.move(self.x-1,self.y)
1

Jak zaczynałem się uczyć pythona, to gierkę rpg robiłem. Masz tu klasę player może jakoś Ci pomoże https://pastebin.com/5xnGuvHh

0

Dzieki na pewno sie przyda.Dodaje link do calego projektu może będzie łatwiej https://app.box.com/s/ls59htb8kou219vhqne4nx74skmizwcs

Dałem printa w

def move_single_axis(self, dx, dy):

     # Move the rect
     self.rect.x += dx
     self.rect.y += dy

     # If you collide with a wall, move out based on velocity
     for wall in walls:
         if self.rect.colliderect(wall.rect):
             if dx > 0:  # Moving right; Hit the left side of the wall
                 self.rect.right = wall.rect.left
                 print("left")

I po w nacisnieciu przycisku nic ;/

0

Zrobiłem coś takiego

import pygame
from Settings import *
from game import *
class Player(object):
    def __init__(self,x,y,k,path):
        self.x = x
        self.y = y
        self.image = pygame.image.load(path)
        self.K =k
        self.myfont = pygame.font.SysFont("cosmicsansms", 30)

        self.rect = pygame.Rect(self.x,self.y,16,16)
        self.move(self.x,self.y)

    def draw(self,screen):
        self.label = self.myfont.render("Gracz!" + str(self.x), 32, (255, 0, 255))
        screen.blit(self.image, (self.x * self.K, self.y * self.K))
        screen.blit(self.label, (self.x * self.K, self.y * self.K))
        self.rect = pygame.Rect(self.x * self.K, self.y * self.K, 16, 16)
        print(self.rect)

    def move_left(self):


        #self.x = self.x - 1
        #self.move(self.x-1, self.y)
        self.move_single_axis(self.x-1,self.y)
    def move_right(self):
        self.x = self.x +1
    def move_up(self):
        self.y =self.y -1
    def move_down(self):
        self.y = self.y+1

    def move(self, dx, dy):
        print(dx)
        # Move each axis separately. Note that this checks for collisions both times.
        if dx != 0:
            self.move_single_axis(dx, 0)
        if dy != 0:
            self.move_single_axis(0, dy)

    def move_single_axis(self, dx, dy):

        # Move the rect
        self.rect.x += dx
        self.rect.y += dy

        # If you collide with a wall, move out based on velocity
        for wall in walls:
            if self.rect.colliderect(wall.rect):
                if dx > 0:  # Moving right; Hit the left side of the wall
                    self.rect.right = wall.rect.left
                    print("left")
                    print(wall.rect.left+wall.rect.right)
                    self.x = dx
                if dx < 0:  # Moving left; Hit the right side of the wall
                    self.rect.left = wall.rect.right
                if dy > 0:  # Moving down; Hit the top side of the wall
                    self.rect.bottom = wall.rect.top
                if dy < 0:  # Moving up; Hit the bottom side of the wall
                    self.rect.top = wall.rect.bottom


class Wall(object):
    def __init__(self, pos):
        walls.append(self)
        self.rect = pygame.Rect(pos[0], pos[1], KRATKA, KRATKA)



I działa kolizjia ale nie tak jak chciałem. Tzn działa ona jak jestem w scianie ...

0

Sprawdzaj kolizję zanim się poruszysz.
Jeśli kolizja zaszła, to po prostu nie wykonuj ruchu.

0

Zrobiłem tak

def move_left(self):
     for wall in walls:
        if self.rect.colliderect(wall.rect):
             if self.x > 0:  # Moving right; Hit the left side of the wall
                 self.rect.right = wall.rect.left
                 print("Kolizjia")
             else:
                 print("OK")
                 self.x = self.x -1

Dalej to samo gdy jestem w scianie pisze kolizjia... poza nia nie.Ale else wgl nie działa

1

Ja bym nie ustawiał przy kolizji koordynatów gracza na koordynaty ściany, tylko dodał do klasy gracza self.speed, który definiuje szybkość poruszania i przy kolizji zmieniał jego wartość na 0.

if self.x > 0:  # Moving right; Hit the left side of the wall
      self.rect.right = wall.rect.left
      print("Kolizjia")
else:
     print("OK")
     self.x = self.x -1

Nie rozumiem dalej co ma sprawdzać self.x > 0 bo to będzie zawsze True. Jeżeli chodzi o sprawdzenie kierunku, z którego nadeszła kolizja, to tak nie działa i musisz mieć w klasie gracza coś w stylu player_direction, która przechowuje kierunek, w którym aktualnie porusza się gracz, przy kolizji speed gracza ustawiasz na 0 i zmieniasz na normalny tylko wtedy, gdy player_direction jest różny od player_direction w momencie wystąpienia kolizji.

0

Troche poprawiłem i cos zaczyna sie dziać. Pojawił sie nowy problem dziwny

  def move_left(self):
       for wall in walls:
          if self.rect.colliderect(wall.rect):
               self.rect.right = wall.rect.left
               print("Kolizjia")
               self.x = self.x -1


   def move_right(self):
       #self.x = self.x +1
       for wall in walls:
          if self.rect.colliderect(wall.rect):
               self.rect.left = wall.rect.right
               print("Kolizjia")
               self.x = self.x +1

Kod podobny a roznica w działaniu duza. Gdy gracz znajduje sie w scianie moze isc w lewo o jedno przesuniecie i na koncu sie blokuje.A gdy klikne w prawo Od razu wyrzuca gracza na sam koniec sciany i juz ruszyc sie nie moge

0

Wygląda jakby w Twojej grze ruch był skokowy.
self.K to wielkość kafelka?
Po co w takim razie bawisz się w prostokąty i mechanizmy wykrywania kolizji, skoro Twoja postać może poruszać się po tablicy dwuwymiarowej?
Przy każdym ruchu odczytujesz, co jest pod nowymi współrzędnymi. Jeśli nie da się iść w dane miejsce (np. kafelek ze ścianą), to nie wykonujesz ruchu.

0

Tak self.K odpowiada wielkosci kafelka.Rysuje po to by odejsc od tablic chce nauczyc sie robic kolizji wlasnie przez prostokąty. Mam pewien pomysl na rozwiazanie tego. Kiedys gdzies na jakims forum przewinelo mi sie ze mozna jakos raz cos wykonac w petli. Przykladowo jest cos tam while 100 i bedzie tam print ktory tylko raz sie wykona, Kojarzy ktos cos takiego ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1