好的,所以我的代码已启动并运行,现在当玩家在用户按住右或左时与墙壁发生碰撞时,玩家将慢慢滑下墙壁,如果玩家释放方向(左或右),则玩家继续正常下降。
我想做的事情是,当玩家撞到墙上时,他会“粘”在墙上,这意味着他仍然会向下滑动并将向下滑动直到他撞到地面(用户不必保持方向)或用户可以跳墙。(对于那些玩过或看过游戏或超人的人来说,想想超级肉男孩)。任何人都可以提出一个解决这个问题的好方法吗?
import pygame, time
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
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("#000000"))
entities = pygame.sprite.Group()
player = Player(32, 32)
platforms = []
space_num = 0
x = y = 0
level = [
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P E P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P P",
"P PPPPPP P",
"P P",
"P P",
"PPPPP P",
"P P",
"P PPPPPPP P",
"P P",
"P PPPPPP P",
"P P",
"P PPPPPPPPPPP P",
"P P",
"P PPPPPPPPPPP P",
"P P",
"P P",
"P P",
"P P",
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",]
# 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)
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.onWall = 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 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
self.rect.top += self.yvel # increment in y direction
self.onGround = False; # assuming we're in the air
self.onWall = False
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
self.onWall = True
if xvel < 0:
self.rect.left = p.rect.right
self.onWall = True
if yvel > 0:
self.rect.bottom = p.rect.top
self.onGround = True
self.onWall = False
self.yvel = 0
if yvel < 0: self.rect.top = p.rect.bottom
if self.onWall:
self.yvel = 3
class Platform(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface((32, 32))
self.image.convert()
self.image.fill(Color("#F0FFFF"))
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.fill(Color("#00ff00"))
if __name__ == "__main__":
main()