简体   繁体   English

Python pygame - 使用浮点数平滑移动

[英]Python pygame - smooth movement with float numbers

So I'm new to python and I'm trying to learn the pygame module by programming a little cars game.所以我是 python 的新手,我正在尝试通过编写一个小汽车游戏来学习 pygame 模块。 The "engine" of the game is based on scrolling background that moves down when the user press the "up" key.游戏的“引擎”基于当用户按下“向上”键时向下移动的滚动背景。

I'm trying to make a deceleration of the car (when the user release the "up" key) instead of immediate stop.我试图使汽车减速(当用户释放“向上”键时)而不是立即停止。 So for that I've tried to use a float for loop (using numpy module) that decrease the speed of the background movement from 5 to 0 by -0.1, but it doesn't work properly.因此,为此我尝试使用浮点循环(使用 numpy 模块)将背景移动的速度从 5 降低到 0 为 -0.1,但它无法正常工作。 What actually happened is that when I release the "up" key, the game freeze for a sec and then the background unsmoothly moves a few pixels down.实际发生的情况是,当我松开“向上”键时,游戏会冻结一秒钟,然后背景会不流畅地向下移动几个像素。

This is my code, hope you can help me fix that:这是我的代码,希望你能帮我解决这个问题:

import pygame
import numpy

pygame.init()
clock = pygame.time.Clock()
run = True

# screen & bg setting
wnw = 500
wnh = 700
wn = pygame.display.set_mode((wnw, wnh))
bgcolor = (70, 190, 255)
bg = pygame.image.load('road.jpg')
bgy = 0
bgy2 = -bg.get_height()

# loading objects
class Car():
    sprite = pygame.image.load('car.gif')
    w = 100
    h = 100
    x = 200
    y = 350
    ver_spd = 5
    hor_spd = 2
car = Car()

def drawbg():
    wn.blit(bg, (0, bgy))
    wn.blit(bg, (0, bgy2))
drawbg()

while run:

    clock.tick(60)

    # keys binding
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        if car.x + car.hor_spd > 0:
            drawbg()
            car.x -= car.hor_spd
    if keys[pygame.K_RIGHT]:
        if car.x + car.hor_spd < wnw - car.w:
            drawbg()
            car.x += car.hor_spd
    if keys[pygame.K_UP]:
        if car.y - car.ver_spd > 0:
            bgy, bgy2 = bg_movement(bgy, bgy2, car.ver_spd)
    def bg_movement(bgy, bgy2, spd):
        drawbg()
        bgy += float(spd)
        bgy2 += float(spd)
        if bgy > bg.get_height():
            bgy = -bg.get_height()
        if bgy2 > bg.get_height():
            bgy2 = -bg.get_height()
        return bgy, bgy2


    for event in pygame.event.get():
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_UP:
                for i in numpy.arange(5.0, 0.0, -0.1):
                    bgy, bgy2 = bg_movement(bgy, bgy2, float(i))

    wn.blit(car.sprite, (car.x, car.y))

    pygame.display.update()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        print(event)

pygame.quit()

First of pygame.event.get() get all the messages and remove them from the queue.首先pygame.event.get()获取所有消息并将它们从队列中删除。 So either the 1st or the 2nd loop gets an event, but never both loops will get all events.因此,第一个或第二个循环获取一个事件,但永远不会两个循环都获取所有事件。 That causes that some events seems to be missed.这导致某些事件似乎被遗漏了。
implement 1 event loop in your application.在您的应用程序中实现 1 个事件循环。

Once UP is released, you've to set a decelerate state.释放UP 后,您必须设置decelerate状态。 Decrease the variable and move the care forward by the amount in every frame as long decelerate > 0 :减少变量并将每帧中的 care 向前移动一定量,只要 long decelerate > 0

def drawbg():
    wn.blit(bg, (0, int(bgy)))
    wn.blit(bg, (0, int(bgy2)))
drawbg()

def bg_movement(bgy, bgy2, spd):
        bgy += float(spd)
        bgy2 += float(spd)
        if bgy > bg.get_height():
            bgy = -bg.get_height()
        if bgy2 > bg.get_height():
            bgy2 = -bg.get_height()
        return bgy, bgy2

decelerate = 0
while run:

    clock.tick(60)

    # keys binding
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        if car.x + car.hor_spd > 0:

            car.x -= car.hor_spd
    if keys[pygame.K_RIGHT]:
        if car.x + car.hor_spd < wnw - car.w:
            car.x += car.hor_spd
    if keys[pygame.K_UP]:
        decelerate = 0
        if car.y - car.ver_spd > 0:
            bgy, bgy2 = bg_movement(bgy, bgy2, car.ver_spd)

    if decelerate > 0:
        bgy, bgy2 = bg_movement(bgy, bgy2, decelerate)
        decelerate -= 0.1


    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_UP:
                decelerate = car.ver_spd


    drawbg()
    wn.blit(car.sprite, (car.x, car.y))

    pygame.display.update()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM