Как проверить столкновение прямоугольника и предыдущую позицию прямоугольника в Pygame? - PullRequest
0 голосов
/ 01 марта 2019

Я создаю игру Tron (https://www.classicgamesarcade.com/game/21670/tron-game.html) и мне нужно проверить всех гонщиков, сталкиваются ли они друг с другом.

import pygame
pygame.init()

screenWidth = 500
screenHeight = 500
clock = pygame.time.Clock()
win = pygame.display.set_mode((screenWidth,screenHeight))
#both width and height of the characters
radius = 5
#amount of change in the x or y of the characters every frame
vel = 5

pygame.display.set_caption("Tron")


class character(object):
    #'direction' is the direction the character will move
    #'keyBinds' are the keys that can change the direction
    def __init__(self, x, y, color, direction, keyBinds):
        self.x = x
        self.y = y
        self.color = color
        self.direction = direction
        self.keyBinds = keyBinds

    #changes the direction the character moves
    def changeDirection(self, keys):
        #only changes when the right key was pressed and the character isn't already moving the opposite direction
        if keys[self.keyBinds[0]] and self.direction != 'r': 
            self.direction = 'l'
        elif keys[self.keyBinds[1]] and self.direction != 'l':
            self.direction = 'r'
        elif keys[self.keyBinds[2]] and self.direction != 'd':
            self.direction = 'u'
        elif keys[self.keyBinds[3]] and self.direction != 'u':
            self.direction = 'd'

    def move(self, vel):
        if self.direction == 'l':
            self.x -= vel
        elif self.direction == 'r':
            self.x += vel
        elif self.direction == 'u':
            self.y -= vel
        elif self.direction == 'd':
            self.y += vel

    #returns True if the character should be dead
    def checkDead(self, radius, screenWidth, screenHeight):
        #check if the character is out of bounds
        if (self.x < 0) or (self.x + radius > screenWidth) or (self.y < 0) or (self.y + radius > screenWidth):
            return True
        #check if the character has collided WIP


#makes a list with characters
chars = [
    character(480, 250, (255,0,0), 'l', (pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN)),
    character(20, 250, (0,255,0), 'r', (pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s))
    ]
run = True

#main loop
while run:
    #makes the loop run 30 times a second
    clock.tick(30)

    #closes the window, if 'X' is pressed
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    #logs all keys being pressed in a list I think xd
    keys = pygame.key.get_pressed()

    #closes the window, if there are no characters left in 'chars'
    if len(chars) > 0:
        #runs all object functions of every character in 'chars'
        for char in chars:
            char.changeDirection(keys)
            char.move(vel)
            #draws a rectangle representing the charater
            pygame.draw.rect(win, char.color, (char.x, char.y, radius, radius))
            #removes the character from 'chars' if checkDead returns True
            if char.checkDead(radius, screenWidth, screenHeight):
                chars.pop(chars.index(char))
    else:
        run = False

    pygame.display.update()

pygame.quit()

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

Теперь возникает большая проблема. Как и в классическом Троне, мне нужно учитывать и предыдущие позиции гонщиков для столкновений.

Кроме этого, я всегда ценю советыо том, как я могу улучшить свой код, поэтому, если вы видите что-то, что вы обрабатываете по-другому, пожалуйста, дайте мне знать!

Заранее спасибо!

Редактировать 1: Изменил название с: Как я могупроверить столкновение прямоугольника нескольких объектов в Pygame? to: Как проверить столкновение прямоугольника и предыдущую позицию прямоугольника в Pygame ?, потому что на главный вопрос уже был дан ответ в другом посте, но естьЕще есть вопросы, требующие ответа.Кроме того, в моей структуре моего кода проверка на столкновение была бы в checkDead ()

1 Ответ

0 голосов
/ 01 марта 2019

В конце концов, Tron - это игра, основанная на сетке, поэтому простое решение - просто сохранить список очков / плиток, которые уже «взяты», а затем проверить, пытается ли игрок перейти к уже взятой плитке.,

...
painted = set()
...
class character(object):
    ...
    #returns True if the character should be dead
    def checkDead(self, radius, screenWidth, screenHeight, painted):
        #check if the character is out of bounds
        if (self.x < 0) or (self.x + radius > screenWidth) or (self.y < 0) or (self.y + radius > screenWidth):
            return True

        #check if the character has collided WIP
        return (char.x / radius, char.y / radius) in painted

...
while run:
    ...
    #closes the window, if there are no characters left in 'chars'
    if len(chars) > 0:
        #runs all object functions of every character in 'chars'
        for char in chars:
            char.changeDirection(keys)
            char.move(vel)
            #removes the character from 'chars' if checkDead returns True
            if char.checkDead(radius, screenWidth, screenHeight, painted):
                chars.pop(chars.index(char))

        for char in chars:
            painted.add((char.x / radius, char.y / radius))

        for char in chars:
            #draws a rectangle representing the charater
            pygame.draw.rect(win, char.color, (char.x, char.y, radius, radius))

Обратите внимание, что это работает, потому что вы перемещаете одну плитку за кадр.Если вы решите позволить своим игрокам перемещать более одной плитки за кадр, вам придется добавить эти дополнительные плитки также в набор painted.

Конечно, есть много разных способов сделать это.это по-другому.Например, вы можете проверить часть экрана, на которой вы собираетесь рисовать прямоугольник, на наличие любых не черных пикселей.Или вы можете сохранить все списки, которые вы рисуете на экране, в списке и использовать Rect.colliderect для проверки столкновений (возможно, медленных).Так что давайте будем простыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...