Pygame LEVEL变化
我需要改变一个级别,但我无法得到它的工作。我正在尝试像this那样做。Pygame LEVEL变化
当我尝试开始时,我根本没有水平。我的代码:
#! /usr/bin/python
import pygame
from pygame import *
#import pyganim
#=========Display======#
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
#=========Game main==#
def main():
global cameraX, cameraY
pygame.init()
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
timer = pygame.time.Clock()
currentLevel = 0
up = down = left = right = running = False
bg = Surface((32,32))
#bg = pygame.image.load('BG\BGL1.png').convert()
bg.fill(Color("#000000"))
entities = pygame.sprite.Group()
player = Player(32, 55)
levels = [[
"",
"",
"",
"",
"",
"SSSSSSSSSSSSSSSS",
"PPPPPPPPPSSSSSSS ",
" ",
"
],
[
"",
"",
"",
"",
"PPPPPPPPPPPP",
"PPPPPPPPPPPP"
]]
# Level Generating code
def load_level(level):
platforms = []
x = y = 0
for row in levels:
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 == "G":
g = Platform1(x, y)
platforms.append(g)
entities.add(g)
if col == "A":
a = Stone(x, y)
platforms.append(a)
entities.add(a)
if col == "S":
s = Stone0(x, y)
platforms.append(s)
entities.add(s)
if col == "H":
h = HalfPlaform0(x, y)
platforms.append(h)
entities.add(h)
if col == "B":
b = StoneBack(x, y)
entities.add(b)
if col == "T":
t = Bridge(x,y)
x += 32
y += 32
x = 0
return platforms, entities
platforms, entities = load_level(currentLevel)
load_level(currentLevel)
total_levels_width = len(levels[0])*32
total_levels_height = len(levels)*32
camera = Camera(complex_camera, total_levels_width, total_levels_height)
entities.add(player)
while 1:
load_level(currentLevel)
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:
running = True
if e.type == KEYUP and e.key == K_l:
currentLevel += 1
load_level(currentLevel)
print(level)
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_RIGHT:
right = False
if e.type == KEYUP and e.key == K_LEFT:
left = False
for y in range(32):
for x in range(32):
screen.blit(bg, (x * 32, y * 32))
##Update player, draw everything else##
###THE PROBLEM IS HERE I THINK###
for e in entities:
screen.blit(e.image, camera.apply(e))
'''
BegimoAnim.anchor(anchorPoint = 'east')
BegimoAnim.blit(screen, (player))
'''
camera.update(player)
pygame.display.update()
player.update(up, down, left, right, running, platforms)
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 at the left edge##
#l = max(-(camera.width-WIN_WIDTH), l) ## stop scrolling at the right edge##
t = max(-(camera.height-WIN_HEIGHT), t) ## stop scrolling at the bottom##
t = min(0, t) ## stop scrolling at the top##
return Rect(l, t, w, h)
#============PLAYER===============#
right_standing = pygame.image.load('PlayerModels\Sprites\PlayerStill2.gif')
left_standing = pygame.transform.flip(right_standing, True, False)
animTypes = 'right_walk'.split()
'''
BegimoAnim = pyganim.PygAnimation([
('PlayerModels\Sprites\Player_right_walk1.gif', 0.2,),
('PlayerModels\Sprites\Player_right_walk2.gif', 0.2,),
])
'''
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 = right_standing
self.rect = self.image.get_rect()
def update(self, up, down, left, right, running, platforms):
a = 0
#BegimoAnim.blit(screen, (player))
if up:
# Pasokti tik ant zemes
if self.onGround: self.yvel -= 7
if down:
pass
if running:
self.xvel = 12
if left:
self.xvel = -5
self.image = left_standing
if right:
self.xvel = 5
self.image = right_standing
#BegimoAnim.play()
if not self.onGround:
# gravitacija + acceleracija
self.yvel += 0.3
# Max kritimo greitis
if self.yvel > 100: self.yvel = 100
if not(left or right):
self.xvel = 0
# Prieaugis X direkcijoje
self.rect.left += self.xvel
# daryti X axis collision
self.collide(self.xvel, 0, platforms)
# Prieaugis Y direkcijoje
self.rect.top += self.yvel
# Ar ore?
self.onGround = False;
# daryti Y axis collision
self.collide(0, self.yvel, platforms)
def collide(self, xvel, yvel, platforms):
level = 0
for p in platforms:
if pygame.sprite.collide_rect(self, p):
if isinstance(p, ExitBlock):
currentLevel += 1
walls, players, finishes = load_level(currentLevel)
print(level)
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
#=========Platforms, ground
class Platform(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface = pygame.image.load("GroundModels\Ground0.png").convert()
self.rect = Rect(x, y, 32, 32)
def update(self):
pass
class Platform1(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface = pygame.image.load("GroundModels\Ground.png").convert()
self.rect = Rect(x, y, 32, 32)
def update(self):
pass
#================stone
class Stone(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface = pygame.image.load("GroundModels\Stone.png").convert()
self.rect = Rect(x, y, 32, 32)
def update(self):
pass
class Stone0(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface = pygame.image.load("GroundModels\Stone0.png").convert()
self.rect = Rect(x, y, 32, 32)
def update(self):
pass
class StoneBack(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface = pygame.image.load("GroundModels\Stone.png").convert()
self.rect = Rect(x, y, 32, 32)
class Bridge(Entity):
def __init__(self, x, y):
Entity.__init__(self)
def update(self):
pass
#=================pusblokis zeme
class HalfPlaform0(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface = pygame.image.load("GroundModels\HalfGround0.png").convert()
self.rect = Rect(x, y + 16, 32, 16)
def update(self):
pass
class ExitBlock(Platform):
def __init__(self, x, y):
Platform.__init__(self, x, y)
self.image.fill(Color("#0033FF"))
if __name__ == "__main__":
main()
你load_level
功能需要一个level
参数,但它绝不会使用它的任何地方。
相反,它的作用:现在
def load_level(level):
# ...
for row in levels:
for col in row:
,levels
是水平,这是行,这是列的字符串列表清单。
但是你在做for row in levels
,这意味着你命名每个级别row
,然后for col in row
名每一行的水平内一列,一整排的永远不会是== "E"
或任何其他的你检查的东西。所以你找回一个空的平台列表和一个空实体列表。
什么你可能想要的是:
def load_level(level):
# ...
for row in levels[level]:
后你解决这个问题:我不认为你想离开精灵组entities
满1级的精灵,然后添加2级的精灵,然后是3级,依此类推,而不会将其清除。
但是,这正是你在做什么。在main
中,您将entities
分配给一个空组。然后,在load_level
的内部,您只需从外部函数entities
调用add
。然后你返回相同的entities
,其main
分配给entities
,它已经是。
我想你想在load_level
里创建一个新的entities
sprite组,就像你创建一个新的platforms
列表一样。 (如果不是,你绝对不希望修改外部变量的误导性代码然后返回它的值,只是为了将它重新分配给相同的变量...做一个或另一个,而不是两个。)
嗯谢谢我也发现,但我现在当我的负载水平两个级别都加载,然后我得到一些滞后。任何修复? – Justasmig
@Justasmig:你确定两个级别都加载了吗?你肯定会第一次加载3次,这是很大的浪费。另外,正如我所提到的,每次加载一个关卡时,都会将其精灵添加到现有的精灵上,而不是替换现有的精灵。我敢打赌,还有其他一些缺陷,但是有太多的代码试图找到它们,然后猜测你首先看到哪一个。如果您有新问题,请创建一个新问题,然后尝试为该问题编写一个[最小,完整,可验证的示例](http://stackoverflow.com/help/mcve),而不是倾倒所有内容。 – abarnert
我应该如何修复第一级加载3次?我现在想发布一个关于优化的问题,但我认为这是因为我的代码这样做......而且我认为我应该尽量写最小化和完整。 – Justasmig
请只发布信息相关的代码。 – PascalVKooten