-1
\$\begingroup\$

Hi everyone I am trying to make a Mahjong Solitaire game using pygame.

I want to create a list of objects (the tiles of the game) using a for loop, but I can't manage to set a different type (the picture on the tile) for every tile.

I manage to draw them correctly on the screen but by the time the for loop ends all of the tiles are set (overwritten) with the last type and coordinates. I use a click to select the tiles.

Can you explain to me what I am doing wrong?

import pygame
import random

pygame.init()
pygame.display.set_caption("Mahjong")
# icon_img = pygame.image.load("mahjong.png")
# pygame.display.set_icon(icon_img)
WIDTH = 800
HEIGHT = 600
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
# start_screen = pygame.image.load("startscreen.jpg")
# start_screen = pygame.transform.scale(start_screen, (WIDTH, HEIGHT))
start_game_font = pygame.font.SysFont("Corbel", 70, bold=True)
game_font = pygame.font.SysFont("Corbel", 30, bold=True)

state = "game"
# Different pictures of the tiles
tile1 = pygame.image.load("tile 1.png").convert_alpha()
tile2 = pygame.image.load("tile 2.png").convert_alpha()
tile3 = pygame.image.load("tile 3.png").convert_alpha()
tile4 = pygame.image.load("tile 4.png").convert_alpha()
tile5 = pygame.image.load("tile 5.png").convert_alpha()
tile6 = pygame.image.load("tile 6.png").convert_alpha()
tile_type = [tile1, tile2, tile3, tile4, tile5, tile6]


class Tile(pygame.sprite.Sprite):
    def __init__(self, x, y, type):
        super().__init__()
        self.image = tile_type[type]
        self.image = pygame.transform.scale(self.image, (60, 100))
        self.rect = self.image.get_rect()
        self.pos = pygame.mouse.get_pos()
        self.rect.x = x
        self.rect.y = y
        self.type = type

# start screen, disabled for debug
# def intro():
#     start_text = start_game_font.render("Start", True, (0, 0, 0))
#     WIN.blit(start_screen, (0, 0))
#     WIN.blit(start_text, (WIDTH / 2 - 100, HEIGHT / 2))


def game():
    WIN.fill((0, 150, 0))
    newgame_text = game_font.render("New Game", True, (0, 0, 0))
    WIN.blit(newgame_text, (WIDTH - 150, 20))
    all_tiles.draw(WIN)


# Create a list of 48 pieces, in pairs
pieces = 48
count = 0
type = 0  # picture on the tile, range 0-5

# Create a set of tile, in pairs and store them to a list
tiles = []
for x in range(pieces):
    count += 1
    if count == 2:
        count = 0
        type += 1
    if type == 6:
        type = 0
    tiles.append(type)

random.shuffle(tiles)
all_tiles = pygame.sprite.Group()
x_pos = 40
y_pos = 100
count = 0

# Use the value on tiles to create a sprite group, arrange them on the screen
# The issue is probably here
for value in tiles:
    tile = Tile(x_pos, y_pos, value)
    print(value, x_pos, y_pos)
    x_pos += 60
    count += 1
    if count % 12 == 0:  # makes new row
        y_pos += 100
        x_pos = 40
    all_tiles.add(tile)

clock = pygame.time.Clock()
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if state == "intro":
            intro()
        if state == "game":
            game()
        if event.type == pygame.MOUSEBUTTONDOWN:
            if state == "intro" and WIDTH/2 <= mouse[0] >= 300 or WIDTH/2 <= 460 and HEIGHT/2 <= mouse[1] <= HEIGHT/2+40:
                state = "game"
            # Identify which tile has been clicked
            if tile.pos:
                print(tile.type, tile.rect.x, tile.rect.y)

    mouse = pygame.mouse.get_pos()
    pygame.display.update()
    clock.tick(60)

pygame.quit()
\$\endgroup\$
4
  • \$\begingroup\$ I don't understand your issue. The images drawn seem to all have different types, and you have no logic for changing the variable tile that you print out on clicks, so obviously the last tile will always get printed out? Just because you wrote a comment # Identify which tile has been clicked doesn't unfortunately mean that a correct tile will be identified magically. \$\endgroup\$
    – user35344
    Dec 9, 2021 at 18:06
  • \$\begingroup\$ if you click on any tile it will always show the same type and coordinates. So that means that for the pc they are all the same. I need to be able to get the correct type and coords for every single tile so than I can "select" one, tiles and see if they match, so I can kill them \$\endgroup\$ Dec 9, 2021 at 18:10
  • \$\begingroup\$ "if you click on any tile it will always show the same type and coordinates. So that means that for the pc they are all the same." No, that means that you have no logic changing the tile that is printed out. Like I already pointed out, it won't magically change just because you have a comment stating so. \$\endgroup\$
    – user35344
    Dec 9, 2021 at 18:33
  • \$\begingroup\$ you was right I was looking at it the wrong way! I found the solution and added to the question thanks! \$\endgroup\$ Dec 9, 2021 at 18:58

1 Answer 1

0
\$\begingroup\$

I had to change a few line in the main loop, MOUSEBUTTONDOWN event as follows:

        # Identify which tile has been clicked
        pos = pygame.mouse.get_pos()
        clicked = []
        for s in all_tiles:
            if s.rect.collidepoint(pos):
                print(s.type)
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .