Обработка столкновений прямоугольников Python с pygame


В течение последних нескольких дней я проводил обширные исследования на эту тему и, похоже, не могу найти ответ на мою точную проблему.

Итак, у меня есть простая игра, в которой у меня есть игрок на 0, 0 с шириной 10x10

    player= pygame.Rect(0, 0, 10, 10)

И кроме того, игрок имеет скорость x: 0, y: 10, которая заставит его упасть (y положительно, потому что начало экрана находится в левом верхнем углу.)

И у меня есть плитка на 0, 100, как показано:

    dirt= pygame.Rect(0, 100, 10, 10)

Итак, как я могу ручка столкновение, я уже знаю, что могу обнаружить его с помощью Rect.colliderect (прямая кишка).

Я попробовал несколько способов, но столкнулся с некоторыми проблемами:

Я не могу уменьшить скорость игрока до 0, когда он ударяется о что-то, а затем переместить его назад, пока он просто не коснется объекта, потому что это все еще вызывает проблему ходьбы, когда он ходит, я применяю скорость +10 на x, но, к сожалению, игра все еще обрабатывает, что он падает и сталкивается и , двигаясь боком, так что это просто возвращает его туда, откуда он начал.

Я новичок, поэтому простой ответ был бы оценен, и я хотел бы , чтобы мне не пришлось использовать любые сторонние модули, кроме pygame, если бы мне не пришлось.

Обновление:

Вот некоторые из грубых тестовых кодов, которые я пробовал:

    def sim(obj, time, world):
        time= time / 1000
        obj.physProp['vel']= (obj.physProp['vel'][0] + (accel[0] * time), obj.physProp['vel'][1] + (accel[1] * time))
        if obj.physProp['vel'][1] > terminalY:
            obj.physProp['vel']= (obj.physProp['vel'][0], terminalY)
        obj.pos= (obj.pos[0] + (obj.physProp['vel'][0] * time) + ((accel[0] / 2) * (time ** 2)), obj.pos[1] + (obj.physProp['vel'][1] * time) + ((accel[1] / 2) * (time ** 2)))

        for ID in world:
            if obj.getRect().colliderect(world[ID].getRect()) == True:
                pass

        return (obj.pos, obj.physProp['vel'])
2 4

2 ответа:

Pygame API предлагает вам написать все ваши игровые предметы в объектно-ориентированном виде - так, чтобы ваш падающий персонаж имел все "методы" и "атрибуты", чтобы правильно реагировать на вещи по сценарию - например, ударять что-то.

Итак, если ваш персонаж определен для чего-то столь же простого, как:

class Char(object):
    # these start as class attributes, 
    # but whenever they are assigned to with a "self.var = bla" in
    # a method, an instance attribute starts existing
    x, y = 0,0
    vx, vy = 0,0

    def update(self):
        self.x += self.vx
        self.y += self.vy

И ваш внешний код, обнаружив столкновение, может сделать именно это:

def mainloop():
   while True:
       ...
       obj.update()
       if obj.getRect().colliderect(world[ID].getRect()): # don't do "== True" in `if's - it is just silly
             # take character back to the precious position
             obj.x -= obj.vx
             obj.y -= obj.vy
             # zero out velocities to make it stop:
             obj.vx = obj.vy = 0

И так далее-вы скоро будете воспринимать мышление о ваших игровых "вещах" как "объекты", как они используются в программировании, делают потоки кода вполне естественными - как только вы поймете, как это работает, посмотрите на модуль sprite Pygame , который позволяет автоматизировать множество проверок и обновлений без необходимости явно писать циклы for для каждой проверки

Разделите движение x/y.

Переместите x, проверьте, не столкнулись ли они, если да, переместитесь назад и установите xspeed в 0.

Переместите y, проверьте, не столкнулись ли они, если да, переместитесь назад и установите yspeed в 0.

Это действительно означает две проверки столкновений на каждом шаге, но это супер гладко. :)