Dragging object along x-axis in pygame

核能气质少年 提交于 2021-02-17 02:06:19

问题


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()

回答1:


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:

  • handle the events by either pygame.event.pump() or pygame.event.get().
  • update the game states and positions of objects dependent on the input events and time (respectively frames)
  • clear the entire display or draw the background
  • draw the entire scene (blit all the objects)
  • update the display by either pygame.display.update() or pygame.display.flip()

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:

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()


来源:https://stackoverflow.com/questions/61781533/dragging-object-along-x-axis-in-pygame

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!