#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    5
    Rep Power
    0

    Thumbs up 'pygame.display.set_mode' dimensions don't match window


    For those familiar with pygame, hopefully you can help me out... first off, I open up an 800 X 600 window like so, and upload a simple image of a green square:

    Code:
    DISPLAYSURF = pygame.display.set_mode((800, 600))
    gSquare = pygame.image.load('gsquarebase.bmp')
    Secondly, I move the green square around the window, and with the numbers I have below, the green square should stop moving when it hits near the borders of the window.

    Code:
        if keys[K_RIGHT]:
            pSquareX += 3
            if pSquareX >= 790:
                pSquareX -= 3 #stay within boundary
        if keys[K_LEFT]:
            pSquareX -= 3
            if pSquareX <= 10:
                pSquareX += 3
        if keys[K_UP]:
            pSquareY -= 3
            if pSquareY <= 10:
                pSquareY += 3
        if keys[K_DOWN]:
            if pSquareY >= 590:
                pSquareY -= 3
            pSquareY += 3
    Now, when moving the square to the top boundary and the left boundary, it works better; stopping movement closer to 10 pixels in from the window's edges. But when moving the square to the bottom and right edges, the square trails off the screen for quite a distance.

    If I write: 'if pSquareX >= 690:' instead of 'if pSquareX >= 790;' it works more like it should (for the right side).

    It's got to be something simple, but what am I missing here? Why don't the right and bottom dimensions match up with the window size I specify? It's more like the actual display object created is 800 X 600, but the window created when the program is run is 700 X 500.

    Make fun if you like, like I said I'm sure it's something simple.
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,714
    Rep Power
    480
    The trouble may be that the position of the square is the lower left corner, so you need to account for the picture width.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    191
    Rep Power
    2
    You may be interested in the functions pygame.Rect.clamp and pygame.Rect.clamp_ip. They allow you to constrain one rectangle to another rectangle without explicitly needing to state your bounds with inequalities.

    Example:
    python Code:
    import pygame as pg
    import sys,os
     
    #This global constant serves as a very useful convenience for me.
    DIRECTDICT = {pg.K_LEFT  : (-1, 0),
                  pg.K_RIGHT : ( 1, 0),
                  pg.K_UP    : ( 0,-1),
                  pg.K_DOWN  : ( 0, 1)}
     
    def main():
        os.environ["SDL_VIDEO_CENTERED"] = '1'
        pg.init()
        Screen = pg.display.set_mode((800, 600))
        MyClock = pg.time.Clock()
     
        g_square = pg.Surface((50,50)).convert()
        g_square.fill((0,255,0))
        g_square_rect = g_square.get_rect(center=Screen.get_rect().center)
        speed = 3
     
        done = False
        while not done:
            keys = pg.key.get_pressed()
            for event in pg.event.get():
                if event.type == pg.QUIT or keys[pg.K_ESCAPE]:
                    done = True
     
            for key in DIRECTDICT:
                if keys[key]:
                    for i in (0,1):
                        g_square_rect[i] += DIRECTDICT[key][i]*speed
            g_square_rect.clamp_ip(Screen.get_rect())
     
            Screen.fill(0)
            Screen.blit(g_square,g_square_rect)
            pg.display.flip()
            MyClock.tick(60)
     
    if __name__ == "__main__":
        main()
        pg.quit();sys.exit()

    -Mek
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    5
    Rep Power
    0
    Originally Posted by b49P23TIvg
    The trouble may be that the position of the square is the lower left corner, so you need to account for the picture width.
    Hey man, I actually have my square positioned at 350, 350.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    191
    Rep Power
    2
    Originally Posted by irontoad30
    Hey man, I actually have my square positioned at 350, 350.
    As he said, you are not taking into account the width of your sprite. You are blitting by the coordinates at the top-left corner. This means as you have written it, it is the topleft corner that won't get any closer than 10 pixels.

    Essentially, this is what you are doing:
    python Code:
    import pygame as pg
    import sys,os
     
    class Square(object):
        def __init__(self,color,size,loc):
            self.image = pg.Surface(size).convert()
            self.image.fill(color)
            self.rect = self.image.get_rect(center=loc)
     
    class Control(object):
        def __init__(self):
            os.environ["SDL_VIDEO_CENTERED"] = '1'
            pg.init()
            self.Screen = pg.display.set_mode((800, 600))
            self.ScreenRect = self.Screen.get_rect()
            self.keys = pg.key.get_pressed()
            self.Clock = pg.time.Clock()
            self.fps = 60
            self.done = False
            self.GreenSquare = Square((0,255,0),(100,100),(350,350))
        def event_loop(self):
            for event in pg.event.get():
                self.keys = pg.key.get_pressed()
                if event.type == pg.QUIT or self.keys[pg.K_ESCAPE]:
                    self.done = True
        def update(self):
            if self.keys[pg.K_RIGHT]:
                self.GreenSquare.rect.x += 3
                if self.GreenSquare.rect.x >= 790:
                    self.GreenSquare.rect.x -= 3 #stay within boundary
            if self.keys[pg.K_LEFT]:
                self.GreenSquare.rect.x -= 3
                if self.GreenSquare.rect.x <= 10:
                    self.GreenSquare.rect.x += 3
            if self.keys[pg.K_UP]:
                self.GreenSquare.rect.y -= 3
                if self.GreenSquare.rect.y <= 10:
                    self.GreenSquare.rect.y += 3
            if self.keys[pg.K_DOWN]:
                if self.GreenSquare.rect.y >= 590:
                    self.GreenSquare.rect.y -= 3
                self.GreenSquare.rect.y += 3
     
        def draw(self):
            self.Screen.fill(0)
            self.Screen.blit(self.GreenSquare.image,self.GreenSquare)
        def main(self):
            while not self.done:
                self.event_loop()
                self.update()
                self.draw()
                pg.display.flip()
                self.Clock.tick(self.fps)
     
    if __name__ == "__main__":
        RunIt = Control()
        RunIt.main()
        pg.quit();sys.exit()

    This is what you are trying to do:
    python Code:
    import pygame as pg
    import sys,os
     
    class Square(object):
        def __init__(self,color,size,loc):
            self.image = pg.Surface(size).convert()
            self.image.fill(color)
            self.rect = self.image.get_rect(center=loc)
     
    class Control(object):
        def __init__(self):
            os.environ["SDL_VIDEO_CENTERED"] = '1'
            pg.init()
            self.Screen = pg.display.set_mode((800, 600))
            self.ScreenRect = self.Screen.get_rect()
            self.keys = pg.key.get_pressed()
            self.Clock = pg.time.Clock()
            self.fps = 60
            self.done = False
            self.GreenSquare = Square((0,255,0),(100,100),(350,350))
        def event_loop(self):
            for event in pg.event.get():
                self.keys = pg.key.get_pressed()
                if event.type == pg.QUIT or self.keys[pg.K_ESCAPE]:
                    self.done = True
        def update(self):
            if self.keys[pg.K_RIGHT]:
                self.GreenSquare.rect.x += 3
                if self.GreenSquare.rect.x >= 790-self.GreenSquare.rect.width:
                    self.GreenSquare.rect.x -= 3 
            if self.keys[pg.K_LEFT]:
                self.GreenSquare.rect.x -= 3
                if self.GreenSquare.rect.x <= 10:
                    self.GreenSquare.rect.x += 3
            if self.keys[pg.K_UP]:
                self.GreenSquare.rect.y -= 3
                if self.GreenSquare.rect.y <= 10:
                    self.GreenSquare.rect.y += 3
            if self.keys[pg.K_DOWN]:
                if self.GreenSquare.rect.y >= 590-self.GreenSquare.rect.height:
                    self.GreenSquare.rect.y -= 3
                self.GreenSquare.rect.y += 3
     
        def draw(self):
            self.Screen.fill(0)
            self.Screen.blit(self.GreenSquare.image,self.GreenSquare)
        def main(self):
            while not self.done:
                self.event_loop()
                self.update()
                self.draw()
                pg.display.flip()
                self.Clock.tick(self.fps)
     
    if __name__ == "__main__":
        RunIt = Control()
        RunIt.main()
        pg.quit();sys.exit()


    And this is what you should ACTUALLY do:
    python Code:
    import pygame as pg
    import sys,os
     
    #This global constant serves as a very useful convenience for me.
    DIRECTDICT = {pg.K_LEFT  : (-1, 0),
                  pg.K_RIGHT : ( 1, 0),
                  pg.K_UP    : ( 0,-1),
                  pg.K_DOWN  : ( 0, 1)}
     
     
    class Square(object):
        def __init__(self,color,size,loc):
            self.image = pg.Surface(size).convert()
            self.image.fill(color)
            self.rect = self.image.get_rect(center=loc)
            self.speed = 3
     
    class Control(object):
        def __init__(self):
            os.environ["SDL_VIDEO_CENTERED"] = '1'
            pg.init()
            self.Screen = pg.display.set_mode((800, 600))
            self.ScreenRect = self.Screen.get_rect()
            self.ClampRect = self.ScreenRect.inflate(-20,-20)
            self.keys = pg.key.get_pressed()
            self.Clock = pg.time.Clock()
            self.fps = 60
            self.done = False
            self.GreenSquare = Square((0,255,0),(100,100),(350,350))
        def event_loop(self):
            for event in pg.event.get():
                self.keys = pg.key.get_pressed()
                if event.type == pg.QUIT or self.keys[pg.K_ESCAPE]:
                    self.done = True
        def update(self):
            for key in DIRECTDICT:
                if self.keys[key]:
                    self.GreenSquare.rect.x += DIRECTDICT[key][0]*self.GreenSquare.speed
                    self.GreenSquare.rect.y += DIRECTDICT[key][1]*self.GreenSquare.speed
                    self.GreenSquare.rect.clamp_ip(self.ClampRect)
        def draw(self):
            self.Screen.fill(0)
            self.Screen.blit(self.GreenSquare.image,self.GreenSquare)
        def main(self):
            while not self.done:
                self.event_loop()
                self.update()
                self.draw()
                pg.display.flip()
                self.Clock.tick(self.fps)
     
    if __name__ == "__main__":
        RunIt = Control()
        RunIt.main()
        pg.quit();sys.exit()

    -Mek
    Last edited by Mekire; June 12th, 2013 at 06:59 PM.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    5
    Rep Power
    0
    Thanks Mekire, I think I see what's going on now...

IMN logo majestic logo threadwatch logo seochat tools logo