Python Forum
[PyGame] Issue with item counter
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] Issue with item counter
#1
Hi everyone Big Grin ,

I'm new on this forum and i'm student in Python.

Ok here is my issue.
I need to create a game by using an item counter.
Wherever I put the counter, in the pickup function, out of the pickup function, in the main loop, out of the main loop, it doesn't work.
It decrease of 1 when item is picked up but reinitialize itself immediately

I tried to make a function only for the counter, but it doesn't work

I don't see where is the logic,

If you have an idea,
Thanks a lot

Here is the main file :
import pygame
from os import system

# Import personnal modules
from design import maze, constants as cst
from items import player, objects

system('clear')
pygame.init()

def main():
    # ////////////////////// GAME WINDOWS INITIALISATION //////////////////////
    game_window = pygame.display.set_mode(
        (cst.WINDOW_RESOLUTION, cst.WINDOW_RESOLUTION + 55))
    game_title = pygame.display.set_caption(cst.GAME_TITLE)
    game_icon = pygame.image.load(cst.MACGYVER_PIC)
    pygame.display.set_icon(game_icon)
    pygame.display.flip()
    pygame.key.set_repeat(200, 200)

    # Generate labyrinth by the file
    show_game = maze.GameBoard('design/labyrinth')
    show_game.generate_board()
    show_game.display_board(game_window)
    pygame.display.flip()

    # Generate MacGyver and items
    MAC = player.Hero(cst.MACGYVER_PIC, show_game)
    NEEDLE = objects.GameItems(cst.NEEDLE_PIC, show_game)
    NEEDLE.random_pos(cst.NEEDLE_PIC, game_window)
    PIPE = objects.GameItems(cst.PIPE_PIC, show_game)
    PIPE.random_pos(cst.PIPE_PIC, game_window)
    ETHER = objects.GameItems(cst.ETHER_PIC, show_game)
    ETHER.random_pos(cst.ETHER_PIC, game_window)
    SYRINGE = objects.GameItems(cst.SYRINGE_PIC, show_game)
    GAMEOVER = objects.GameItems(cst.BKG_PIC, show_game)

    # /////////////////////////////// MAIN LOOP ///////////////////////////////
    run_window_loop = True
    while run_window_loop:
        pygame.time.Clock().tick(30)  # 30 FPS limit

        win_bg = pygame.image.load(cst.BKG_PIC).convert_alpha()
        game_window.blit(win_bg, [30, 30])

        # Close the game window by the CROSS button or press ESCAPE key
        for event in pygame.event.get():
            if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and \
               event.key == pygame.K_ESCAPE:
                run_window_loop = False

            # MacGyver moves when directional arrows are pressed
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    MAC.mac_direction('RIGHT')
                elif event.key == pygame.K_DOWN:
                    MAC.mac_direction('DOWN')
                elif event.key == pygame.K_UP:
                    MAC.mac_direction('UP')
                elif event.key == pygame.K_LEFT:
                    MAC.mac_direction('LEFT')

        # Refresh new MacGyver position
        game_window.blit(win_bg, [0, 0])
        show_game.display_board(game_window)
        game_window.blit(MAC.mac_pic, [MAC.mac_pos_x, MAC.mac_pos_y])

        # Item picked up, positioning in item bar and display syringe
        NEEDLE.pickup(game_window, NEEDLE.item_pic, NEEDLE.item_pos_x,
                      NEEDLE.item_pos_y, MAC.mac_pos_x, MAC.mac_pos_y, 0, 752)
        PIPE.pickup(game_window, PIPE.item_pic, PIPE.item_pos_x,
                    PIPE.item_pos_y, MAC.mac_pos_x, MAC.mac_pos_y, 50, 752)
        ETHER.pickup(game_window, ETHER.item_pic, ETHER.item_pos_x,
                     ETHER.item_pos_y, MAC.mac_pos_x, MAC.mac_pos_y, 100, 752)
        SYRINGE.syringe(game_window, SYRINGE.item_pic, 390, 752)

        # If MacGyver picked up all items, he wins, else, he loses
        if show_game.game_design[MAC.cell_y][MAC.cell_x] == "G":
            GAMEOVER.win_loose(game_window, win_bg, 0, 0)

        pygame.display.flip()
And here is the item file :
import pygame
from design import constants as cst
from random import randint


class GameItems:
    """ Class for managing items, display and random position """

    def __init__(self, item_pic, game_zone):
        """ Function for initialize items and their random positions """

        self.cell_x = 0
        self.cell_y = 0
        self.item_pos_x = 0
        self.item_pos_y = 0
        self.counter = 3
        self.visible = True

        self.item_pic = pygame.image.load(item_pic).convert_alpha()
        self.game_zone = game_zone

    # ------------------------------------------------------------------------
    def random_pos(self, item_pic, game_zone):
        """ Generate the random position """

        self.get_item_loop = True
        while self.get_item_loop:
            # Randomize X and Y cells (15 sprites)
            self.cell_x = randint(0, 14)
            self.cell_y = randint(0, 14)
            # Check if the cell is empty, positioning and display item
            if self.game_zone.game_design[self.cell_y][self.cell_x] == "0":
                self.item_pos_x = self.cell_x * cst.SPRITE_SIZE
                self.item_pos_y = self.cell_y * cst.SPRITE_SIZE
                # After check, break the loop
                self.get_item_loop = False

    # ------------------------------------------------------------------------
    def pickup(self, game_zone, item_pic, item_pos_x, item_pos_y,
               mac_x, mac_y, item_bar_x, item_bar_y):
        """ Items disappear when MacGyver picked up them """

        if self.visible:
            game_zone.blit(item_pic, [item_pos_x, item_pos_y])
            if (mac_x, mac_y) == (item_pos_x, item_pos_y):
                self.visible = False
                self.counter -= 1
                print(self.counter)
        else:
            game_zone.blit(item_pic, [item_bar_x, item_bar_y])

    # ------------------------------------------------------------------------
    def syringe(self, game_zone, item_pic, item_bar_x, item_bar_y):
        """ When all items are picked up, show syringe item """

        if self.counter == 0:
            game_zone.blit(item_pic, [item_bar_x, item_bar_y])

    # -------------------------------------------------------------------------
    def win_loose(self, game_zone, bgpic, posx, posy):
        """ Win or loose game management """

        if self.counter == 0:
            game_zone = pygame.display.set_mode(
                (cst.WINDOW_RESOLUTION, cst.WINDOW_RESOLUTION))
            game_zone.blit(bgpic, [posx, posy])
            self.win = pygame.image.load(cst.YOUWIN_PIC).convert_alpha()
            game_zone.blit(self.win, [posx, posy])
        else:
            game_zone = pygame.display.set_mode(
                (cst.WINDOW_RESOLUTION, cst.WINDOW_RESOLUTION))
            game_zone.blit(bgpic, [posx, posy])
            self.loose = pygame.image.load(cst.GAMEOVER_PIC).convert_alpha()
            game_zone.blit(self.loose, [posx, posy])
Reply
#2
Just putting the question aside for a bit, I'd like to extrude more on your code. This is very common to see code like this from people new to pygame, and it's very messy. It makes code hard to read, hard to change, less efficient, and just overall not very good. You should work on splitting the logic up more through creating different functions and classes. Also in the Game_Item function, under random_pos there's a while loop without any event detection. If someone were to try and exit while the loop was running it wouldn't work. Another thing that I see is many parameters for your functions. You should try to reduce that through possibly a list or tuple. For example the x's and y's that correlate can go together in a list or tuple. Now for the problem, from what I understand, the counter decreases when an item is picked up. I'd suggest putting the items in a list, then when an item is picked up, remove it from the list, once the list for example has 1 item left, you can end the loop, though there are various other ways if you decide to do it some other way. Hope that helps you with your problem. I would suggest going to the tutorial on using a State Machine from metulburr - https://python-forum.io/Thread-PyGame-Cr...te-machine - This shows a great way to manage everything efficiently.
Reply
#3
Owww!! Ok...

First thank for your reply and your review.
Then, I know this not the best solution, I try to completely rewrite the code by using several classes and functions.
I will go to the link you gave me..
Thanks
Reply
#4
1. Don't capitalize variables unless they are constant. Game items will never be a constant.
2. Load your images once. Then you pass your images. They should be in your constant section. Don't forget to convert/convert_alpha them.

Can't run code or see the rest of code. So here my best guess. To me when you pick up an item. You need another copy of it. So maybe this example will help you.
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __iter__(self):
        yield self.x
        yield self.y

class GameItem:
    def __init__(self, image, zone, count=3):
        self.image = image
        self.zone = zone

        self.counter = count
        self.cell = Point()
        self.visible = True
        self.position = Point()

    def draw(self):
        if self.visible:
            zone.blit(self.image, tuple(self.position))

    def pickup(self, zone, bar_position):
        if visible:
            self.counter -= 1
            if self.counter  <= 0:
                self.visible = False

            item = GameItem(zone, self.image, 1)
            item.position = bar_position
            return item

    def pickup_all(self, zone, bar_position):
        self.zone = zone
        self.position = bar_position

    def random_position(self):
        loop = True
        while loop:
            self.cell.x = randint(0, 14)
            self.cell.y = randint(0, 14)
            if zone.game_design[self.cell.y][self.cell.x] == "0":
                self.position.x = self.cell.x * cst.SPRITE_SIZE
                self.position.y = self.cell.y * cst.SPRITE_SIZE
                loop = False
99 percent of computer problems exists between chair and keyboard.
Reply
#5
Thank you very much for your help..
I'm gonna try that right now !
Reply
#6
Delete post
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020