Не получается добавить коллизии к изометрической игре/выдать их игроку и земле

григорий5643

Новичок
Пользователь
Июн 23, 2021
33
1
8
ОС - Windows 10
Pyrhon 3.9.5

cycler 0.10.0
kiwisolver 1.3.1
matplotlib 3.4.2
numpy 1.20.3
perlin-noise 1.7
Pillow 8.2.0
pip 21.1.2
pygame 2.0.1
pyparsing 2.4.7
python-dateutil 2.8.1
setuptools 56.0.0
six 1.16.0]

Проблема в том, что я вроде-бы прописал коллизии и сделал все как нужно, но когда запускаю код, игрок при нажатии кнопок двигается на пару пикселей и сразу возвращается назад, не могу понять что и где не так, может кто подскажет?

вот:
Python:
import pygame
import sys
import time
import random

from pygame.draw import rect

WIDTH = 700
HEIGHT = 700
from pygame.constants import K_DOWN, K_LEFT, K_RIGHT, K_UP, QUIT

x = 0
y = 0
speed = 5

clock = pygame.time.Clock()


pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32)
pygame.display.set_caption("game base")
display = pygame.Surface((300, 300))

ground_img = pygame.image.load('ground3.png')
ground_img.set_colorkey((0, 0, 0))
stone_img = pygame.image.load("stone2.png").convert()
stone_img.set_colorkey((0, 0, 0))


ground_dict = {}  # словарь {ряд-номер клетки-номер слоя: название картинки}

# читаем данные карты из файла и заполняем ими словарь
with open('map.txt') as f:
    map_data = [[int(c) for c in row.strip()] for row in f]
    for y, row in enumerate(map_data):
        for x, tile in enumerate(row):             
            if tile:
                ground_dict[f'{y}-{x}-1'] = 'stone'
                # для второго слоя
                if random.randint(0, 1):
                    ground_dict[f'{y}-{x}-2'] = 'ground'                       

while True:
    display.fill((0, 0, 0))
    clock.tick(60)
    # проходим в цикле по словарю
    for key, value in ground_dict.items():
        # получаем ряд, номер клетки и номер слоя
        y, x, n = list(map(int, key.split('-')))
        # определяем нужную картинку для клетки
        z = stone_img if value == 'stone' else ground_img
        # отрисовываем в зависимости от номера слоя
        if n == 1:
            display.blit(z, (150 + x * 10 - y * 10, 100 + x * 5 + y * 5))
        elif n == 2:
            display.blit(z, (150 + x * 10 - y * 10, 100 + x * 5 + y * 5 - 14))   
    

    class stone(pygame.sprite.Sprite):
       def __init__(self):
           pygame.sprite.Sprite.__init__(self)
           self.x = 0
           self.y = 0
           self.image = ground_dict
           self.rect = pygame.Rect(self.x,self.y,16,16) #The rect for collision detection.

    class player(pygame.sprite.Sprite):
        def __init__(self,x,y):
            pygame.sprite.Sprite.__init__(self)
            self.image = pygame.image.load('mainhero.png')
            self.rect = rect(x, y, 16, 16)

        def move(self, px, py):
            if px != 0:
                self.move_on_axis(px, 0)
            if py != 0:
                self.move_on_axis(0, py)

        def move_on_axis(self, px, py):
            self.rect.x += px
            self.rect.y += py   

            for stone in ground_dict: 
                if pygame.sprite.collide_rect(self, stone):   
                    if px > 0:
                        self.rect.right = stone.rect.left
                    if px < 0:
                        self.rect.left = stone.rect.right
                    if py > 0:
                        self.rect.bottom = stone.rect.top                       
                    if py < 0:
                        self.rect.top = stone.rect.bottom
    
    keys = pygame.key.get_pressed()

    if keys [K_LEFT]:
        x -= speed
    elif keys [K_RIGHT]:
        x += speed
    elif keys [K_UP]:
        y -= speed
    elif keys [K_DOWN]:
        y += speed
    
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    
    screen.blit(pygame.image.load('mainhero.png'), (x,y))
    screen.blit(pygame.transform.scale(display, screen.get_size()), (55, 55))
    pygame.display.update()
    time.sleep(1)
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
игрок при нажатии кнопок двигается на пару пикселей и сразу возвращается назад
Так происходит потому что для передвижения игрока вы используйте переменные x и y, а они уже используются в цикле выше и каждую итерацию меняют свои значения, из-за чего позиция игрока возвращается к стартовой.
Чтобы игрок двигался переименуйте переменные x и y, например на x1 и y1, в этих строках:

Python:
x = 0
y = 0

if keys [K_LEFT]:
    x -= speed
elif keys [K_RIGHT]:
    x += speed
elif keys [K_UP]:
    y -= speed
elif keys [K_DOWN]:
    y += speed
    
screen.blit(pygame.image.load('mainhero.png'), (x,y))
Также чтобы он двигался быстрее уберите из цикла строку:
Python:
time.sleep(1)
 

Форум IT Специалистов