Как заставить объекты двигаться в программе pygame? - PullRequest
0 голосов
/ 22 марта 2019

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

screen = pygame.display.set_mode( (640, 480) )
pygame.display.set_caption("Wahoo")




background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill( (204,204,255) )



box1 = pygame.Surface((100,100))
box1 = box1.convert()
labelBox(box1, (153, 255, 255), "1")
box1X = 0          # The starting location for this box
box1Y = 0
moveBox1 = False   # If True, this is the box that moves

box2 = pygame.Surface((100,100))
box2 = box2.convert()
labelBox(box2, (255, 255,153), "2")
box2X = 540        # The starting location for this box
box2Y = 0
moveBox2 = False   # If True, this is the box that moves

box3 = pygame.Surface((100,100))
box3 = box3.convert()
labelBox(box3, (153, 255, 153), "3")
box3X = 540        # The starting location for this box
box3Y = 380
moveBox3 = False   # If True, this is the box that moves

box4 = pygame.Surface((100,100))
box4 = box4.convert()
labelBox(box4, (255, 153, 204), "4")
box4X = 0        # The starting location for this box
box4Y = 380
moveBox4 = False   # If True, this is the box that moves



clock = pygame.time.Clock()
keepGoing = True



    clock.tick(30)   # Maintain 30 frame per second refresh.


    for event in pygame.event.get() :
        if   event.type == pygame.QUIT :
                keepGoing = False
        elif event.type == pygame.MOUSEBUTTONDOWN :
            box1X=0
            box1Y=0

            box2X=540
            box2Y=0

            box3X=540
            box3Y=380

            box4X=0
            box4Y=380





        elif event.type == pygame.KEYDOWN :
            if   event.key == pygame.K_ESCAPE :
                keepGoing = False



            elif event.key == pygame.K_1 :
                moveBox1==True
                moveBox2==False
                moveBox3==False
                moveBox4==False

            elif event.key == pygame.K_2 :
                moveBox2==True
                moveBox3==False
                moveBox4==False
                moveBox1==False


            elif event.key == pygame.K_3 :
                moveBox3==True
                moveBox4==False
                moveBox2==False
                moveBox1==False

            elif event.key == pygame.K_4:
                 moveBox4==True
                 moveBox1==False
                 moveBox2==False
                 moveBox3==False



            elif event.key == pygame.K_LEFT :
                if moveBox1==True and box1X>=30:
                    box1X=box1X-30
                elif box2==True and box2X>=30:
                    box2=box2X-30
                elif box3==True and box3X>=30:
                    box3=box3X-30
                elif box4==True and box4X>=30:
                    box4=box4X-30


            elif event.key == pygame.K_RIGHT :
                if moveBox2==True and box2X<=540:
                    box2X=box2X+540
                elif box3==True and box3X<=540:
                    box3=Box3X+540
                elif box4==True and box4X<=540:
                    box4=box4X+540
                elif box1==True and box1X<=540:
                    box1=box1X+540


            elif event.key == pygame.K_UP :
                if moveBox3==True and box3Y<=580:
                    box3Y==box3Y+580
                elif box4==True and box4Y>=580:
                    box4=box4Y+580
                elif box2==True and box2Y>=580:
                    box2=box2Y+580
                elif box1==True and box1Y>=580:
                    box1=box1Y+580



                elif event.key == pygame.K_DOWN :
                    if moveBox4==True and box4Y>=380:
                        box4Y=box4Y-380
                    elif box1==True and box1Y>=580:
                        box1=box1Y-380
                    elif box2==True and box2Y>=580:
                        box2=box2Y-380
                    elif box3==True and box3Y>=580:
                        box3=box3Y-380 






    screen.blit(background, (0,0))
    screen.blit(box1, (box1X, box1Y))
    screen.blit(box2, (box2X, box2Y))
    screen.blit(box3, (box3X, box3Y))
    screen.blit(box4, (box4X, box4Y))

    pygame.display.flip()

1 Ответ

1 голос
/ 22 марта 2019

Существует множество (много) проблем с именами переменных, назначениями и логикой.

Суть проблем заключается в коде движения.Box является поверхностью box1 и имеет координаты box1X и box1Y.Логическое значение moveBox1 определяет, предназначен ли ввод с клавиатуры для выбранного поля (клавиши: 1,2,3,4).

Код, управляющий движением влево:

elif event.key == pygame.K_LEFT :
    if moveBox1==True and box1X>=30:   # <-- this clause is OK
        box1X=box1X-30
    elif box2==True and box2X>=30:     # <-- WRONG, not "box2", use "moveBox2=="
        box2=box2X-30                  # <-- WRONG, not "box2", use "box2X="
    elif box3==True and box3X>=30:
        box3=box3X-30
    elif box4==True and box4X>=30:
        box4=box4X-30

Итакесли пользователь пытался переместить box2, это невозможно, и он повреждает поверхность, сохраненную в box2, с номером box2X-30.Точно так же есть проблемы для всех других кодов движения.

В предложении K_RIGHT движения:

box2X = box2X + 540

Что перемещает прямоугольник на другую сторону экрана, это предназначено?

Я пропатчил код до точки, где я мог бы двигаться box1 влево и вправо на 10 пикселей за раз:

import pygame

pygame.init()
screen = pygame.display.set_mode( (640, 480) )
pygame.display.set_caption("Wahoo")


background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill( (204,204,255) )

# Not supplied by OP
def labelBox( surface, colour, label ):
    surface.fill( colour )

box1 = pygame.Surface((100,100))
#box1 = box1.convert()
labelBox(box1, (153, 255, 255), "1")
box1X = 0          # The starting location for this box
box1Y = 0
moveBox1 = False   # If True, this is the box that moves

box2 = pygame.Surface((100,100))
box2 = box2.convert()
labelBox(box2, (255, 255,153), "2")
box2X = 540        # The starting location for this box
box2Y = 0
moveBox2 = False   # If True, this is the box that moves

box3 = pygame.Surface((100,100))
box3 = box3.convert()
labelBox(box3, (153, 255, 153), "3")
box3X = 540        # The starting location for this box
box3Y = 380
moveBox3 = False   # If True, this is the box that moves

box4 = pygame.Surface((100,100))
box4 = box4.convert()
labelBox(box4, (255, 153, 204), "4")
box4X = 0        # The starting location for this box
box4Y = 380
moveBox4 = False   # If True, this is the box that moves



clock = pygame.time.Clock()
keepGoing = True

while ( keepGoing == True ):

    clock.tick(30)   # Maintain 30 frame per second refresh.


    for event in pygame.event.get() :
        if event.type == pygame.QUIT :
            keepGoing = False
        elif event.type == pygame.MOUSEBUTTONDOWN :
            box1X=0
            box1Y=0

            box2X=540
            box2Y=0

            box3X=540
            box3Y=380

            box4X=0
            box4Y=380

        elif event.type == pygame.KEYDOWN :
            print("KEY...")
            if event.key == pygame.K_ESCAPE :
                keepGoing = False

            elif event.key == pygame.K_1 :
                moveBox1=True
                moveBox2=False
                moveBox3=False
                moveBox4=False

            elif event.key == pygame.K_2 :
                moveBox2=True
                moveBox3=False
                moveBox4=False
                moveBox1=False

            elif event.key == pygame.K_3 :
                moveBox3=True
                moveBox4=False
                moveBox2=False
                moveBox1=False

            elif event.key == pygame.K_4:
                moveBox4=True
                moveBox1=False
                moveBox2=False
                moveBox3=False

            elif event.key == pygame.K_LEFT :
                print("LEFT")
                if moveBox1==True and box1X>=30:
                    box1X -= 10
                    print("MOVE 1 LEFT, box1X=%d" % (box1X))
                elif moveBox2==True and box2X>=30:
                    box2X -= 10
                elif moveBox3==True and box3X>=30:
                    box3X -= 10
                elif moveBox4==True and box4X>=30:
                    box4X -= 10

            elif event.key == pygame.K_RIGHT :
                print("RIGHT")
                if moveBox1==True and box1X<=540:
                    box1X += 10
                    print("MOVE 1 RIGHT, box1X=%d" % (box1X))
                elif moveBox2==True and box2X<=540:
                    box2X += 10
                elif moveBox3==True and box3X<=540:
                    box3X += 10
                elif moveBox4==True and box4X<=540:
                    box4X += 10

            elif event.key == pygame.K_UP :
                if moveBox3==True and box3Y<=580:
                    box3Y==box3Y+580
                elif moveBox4==True and box4Y>=580:
                    box4Y=box4Y+580
                elif moveBox2==True and box2Y>=580:
                    box2Y=box2Y+580
                elif moveBox1==True and box1Y>=580:
                    box1Y=box1Y+580

            elif event.key == pygame.K_DOWN :
                if moveBox4==True and box4Y>=380:
                    box4Y=box4Y-380
                elif moveBox1==True and box1Y>=580:
                    box1Y=box1Y-380
                elif moveBox2==True and box2Y>=580:
                    box2Y=box2Y-380
                elif moveBox3==True and box3Y>=580:
                    box3Y=box3Y-380 

    screen.blit(background, (0,0))
    screen.blit(box1, (box1X, box1Y))
    screen.blit(box2, (box2X, box2Y))
    screen.blit(box3, (box3X, box3Y))
    screen.blit(box4, (box4X, box4Y))

    pygame.display.flip()

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

Операционные функции box могут легкохранится в списке, например:

box1 = [ "Box1", Surface(100,100), (0,0),   True  ]
box2 = [ "Box2", Surface(100,100), (500,0), False ]
...

box_list = [ box1, box2, ... ] # for N boxes

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

#... LEFT key pressed
for box in box_list:
    label, surface, coord, selected = box
    if ( selected == True ):
        ... do stuff to move box

Это устраняет тиранию наличия огромной связки с одинаковыми именамипеременные положения.С таким количеством людей легко запутаться со всеми их приходами и уходами.

Так что, еще лучше, поместите все о Box в класс, который объединит все это и обеспечит более осмысленный «читабельный»код:

class Box:
    def __init__( self, label, size, position, colour ):
        self.surface  = pygame.Surface( ( size, size ) )
        self.rect     = self.surface.get_rect()
        self.rect.x   = position[0]
        self.rect.y   = position[1]
        self.selected = False
        self.surface.fill( colour )
        # TODO: put label on box

   def moveLeft( self ):
       self.rect.x -= 30

   def paint( self, window ):
       window.blit( self.surface, ( self.rect.x, self.rect.y ) )

...

#... LEFT key pressed
for box in box_list:
    if ( box.selected == True ):
        box.moveLeft()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...