Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
112 views
in Technique[技术] by (71.8m points)

python - Dragging object along x-axis in pygame

I want to be able to drag the blue object along the x-axis (black line) using mouse so that it does not move in y-direction. When I try to drag it, nothing happens. Where is the problem?

import pygame

def initialize():
    pygame.init()
    global height, width
    height = 600
    width = 900
    screen = pygame.display.set_mode((width, height))
    screen.fill((255, 255, 255))
    pygame.draw.line(screen, (0, 0 ,0), (0, height / 2), (width, height / 2), 3)
    return screen

def object():
    dragging = False
    object_1 = pygame.rect.Rect(width / 4, height / 2 - 75, 50, 150)

    if event.type == pygame.MOUSEBUTTONDOWN:
        if event.button == 1:
            if object_1.collidepoint(event.pos):
                dragging = True
                mouse_x, mouse_y = event.pos
                offset_x = object_1.x - mouse_x

    elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                dragging = False

    elif event.type == pygame.MOUSEMOTION:
        if dragging:
            mouse_x, mouse_y = event.pos
            object_1.x = mouse_x + offset_x

    return object_1

if __name__ == "__main__":
    running = True
    screen = initialize()

    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            object_1 = object()
        pygame.draw.rect(screen, (0, 0, 250), object_1)
        pygame.display.update()
question from:https://stackoverflow.com/questions/65919817/is-there-a-way-to-drag-a-sprite-on-a-slider-with-mouse

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You have to create the object once before the main application loop and you have to handle the events in the application loop.
Furthermore you have to redraw the entire scene in the application loop. The main application loop has to:

Add a function which creates an object:

def create_object():
    object_1 = pygame.rect.Rect(width / 4, height / 2 - 75, 50, 150)
    return object_1

Create an object before the application loop:

if __name__ == "__main__":
    # [...]

    object_1 = create_object()

    while running:
        # [...]

Add a function which can drag an object:

dragging = False
def drag_object(events, object_1):
    global dragging, offset_x

    for event in events:
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                if object_1.collidepoint(event.pos):
                    dragging = True
                    mouse_x, mouse_y = event.pos
                    offset_x = object_1.x - mouse_x

        elif event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:
                    dragging = False

        elif event.type == pygame.MOUSEMOTION:
            if dragging:
                mouse_x, mouse_y = event.pos
                object_1.x = mouse_x + offset_x

Get the list of events once in the application loop and pass the events to the function drag_object:

while running:
    # [...]

    drag_object(events, object_1)

Clear the display, draw the scene and update the display in the application loop:

while running:
    # [...]

    screen.fill((255, 255, 255))
    pygame.draw.line(screen, (0, 0 ,0), (0, height / 2), (width, height / 2), 3)
    pygame.draw.rect(screen, (0, 0, 250), object_1)
    pygame.display.update()

See the example:

enter image description here

import pygame

def initialize():
    pygame.init()
    global height, width
    height = 600
    width = 900
    screen = pygame.display.set_mode((width, height))
    return screen

def create_object():
    object_1 = pygame.rect.Rect(width / 4, height / 2 - 75, 50, 150)
    return object_1

dragging = False
def drag_object(events, object_1):
    global dragging, offset_x

    for event in events:
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                if object_1.collidepoint(event.pos):
                    dragging = True
                    mouse_x, mouse_y = event.pos
                    offset_x = object_1.x - mouse_x

        elif event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:
                    dragging = False

        elif event.type == pygame.MOUSEMOTION:
            if dragging:
                mouse_x, mouse_y = event.pos
                object_1.x = mouse_x + offset_x

if __name__ == "__main__":
    running = True
    screen = initialize()

    object_1 = create_object()

    while running:

        events = pygame.event.get()
        for event in events:
            if event.type == pygame.QUIT:
                running = False

        drag_object(events, object_1)

        screen.fill((255, 255, 255))
        pygame.draw.line(screen, (0, 0 ,0), (0, height / 2), (width, height / 2), 3)
        pygame.draw.rect(screen, (0, 0, 250), object_1)
        pygame.display.update()

Alternatively you can create a class for the object:

import pygame

def initialize():
    pygame.init()
    global height, width
    height = 600
    width = 900
    screen = pygame.display.set_mode((width, height))
    return screen

class MyObject:
    def __init__(self):
        self.rect = pygame.rect.Rect(width / 4, height / 2 - 75, 50, 150)
        self.dragging = False
        self.offset_x = 0 

    def drag(self, events):
        for event in events:
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    if self.rect.collidepoint(event.pos):
                        self.dragging = True
                        self.offset_x = self.rect.x - event.pos[0]
            elif event.type == pygame.MOUSEBUTTONUP:
                    if event.button == 1:
                        self.dragging = False
            elif event.type == pygame.MOUSEMOTION:
                if self.dragging:
                   self.rect.x = event.pos[0] + self.offset_x

    def draw(self, surf):
        pygame.draw.rect(surf, (0, 0, 250), object_1)

if __name__ == "__main__":
    running = True
    screen = initialize()

    object_1 = MyObject()

    while running:

        events = pygame.event.get()
        for event in events:
            if event.type == pygame.QUIT:
                running = False

        object_1.drag(events)

        screen.fill((255, 255, 255))
        pygame.draw.line(screen, (0, 0 ,0), (0, height / 2), (width, height / 2), 3)
        object_1.draw(screen)
        pygame.display.update()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...