I am trying to make an inventory system in which you can click on items within the inventory. The inventory itself is a separate surface that is created and drawn when the user clicks on an 'Inven' button.
I have a sample item in the inventory right now. I'm wanting text to render and be drawn when the user hovers over the item.
I was going about this by checking for a mousemotion event, and then seeing if the event position collides with the inventory item rect.
This works... but the resulting text is drawn at the postion of the rect were it on the main surface, not the smaller, inventory specific surface. I found that when passing coordinates to items I wanted drawn only on the inventory surface, that the coordinates had to be relative to the surface they were being used on.
For example: Bliting inventory item at (0,0) on the inventory surface places it in the top left of the inventory surface, not the main surface. So I don't pass the actual coordinates that the item would be relative to the entire game.
But when I check for collision with the mouse, it is indeed using the inventory item's coordinates relative to the entire game. not just the main surface.
I figured I would have to find the actual coordinates of the items relative to the entire game, but this seems odd considering that Pygame is able to understand coordinates relative to the surface an item is being drawn on.
Is there a way in code to get the coordinates of an item relative to the main surface, that is not being drawn on the main surface? Or is there a way to check mousemotion collisions relative to only a specific surface?
Relevant code below.
class Game:
"""Game settings and options"""
def __init__(self, gameTitle):
self.width = 800
self.height = 600
self.clock = pygame.time.Clock()
self.screen = pygame.display.set_mode((self.width, self.height)) # main surface
self.fps = 60
pygame.display.set_caption(gameTitle)
self.statusTextTimer = -1
self.textBlurbShowing = False # the 'blurb' is the text to be shown on hover
self.textBlurbTimer = -1
self.textBlurb = None
# creates text on hover
def hoverText(text, pos):
gameMaster.textBlurbShowing = True
gameMaster.textBlurbTimer = 0
gameMaster.textBlurb = gameMaster.Text(12, gameMaster)
gameMaster.textBlurb.create(text, 'Black', pos[0], pos[1])
if event.type == MOUSEMOTION and gameMaster.textBlurbShowing == False and inventoryClicked:
for item in player.inventory.contents:
if item.rect.collidepoint((event.pos)):
print('Collided') # was making sure event was registering
hoverText(item.desc, (event.pos[0], event.pos[1]))
class Inventory:
def __init__(self, posx, posy, size):
self.posx = posx
self.posy = posy
self.size = size
self.surf = pygame.Surface((size,size), pygame.SRCALPHA)
self.rect = self.surf.get_rect(x=posx, y=posy)
self.textSurf = pygame.font.SysFont('Lucidia Console', 22).render('Inventory', True, 'White')
self.textRect = self.textSurf.get_rect()
self.textRect.x = self.textRect.x + 10
self.textRect.y = self.textRect.y + 10
self.slotCoords = {
1:(0,100), 2:(100,100), 3:(200,100), 4:(300,100),
5:(0,200), 6:(100,200), 7:(200,200), 8:(300,200),
9:(0,300), 10:(100,300), 11:(200,300), 12:(300,300),} # inv slot : (x,y) all slots must be 100x100
# ^^^ these are the coordinates each inventory slot uses, they're passed to an item in the slot for drawing.
# Checking collisions uses these coordinates relative to the main surface, but when drawing, it works with the inventory surface.
self.contents = []
Any help is appreciated.
Is there a way in code to get the coordinates of an item relative to the main surface, that is not being drawn on the main surface?
You have to know the position of the destination Surface of the item.
Lets assume, drawing an item_image
at the position (item_x
, item_y
) on the pygame.Surface
dest_surf
:
item_rect = item_image.get_rect(topleft = (item_x, item_y))
dest_surf.blit(item_image, item_rect)
Later you blit
the dest_surf
on the screen
at (dest_x
, dest_y
):
screen.blit(dest_surf, (dest_x, dest_y))
The bounding rectangle of item_image
on the screen can be computed by adding (dest_x
, dest_y
) to the position of item_rect
:
screen_item_rect = item_rect.copy()
screen_item_rect.x += dest_x
screen_item_rect.y += dest_y
This can be simplified by using gyame.Rect.move
:
screen_item_rect = item_rect.move(dest_x, dest_y)