[Pygame] aligning text with another surface

[Pygame] aligning text with another surface

Postby metulburr » Tue Apr 23, 2013 10:54 pm

I really thought this would of worked. I mean in theory it works, unless i typoed something. But currently variable buff, never seems to get updated upon each loop, nor does that vars. that leads up to it.

Code: Select all
      spacer = self.images.image[1].get_width() // self.text_size[1]
      print('spacer {}'.format(spacer))
      buff = spacer // 2
      print('buff {}'.format(buff))


These values stay the same upon each loop. I would of thought they change, where self.images.image is a list of tuples, where index 1 is the image object.

and self text size is the labels's get_size() value. self.text() returns the label.
Code: Select all
      #assignments
      self.images.image = self.images.album[self.images.image_ind]
      text = self.text(self.images.image[0], color=(0,0,0))
      self.text_size = text.ge



I jsut thought they would update upon each loop of the current images' get_size() value upon each loop, but they are jsut staying the same.

full code:
Code: Select all
import pygame
import os
import time

class ImageClass:
   def __init__(self):
      self.image_dir = '/home/metulburr/Pictures/alchemy_images'
      self.album = []
      self.image = None
      self.image_ind = 0
      self.rect = None
      self.highlight = False
      self.get_images()
      self.rect = self.album[0][1].get_rect() #set initial first rect
      
   def get_images(self):
      for f in os.listdir(self.image_dir):
         if f.endswith('.png'):
            orig_image = pygame.image.load(os.path.join(self.image_dir, f)).convert_alpha()
            rect = orig_image.get_rect()
            highlight_image = self.make_highlight(rect, orig_image)
            self.album.append(
                  (
                     os.path.splitext(f)[0].replace('_',' ').title(),
                     orig_image,
                     highlight_image,
                     rect
                  )
               )
   def make_highlight(self, rect, img):
      temp = pygame.Surface(rect.size).convert()
      temp.set_colorkey((255,255,255))
      temp.fill((255,255,255))
      temp.blit(img,(0,0))
      temp.set_alpha(100)
      return temp
      
class Control:
   def __init__(self):
      pygame.init()
      self.screensize = (600,600)
      self.screen = pygame.display.set_mode(self.screensize)
      self.clock = pygame.time.Clock()
      self.mouseX = 0
      self.mouseY = 0
      self.keys = None
      self.mouse_keys = (0,0,0)
      self.mouse_held = False
      self.is_dragging = False
      self.text_size = (0,0)
      
      
      self.images = ImageClass()
      
   def text(self, displaytext, color=(0,0,0), size=15, ul=False, bold=False,
         ital=False, font='timesnewroman'):
      font = pygame.font.SysFont(font, size)
      font.set_underline(ul)
      font.set_bold(bold)
      font.set_italic(ital)
      label = font.render(displaytext, 1, color)
      #self.text_size = label.get_size()
      return label
      


   def update(self):
      #adjust index to 0 if past list
      if self.images.image_ind > len(self.images.album)-1:
         self.images.image_ind = 0
      
      #assignments
      self.images.image = self.images.album[self.images.image_ind]
      text = self.text(self.images.image[0], color=(0,0,0))
      self.text_size = text.get_size()
      
      #check for mouse over image, with no click
      if self.images.rect.collidepoint((self.mouseX, self.mouseY)):# and not self.mouse_held:
         self.images.highlight = True
      else:
         self.images.highlight = False
      
      #check for mouse over image and click
      if self.images.rect.collidepoint((self.mouseX, self.mouseY)) and self.mouse_held:
         self.is_dragging = True
         
      #mouse image with mouse upon dragging
      if self.is_dragging: #keep moving box if mouse is still holding but movees too fast
         self.images.rect[1] = self.mouseY - self.images.image[1].get_size()[1] // 2
         self.images.rect[0] = self.mouseX - self.images.image[1].get_size()[0] // 2
      
      #choose highlight image or original to draw
      if not self.images.highlight:
         image_to_draw = self.images.image[1]
      else:
         image_to_draw = self.images.image[2]
      
      #self.text_adjust()
      
      print('self.images.image[1].get_width() {}'.format(self.images.image[1].get_width() ))
      print('self.text_size[1] {}'.format(self.text_size[1] ))

      
      spacer = self.images.image[1].get_width() // self.text_size[1]
      print('spacer {}'.format(spacer))
      buff = spacer // 2
      print('buff {}'.format(buff))
         
      self.screen.blit(image_to_draw, (self.images.rect[0],self.images.rect[1]))
      self.screen.blit(
            text,
               (
                  self.images.rect[0] + buff,
                  self.images.rect[1] + 75
               )
         )
         
      self.test()
      
   def test(self):
      #print(self.images.image[1].get_colorkey())
      ...
      
   def main(self):
      run = True
      while run:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
               run = False
            if event.type == pygame.KEYDOWN:
               if event.key == pygame.K_SPACE:
                  self.images.image_ind += 1
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
               self.mouse_held = True
            if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
               self.mouse_held = False
               self.is_dragging = False
                  
         self.keys = pygame.key.get_pressed()
         self.mouseX, self.mouseY = pygame.mouse.get_pos()
         self.mouse_keys = pygame.mouse.get_pressed()

         self.screen.fill((150,150,150))
         self.update()
         pygame.display.flip()
         self.clock.tick(60)
         

controller = Control()
controller.main()
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1301
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] aligning text with another surface

Postby metulburr » Wed Apr 24, 2013 12:58 am

i made a specific code for this, but i am still stuck at where i was before. I am not sure how to properly align the text's center with the center of the image above on its y axis

Code: Select all
import pygame

class Control:
   def __init__(self):
      pygame.init()
      self.screensize = (600,600)
      self.screen = pygame.display.set_mode(self.screensize)
      self.mouseX = 0
      self.mouseY = 0
      self.gamestate = True
      self.text_test = ['Test', 'Something Random', 'chocolate milking cow']
      self.text_test_ind = 0
      self.text_to_draw = None
      
      self.image = pygame.Surface([50,50]).convert_alpha()
      self.image.fill((0,0,0))
      self.image_location = (0,0)
      self.text_location = (100,100)
      
   def text(self, displaytext, color=(0,0,0), size=15, ul=False, bold=False,
         ital=False, font='timesnewroman'):
      font = pygame.font.SysFont(font, size)
      font.set_underline(ul)
      font.set_bold(bold)
      font.set_italic(ital)
      label = font.render(displaytext, 1, color)
      self.text_size = label.get_size()
      return label

   def main(self):
      while self.gamestate:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
               self.gamestate = False
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
               self.text_test_ind += 1
         
         self.screen.fill((175,175,175))
         self.update()
         pygame.display.flip()
         

         
   def update(self):
      self.keys = pygame.key.get_pressed()
      self.mouseX, self.mouseY = pygame.mouse.get_pos()
      self.mouse_btn = pygame.mouse.get_pressed()
      
      #switch texts
      if self.text_test_ind > len(self.text_test)-1:
         self.text_test_ind = 0
      self.text_to_draw = self.text_test[self.text_test_ind]
      
      self.image_location = pygame.mouse.get_pos()
      
      text_y_padding = 0
      self.text_location = (self.image_location[0]+text_y_padding, self.image_location[1]+55)
      
      self.screen.blit(self.image, self.image_location)
      self.screen.blit(self.text(self.text_to_draw), self.text_location)

controller = Control()
controller.main()




New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1301
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] aligning text with another surface

Postby metulburr » Wed Apr 24, 2013 12:25 pm

the next thing i tried was centering the image on the mouse, centering the text surface on the mouse, and then just adding a padding for the Y axis to drop the text below the box. But i cant for some reason figure out why the text's surface y axis is aligned with the box y axis still after centering both on the mouse.

the update funtion attempting to get the centering
Code: Select all
   def update(self):
      self.keys = pygame.key.get_pressed()
      self.mouseX, self.mouseY = pygame.mouse.get_pos()
      self.mouse_btn = pygame.mouse.get_pressed()
      
      #switch texts
      if self.text_test_ind > len(self.text_test)-1:
         self.text_test_ind = 0
      self.text_to_draw = self.text_test[self.text_test_ind]
      
      #self.image_location = pygame.mouse.get_pos()
      self.image_rect = self.image.get_rect(center=(self.mouseX,self.mouseY))
      self.text_rect = self.image.get_rect(center=(self.mouseX,self.mouseY))
      
      #text_y_padding = 0
      #self.text_location = (self.image_rect[0]+text_y_padding, self.image_rect[1]+55)
      
      self.screen.blit(self.image, self.image_rect)
      self.screen.blit(self.text(self.text_to_draw), (self.text_rect[0], self.text_rect[1] + 55))



full code:
Code: Select all
import pygame

class Control:
   def __init__(self):
      pygame.init()
      self.screensize = (600,600)
      self.screen = pygame.display.set_mode(self.screensize)
      self.mouseX = 0
      self.mouseY = 0
      self.gamestate = True
      self.text_test = ['Test', 'Something Random', 'chocolate milking cow']
      self.text_test_ind = 0
      self.text_to_draw = None
      
      #path = '/home/metulburr/Pictures/alchemy_images/fire.png'
      #self.image = pygame.image.load(path).convert_alpha()
      self.image = pygame.Surface([50,50]).convert_alpha()
      self.image.fill((0,0,0))
      self.image_rect = self.image.get_rect(center=(self.mouseX,self.mouseY))
      self.text_rect = self.image.get_rect(center=(self.mouseX,self.mouseY))
      self.image_location = (0,0)
      self.text_location = (100,100)
      
   def text(self, displaytext, color=(0,0,0), size=15, ul=False, bold=False,
         ital=False, font='timesnewroman'):
      font = pygame.font.SysFont(font, size)
      font.set_underline(ul)
      font.set_bold(bold)
      font.set_italic(ital)
      label = font.render(displaytext, 1, color)
      self.text_size = label.get_size()
      return label

   def main(self):
      while self.gamestate:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
               self.gamestate = False
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
               self.text_test_ind += 1
         
         self.screen.fill((175,175,175))
         self.update()
         pygame.display.flip()
         

         
   def update(self):
      self.keys = pygame.key.get_pressed()
      self.mouseX, self.mouseY = pygame.mouse.get_pos()
      self.mouse_btn = pygame.mouse.get_pressed()
      
      #switch texts
      if self.text_test_ind > len(self.text_test)-1:
         self.text_test_ind = 0
      self.text_to_draw = self.text_test[self.text_test_ind]
      
      #self.image_location = pygame.mouse.get_pos()
      self.image_rect = self.image.get_rect(center=(self.mouseX,self.mouseY))
      self.text_rect = self.image.get_rect(center=(self.mouseX,self.mouseY))
      
      #text_y_padding = 0
      #self.text_location = (self.image_rect[0]+text_y_padding, self.image_rect[1]+55)
      
      self.screen.blit(self.image, self.image_rect)
      self.screen.blit(self.text(self.text_to_draw), (self.text_rect[0], self.text_rect[1] + 55))

controller = Control()
controller.main()




New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1301
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] aligning text with another surface

Postby Mekire » Wed Apr 24, 2013 2:26 pm

My drag/drop example modified to always draw a centered message below the box:
Code: Select all
import os,sys
import pygame as pg

class Character:
    def __init__(self,rect):
        self.rect = pg.Rect(rect)
        self.click = False
        self.image = pg.Surface(self.rect.size).convert()
        self.image.fill((255,0,0))

        self.text,self.text_rect = self.setup_font()

    def update(self,surface):
        if self.click:
            self.rect.center = pg.mouse.get_pos()
        self.text_rect.center = self.rect.centerx,self.rect.centery+90
        surface.blit(self.image,self.rect)
        surface.blit(self.text,self.text_rect)

    def setup_font(self):
      font = pg.font.SysFont('timesnewroman', 30)
      message = "I'm a red square"
      label = font.render(message, 1, (255,255,255))
      label_rect = label.get_rect()
      return label,label_rect

def main(Surface,Player):
    game_event_loop(Player)
    Surface.fill(0)
    Player.update(Surface)
def game_event_loop(Player):
    for event in pg.event.get():
        if event.type == pg.MOUSEBUTTONDOWN:
            if Player.rect.collidepoint(event.pos):
                Player.click = True
        elif event.type == pg.MOUSEBUTTONUP:
            Player.click = False
        elif event.type == pg.QUIT:
            pg.quit(); sys.exit()

if __name__ == "__main__":
    os.environ['SDL_VIDEO_CENTERED'] = '1'
    pg.init()
    Screen = pg.display.set_mode((1000,600))
    MyClock = pg.time.Clock()
    MyPlayer = Character((0,0,150,150))
    MyPlayer.rect.center = Screen.get_rect().center
    while 1:
        main(Screen,MyPlayer)
        pg.display.update()
        MyClock.tick(60)

-Mek

Edit: Oh yeah. Thought I should mention, don't use SysFont in anything but personal experimentation. It is too unreliable. You should generally package your font with your program to avoid issues.
User avatar
Mekire
 
Posts: 979
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: [Pygame] aligning text with another surface

Postby metulburr » Wed Apr 24, 2013 3:48 pm

OMG thank you. This has been giving me a headache since last night. Ill have ot check it out and look over it a bit though, jsut wanted to say thanks now.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1301
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] aligning text with another surface

Postby metulburr » Wed Apr 24, 2013 8:14 pm

you know that makes sense, with the code by itself, but when i tried to implement into the mainstream of the program. I really just end up getting lost in why its not working.

Code: Select all
import pygame
import os
import time

class ImageClass:
   def __init__(self):
      self.image_dir = '/home/metulburr/Pictures/alchemy_images'
      self.album = []
      self.image = None
      self.image_ind = 0
      self.rect = None
      self.highlight = False
      self.get_images()
      self.rect = self.album[0][1].get_rect() #set initial first rect
      
   def get_images(self):
      for f in os.listdir(self.image_dir):
         if f.endswith('.png'):
            orig_image = pygame.image.load(os.path.join(self.image_dir, f)).convert_alpha()
            rect = orig_image.get_rect()
            highlight_image = self.make_highlight(rect, orig_image)
            self.album.append(
                  (
                     os.path.splitext(f)[0].replace('_',' ').title(),
                     orig_image,
                     highlight_image,
                     rect
                  )
               )
   def make_highlight(self, rect, img):
      temp = pygame.Surface(rect.size).convert()
      temp.set_colorkey((255,255,255))
      temp.fill((255,255,255))
      temp.blit(img,(0,0))
      temp.set_alpha(100)
      return temp
      
class Control:
   def __init__(self):
      pygame.init()
      self.screensize = (600,600)
      self.screen = pygame.display.set_mode(self.screensize)
      self.clock = pygame.time.Clock()
      self.mouseX = 0
      self.mouseY = 0
      self.keys = None
      self.mouse_keys = (0,0,0)
      self.mouse_held = False
      self.is_dragging = False
      self.text_size = (0,0)
      
      
      self.images = ImageClass()
      
   def text(self, displaytext, color=(0,0,0), size=15, ul=False, bold=False,
         ital=False, font='timesnewroman'):
      font = pygame.font.SysFont(font, size)
      font.set_underline(ul)
      font.set_bold(bold)
      font.set_italic(ital)
      label = font.render(displaytext, 1, color)
      label_rect = label.get_rect()
      return label,label_rect



   def update(self):
      #adjust index to 0 if past list
      if self.images.image_ind > len(self.images.album)-1:
         self.images.image_ind = 0
      
      #assignments
      self.images.image = self.images.album[self.images.image_ind]
      self.text_str, self.text_rect = self.text(self.images.image[0], color=(0,0,0))
      #text = self.text(self.images.image[0], color=(0,0,0))
      #self.text_size = text.get_size()
      
      #check for mouse over image, with no click
      if self.images.rect.collidepoint((self.mouseX, self.mouseY)):# and not self.mouse_held:
         self.images.highlight = True
      else:
         self.images.highlight = False
      
      #check for mouse over image and click
      if self.images.rect.collidepoint((self.mouseX, self.mouseY)) and self.mouse_held:
         self.is_dragging = True
         
      #mouse image with mouse upon dragging
      if self.is_dragging: #keep moving box if mouse is still holding but movees too fast
         self.images.rect[1] = self.mouseY - self.images.image[1].get_size()[1] // 2
         self.images.rect[0] = self.mouseX - self.images.image[1].get_size()[0] // 2
      
      #choose highlight image or original to draw
      if not self.images.highlight:
         image_to_draw = self.images.image[1] #original image
      else:
         image_to_draw = self.images.image[2] #highlight image
      
      self.text_rect.center = self.images.image[3].centerx, self.images.image[3].centery + 90
      
      #self.text_rect = (0,0)
      self.screen.blit(image_to_draw, (self.images.rect[0],self.images.rect[1]))
      self.screen.blit(self.text_str, self.text_rect)
      
   def main(self):
      run = True
      while run:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
               run = False
            if event.type == pygame.KEYDOWN:
               if event.key == pygame.K_SPACE:
                  self.images.image_ind += 1
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
               self.mouse_held = True
            if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
               self.mouse_held = False
               self.is_dragging = False
                  
         self.keys = pygame.key.get_pressed()
         self.mouseX, self.mouseY = pygame.mouse.get_pos()
         self.mouse_keys = pygame.mouse.get_pressed()

         self.screen.fill((150,150,150))
         self.update()
         pygame.display.flip()
         self.clock.tick(60)
         

controller = Control()
controller.main()

also this is somewhat confusing to me:
[code]        if self.click:
            self.rect.center = pg.mouse.get_pos()
        self.text_rect.center = self.rect.centerx, self.rect.centery + 90[/code]

how can self.text_rect be accurate if not self.click?
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1301
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] aligning text with another surface

Postby metulburr » Wed Apr 24, 2013 8:31 pm

i think my whole code is garbage, i think i need to erase it and start again from scratch
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1301
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] aligning text with another surface

Postby Mekire » Thu Apr 25, 2013 12:20 am

Here is your code running. It is maybe a bit messy but not irredeemable. One thing you will have to do is create a class to represent your elements. Keeping track of this in control will be nightmarish. Once your code is complicated to warrant it the Control class will probably not contain anything except the toplevel event_loop and a some variables to keep track of game state. Once you do that, that text method will go in that class. Take a look back at IvyMike's thread if you want to see how I did this.

Code: Select all
import pygame
import os,sys

class ImageClass:
   def __init__(self):
      self.image_dir = '/home/metulburr/Pictures/alchemy_images'
##      self.image_dir = '.'
      self.album = []
      self.image = None
      self.image_ind = 0
      self.rect = None
      self.highlight = False
      self.get_images()
      self.rect = self.album[0][1].get_rect() #set initial first rect

   def get_images(self):
      for f in os.listdir(self.image_dir):
         if f.endswith('.png'):
            orig_image = pygame.image.load(os.path.join(self.image_dir, f)).convert_alpha()
            rect = orig_image.get_rect()
            highlight_image = self.make_highlight(rect, orig_image)
            self.album.append(
                  (
                     os.path.splitext(f)[0].replace('_',' ').title(),
                     orig_image,
                     highlight_image,
                     rect
                  )
               )
   def make_highlight(self, rect, img):
      temp = pygame.Surface(rect.size).convert()
      temp.set_colorkey((255,255,255))
      temp.fill((255,255,255))
      temp.blit(img,(0,0))
      temp.set_alpha(100)
      return temp

class Control:
   def __init__(self):
      pygame.init()
      self.screensize = (600,600)
      self.screen = pygame.display.set_mode(self.screensize)
      self.clock = pygame.time.Clock()
      self.mouseX = 0
      self.mouseY = 0
      self.keys = None
      self.mouse_keys = (0,0,0)
      self.mouse_held = False
      self.is_dragging = False
      self.text_size = (0,0)

      self.images = ImageClass()

   def text(self, displaytext, color=(0,0,0), size=15, ul=False, bold=False,
         ital=False, font='timesnewroman'):
      font = pygame.font.SysFont(font, size)
      font.set_underline(ul)
      font.set_bold(bold)
      font.set_italic(ital)
      label = font.render(displaytext, 1, color)
      label_rect = label.get_rect()
      return label,label_rect

   def update(self):
      #adjust index to 0 if past list
      if self.images.image_ind > len(self.images.album)-1:
         self.images.image_ind = 0

      #assignments
      self.images.image = self.images.album[self.images.image_ind]
      self.text_str, self.text_rect = self.text(self.images.image[0], color=(0,0,0))

      #check for mouse over image, with no click
      if self.images.rect.collidepoint((self.mouseX, self.mouseY)):# and not self.mouse_held:
         self.images.highlight = True
      else:
         self.images.highlight = False

      #check for mouse over image and click
      if self.images.rect.collidepoint((self.mouseX, self.mouseY)) and self.mouse_held:
         self.is_dragging = True

      #mouse image with mouse upon dragging
      if self.is_dragging: #keep moving box if mouse is still holding but movees too fast
         self.images.rect.center = pygame.mouse.get_pos()

      #choose highlight image or original to draw
      if not self.images.highlight:
         image_to_draw = self.images.image[1] #original image
      else:
         image_to_draw = self.images.image[2] #highlight image

      self.text_rect.center = self.images.rect.centerx, self.images.rect.centery + 50

      self.screen.blit(image_to_draw,self.images.rect)
      self.screen.blit(self.text_str,self.text_rect)

   def main(self):
      run = True
      while run:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
               run = False
            if event.type == pygame.KEYDOWN:
               if event.key == pygame.K_SPACE:
                  self.images.image_ind += 1
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
               self.mouse_held = True
            if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
               self.mouse_held = False
               self.is_dragging = False

         self.keys = pygame.key.get_pressed()
         self.mouseX, self.mouseY = pygame.mouse.get_pos()
         self.mouse_keys = pygame.mouse.get_pressed()

         self.screen.fill((150,150,150))
         self.update()
         pygame.display.flip()
         self.clock.tick(60)


controller = Control()
controller.main()
pygame.quit();sys.exit()


also this is somewhat confusing to me:
Code: Select all
        if self.click:
            self.rect.center = pg.mouse.get_pos()
        self.text_rect.center = self.rect.centerx, self.rect.centery + 90

how can self.text_rect be accurate if not self.click?

The text_rect is always updated based on the position of its corresponding element's rect regardless of whether it is being dragged or not.

-Mek
Last edited by Mekire on Thu Apr 25, 2013 2:27 am, edited 1 time in total.
User avatar
Mekire
 
Posts: 979
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: [Pygame] aligning text with another surface

Postby metulburr » Thu Apr 25, 2013 1:30 am

One thing you will have to do is create a class to represent your elements. Keeping track of this in control will be nightmarish. Once your code is complicated to warrant it the Control class will probably not contain anything except the toplevel event_loop and a variable Once you do that, that text method will go in that class.

That was my next goal after figuring out the centering of the text surface, was to clear out the Control.update() method of the non-related, and either create a new class or put it in the image class. The elements class i was going to create at some point when after i made the layout of the board so i had the elements to put them in on the right side, plus hold the the list of original elements, and the appending new elements, etc.

So i think i am going to clear out Control of anything not suppose to be in there, just after figuring out what you did. Speaking of which:
I noticed you switch the image to follow the mouse at the image's center
yours:
Code: Select all
self.images.rect.center = pygame.mouse.get_pos()

mine:
Code: Select all
         self.images.rect[1] = self.mouseY - self.images.image[1].get_size()[1] // 2
         self.images.rect[0] = self.mouseX - self.images.image[1].get_size()[0] // 2

which obviously yours is a hell of a lot clearer. To be honest i wasnt really aware of Surface.get_rect,center. Now is that any different than Surface.get_rect(center=SOMETHING) ?

also as i dont see anything set, i am guessing these are variables of the method get_rect() too, in which i also did not know about: (meaning the .get_rect().centerx and get_rect().centery)
Code: Select all
self.images.rect.centerx, self.images.rect.centery


I was thinking i had to get size, divide by 2 to get half point. I guess pygame makes this more simple then.

Other than that your additions makes sense.

Actually before moving on to building the elements class, i think i might tinker with this in a new test class, to make sure i know what exactly you added and how to implement it myself in the future.


Pygame has the worst documentation i have ever seen:
pygame 1.9.2 pre
Code: Select all
metulburr@ubuntu:~$ python3
Python 3.2.3 (default, Oct 19 2012, 20:10:41)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pygame
>>> help(pygame.Surface.get_rect)

Code: Select all
get_rect(...)
    get_rect(**kwargs) -> Rect
    get the rectangular area of the Surface


and its not like pygame 1.9.1 has any better docs either:
Code: Select all
metulburr@ubuntu:~$ python
Python 2.7.3 (default, Aug  1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pygame
>>> help(pygame.Surface.get_rect)

Code: Select all
get_rect(...)
    Surface.get_rect(**kwargs): return Rect
    get the rectangular area of the Surface


The only place i have seen center as an argument to get_rect() is one sentance in pygame.org doc, in which he does not really describe it well for someone just starting in game programming. And also i have never seen doc regarding get_rect().center or get_rect().centerx or get_rect().centery. Well the last 2 are somewhat obvious i guess.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1301
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] aligning text with another surface

Postby Mekire » Thu Apr 25, 2013 2:08 am

Ok so rects are amazingly convenient things. Using them should obviate the need to ever really keep track of the Cartesian coordinates of something manually.

A rect is declared as follows:
Code: Select all
MyRect = pygame.Rect(x_coord,y_coord,width,height)

Rects have a number of attributes; all of which can be assigned to. These include:
Code: Select all
x,y
top, left, bottom, right
topleft, bottomleft, topright, bottomright
midtop, midleft, midbottom, midright
center, centerx, centery
size, width, height
w,h

This makes assigning or getting the information for any basic location in the rectangle trivial. Let's look at a simple example:
Code: Select all
>>> import pygame
>>> MyRect = pygame.Rect(125,125,50,50)
>>> MyRect.size
(50, 50)
>>> MyRect.bottomleft
(125, 175)
>>> MyRect.center
(150, 150)
>>> MyRect.centerx,MyRect.centery
(150, 150)
>>> MyRect.center = 325,200
>>> MyRect
<rect(300, 175, 50, 50)>
>>>

So you can find out the location of any edge, center/middle point, corner, and find the size,width, and height. All of these can also be assigned directly to and will change the entire rectangle accordingly.

Now Surface.get_rect() on the other hand takes a Surface and returns its bounding rect. By default the topleft corner is set to (0,0). You can however, assign to any of the previous rectangle variables by keyword when using it.

IE:
Code: Select all
image = pygame.image.load("fire.png").convert_alpha()
rect = image.get_rect()
print(rect)

rect = image.get_rect(topleft=(150,150))
print(rect)
Output:
Code: Select all
<rect(0, 0, 74, 74)>
<rect(150, 150, 74, 74)>

-Mek

Edit: As pygame.Surface.get_rect() returns a Rect, you can of course write pygame.Surface.get_rect().center. The most common use of this would be quickly determining the center point of our window.

The rect given by:
Code: Select all
SCREEN.get_rect()
is the bounding box of our window (where SCREEN is our display surface) with the topleft corner set as (0,0). Therefore,
Code: Select all
SCREEN.get_rect().center
is the center of our window.
User avatar
Mekire
 
Posts: 979
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: [Pygame] aligning text with another surface

Postby metulburr » Thu Apr 25, 2013 2:19 am

so Surface.get_rect() returns the pygame.Rect() of whatever Surface you are using? For some reason i thought they were two different, methods with different attributes.

man, do i feel stupid now. There are so many times i could of used those attributes to my advantage, lol. Because i didnt use them i endded up complicating the code doing basic division to get the center, for example.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1301
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] aligning text with another surface

Postby Mekire » Thu Apr 25, 2013 2:21 am

pygame.Rect is a class. get_rect() is a method of the class pygame.Surface which returns an instance of pygame.Rect corresponding to said Surface.

-Mek
User avatar
Mekire
 
Posts: 979
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: [Pygame] aligning text with another surface

Postby metulburr » Thu Apr 25, 2013 2:27 am

ok that makes sense.

Dude, you should write a pygame book, i could learn more in 10 pages from you than i could from every other pygame book out there combined.

I mean the pygame docs does describe things, but they dont really link them togather like that for a newbie game programmer to understand.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1301
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] aligning text with another surface

Postby Mekire » Thu Apr 25, 2013 8:37 am

metulburr wrote:Dude, you should write a pygame book, i could learn more in 10 pages from you than i could from every other pygame book out there combined.

Thanks.

The problem with most of the books I have seen (other than those that are just plain bad) is that they are books for "the beginning programmer" not books for "the beginning game programmer." As in most fields, a book that promises the world gets more attention than a book that gives you the honest truth.

The book "Learn Japanese in 30 days," is guaranteed to sell more copies than a book titled "Learn Japanese in 10 quick years."

I think I could write up some fairly instructive material regarding pygame; but the fact that I believe one should go back and properly learn their basics before even thinking about it isn't as appealing as a, "Write your first game in one hour," type book.

Anyway, I appreciate the compliment. Also you should note that as knowledgeable as I can sometimes appear about pygame, I am completely ignorant when it comes to networking/website related code (which is unfortunately the thing much more likely to find one a job).

-Mek
User avatar
Mekire
 
Posts: 979
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan


Return to Game Development

Who is online

Users browsing this forum: No registered users and 0 guests