问题
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