Abdullah Bera Koksal
Abdullah Bera Koksal

Reputation: 49

Class object distinction

I'm currently working on a Space Ship Simulator project and I came across a problem. In my code I have an Arrow class and I create 4 arrow objects that are going to be buttons.

This is my code:

from pygame.locals import *
pygame.init()

SCR_WIDTH = 700
SCR_HEIGHT = 900

screen = pygame.display.set_mode((SCR_WIDTH, SCR_HEIGHT))
pygame.display.set_caption("Space Ship Simulator")

# image loads
bg_image = pygame.image.load("img/space_background.jpg")
bg_image = pygame.transform.scale(bg_image, (SCR_WIDTH, SCR_HEIGHT))
ss_board = pygame.image.load("img/spaceship_board.png")


class Arrow:
    def __init__(self, degree, x, y):
        self.degree = degree
        self.active = 0
        self.arrow_list = []
        self.x = x
        self.y = y
        self.active = 0
        self.released = True
        # arrow color: R: 0, G: 234, B: 0
        for x in range(2):
            img = pygame.image.load(f"img/arrow_{x}.png")
            self.arrow_list.append(img)

        self.image = pygame.transform.rotate(self.arrow_list[self.active], self.degree)
        self.width = self.image.get_width()
        self.height = self.image.get_height()
        self.rect = Rect((self.x, self.y), (self.width, self.height))

    def draw(self):
        # get mouse position
        mouse_pos = pygame.mouse.get_pos()

        # check mouseover and clicked conditions
        if self.rect.collidepoint(mouse_pos):
            if pygame.mouse.get_pressed()[0] == 1 and self.active == 0 and self.released:
                self.active = 1
                self.released = False
                print('Active')

            if pygame.mouse.get_pressed()[0] == 0:
                self.released = True

            if self.active and self.released:
                if pygame.mouse.get_pressed()[0] == 1:
                    self.active = 0
                    print('Inactive')
                    self.released = False

        # draw arrow on screen
        self.image = pygame.transform.rotate(self.arrow_list[self.active], self.degree)
        screen.blit(self.image, (self.x, self.y))


arrowRight = Arrow(0, 553, 700)
arrowLeft = Arrow(180, 425, 700)
arrowUp = Arrow(91, 440, 776)
arrowDown = Arrow(271, 557, 779)

run = True
while run:
    # background
    screen.blit(bg_image, (0, 0))
    screen.blit(ss_board, (0, 200))

    # draw arrows
    arrowRight.draw()
    arrowLeft.draw()
    arrowUp.draw()
    arrowDown.draw()

    # event handlers
    for event in pygame.event.get():
        # quit game
        if event.type == pygame.QUIT:
            run = False
    pygame.display.update()
pygame.quit()

I have two requirements for the buttons:

  1. If I click a button that is active, it should be deactivated again. I already managed to implement this.

  2. If I click a button that is not active, it should be activated, and every other active button should be deactivated.

How can I implement the second requirement? Right now, it is possible for all four buttons to be active at the same time.

Upvotes: 0

Views: 44

Answers (2)

Papop Lekhapanyaporn
Papop Lekhapanyaporn

Reputation: 587

i think you should make a list of array button like

arrow_list = [arrowRight,arrowLeft,arrowUp,arrowDown]

then in the game loop you can can function to do the rest of the work

def button_activation(arrow_list):
    index = none
    for i,arrow in enumerate(arrow_list):
        if arrow.activate:
           index = i
    for i,arrow in enumerate(arrow_list):
        if index != i:
            arrow.activate = False

Upvotes: 0

Rabbid76
Rabbid76

Reputation: 211136

You need to link the buttons. Create a list of the buttons and set the list of buttons to each button object:

class Arrow:
    def __init__(self, degree, x, y):
        self.linkedButtons = []
        self.active = 0
        # [...]
arrowList = [
    Arrow(0, 553, 700)
    Arrow(180, 425, 700)
    Arrow(91, 440, 776)
    Arrow(271, 557, 779)
]
for arrow in arrowList:
    arrow.linkedButtons = arrowList

Deactivate all buttons before you activate a button:

class Arrow:
    # [...]

    def draw(self):
        # get mouse position
        mouse_pos = pygame.mouse.get_pos()

        # check mouseover and clicked conditions
        if self.rect.collidepoint(mouse_pos):
            if pygame.mouse.get_pressed()[0] == 1 and self.active == 0 and self.released:
                
                # deactivate all buttons 
                for button in self.linkedButtons: 
                    button.active = 0                

                # activate this button
                self.active = 1
                self.released = False
                print('Active')
   
            # [...]

Draw the buttons in a loop:

run = True
while run:
    # background
    screen.blit(bg_image, (0, 0))
    screen.blit(ss_board, (0, 200))

    # draw arrows
    for arrow in arrowList:
        arrow.draw()

    # event handlers
    for event in pygame.event.get():
        # quit game
        if event.type == pygame.QUIT:
            run = False
    pygame.display.update()
pygame.quit()

Upvotes: 1

Related Questions