Character only maintains movement while mouse is m

2019-08-08 02:31发布

问题:

My while loops only maintains the movement for the sprite while the cursor is moving inside of the screen. I've tried reorganizing some of the screen.blits and display.update() and display.flip(). I can't seem to figure out why the character stops after a change in one pixel instead of continuing like it I intended.

    background_image = 'Terrain_Grass_First.png'
    import pygame, sys
    from pygame.locals import *
    pygame.init()
    pygame.display.set_caption('Hans')
    screen_width = 600
    screen_height = 400
    screen = pygame.display.set_mode((screen_width, screen_height),0,32)
    pygame.mouse.set_visible(False)
    sprite = pygame.image.load('Hans_front_still.png').convert_alpha()
    x,y = (0,0)
    movex, movey = (0,0)
    while True:
        for event in pygame.event.get():
                if event.type == QUIT:
                        pygame.quit()
                        sys.exit()

                if event.type == KEYDOWN:
                        if event.key == K_ESCAPE:
                                pygame.quit()
                                sys.exit()
                        if event.key == K_w:
                                y = -1

                        elif event.key == K_a:
                                x = -1

                        elif event.key == K_s:
                                y = +1

                        elif event.key == K_d:
                                x = +1

                elif event.type == KEYUP:
                        if event.key == K_w:
                                y = 0

                        elif event.key == K_a:
                                x = 0

                        elif event.key == K_s:
                                y = 0

                        elif event.key == K_d:
                                x = 0
                movex += x
                movey += y


        screen.fill((0,0,0))
        screen.blit(sprite,(movex,movey))
        pygame.display.flip()

回答1:

Your loop blocks on pygame.event.get.

You don't schedule any events of your own.

So, you do nothing until the OS has an event (mouse move, redraw, etc.) to give you.


And, even if you fixed that, you're calling movex += x once per event. So, when the OS is throwing a lot of events at you, your sprite will go zipping madly across the screen, but when the events are coming more slowly, it will crawl along. That's almost never what you want.


An easy fix for both problems is to just schedule your own events. For example, with pygame.time.set_timer(), you can make sure you get an event every, say, 250 milliseconds, and you can only move the sprite on those events. For example:

timer_event = pygame.USEREVENT + 1
pygame.time.set_timer(timer_event, 250)
while True:
    for event in pygame.event.get():
        # ...
        elif event.type == timer_event:
            movex += x
            movey += y

Another alternative is to design your game with a fixed framerate.

A trivial example looks like this:

FRAME_TIME = 50 # 50ms = 20fps
next_frame_time = pygame.time.get_ticks() + FRAMES
while True:
    while True:
        event = pygame.event.poll()
        if event.type == pygame.NOEVENT:
            break
        elif # ...
    pygame.display.flip()
    now = pygame.time.get_ticks()
    if now < next_frame_time:
        pygame.time.wait(next_frame_time - now)
    next_frame_time += FRAMES

Now you can just move every 5th frame.

A realistic example has to deal with missed frames, too many events in the queue, choose between wait and delay appropriately, etc.

But I'd go with the event-driven version with a timer instead of a fixed-framerate version in most cases, especially if you're already going down that line.



回答2:

The only problem is your Indentation!

The fifth and sixth lines from the bottom have wrong indentation, and you need to delete them.

These two lines:
            movex += x
            movey += y

should be:
        movex += x
        movey += y

And it works



标签: python pygame