英文:
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("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)) #Bounding box of slider
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)) #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,"null")
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 >= 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.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, "null")
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 >= 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)) # 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()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论