gpt4 book ai didi

python - Pygame 碰撞检测

转载 作者:太空宇宙 更新时间:2023-11-03 19:07:04 25 4
gpt4 key购买 nike

我的问题:

在我的游戏中,我想添加一些功能,例如双跳、墙跳等。
然而,我的碰撞检测遇到了问题,而且我似乎无法解决它。
问题是,当我的角色与地面碰撞时,它会记录碰撞。
然而,即使我在地面上,下一个刻度也不再记录碰撞。
这会在检测我是否与墙壁碰撞或者当前是否与地面碰撞等方面产生问题。
这会产生更多问题,因为当它没有检测到碰撞时,我的 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()

最佳答案

看起来只要不按住空格,更新代码就会将你设置为在空中:

def update(self, up, down, left, right, platforms, space):
if space:
else:
self.onGround = False; # assuming we're in the air
self.collide(0, self.yvel, platforms) # do y-axis collisions

如果角色没有移动单个像素来重叠平台,而是恰好在平台上,那么 pygame 的碰撞代码也许不会检测到碰撞?在这种情况下,你会经历一个着陆循环,将 yvel 设置为 0。好吧,我们正在下降,0.3,下降,0.6,下降,0.9,下降...好吧,我们移动了 1 个像素,然后重叠,我们着陆了,将 yvel 设置为 0。然后从头开始重复。

关于python - Pygame 碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14449651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com