我正在尝试找到一种在学校的平台游戏中实现完美碰撞的方法。大部分都可以,但是有一个小问题。当我站在高于地面的平台上并向左或向右移动时,玩家会继续漂浮在半空中,与我所离开平台的高度相同。可以通过跳跃解决此问题,并且碰撞恢复正常。我正在使用状态系统,通过拥有可能的玩家状态的文件夹并在它们之间进行切换来跟踪玩家是否站立。默认情况下,此设置为“掉落”,因为当游戏运行时,玩家从空中开始。游戏代码在下面分为三个独立的文件(main.py,obj.py和settings.py)。请告诉我如何解决此故障。
Main.py
import pygame
import random
from settings import *
from obj import *
pygame.init()
pygame.mixer.init()
pygame.font.init()
pygame.display.set_caption(TITLE)
screen = pygame.display.set_mode([WIDTH,HEIGHT])
clock = pygame.time.Clock()
me = Player()
all_sprites.add(me)
platforms = []
pf = Wall(20,40,500,480, 0)
pf2 = Wall(WIDTH,40, 400,500, 0)
platforms.append(pf)
platforms.append(pf2)
for i in platforms:
wall_sprites.add(i)
running = True
while running:
clock.tick(FPS)
all_sprites.update()
wall_sprites.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill(GREY)
all_sprites.draw(screen)
wall_sprites.draw(screen)
pygame.display.update()
pygame.quit()
obj.py
import pygame
import math
from settings import *
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((40,40))
self.image.fill(BLACK)
self.rect = self.image.get_rect()
self.rect.x = WIDTH / 2
self.rect.y = 70
self.vx = 0
self.vy = 0
self.SW = False # Can you screen wrap?
self.player_states = ["Standing","Falling"]
self.state = self.player_states[1]
def update(self):
self.vx = 0 # X speed set to 0 if no input is received
if self.state == self.player_states[1]:
self.vy += GRAVITY # Gravity only added while falling
else:
self.vy = 0
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.vx = -SPEED
if keys[pygame.K_RIGHT]:
self.vx = SPEED
if keys[pygame.K_SPACE] and self.state == self.player_states[0]:
self.vy -= JUMP_SPEED
self.state = self.player_states[1]
self.rect.left += self.vx # X and Y positions are updated
self.collide(self.vx, 0, wall_sprites) # Collision is checked. Second param is 0 b/c we aren't checking for vertical collision here
self.rect.top += self.vy
self.collide(0, self.vy, wall_sprites)
if self.SW:
if self.rect.left > WIDTH:
self.rect.right = 0
if self.rect.right < 0:
self.rect.left = WIDTH
if self.rect.top > HEIGHT:
self.rect.bottom = 0
if self.rect.bottom < 0:
self.rect.top = HEIGHT
def collide(self, xDif, yDif, platform_list):
for i in platform_list: # Shuffle through list of platforms
if pygame.sprite.collide_rect(self, i): # If there is a collision between the player and a platform...
if xDif > 0: # And our x (horizontal) speed is greater than 0...
self.rect.right = i.rect.left # That means that we are moving right,
if xDif < 0: # So our right bounding box becomes equal to the left bounding box of all platforms and we don't collide
self.rect.left = i.rect.right
if yDif > 0:
self.rect.bottom = i.rect.top
self.state = self.player_states[0]
if yDif < 0:
self.rect.top = i.rect.bottom
class Wall(pygame.sprite.Sprite): # Collision is added for platforms just in case that they are moving. If they move to you, they push you
def __init__(self, width, height, xpos, ypos, speed):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((width,height))
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.rect.centerx = xpos
self.rect.centery = ypos
self.speed = speed
def update(self):
self.rect.left += self.speed
self.collide(self.speed, all_sprites) # Collision only for platforms moving left and right. Not up and down yet
def collide(self, xDif, player_list):
for i in player_list:
if pygame.sprite.collide_rect(self, i):
if xDif > 0: # If the platform is moving right... (has positive speed)
i.rect.left += self.speed # Platform pushes player
self.rect.right = i.rect.left # Player sticks to the wall and is pushed
if xDif < 0:
i.rect.right -= self.speed
self.rect.left = i.rect.right
settings.py
import pygame
FPS = 60
WIDTH = 800
HEIGHT = 600
TITLE = "Perfect collision"
GREY = (150,150,150)
BLACK = (0,0,0)
BLUE = (0,0,255)
SPEED = 5
JUMP_SPEED = 9
GRAVITY = 0.3
all_sprites = pygame.sprite.Group()
wall_sprites = pygame.sprite.Group()
答案 0 :(得分:0)
只需在每帧中将printf("This is pthread %lld\n",(long long) self_id);
添加到main
并在精灵接触地面时将GRAVITY
设置为0:
self.vy