2013-05-02 63 views
0

我對這個網站真的很陌生,所以請耐心等待。我目前正在爲一個學校項目製作一個類似於塗鴉的遊戲,並且我一直無法讓玩家一直上下跳動。問題是,如果跳躍的命令行執行超過幾秒鐘,它會開始變得不一致(不能在正確的高度着陸,跳躍距離減少......)。我能想到的唯一可能導致這種不一致的是clock.tick()函數。請注意,您必須按空間才能啓動此過程。任何關於改善遊戲的建議和單元碰撞的提示以及隨着玩家進步而使屏幕「向上移動」也是受歡迎的。我再一次道歉,因爲我是pygame和本站的絕對新手。clock.tick()中的差異?

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() 
+2

而不是......無論是用於跳躍的瘋狂系統,你都要實現一個合適的重力系統,例如, 1)如果你在地面上,跳躍的作品,並設置你的向上速度爲Y 2)每一幀,你上升Y,但Y由重力減少,G 3)如果你碰撞一個地板,那麼你現在接地 - 將Y設置爲0並停止更改,等等。 – Patashu 2013-05-02 03:18:33

回答

1

正如Patashi提到的那樣,使用重力系統來處理跳躍會更有意義。下面是我自己的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將開始朝向地面返回。

在我的代碼的另一部分,我有一個pygame.Rect對象爲Player對象,併爲「地面」。我檢查,如果他們發生了碰撞,如果他們有,我改變PlayeronGround標誌回到True,使其停止施加gravit它:

if playerRect.colliderect(ground): 
     collisionShift = gameUtils.getMinTransVect(playerRect, ground) 
     player1.playerForces.append([0, collisionShift[1]]) 
     player1.onGround = True 
     player1.playerVel[1] = 0 

正如你可以從看,碰撞後,我還對Player物體的位置做了一個小的「修正」。這確保了每當Player「落地」在地面上時,它都不會「凹陷」。如果在一幀內物體在一個方向上移動的像素多於在兩個可碰撞物體之間移動的像素(如果在物體與地面之間存在4像素間隙,並且Player在一幀中向下移動8個像素,則會發生這種情況。在這種情況下,如果您在檢測到碰撞後停止移動Player,它會沉入地下)。

+0

非常感謝! – user2341500 2013-05-17 02:54:04