2

I am creating a covid simulator and am using sliders to allow the user to adjust the figures such as the amount of people that will stay at home. I have been able to successfully create the sliders, but for some reason when i try to move one they both move. The code i have created goes:

def saved_sim():
    slider1 = 600
    slider2 = 600
    #size_of_gas_cloud = 400
    running = True
    while running:
        menu.fill(BACKGROUND_COLOR)
        title = Label(menu, "Editting features for simulation", 1, font_title, BLACK, 330, 30)
        Sub_heading = Label(menu, "Please edit the features using sliders before selecting a location", 1, font_para, BLACK, 5, 100)

        if pygame.mouse.get_pressed()[0] != 0:
            # collision detection also needed here
            slider1 = pygame.mouse.get_pos()[0] - 5
            if slider1 < 600:
                slider1 = 600
            if slider1 > 800:
                slider1 = 800

        if pygame.mouse.get_pressed()[0] != 0:
            # collision detection also needed here
            slider2 = pygame.mouse.get_pos()[0] - 5
            if slider2 < 600:
                slider2 = 600
            if slider2 > 800:
                slider2 = 800

        pygame.draw.rect(menu, BLACK, Rect(600, 300, 210, 10))
        pygame.draw.rect(menu, RED, Rect(slider1, 300, 10, 10))

        pygame.draw.rect(menu, BLACK, Rect(600, 400, 210, 10))
        pygame.draw.rect(menu, RED, Rect(slider2, 400, 10, 10))

Thanks for any help in advance.

2 Answers2

2

Here is a slider class that might help you with creating sliders in a more convenient way. The code is commented but feel free to questions if you have any.

import pygame

d = pygame.display.set_mode((500, 500))
pygame.init()

#Takes rectangle's size, position and a point. Returns true if that
#point is inside the rectangle and false if it isnt.
def pointInRectanlge(px, py, rw, rh, rx, ry):
    if px > rx and px < rx  + rw:
        if py > ry and py < ry + rh:
            return True
    return False

#Blueprint to make sliders in the game
class Slider:
    def __init__(self, position:tuple, upperValue:int=10, sliderWidth:int = 30, text:str="Editing features for simulation",
                 outlineSize:tuple=(300, 100))->None:
        self.position = position
        self.outlineSize = outlineSize
        self.text = text
        self.sliderWidth = sliderWidth
        self.upperValue = upperValue
        
    #returns the current value of the slider
    def getValue(self)->float:
        return self.sliderWidth / (self.outlineSize[0] / self.upperValue)

    #renders slider and the text showing the value of the slider
    def render(self, display:pygame.display)->None:
        #draw outline and slider rectangles
        pygame.draw.rect(display, (0, 0, 0), (self.position[0], self.position[1], 
                                              self.outlineSize[0], self.outlineSize[1]), 3)
        
        pygame.draw.rect(display, (0, 0, 0), (self.position[0], self.position[1], 
                                              self.sliderWidth, self.outlineSize[1] - 10))

        #determite size of font
        self.font = pygame.font.Font(pygame.font.get_default_font(), int((15/100)*self.outlineSize[1]))

        #create text surface with value
        valueSurf = self.font.render(f"{self.text}: {round(self.getValue())}", True, (255, 0, 0))
        
        #centre text
        textx = self.position[0] + (self.outlineSize[0]/2) - (valueSurf.get_rect().width/2)
        texty = self.position[1] + (self.outlineSize[1]/2) - (valueSurf.get_rect().height/2)

        display.blit(valueSurf, (textx, texty))

    #allows users to change value of the slider by dragging it.
    def changeValue(self)->None:
        #If mouse is pressed and mouse is inside the slider
        mousePos = pygame.mouse.get_pos()
        if pointInRectanlge(mousePos[0], mousePos[1]
                            , self.outlineSize[0], self.outlineSize[1], self.position[0], self.position[1]):
            if pygame.mouse.get_pressed()[0]:
                #the size of the slider
                self.sliderWidth = mousePos[0] - self.position[0]

                #limit the size of the slider
                if self.sliderWidth < 1:
                    self.sliderWidth = 0
                if self.sliderWidth > self.outlineSize[0]:
                    self.sliderWidth = self.outlineSize[0]

slider = Slider((100, 100))

while True:
    pygame.event.get()
    d.fill((255, 255, 255))

    slider.render(d)
    slider.changeValue()
    print(slider.getValue())
    
    pygame.display.update()
1

You have to check if the mouse cursor is in the rectangular area of the slider. Use pygame.Rect objects and collidepoint() to test if the mouse cursor is on the slider. The position of the mouse cursor can be get with pygame.mouse.get_pos().

slider_rect1 = pygame.Rect(600, 300, 210, 10)
slider_rect2 = pygame.Rect(600, 400, 210, 10)
mouse_pos = pygame.mouse.get_pos()

if slider_rect1.collidepoint(mouse_pos) and pygame.mouse.get_pressed()[0] != 0:
    # [...]

if slider_rect2.collidepoint(mouse_pos) and pygame.mouse.get_pressed()[0] != 0:
    # [...]

See also How to detect when a rectangular object, image or sprite is clicked

Function saved_sim:

def saved_sim():
    slider1 = 600
    slider2 = 600
    #size_of_gas_cloud = 400

    slider_rect1 = pygame.Rect(600, 300, 210, 10)
    slider_rect2 = pygame.Rect(600, 400, 210, 10)

    running = True
    while running:
        menu.fill(BACKGROUND_COLOR)
        title = Label(menu, "Editting features for simulation", 1, font_title, BLACK, 330, 30)
        Sub_heading = Label(menu, "Please edit the features using sliders before selecting a location", 1, font_para, BLACK, 5, 100)

        mouse_pos = pygame.mouse.get_pos()

        if slider_rect1.collidepoint(mouse_pos) and pygame.mouse.get_pressed()[0] != 0:
            # collision detection also needed here
            slider1 = pygame.mouse.get_pos()[0] - 5
            if slider1 < 600:
                slider1 = 600
            if slider1 > 800:
                slider1 = 800

        if slider_rect2.collidepoint(mouse_pos) and pygame.mouse.get_pressed()[0] != 0:
            # collision detection also needed here
            slider2 = pygame.mouse.get_pos()[0] - 5
            if slider2 < 600:
                slider2 = 600
            if slider2 > 800:
                slider2 = 800

        pygame.draw.rect(menu, BLACK, slider_rect1)
        pygame.draw.rect(menu, RED, Rect(slider1, 300, 10, 10))

        pygame.draw.rect(menu, BLACK, slider_rect2)
        pygame.draw.rect(menu, RED, Rect(slider2, 400, 10, 10))
Rabbid76
  • 202,892
  • 27
  • 131
  • 174