我的问题:
在我的游戏中,我想添加一些功能,如二段跳、墙跳等。
但是我的碰撞检测遇到了问题,我似乎无法解决它。
问题是当我的角色与地面发生碰撞时,它会发生碰撞。
然而,即使我在地上,它也不再记录碰撞。
这会在检测我是否与墙壁碰撞或我当前是否与地面碰撞等方面产生问题。
这会产生更多问题,因为当它未检测到碰撞时,我的 y 速度将不断降低。
所以,我的玩家有一个恒定的 y 速度,它在增加,而不是在地面上时它只是 0。
例子:
正如您在左手角看到的那样,我的 y 速度在这样的数字中跳跃:
0
0
0.3
0.6
0.9
然后重新开始。
我真正需要的是,当我在地面上时,它始终为 0,并且代码能够识别我在地面上。
但事实并非如此,我不知道为什么,有人可以帮忙吗?
代码:
import pygame
from pygame import *
WIN_WIDTH = 800
WIN_HEIGHT = 640
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)
DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
CAMERA_SLACK = 30
def main():
pygame.init()
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
#pygame.display.set_caption("Use arrows to move!")
timer = pygame.time.Clock()
up = down = left = right = space = False
bg = Surface((32,32))
bg.convert()
bg.fill(Color("#0094FF"))
entities = pygame.sprite.Group()
player = Player(32, 32)
platforms = []
plants = []
space_num = 0
x = 0
y = 0
level = [
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP PPPPPPP",
"P PPPP",
"P PPPP",
"P PPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",]
# build the level
for row in level:
for col in row:
if col == "P":
p = Platform(x, y)
platforms.append(p)
entities.add(p)
if col == "E":
e = ExitBlock(x, y)
platforms.append(e)
entities.add(e)
if col == "p":
p = Plant(x, y)
plants.append(p)
entities.add(p)
x += 32
y += 32
x = 0
total_level_width = len(level[0]) * 32
total_level_height = len(level) * 32
camera = Camera(complex_camera, total_level_width, total_level_height)
entities.add(player)
while 1:
timer.tick(60)
for e in pygame.event.get():
if e.type == QUIT: raise SystemExit, "QUIT"
if e.type == KEYDOWN and e.key == K_ESCAPE:
raise SystemExit, "ESCAPE"
if e.type == KEYDOWN and e.key == K_UP:
up = True
if e.type == KEYDOWN and e.key == K_DOWN:
down = True
if e.type == KEYDOWN and e.key == K_LEFT:
left = True
if e.type == KEYDOWN and e.key == K_RIGHT:
right = True
if e.type == KEYDOWN and e.key == K_SPACE:
if space_num < 6:
space = True
space_num += 1
if e.type == KEYUP and e.key == K_UP:
up = False
if e.type == KEYUP and e.key == K_DOWN:
down = False
if e.type == KEYUP and e.key == K_LEFT:
left = False
if e.type == KEYUP and e.key == K_RIGHT:
right = False
if e.type == KEYUP and e.key == K_SPACE:
space = False
# draw background
for y in range(20):
for x in range(25):
screen.blit(bg, (x * 32, y * 32))
camera.update(player)
# update player, draw everything else
player.update(up, down, left, right, platforms, space)
for e in entities:
screen.blit(e.image, camera.apply(e))
pygame.display.update()
class Camera(object):
def __init__(self, camera_func, width, height):
self.camera_func = camera_func
self.state = Rect(0, 0, width, height)
def apply(self, target):
return target.rect.move(self.state.topleft)
def update(self, target):
self.state = self.camera_func(self.state, target.rect)
#def simple_camera(camera, target_rect):
# l, t, _, _ = target_rect
# _, _, w, h = camera
# return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h)
def complex_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
l, t, _, _ = -l + HALF_WIDTH, -t+HALF_HEIGHT, w, h
l = min(0, l) # stop scrolling left
l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling right
t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling bottom
return Rect(l, t, w, h)
class Entity(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class Player(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.xvel = 0
self.yvel = 0
self.onGround = False
self.image = Surface((32,32))
self.image.fill(Color("#0000FF"))
self.image.convert()
self.rect = Rect(400, 400, 32, 32)
def update(self, up, down, left, right, platforms, space):
if space:
if not self.onGround:
self.yvel = -12
if self.onGround:
self.yvel = 0
else:
if up:
if self.onGround: self.yvel -= 10 # only jump if on the ground
if down:
pass
if left:
self.xvel = -8
if right:
self.xvel = 8
if not self.onGround:
self.yvel += 0.3 # only accelerate with gravity if in the air
if self.yvel > 40: self.yvel = 40 # max falling speed
if not(left or right):
self.xvel = 0
self.rect.left += self.xvel # increment in x direction
self.collide(self.xvel, 0, platforms) # do x-axis collisions
self.rect.top += self.yvel # increment in y direction
self.onGround = False; # assuming we're in the air
self.collide(0, self.yvel, platforms) # do y-axis collisions
def collide(self, xvel, yvel, platforms):
for p in platforms:
if pygame.sprite.collide_rect(self, p):
if isinstance(p, ExitBlock):
pygame.event.post(pygame.event.Event(QUIT))
if xvel > 0: self.rect.right = p.rect.left
if xvel < 0: self.rect.left = p.rect.right
if yvel > 0:
self.rect.bottom = p.rect.top
self.onGround = True
self.yvel = 0
if yvel < 0: self.rect.top = p.rect.bottom
class Platform(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface((32, 32))
self.image.convert()
self.image.fill(Color("#DDDDDD"))
self.rect = Rect(x, y, 32, 32)
def update(self):
pass
class ExitBlock(Platform):
def __init__(self, x, y):
Platform.__init__(self, x, y)
self.image = pygame.image.load("bush.png")
class Decoration(Entity):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class Plant(Decoration):
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface((64, 64))
self.image.convert()
#self.image = pygame.image.load("bush.png")
self.rect = Rect(x, y, 64, 64)
if __name__ == "__main__":
main()