PYGAME:碰撞无法正常工作。玩家和平台表现不佳。救命,这里是python新手
这是我在stackoverflow中的第一个问题。我3个月前开始学习python,我正在用精灵构建一个平台游戏。我必须隔离问题,所以我只发布问题所在的部分 每当正方形降落在任何平台上时,都会检测到碰撞,但正方形实际上向下穿过平台约10像素(在碰撞期间),然后又向上移动,并在平台顶部稳定下来 如果将FPS调整为2,可以更好地看到效果。 我怎样才能解决这个问题?我记得以前做过一个游戏,但是没有在“x”轴(摩擦力)和“y”轴(重力)上使用加速度,只是快速停止方块运动(左/右/上/下)检测碰撞,方块从未穿过平台 这是一个孤立的问题:PYGAME:碰撞无法正常工作。玩家和平台表现不佳。救命,这里是python新手,python,oop,pygame,sprite,game-physics,Python,Oop,Pygame,Sprite,Game Physics,这是我在stackoverflow中的第一个问题。我3个月前开始学习python,我正在用精灵构建一个平台游戏。我必须隔离问题,所以我只发布问题所在的部分 每当正方形降落在任何平台上时,都会检测到碰撞,但正方形实际上向下穿过平台约10像素(在碰撞期间),然后又向上移动,并在平台顶部稳定下来 如果将FPS调整为2,可以更好地看到效果。 我怎样才能解决这个问题?我记得以前做过一个游戏,但是没有在“x”轴(摩擦力)和“y”轴(重力)上使用加速度,只是快速停止方块运动(左/右/上/下)检测碰撞,方块从未
import pygame as pg
import random
WIDTH = 900
HEIGHT = 600
NAME = "square"
FPS = 60
green = (0, 150, 0)
white = (255, 255, 255)
black = (0, 0, 0)
class Platform(pg.sprite.Sprite):
def __init__(self, x, y, width, height, color):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((width, height))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Player(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((40, 40))
self.image.fill(black)
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
self.posx = WIDTH / 2
self.posy = HEIGHT * 0.10
self.velx = 0
self.vely = 0
self.accx = 0
self.accy = 0
self.jumping = False
self.jump_go = False
def jump(self):
if self.jumping == False:
self.jumping = True
self.vely = -25
def update(self):
self.accx = 0 #FRICTION
self.accy = 1 #GRAVITY
keys = pg.key.get_pressed()
if keys[pg.K_RIGHT]:
self.accx = 1
if keys[pg.K_LEFT]:
self.accx = -1
if self.vely != 0:
self.jump_go = False
#MOVEMENT IN X:
self.accx = self.accx + (self.velx * (-0.10))
self.velx = self.velx + self.accx
self.posx = self.posx + self.velx
self.rect.x = self.posx
if abs(self.velx) < 0.5:
self.velx = 0
#MOVEMENT IN Y:
self.accy = self.accy + (self.vely * (-0.05))
self.vely = self.vely + self.accy
self.posy = self.posy + self.vely
self.rect.y = self.posy
#IF PLAYER FALLS TO EDGE OF SCREEN:
if self.posy > HEIGHT:
self.posy = 0
if self.posx < 0:
self.posx = WIDTH
if self.posx > WIDTH:
self.posx = 0
class Game:
def __init__(self):
pg.init()
pg.mixer.init()
pg.font.init()
self.screen = pg.display.set_mode((WIDTH, HEIGHT))
self.clock = pg.time.Clock()
self.running = True
def new(self):
self.all_sprites = pg.sprite.Group()
self.all_platforms = pg.sprite.Group()
for i in range(3):
self.platform = Platform(random.randint(0, WIDTH), random.randint(HEIGHT * .15,
HEIGHT - 25), random.randint(100, 300), 50, green)
self.all_platforms.add(self.platform)
self.all_sprites.add(self.platform)
self.player = Player()
self.all_sprites.add(self.player)
self.run()
def run(self):
self.playing = True
while self.playing:
self.clock.tick(FPS)
self.eventos()
self.update()
self.draw()
def eventos(self):
for event in pg.event.get():
if event.type == pg.QUIT:
if self.playing:
self.playing = False
self.running = False
if event.type == pg.KEYDOWN:
if self.player.jump_go:
if event.key == pg.K_a:
self.player.jump()
def update(self):
self.all_sprites.update()
# Check if player hit platfom:
if self.player.vely > 0:
hits = pg.sprite.spritecollide(self.player, self.all_platforms, False)
if hits:
for hit in hits:
if self.player.rect.top < hit.rect.top:
self.player.posy = hit.rect.top - self.player.rect.height
self.player.vely = 0
self.player.jumping = False
self.player.jump_go = True
def draw(self):
self.screen.fill(white)
self.all_sprites.draw(self.screen)
pg.display.flip()
g = Game()
while g.running:
g.new()
pg.quit()
将pygame导入为pg
随机输入
宽度=900
高度=600
NAME=“square”
FPS=60
绿色=(0,150,0)
白色=(255,255,255)
黑色=(0,0,0)
课堂讲台(第三页:雪碧、雪碧):
定义初始值(自、x、y、宽度、高度、颜色):
精灵精灵。精灵。精灵初始(自我)
self.image=pg.Surface((宽度、高度))
self.image.fill(颜色)
self.rect=self.image.get_rect()
self.rect.x=x
自校正y=y
职业玩家(第三页精灵):
定义初始化(自):
精灵精灵。精灵。精灵初始(自我)
self.image=pg.Surface((40,40))
self.image.fill(黑色)
self.rect=self.image.get_rect()
self.rect.center=(宽度/2,高度/2)
self.posx=宽度/2
self.posy=高度*0.10
self.velx=0
self.vely=0
self.accx=0
self.accy=0
自我跳跃=错误
self.jump\u go=False
def跳转(自):
如果self.jumping==False:
self.jumping=True
self.vely=-25
def更新(自我):
self.accx=0#摩擦力
self.accy=1#重力
keys=pg.key.get_pressed()
如果键[pg.K_RIGHT]:
self.accx=1
如果键[pg.K_左]:
self.accx=-1
如果自作主张!=0:
self.jump\u go=False
#X中的运动:
self.accx=self.accx+(self.velx*(-0.10))
self.velx=self.velx+self.accx
self.posx=self.posx+self.velx
self.rect.x=self.posx
如果abs(自粘性)小于0.5:
self.velx=0
#Y方向的运动:
self.accy=self.accy+(self.vely*(-0.05))
self.vely=self.vely+self.accy
self.posy=self.posy+self.voly
self.rect.y=self.posy
#如果玩家跌落到屏幕边缘:
如果self.posy>高度:
self.posy=0
如果self.posx<0:
self.posx=宽度
如果self.posx>宽度:
self.posx=0
班级游戏:
定义初始化(自):
第init页()
pg.mixer.init()
pg.font.init()
self.screen=pg.display.set_模式((宽度、高度))
self.clock=pg.time.clock()
self.running=True
def新(自我):
self.all_sprite=pg.sprite.Group()
self.all_platforms=pg.sprite.Group()
对于范围(3)中的i:
self.platform=平台(random.randint(0,宽度),random.randint(高度*.15,
高度-25),随机。随机数(100300),50,绿色)
self.all_platforms.add(self.platform)
self.all_sprites.add(self.platform)
self.player=player()
self.all_精灵添加(self.player)
self.run()
def运行(自):
自弹=真
自娱自乐时:
自我时钟滴答声(FPS)
self.eventos()
self.update()
self.draw()
def事件(自):
对于pg.event.get()中的事件:
如果event.type==pg.QUIT:
如果自己玩:
自我表现=错误
self.running=False
如果event.type==pg.KEYDOWN:
如果self.player.jump_go:
如果event.key==pg.K_a:
self.player.jump()
def更新(自我):
self.all_sprites.update()
#检查玩家是否击中平台:
如果self.player.vely>0:
hits=pg.sprite.spritecollide(self.player,self.all_platforms,False)
如果点击:
点击率:
如果self.player.rect.top
在碰撞检查中,您会得到所有的命中次数
,然后检查每个命中次数
if self.player.rect.top < hit.rect.top:
导致您看到的所描述的“通过和跳起”效果
您可以通过更改
if self.player.rect.top < hit.rect.top:
减少“通过”效应。我认为您应该将碰撞检测移动到
Player.update()
和Player.jump()
函数
这背后的原因是碰撞检测的复杂性。每次update()
您的播放器都会在二维空间中移动一定数量的像素。但是让我们只考虑一个维度,让它更简单……
假设你的播放器向右移动了5个像素(+x
),而障碍物距离你3个像素远。显然,它将与2个像素的重叠发生碰撞。那么在这种情况下会发生什么呢?这取决于你的游戏逻辑,但在大多数情况下,玩家应该停止一个只有+3像素,休息的障碍物旁边。这是一个知道运动方向和尺寸的简单计算
if self.player.rect.top < hit.rect.top:
if (self.player.rect.top - self.player.rect.height) < hit.rect.top:
self.bottom_quart = self.rect.y + (self.rect.height/2)
def update(self):
self.all_sprites.update()
#Check if player hit platfom:
if self.player.vely > 0:
hits = pg.sprite.spritecollide(self.player, self.all_platforms, False)
if hits:
for hit in hits:
if self.player.rect.bottom > hit.rect.top > self.player.rect.top
and self.player.bottom_quart < hit.rect.top:
self.player.rect.bottom = hit.rect.top
self.player.posy = hit.rect.top - self.player.rect.height
self.player.vely = 0
self.player.jumping = False
self.player.jump_go = True
self.player.rect.bottom = hit.rect.top
self.player.posy = hit.rect.top - self.player.rect.height
self.bottom_quart = self.rect.y + (self.rect.height/2)