0

I'm programming a game with moving boxes. I've done everything and got it to run and show up, however the boxes cannot go outside of the screen. I think it's something with the elifs or within them. Where is my error and how can I get them to move?

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()
0

1 Answer 1

1

There are multiple (many) problems with your variable names, assignments and the logic.

The core of the problems are in the movement code. a Box is a surface box1, and has co-ordinates box1X and box1Y. The boolean moveBox1 determines if the keyboard input is for the selected box (keys: 1,2,3,4).

The code governing movement left is:

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

So if the user was trying to move box2, it's not possible, and is corrupting the surface stored in box2 with the number of box2X-30. Similarly there's issues for all the other movement code.

In the K_RIGHT movement clause:

box2X = box2X + 540

Which moves the box to the other side of the screen, is this intended?

I patched the code to the point where I could move box1 left & right by 10 pixels at a time:

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()

I don't want to sound harsh - because we all beginners once, but this code is a good example of why data structures and classes, although more work initially, make the coding much easier and faster.

The OP's boxes could easily stored in a list, like:

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

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

And then just iterate through the list, doing the processing:

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

This removes the tyranny of having a huge bunch of similarly-named position variables. With so many, it's easy to get confused with all their comings & goings.

So, better yet, put everything about a Box in a class, which keeps it all together, and would provide more meaningful "readable" code:

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()
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you so much. I'm very much an amateur so I'm afraid I'm not familiar with classes. Unfortunately because of my requirements I can't use classes or lists. I tried fixing it and here's how it went. Kept getting error saying: screen.blit(box4, (box4X, box4Y)) TypeError: argument 1 must be pygame.Surface, not int. Here is how the code looks now. Also 3 only moves right one unit and 4 only moves up to the top of the screen. My goal is to have the numbers move in all directions yet have them not off the screen. Thanks again.
@Josie - The error: argument 1 must be pygame.Surface, not int. means you've overwriting the Surface you created with something else. Maybe there's still a box4 assignment that should be box4Y ? Search your code for box4= (or box4 =) there should only be that first assignment statement.
@Josie Unfortunately because of my requirements I can't use classes or lists: TBH that's a strange requirement because clearly you already use the Surface and the Clock classes. Also, you already use tuples, so how can lists be a problem?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.