Есть ли решение, что значение Y моего ящика будет увеличиваться или уменьшаться после того, как оно «ударит» о стену? - PullRequest
1 голос
/ 25 апреля 2020

Основная идея проста: у меня есть поле, и оно меняет свою позицию на ШИРИНУ каждые x секунд (управляется значением "галочка"), а также, когда оно касается боковой части экрана, оно меняет направление , Если он попадает в правую часть экрана, значение Y увеличивается на величину поля HEIGHT, если оно попадает в левую сторону, значение Y уменьшается.

Моя проблема в том, что после того, как мой ящик врезается в стену, он несколько раз увеличивает свое значение Y, прежде чем изменить направление. Я хочу, чтобы он менялся 1 раз, а затем go в другом направлении.

Я пытался изменить значение X блока, извлекая или добавляя 1 из / к нему, чтобы между стеной и блоком был промежуток; поэтому оператор IF будет ложным до следующего кадра, и он не будет увеличивать значение Y, и у блока будет время изменить направление и перейти в другое направление. Это решение вроде работало, но коробка все равно подскочила вдвое выше или ниже, а не точно на 1 ВЫСОТУ. Я также попробовал несколько вещей, но это было лучшее, что я мог придумать: /

Вот пример кода, я добавил сетку, чтобы вы могли точно увидеть, в чем моя проблема. ЗДЕСЬ ИЗОБРАЖЕНИЕ

import pygame
pygame.init()

WIN_W, WIN_H = 200, 500
FPS = 60

screen = pygame.display.set_mode((WIN_W, WIN_H))
clock = pygame.time.Clock()

# rect pos, dimensions
rct_x, rct_y = 100, 80
rct_w, rct_h = 20, 10

ct = 0
tick = .5
direction = True

run = True
while run:
    dt = clock.tick(FPS) / 1000
    screen.fill((0, 0, 0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    rct = pygame.Rect((rct_x, rct_y), (rct_w, rct_h))
    pygame.draw.rect(screen, (255, 50, 50), rct)

    # grid for better viualisation
    for row in range(50):
        pygame.draw.rect(screen, (50, 100, 50), pygame.Rect((0, row * 10), (WIN_W-1, 1)), 1)
        for col in range(35):
            pygame.draw.rect(screen, (50, 100, 50), pygame.Rect((col * 20, 0), (1, WIN_H)), 1)

    # if rect Xpos + WIDTH greater than SCREEN WIDTH
    if rct_x + rct_w >= WIN_W:
        # increase rect Ypos by its HEIGHT
        rct_y += rct_h
        direction = False
    # if rect Xpos less than 0
    elif rct_x <= 0:
        # decease rect Ypos by its HEIGHT
        rct_y -= rct_h
        direction = True

    ct += dt
    if ct >= tick:
        ct = 0

        if direction:
            # move rect right if direction true
            rct_x += rct_w
        else:
            # move rect left if direction false
            rct_x -= rct_w

    pygame.display.update()

Ответы [ 2 ]

1 голос
/ 25 апреля 2020

Вы должны делать все движения только if ct >= tick:. Если объект перемещается по y, то ему не разрешено перемещаться по x. Добавьте переменную move_x, в которой указывается, разрешено ли перемещение объектов в x.
Объект перемещается вниз один раз if direction == True and rct_x + rct_w >= WIN_W, и он перемещается вверх один раз if direction == False and rct_x <= 0:

while run:
    # [...]

    ct += dt
    if ct >= tick:
        ct = 0
        move_x = True

        # if rect Xpos + WIDTH greater than SCREEN WIDTH
        if direction == True and rct_x + rct_w >= WIN_W:
            # increase rect Ypos by its HEIGHT
            rct_y += rct_h
            direction = False
            move_x = False

        # if rect Xpos less than 0
        elif direction == False and rct_x <= 0:
            # decease rect Ypos by its HEIGHT
            rct_y -= rct_h
            direction = True 
            move_x = False   

        if move_x:
            if direction:
                # move rect right if direction true
                rct_x += rct_w
            else:
                # move rect left if direction false
                rct_x -= rct_w
1 голос
/ 25 апреля 2020

Вы можете сделать ct = tick, когда он столкнется со стеной, но это заставит его двигаться очень быстро, что, вероятно, не то, что вы после.

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

    ct += dt
if ct >= tick:
    ct = 0
    # if rect Xpos + WIDTH greater than SCREEN WIDTH
    if rct_x + rct_w >= WIN_W:
        if direction != "left":
            direction = "down"
    # if rect Xpos less than 0
    elif rct_x <= 0:
        if direction != "right":
            direction = "up"        

    if direction == "right":
        rct_x += rct_w
    elif direction == "left":
        rct_x -= rct_w
    elif direction == "down":
        rct_y += rct_h
        direction = "left"
    elif direction == "up":
        rct_y -= rct_h
        direction = "right"

Проверка, находилась ли на краю, а затем перемещение влево или вправо означало, что он двигался влево или вправо каждый раз, а это не то, что вы хотите, так как вы хотите, чтобы он также двигался вверх и вниз без движения влево или вправо. Так что я изменил направление на 4 направления, чтобы он мог двигаться только в одном направлении каждый тик. если он находится на краю, он изменит направление движения вверх или вниз, затем переместится, в следующем кадре он все еще будет на краю и будет двигаться вверх или вниз, поэтому я добавил if direction != "left", поэтому он будет только go вниз если он на краю и движется вправо, чего вы хотите.

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