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() 
+1

请只发布信息相关的代码。 – PascalVKooten

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列表一样。 (如果不是,你绝对不希望修改外部变量的误导性代码然后返回它的值,只是为了将它重新分配给相同的变量...做一个或另一个,而不是两个。)

+0

嗯谢谢我也发现,但我现在当我的负载水平两个级别都加载,然后我得到一些滞后。任何修复? – Justasmig

+0

@Justasmig:你确定两个级别都加载了吗?你肯定会第一次加载3次,这是很大的浪费。另外,正如我所提到的,每次加载一个关卡时,都会将其精灵添加到现有的精灵上,而不是替换现有的精灵。我敢打赌,还有其他一些缺陷,但是有太多的代码试图找到它们,然后猜测你首先看到哪一个。如果您有新问题,请创建一个新问题,然后尝试为该问题编写一个[最小,完整,可验证的示例](http://*.com/help/mcve),而不是倾倒所有内容。 – abarnert

+0

我应该如何修复第一级加载3次?我现在想发布一个关于优化的问题,但我认为这是因为我的代码这样做......而且我认为我应该尽量写最小化和完整。 – Justasmig