My pygame slider moves back to the default position when mouse click is released rather than staying where it was left

huangapple go评论56阅读模式
英文:

My pygame slider moves back to the default position when mouse click is released rather than staying where it was left

问题

当我单击滑块对象时,我可以按预期在指定的框边界内移动滑块,但是当我松开鼠标按钮时,蓝色滑块会瞬移到框的左侧。

如何才能让滑块在我松开鼠标按钮时保持在原地?

import pygame

pygame.init()
WIDTH = 1820
HEIGHT = 960
res = (WIDTH, HEIGHT)
screen = pygame.display.set_mode(res)
clock = pygame.time.Clock()
WHITE = [255, 255, 255]
GRAY = [125, 125, 125]
BLACK = [0, 0, 0]
BLUE = [0, 0, 155]

class ui(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height, colour, name):
        self.x = x
        self.y = y
        self.w = width
        self.h = height
        self.c = colour
        self.n = name
        self.font = pygame.font.SysFont("Arial", 25)

class slider(ui):
    def __init__(self, x, y, width, height):
        super().__init__(x, y, width, height, GRAY, "null")

    def draw(self):
        pygame.draw.rect(screen, GRAY, (self.x, self.y, self.w, self.h))  # 滑块的边界框

    def click(self, event):
        bound = False
        button = pygame.mouse.get_pressed()
        x, y = pygame.mouse.get_pos()
        if x >= self.x and x <= self.x + self.w:
            if y >= self.y and y <= self.y + self.h:
                bound = True
        else:
            bound = False

        if bound == True:
            if button[0] != 0:
                self.x = x
            if event.type == pygame.MOUSEBUTTONUP:
                self.x = x

        pygame.draw.rect(screen, BLUE, (self.x, self.y, 10, self.h))  # 可单击的滑块本身

def main():
    done = False
    while not done:
        event_list = pygame.event.get()
        for event in event_list:
            if event.type == pygame.QUIT:
                done = True
        screen.fill((255, 255, 255))
        slider1 = slider(250, 250, 300, 100)
        slider1.draw()
        slider1.click(event)

        pygame.display.flip()
        clock.tick(60)

main()

我尝试了一些鼠标按钮松开时的检测:

if event.type == pygame.MOUSEBUTTONUP:
   self.x = x

这在我松开鼠标按钮后有效,但一旦我将鼠标移出滑块或输入任何键盘按键后,滑块会瞬移到其他位置。

英文:

When I click on my slider object, I can move the slider around in the given boundaries of the box as expected however when I let go of my mouse button, the blue slider teleports to the left side of the box.

How can I get it so the slider is left when I release the mouse button?

import pygame
pygame.init()
WIDTH = 1820
HEIGHT = 960
res = (WIDTH, HEIGHT)
screen = pygame.display.set_mode(res)
clock = pygame.time.Clock()
WHITE = [255, 255, 255]
GRAY = [125, 125, 125]
BLACK = [0, 0, 0]
BLUE = [0, 0, 155]
class ui(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, colour, name):
self.x = x
self.y = y
self.w = width
self.h = height
self.c = colour
self.n = name
self.font = pygame.font.SysFont(&quot;Arial&quot;,25)
class slider(ui):
def __init__(self, x, y,width,height):
super().__init__(x,y,width,height,GRAY,&quot;null&quot;)
def draw(self):
pygame.draw.rect(screen, GRAY, (self.x, self.y, self.w, self.h)) #Bounding box of slider
def click(self, event):
bound = False
button = pygame.mouse.get_pressed()
x, y = pygame.mouse.get_pos()
if x &gt;= self.x and x &lt;= self.x + self.w:
if y &gt;= self.y and y &lt;= self.y + self.h:
bound = True
else:
bound = False
if bound == True:
if button[0] != 0:
self.x = x
if event.type == pygame.MOUSEBUTTONUP:
self.x = x
pygame.draw.rect(screen, BLUE, (self.x, self.y, 10, self.h)) #actual clickable slider itself
def main():
done = False
while not done:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
done = True
screen.fill((255,255,255))
slider1 = slider(250,250,300,100)
slider1.draw()
slider1.click(event)
pygame.display.flip()
clock.tick(60)
main()

I've tried writing some detection for when the user lets go of the mouse button.

if event.type == pygame.MOUSEBUTTONUP:
self.x = x

That works once I let go of the mouse button but then teleports once I move my mouse off the slider or input any key.

答案1

得分: 0

以下是您代码的翻译部分:

原代码中有两个错误:

  • 滑块在每帧中被删除并重新创建。
  • 你没有移动滑块上的滑块条,而是整个滑块本身。

为了修复这个问题,只需创建 slider1 一次,并有一个变量来跟踪位置:

...

class slider(ui):
    def __init__(self, x, y, width, height):
        super().__init__(x, y, width, height, GRAY, "null")
        self.pos = x

    def draw(self):
        pygame.draw.rect(screen, GRAY, (self.x, self.y, self.w, self.h))  # 滑块的边界框

    def click(self):
        button = pygame.mouse.get_pressed()

        x, y = pygame.mouse.get_pos()
        if x >= self.x and x <= self.x + self.w and y >= self.y and y <= self.y + self.h:
            if True in button and not self.pressed:
                self.bound = True

        if not True in button:
            self.bound = False

        if self.bound:
            self.pos = max(self.x, min(self.x + self.w, x))

        pygame.draw.rect(screen, BLUE, (self.pos, self.y, 10, self.h))  # 实际可点击的滑块本身

        self.pressed = True in button


def main():
    done = False
    slider1 = slider(250, 250, 300, 100)

    while not done:
        event_list = pygame.event.get()
        for event in event_list:
            if event.type == pygame.QUIT:
                done = True
        screen.fill((255, 255, 255))

        slider1.draw()
        slider1.click()

        pygame.display.flip()
        clock.tick(60)

    pygame.quit()


main()
英文:

You actually have two mistakes in your code:

  • The slider is deleted and created again each frame.
  • You don't move the bar on the slider but instead the whole slider itself.

To fix this only create slider1 once and have a variable that traces the position:

...
class slider(ui):
def __init__(self, x, y,width,height):
super().__init__(x,y,width,height,GRAY,&quot;null&quot;)
self.pos = x
def draw(self):
pygame.draw.rect(screen, GRAY, (self.x, self.y, self.w, self.h)) #Bounding box of slider
def click(self, event):
bound = False
button = pygame.mouse.get_pressed()
x, y = pygame.mouse.get_pos()
if x &gt;= self.x and x &lt;= self.x + self.w:
if y &gt;= self.y and y &lt;= self.y + self.h:
bound = True
else:
bound = False
if bound == True:
if button[0] != 0:
self.pos = x # (changed to pos)
if event.type == pygame.MOUSEBUTTONUP:
self.pos = x
pygame.draw.rect(screen, BLUE, (self.pos, self.y, 10, self.h)) #actual clickable slider itself
def main():
done = False
slider1 = slider(250,250,300,100) # add
while not done:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
done = True
screen.fill((255,255,255))
#slider1 = slider(250,250,300,100) (remove)
slider1.draw()
slider1.click(event)
pygame.display.flip()
clock.tick(60)
pygame.quit()
main()

Now you have a slider. But to make the movement more intuitively you might only move the slider when the mouse button started to be pressed on the slider:

...
class slider(ui):
def __init__(self, x, y, width, height):
super().__init__(x, y, width, height, GRAY, &quot;null&quot;)
self.pos = x
self.pressed = False
self.bound = False
def draw(self):
pygame.draw.rect(screen, GRAY, (self.x, self.y, self.w, self.h)) # Bounding box of slider
def click(self):
button = pygame.mouse.get_pressed()
x, y = pygame.mouse.get_pos()
if x &gt;= self.x and x &lt;= self.x + self.w and y &gt;= self.y and y &lt;= self.y + self.h:
if True in button and not self.pressed:
self.bound = True
if not True in button:
self.bound = False
if self.bound:
self.pos = max(self.x, min(self.x + self.w, x))
pygame.draw.rect(screen, BLUE, (self.pos, self.y, 10, self.h)) # actual clickable slider itself
self.pressed = True in button
def main():
done = False
slider1 = slider(250, 250, 300, 100)
while not done:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
done = True
screen.fill((255, 255, 255))
slider1.draw()
slider1.click()
pygame.display.flip()
clock.tick(60)
pygame.quit()
main()

huangapple
  • 本文由 发表于 2023年2月16日 18:19:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75470813.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定