Обработка столкновений прямоугольников 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 ответа:
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.
Это действительно означает две проверки столкновений на каждом шаге, но это супер гладко. :)