2013-10-03 2 views
1

Я делаю платформу 8-битного стиля. Игрок падает и получает скорость из-за псевдо-гравитации, но он упадет на несколько пикселей на уровень земли. Без силы тяжести он приземлится на землю и не упадет, хотя это постоянная скорость падения. Когда в земле вы можете подняться, но он упадет, когда вы опуститесь. Он не спустится, так что пока это не проблема. Любая помощь будет оценена по достоинству.Python-Pygame sprite отскакивает при использовании силы тяжести

Категория игрока/файл.

import pygame,sys 
from pygame.locals import * 
class Player: 
    x=0 
    y=0 
    offset = 5 
    L=False 
    R=False 
    U=False 
    D=False 
    image = None 
    gravity = .25 
    velocity = offset 
    objectDict = None #this si the list of the current objects so that collision can be check with every 
    #object.. get updated every loop to keep a accurate check of locations 
    rect = None 
    grav = True #TODO use this to check if we are paying attention to the gravity 
    def __init__(self,x,y): 
     self.x = x 
     self.y = y 
     self.image = pygame.image.load('Resources/Pics/player.png') 



    def draw(self,DISPLAY): 
     #print('draw will go here') 
     imgRect = self.image.get_rect() 
     imgRect.midleft = (self.x,self.y) 
     self.rect = imgRect 
     DISPLAY.blit(self.image, imgRect) 
     #and now im here 

    def checkCollide(self,otherRect): 
     return self.rect.colliderect(otherRect) 

    def checkCollideAll(self): 
     if(self.objectDict != None): 
      # print(len(self.objectDict)) 
     #  for x in range(1,len(self.objectDict)): 
     #   newb = self.checkCollide(self.objectDict[x].getRect()) 
     #   print(self.objectDict[x].getRect()) 
     #  if(newb): 
     #   return True 
     # return False 
      collideNum = self.rect.collidelist(self.objectDict) 
      if(collideNum == -1): 
       return False 
      else: 
       return True 

    def willCollideBelow(self): 
     if(self.objectDict): 
      checkRect = (self.x,(self.y),self.image.get_size()) 
      collideNum = self.rect.collidelist(self.objectDict) 
      if collideNum == -1: 
       return False 
      else: 
       return True 


    def objUpdate(self,dict): 
     self.objectDict = dict 

    def getRect(self): 
     return self.rect 

    def update(self): 
     # while(self.checkCollideAll()): 
     #  print('while happened') 
     #  self.y -= self.offset 
     #  imgRect = self.image.get_rect() 
     #  imgRect.midleft = (self.x,self.y) 
     #  self.rect = imgRect 
     # print(self.willCollideBelow()) 
     if not self.willCollideBelow(): 
      self.D = True 
      # print('will fall') 
     else: 
      self.D = False 

     if self.U == True: 
      self.y -= self.offset 

     if self.D == True: 
       self.y += self.velocity 
       if not self.velocity >= 9.8: 
        self.velocity += self.gravity 
     else: 
      self.velocity = self.offset 
     if self.L == True: 
       self.x -= self.offset 

     if self.R == True: 
       self.x += self.offset 
+0

Вы хотите сказать, что ваш персонаж падает так, что он пересекает землю? Если это так, то это потому, что в один момент времени он падает на большее расстояние, чем он был выше земли, и это не похоже, что у вас есть код для разрешения этого перекрестка. – kevintodisco

ответ

2

Вы не предоставили бегущий пример и ваш код трудно читать (паскаль случая, много ненужной скобки), но вот мое предположение:

В вашей willCollideBelow функции, проверить, если вы попали объект под игрока:

def willCollideBelow(self): 
     if(self.objectDict): 
      checkRect = (self.x,(self.y),self.image.get_size()) 
      collideNum = self.rect.collidelist(self.objectDict) 
      if collideNum == -1: 
       return False 
      else: 
       return True 

вместо того, чтобы просто возвращение True или False, вернуть объект (или индекс объекта) вы на самом деле сталкиваются с:

def will_collide_below(self): 
     if(self.objectDict): 
      # using 'collidelistall' would be better, but that's another topic 
      return self.rect.collidelist(self.objectDict) 

Теперь, когда вы знаете, какой именно объект игрок сталкивается с, вы можете настроить вертикальное положение игрока:

ground_i = self.will_collide_below() 
if ground_i: 
    ground = self.objectDict[ground_i] 
    self.velocity = 0 
    self.rect.bottom = ground.top # or self.y = ground.top 

Вы получаете идею.


еще несколько заметок:

Вы можете использовать различные переменные для сохранения позиции игрока (я вижу x, y, rect и imgRect). Это сделало бы вы код намного проще, если бы вы просто использовать один Rect для хранения позиции:

class Player: 
    ... 
    def __init__(self,x,y): 
     self.image = pygame.image.load('Resources/Pics/player.png') 
     self.rect = self.image.get_rect(midleft=(x,y)) 

    def draw(self, display): 
     display.blit(self.image, self.rect) 

    def update(self): 
     ... 
     if self.L: # no need to check == True 
      self.rect.move_ip(-self.offset) 

     if self.R: # simply use move_ip to alter the position 
      self.rect.move_ip(self.offset) 

Вы также использовать кучу переменных класса, где вы действительно должны использовать переменные экземпляра, как rect, L, R , U и D.

+0

Спасибо, что имеет смысл. Кроме того, camelcase и скобки связаны с тем, что у нас есть опыт работы в VB и Java, которые полностью разрушают все логическое форматирование, когда дело доходит до перехода на Python. – ddaniels

Смежные вопросы