我对这个网站很新,所以请耐心等待。我目前正在为一个学校项目制作一个类似涂鸦的游戏,我无法让玩家一直上下跳跃。问题是如果跳转的命令行执行超过几秒钟,它就开始变得不一致(没有降落在正确的高度,跳跃距离减少......)。我能想到的唯一可能导致这种不一致的是clock.tick()
函数。请注意,您必须按空格键才能启动此过程。任何关于改进游戏的建议和单位碰撞的提示以及随着玩家的进展让屏幕“向上移动”也是受欢迎的。我再一次道歉,因为我是pygame和这个网站的绝对新手。
bif = "Background.jpg"
mif = "Ball.png"
import pygame, sys
import random
import os
from pygame.locals import*
import time
class Ball(object):
def __init__(self):
x = 320
y = 460
self.dx = 0
self.dy = 0
self.g = 0
self.rect = pygame.Rect(x,y,16,16)
def update(self):
self.rect.x += self.dx
self.rect.y += self.dy
self.dx = 0
self.dy = 0
def aground(self):
if self.g <= 500:
return True
elif self.g > 500:
return False
def moveleft(self):
if self.rect.x > 640:
self.rect.x = 0
elif self.rect.x < 0:
self.rect.x = 640
self.dx = (-(speed*seconds))
self.update()
def moveright(self):
if self.rect.x > 640:
self.rect.x = 0
elif self.rect.x < 0:
self.rect.x = 640
self.dx = (speed*seconds)
self.update()
def jump(self):
if self.g == 1000:
self.g = 0
if self.aground() == True:
self.dy = -(speed*seconds)
self.g += 1
self.update()
elif self.aground() == False:
self.dy = (speed*seconds)
self.g += 1
self.update()
pygame.init()
screen = pygame.display.set_mode((640,480),0,32)
background = pygame.image.load(bif).convert()
ball = pygame.image.load(mif).convert_alpha()
x = 0
a = 0
y = 480
player = Ball()
clock = pygame.time.Clock()
speed = 1000
j = 0
start = 0
init = 0
while True:
screen.blit(background,(0,0))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
key = pygame.key.get_pressed()
if key[pygame.K_LEFT]:
player.moveleft()
if key[pygame.K_RIGHT]:
player.moveright()
if key[pygame.K_SPACE]:
init = 1
if init == 1:
player.jump()
milli = clock.tick()
seconds = milli/1000.
if a%10 == 0:
pygame.draw.rect(background,(140,240,130), Rect((x,y),(70,30)))
a +=12
x = random.randint(0,640)
y -= 15
pygame.draw.rect(screen,(255, 200, 0),player.rect)
pygame.display.update()
答案 0 :(得分:1)
正如Patashu所说,使用重力系统处理你的跳跃会更有意义。以下是我自己的一个pygame项目的一些片段,让您了解它是如何工作的:
def update(self):
self.find_state()
self.find_move()
self.do_move()
if not(self.onGround): # player is in the air
self.playerForces.append(Player.gravity)
if self.primary_state == PlayerState.JUMPFORWARD:
self.playerVel[0] = self.walkingSpeed * (-1 if self.facing_left else 1)
elif self.primary_state == PlayerState.JUMPBACKWARD:
self.playerVel[0] = self.backSpeed * (1 if self.facing_left else -1)
else: # player is on the ground
if self.secondary_state == PlayerState.WALKING:
self.playerVel[0] = self.walkingSpeed * (-1 if self.facing_left else 1)
elif self.secondary_state == PlayerState.BACKING:
self.playerVel[0] = self.backSpeed * (1 if self.facing_left else -1)
else:
self.playerVel[0] = 0
# first frame of jumping
if self.primary_state == PlayerState.JUMPING:
self.playerForces.append([0, -self.jumpHeight])
self.onGround = False
self.apply_forces()
self.playerForces = list() # after applying forces for this frame, clear the list
您可以看到我的Player
类有一个名为onGround
的标记。当玩家跳跃时,它会设置为False
,并用于确定是否对Player
对象施加重力。通过这样做,Player.jumpHeight
值可能从10开始(这意味着每帧向上移动10个像素),以及Player
在空中的每一帧,该数量减少了一定数量数量(重力值)。最终重力将克服跳跃的力量,Player
将开始回到地面。
在我的代码的另一部分中,我有一个pygame.Rect
对象用于Player
对象,对于&#34; ground&#34;。我检查他们是否相撞,如果有,我将Player
的{{1}}标志更改回onGround
,以便它停止对它施加重力:
True
正如你可以从中看到的那样,我也做了一个小小的纠正&#34;到碰撞后 if playerRect.colliderect(ground):
collisionShift = gameUtils.getMinTransVect(playerRect, ground)
player1.playerForces.append([0, collisionShift[1]])
player1.onGround = True
player1.playerVel[1] = 0
对象的位置。这确保了每次Player
&#34;登陆&#34;在地面上,它不会沉没&#34;沉没&#34;在所有。如果在一个帧中一个对象在一个方向上移动的像素多于两个可碰撞对象之间的像素(如果Player
对象与地面之间有4个像素的间隙,那么Player
在一帧中向下移动8个像素。在这种情况下,如果你只是在检测到碰撞后停止移动Player
,它就会沉入地下。)