在pygame中计算重力/跳跃 [英] Calculate gravity/jump in pygame

查看:113
本文介绍了在pygame中计算重力/跳跃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 pygame 中计算重力的最佳方法是什么?我基本上只需要它,所以当玩家按下向上"时,角色会跳跃.到目前为止,这是我的代码(只是一个带有红色块的白色屏幕,可以四处移动)

What is the best way to calculate gravity in pygame? I basically just need it so when the player pushes "Up", the character jumps. Here is my code so far (just a white screen with a red block that moves around)

import pygame
import random

# Define colors
black    = (   0,   0,   0)
white    = ( 255, 255, 255)
green    = (   0, 255,   0)
red      = ( 255,   0,   0)

#Classes
class Player(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        pygame.sprite.Sprite.__init__(self) 
        self.image = pygame.Surface([width, height])
        self.image.fill(color)
        self.rect = self.image.get_rect()

    def move(self, x_change, y_change):
        self.rect.x += x_change
        self.rect.y +=  y_change


#Lists
all_sprites_list = pygame.sprite.Group()

#Spawn player
player = Player(red,16,16) 
all_sprites_list.add(player)
player.rect.x = 0
player.rect.y = 484

#Initalize
pygame.init()
#Set the width and height of the screen [width,height]
screen_height = 700
screen_width = 500
size=[screen_height,screen_width]
screen=pygame.display.set_mode(size)
#Name on top tab
pygame.display.set_caption("My Game")

#DONT CHANGE
done = False
clock=pygame.time.Clock()

#MAIN LOOP
while done == False:
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done = True # Quit

        if event.type == pygame.KEYUP:
                    # If it is an arrow key, reset vector back to zero
                    if event.key == pygame.K_LEFT:
                        None      

    keyDown = pygame.key.get_pressed()
    if keyDown[pygame.K_RIGHT]:
        player.move(3, 0)   
    if keyDown[pygame.K_LEFT]:
        player.move(-3, 0)        
    if keyDown[pygame.K_DOWN]:
        player.move(0, 3)                        
    if keyDown[pygame.K_UP]:
        player.move(0,-3)

    #If player hits side of screen, do this
    if player.rect.x < 0:
        player.rect.x = 0
    if player.rect.x > 684:
        player.rect.x = 684
    if player.rect.y < 0:
        player.rect.y = 0
    if player.rect.y > 484:
        player.rect.y = 484    


    #Clear screen
    screen.fill(white)

    #Drawing
    all_sprites_list.draw(screen)

    #FPS Lock
    clock.tick(60)

    #Update screen
    pygame.display.flip()

# Close the window and quit.
pygame.quit()

推荐答案

超级马里奥克隆人通常会向上移动特定的时间,然后向下移动,直到他碰到固体(地板,或者可能是龟).您可能知道,这看起来很不现实.

Super Mario clones typically move a specific amount of time up, then down until he hits something solid (the floor, or possibly a turtle). As you may know, it looks very unrealistic.

跳跃和下落"的物理公式为:d = (at²)/2,其中d是跳起来的距离,acode> 是重力,t 是时间.但是,对于简单可以调整的游戏:)

The physics formula for "jumping and falling" is: d = (at²)/2, where d is the distance jumped up, a is the gravity, and t is the time. However, for a simple game that can be adjusted :)

  1. 为你的跳跃设定一个目标高度";例如,总共 32 个像素.
  2. 使用 1 表示重力.
  3. 在游戏滴答中测量时间 t.
  4. 这为您提供了达到 32 像素所需的时间:

  1. Set a target 'height' for your jumps; for example, 32 pixels in total.
  2. Use 1 for gravity.
  3. Measure time t in game ticks.
  4. That gives you the time it takes to reach 32 pixels:

 32 = (t²)/2
 t² = 64
 t = 8

  • 你跳跃的速度"是v = at.由于您在上面假设 a=1v = t,即 v = 8.看起来,您的初始 ypos 需要设置为 speed/2(可能是因为这是一个近似值..)

  • The 'speed' of your jump is v = at. Since you assume a=1 above, v = t, i.e., v = 8. As it appears, your initial ypos needs to be set to speed/2 (probably because this is an approximation..)

    现在,从您按下向上"的那一刻起,每个游戏滴答都会发生以下情况(假设开始时 y=0):

    Now the following will happen in each game tick from the moment you press 'up' (assuming y=0 at start):

    1. speed = 8 -> y=4(因为这是跳转 0")
    2. speed = 7 -> y=11
    3. speed = 6 -> y=17
    4. speed = 5 -> y=22
    5. speed = 4 -> y=26
    6. speed = 3 -> y=29
    7. speed = 2 -> y=31
    8. speed = 1 -> y=32
    9. speed = 0 -> y=32
    10. speed = -1 -> y=31
    11. speed = -2 -> y=29...再次下降到 0(但检查溢出是否低于零).
    1. speed = 8 -> y=4 (since this is "jump 0")
    2. speed = 7 -> y=11
    3. speed = 6 -> y=17
    4. speed = 5 -> y=22
    5. speed = 4 -> y=26
    6. speed = 3 -> y=29
    7. speed = 2 -> y=31
    8. speed = 1 -> y=32
    9. speed = 0 -> y=32
    10. speed = -1 -> y=31
    11. speed = -2 -> y=29 ... down to 0 again (but check on overflow for lower-than-zero).

  • 关于半速"修复:奇怪.. 数学是这样计算的(你在正确的高度上悬停片刻)但我无法立即弄清楚为什么你不应该从实际速度.

    On the "half speed" fix: strange .. the math works out this way (you hover for just a moment on exactly the right height) but I can't figure out off-hand why you should not start with the actual speed.

    刚刚想到我的数学表现不佳的原因.

    Just thought of the reason why my maths seemed off.

    问题在于我的声明,如果你的初始速度——在跳跃开始时——是8(每游戏滴答的像素),你最终正好是8在那个刻度的结束"处更高的像素.你不会,因为一旦你离开地面,重力"就会立即起作用.在游戏滴答结束"时,您的速度已降至7;因此,您的 平均 速度从本次滴答的开始到结束不是 8,它只是 7.5,并且您最终处于 y-pos7.5 像素.每个下一个刻度也是如此;你的速度仍然会以 1 的速度下降.

    The problem lies in my statement that if your initial velocity -- at Start of Jump -- is 8 (pixels per game tick), you end up exactly 8 pixels higher at the "end" of that tick. You don't, because the "gravity" kicks in immediately, as soon as you leave the ground. At the "end" of the game tick, your speed has decreased to 7; therefore, your average speed is not 8 from start to end of this tick, it's only 7.5, and you end up on an y-pos of 7.5 pixels. The same goes for every next tick; your speed still decreases with 1 per tick.

    因此,在(正确计算!)8 个滴答的总跳跃时间之后,您旅行了

    So, after the (correctly calculated!) total jumping-up time of 8 ticks, you traveled

    7.5 + 6.5 + 5.5 + 4.5 + 3.5 + 2.5 + 1.5 + 0.5 = 32 pixels
    

    正确"实现它是可能的,但它在目前仅支持整数的计算中引入了浮点算术,并且需要您在7.5 像素"的 y 位置绘制精灵.浮点计算可能会遇到舍入和精确"比较问题,因此最好尽可能避免它——当然对于这种简单的物理.

    It's possible to "correctly" implement it, but it introduces floating-point arithmetics in what is currently an integer-only calculation, and it would require you to draw your sprite at an y position of "7.5 pixels". Floating-point calculations may suffer from rounding and 'exact' comparison issues, so that's why it is best to avoid it where possible -- certainly for this kind of simple physics.

    这篇关于在pygame中计算重力/跳跃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆