2013-02-05 11 views
6

私のコードでは、レベルをコントロールするためのゲーム状態を実装する最も簡単で簡単な方法は何でしょうか?タイトル画面から始めてレベルを読み込み、完了したら次のレベルに進んでいきたいですか?もし誰かがこれを扱う最も簡単な方法を説明できたらそれはすばらしいでしょう!ゲームレベル/メニュー状態

import pygame 
from pygame import * 

WIN_WIDTH = 1120 - 320 
WIN_HEIGHT = 960 - 320 
HALF_WIDTH = int(WIN_WIDTH/2) 
HALF_HEIGHT = int(WIN_HEIGHT/2) 

DISPLAY = (WIN_WIDTH, WIN_HEIGHT) 
DEPTH = 0 
FLAGS = 0 
CAMERA_SLACK = 30 

def main(): 
    global level 
    pygame.init() 
    screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) 
    pygame.display.set_caption("ABCDEFGHIJKLMNOPQRSTUVWXYZ") 
    timer = pygame.time.Clock() 
    level = 0 

    bg = Surface((32,32)) 
    bg.convert() 
    bg.fill(Color("#0094FF")) 

    up = left = right = False 
    entities = pygame.sprite.Group() 
    player = Player(32, 32) 
    enemy = Enemy(32,32) 
    platforms = [] 

    x = 0 
    y = 0 

    if level == 0: 
     level = [ 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           ", 
      "           E ", 
      "       PPPPPPPPPPPPPPPP", 
      "       PPPPPPPPPPPPPPPP", 
      "       PPPPPPPPPPPPPPPP", 
      "    PPPPP  PPPPPPPPPPPPPPPP", 
      "       PPPPPPPPPPPPPPPP", 
      "       PPPP   P", 
      "       PPPP   P", 
      "       PPPP  PPPPPPP", 
      "      PPPPPPPPPP  PPPPPPP", 
      "       PPPP  PPPPPPP", 
      "  PPPP     PPPP  PPPPPPP", 
      "       PPPP  PPPPPPP", 
      "       PPPP  PPPPPPP", 
      "       PPPP  PPPPPPP", 
      "PPPPP      PPPP  PPPPPPP", 
      "PPP       PPPP  PPPPPPP", 
      "PPP       PPPP  PPPPPPP", 
      "PPP       PPPP  PPPPPPP", 
      "PPP   PPPPP   PPPP  PPPPPPP", 
      "PPP          PPPP", 
      "PPP          PPPP", 
      "PPP          PPPP", 
      "PPP      PPPPPPPPPPPPPPPPPP", 
      "PPP      PPPPPPPPPPPPPPPPPP", 
      "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
      "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
      "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
      "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
      "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP",] 

     #background = pygame.image.load("Untitled.png") 


    total_level_width = len(level[0]) * 32 
    total_level_height = len(level) * 32 

    # 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 

    camera = Camera(complex_camera, total_level_width, total_level_height) 
    entities.add(player) 
    entities.add(enemy) 

    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_LEFT: 
       left = True 
      if e.type == KEYDOWN and e.key == K_RIGHT: 
       right = True 

      if e.type == KEYUP and e.key == K_UP: 
       up = False 
      if e.type == KEYUP and e.key == K_LEFT: 
       left = False 
      if e.type == KEYUP and e.key == K_RIGHT: 
       right = False 

     # draw background 
     for y in range(20): 
      for x in range(25): 
       screen.blit(bg, (x * 32, y * 32)) 

     # draw background 
     #screen.blit(background, camera.apply((0,0))) 
     #draw entities 
     for e in entities: 
      screen.blit(e.image, camera.apply(e)) 
     # update player, update camera, and refresh 
     player.update(up, left, right, platforms) 
     enemy.update(platforms) 
     camera.update(player) 
     pygame.display.flip() 

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): 
     try: 
      return target.rect.move(self.state.topleft) 
     except AttributeError: 
      return map(sum, zip(target, self.state.topleft)) 

    def update(self, target): 
     self.state = self.camera_func(self.state, target.rect) 

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(200, 1200, 32, 32) 


    def update(self, up, left, right, platforms): 
     if self.rect.top > 1440 or self.rect.top < 0: 
      main() 
     if self.rect.left > 1408 or self.rect.right < 0: 
      main() 
     if up: 
      if self.onGround: 
       self.yvel = 0 
       self.yvel -= 10 # only jump if on the ground 
     if left: 
      self.xvel = -10 
     if right: 
      self.xvel = 10 
     if not self.onGround: 
      self.yvel += 0.3 # only accelerate with gravity if in the air 
      if self.yvel > 80: self.yvel = 80 # 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 
       if yvel < 0: 
        self.rect.top = p.rect.bottom 


class Enemy(Entity): 
    def __init__(self, x, y): 
     Entity.__init__(self) 
     self.yVel = 0 
     self.xVel = 0 
     self.image = Surface((32,32)) 
     self.image.fill(Color("#00FF00")) 
     self.image.convert() 
     self.rect = Rect(300, 1200, 32, 32) 
     self.onGround = False 
     self.right_dis = False 

    def update(self, platforms): 
     if not self.onGround: 
      self.yVel += 0.3 

     if self.rect.left == 96: 
      self.right_dis = False 
     if self.rect.right == 480: 
      self.right_dis = True 
     if not self.right_dis: 
      self.xVel = 2 
     if self.right_dis: 
      self.xVel = -2 

     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 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 
       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], pygame.SRCALPHA, 32) #makes blocks invisible for much better artwork 
     self.image = Surface((32,32)) #makes blocks visible for building levels 
     self.image.convert() 
     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("end.png") 




if __name__ == "__main__": 
    main() 
+0

レベルをロードする機能があれば、タイトル画面でボタンをクリックすると 'load_map(" level1 ")'が実行されます。 level1はレベルwinのチェックを行い、そのマップの完成時に次のマップをロードします。 'load_map(" level2 ")'などとなります。 – ninMonkey

答えて

25

まず、ブロック場合のは、これらの醜いを取り除くみましょう:

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_LEFT: 
     left = True 
    if e.type == KEYDOWN and e.key == K_RIGHT: 
     right = True 

    if e.type == KEYUP and e.key == K_UP: 
     up = False 
    if e.type == KEYUP and e.key == K_LEFT: 
     left = False 
    if e.type == KEYUP and e.key == K_RIGHT: 
     right = False 

として私たちはそれらを書き換えることができます。これは、後に便利になるだろう

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" 

pressed = pygame.key.get_pressed() 
up, left, right = [pressed[key] for key in (K_UP, K_LEFT, K_RIGHT)] 


トピックに戻る:私たちが欲しいのは違うシーンの束です。各シーンは、画面とイベント処理の独自の描画を担当する必要があります。

ゲームシーンに既存のコードを抽出して、後で他のシーンを追加することができます。私たちは、シーンの基底クラスとなり、空Sceneクラスを作成することで起動します。

class Scene(object): 
    def __init__(self): 
     pass 

    def render(self, screen): 
     raise NotImplementedError 

    def update(self): 
     raise NotImplementedError 

    def handle_events(self, events): 
     raise NotImplementedError 

我々の計画は、各サブクラスの各メソッドを上書きすることで、私たちは私たち簡単に基底クラスでNotImplementedError秒を上げますそれを忘れるかどうかを発見してください(ABCを使うこともできますが、単純にしておきましょう)。

ここでは、ゲームの状態(基本的にはすべて)に関するすべてを新しいGameSceneクラスに入れてみましょう。

class GameScene(Scene): 
    def __init__(self): 
     super(GameScene, self).__init__() 
     level = 0 
     self.bg = Surface((32,32)) 
     self.bg.convert() 
     self.bg.fill(Color("#0094FF")) 
     up = left = right = False 
     self.entities = pygame.sprite.Group() 
     self.player = Player(32, 32) 
     self.enemy = Enemy(32,32) 
     self.platforms = [] 

     x = 0 
     y = 0 

     if level == 0: 
      level = [ 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           ", 
       "           E ", 
       "       PPPPPPPPPPPPPPPP", 
       "       PPPPPPPPPPPPPPPP", 
       "       PPPPPPPPPPPPPPPP", 
       "    PPPPP  PPPPPPPPPPPPPPPP", 
       "       PPPPPPPPPPPPPPPP", 
       "       PPPP   P", 
       "       PPPP   P", 
       "       PPPP  PPPPPPP", 
       "      PPPPPPPPPP  PPPPPPP", 
       "       PPPP  PPPPPPP", 
       "  PPPP     PPPP  PPPPPPP", 
       "       PPPP  PPPPPPP", 
       "       PPPP  PPPPPPP", 
       "       PPPP  PPPPPPP", 
       "PPPPP      PPPP  PPPPPPP", 
       "PPP       PPPP  PPPPPPP", 
       "PPP       PPPP  PPPPPPP", 
       "PPP       PPPP  PPPPPPP", 
       "PPP   PPPPP   PPPP  PPPPPPP", 
       "PPP          PPPP", 
       "PPP          PPPP", 
       "PPP          PPPP", 
       "PPP      PPPPPPPPPPPPPPPPPP", 
       "PPP      PPPPPPPPPPPPPPPPPP", 
       "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
       "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
       "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
       "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
       "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP",] 

      #background = pygame.image.load("Untitled.png") 


     total_level_width = len(level[0]) * 32 
     total_level_height = len(level) * 32 

     # build the level 
     for row in level: 
      for col in row: 
       if col == "P": 
        p = Platform(x, y) 
        self.platforms.append(p) 
        self.entities.add(p) 
       if col == "E": 
        e = ExitBlock(x, y) 
        self.platforms.append(e) 
        self.entities.add(e) 
       x += 32 
      y += 32 
      x = 0 

     self.camera = Camera(complex_camera, total_level_width, total_level_height) 
     self.entities.add(self.player) 
     self.entities.add(self.enemy) 

    def render(self, screen): 
     for y in range(20): 
      for x in range(25): 
       screen.blit(self.bg, (x * 32, y * 32)) 

     for e in self.entities: 
      screen.blit(e.image, self.camera.apply(e)) 

    def update(self): 
     pressed = pygame.key.get_pressed() 
     up, left, right = [pressed[key] for key in (K_UP, K_LEFT, K_RIGHT)] 
     self.player.update(up, left, right, self.platforms) 
     self.enemy.update(self.platforms) 
     self.camera.update(self.player) 

    def handle_events(self, events): 
     for e in events: 
      if e.type == KEYDOWN and e.key == K_ESCAPE: 
       pass #somehow go back to menu 

まだ完璧ではありませんが、良いスタートです。実際のゲームプレイに関連するものはすべて、それ自身のクラスに抽出されます。いくつかの変数はインスタンス変数でなければならないため、selfでアクセスする必要があります。これがあるから、私が最初に可能QUIT -eventを得るだけにpygame.event.get(QUIT)を使用します。私は2台のささいなことを変え

def main(): 
    pygame.init() 
    screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) 
    pygame.display.set_caption("ABCDEFGHIJKLMNOPQRSTUVWXYZ") 
    timer = pygame.time.Clock() 
    running = True 

    scene = GameScene() 

    while running: 
     timer.tick(60) 

     if pygame.event.get(QUIT): 
      running = False 
      return 
     scene.handle_events(pygame.event.get()) 
     scene.update() 
     scene.render(screen) 
     pygame.display.flip() 

注:

は、今、私たちは実際にこのクラスを使用するmain -functionを変更する必要があります私たちの主なループで私たちがinteressetている唯一のイベントです。他のすべてのイベントは現在のシーンに直接渡されます:scene.handle_events(pygame.event.get())

この時点で、いくつかのクラスを自分のファイルに抽出することについて考えることができましたが、その代わりに進んでいきます。

のは、タイトルメニューを作成してみましょう:

class TitleScene(object): 

    def __init__(self): 
     super(TitleScene, self).__init__() 
     self.font = pygame.font.SysFont('Arial', 56) 
     self.sfont = pygame.font.SysFont('Arial', 32) 

    def render(self, screen): 
     # beware: ugly! 
     screen.fill((0, 200, 0)) 
     text1 = self.font.render('Crazy Game', True, (255, 255, 255)) 
     text2 = self.sfont.render('> press space to start <', True, (255, 255, 255)) 
     screen.blit(text1, (200, 50)) 
     screen.blit(text2, (200, 350)) 

    def update(self): 
     pass 

    def handle_events(self, events): 
     for e in events: 
      if e.type == KEYDOWN and e.key == K_SPACE: 
       self.manager.go_to(GameScene(0)) 

これはちょうど緑の背景といくつかのテキストを表示します。プレイヤーがSPACEを押すと、最初のレベルを開始します。この行に注意してください。ここで

self.manager.go_to(GameScene(0)) 

私は0GameSceneクラスに引数を渡すので、このパラメータ受け入れるそれでは、それを変更してみましょう:

class GameScene(Scene): 
    def __init__(self, level): 
     ... 

ラインlevel = 0を除去することができるが、あなたがすでに推測として、 。

だからそれは何ですかself.manager?それは私たちのためにシーンを管理するちょっとしたヘルパークラスです。

class SceneMananger(object): 
    def __init__(self): 
     self.go_to(TitleScene()) 

    def go_to(self, scene): 
     self.scene = scene 
     self.scene.manager = self 

それはタイトルシーンから始まり、現在のシーンの変更を許可するように自分自身に各シーンにmanagerフィールドを設定します。このようなシーンマネージャをどのように実装するかは、多くの可能性があり、これが最も簡単なアプローチです。欠点は、各シーンがどのシーンが後に来るのかを知る必要がありますが、それは今私たちを悩ますべきではありません。

のは、私たちの新しいSceneManangerを使用してみましょう:

def main(): 
    pygame.init() 
    screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) 
    pygame.display.set_caption("ABCDEFGHIJKLMNOPQRSTUVWXYZ") 
    timer = pygame.time.Clock() 
    running = True 

    manager = SceneMananger() 

    while running: 
     timer.tick(60) 

     if pygame.event.get(QUIT): 
      running = False 
      return 
     manager.scene.handle_events(pygame.event.get()) 
     manager.scene.update() 
     manager.scene.render(screen) 
     pygame.display.flip() 

単純明快。すぐに2番目のレベルと勝敗の画面を追加しましょう。

class CustomScene(object): 

    def __init__(self, text): 
     self.text = text 
     super(CustomScene, self).__init__() 
     self.font = pygame.font.SysFont('Arial', 56) 

    def render(self, screen): 
     # ugly! 
     screen.fill((0, 200, 0)) 
     text1 = self.font.render(self.text, True, (255, 255, 255)) 
     screen.blit(text1, (200, 50)) 

    def update(self): 
     pass 

    def handle_events(self, events): 
     for e in events: 
      if e.type == KEYDOWN: 
       self.manager.go_to(TitleScene()) 

以下は完全なコードです。 Playerクラスへの変更に注意してください。main関数を再度呼び出すのではなく、シーン上のメソッドを呼び出して、プレーヤーが終了したか、死んだことを示します。

また、プレイヤーと敵の配置を変更しました。ここで、エンティティがレベルに表示される場所を指定します。例えば。 Player(5, 40)は、レベル5の列40にプレーヤーを作成します。ボーナスとして、適切な衝突検出の敵。

レベルの説明をlevelsという辞書に解凍したので、必要に応じてレベルを変更して追加するのは簡単です(後で、レベルごとに1つのファイルが必要なので、これは良いスタートです)。プレイヤーの開始位置を保持するように拡張することもできますが、開始位置に*、敵のレベル記述にEなどの特殊なタイルを作成することもできます。

import pygame 
from pygame import * 

WIN_WIDTH = 1120 - 320 
WIN_HEIGHT = 960 - 320 
HALF_WIDTH = int(WIN_WIDTH/2) 
HALF_HEIGHT = int(WIN_HEIGHT/2) 

DISPLAY = (WIN_WIDTH, WIN_HEIGHT) 
DEPTH = 0 
FLAGS = 0 
CAMERA_SLACK = 30 

levels = {0: {'level': [ 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           E ", 
        "       PPPPPPPPPPPPPPPP", 
        "       PPPPPPPPPPPPPPPP", 
        "       PPPPPPPPPPPPPPPP", 
        "    PPPPP  PPPPPPPPPPPPPPPP", 
        "       PPPPPPPPPPPPPPPP", 
        "       PPPP   P", 
        "       PPPP   P", 
        "       PPPP  PPPPPPP", 
        "      PPPPPPPPPP  PPPPPPP", 
        "       PPPP  PPPPPPP", 
        "  PPPP     PPPP  PPPPPPP", 
        "       PPPP  PPPPPPP", 
        "       PPPP  PPPPPPP", 
        "       PPPP  PPPPPPP", 
        "PPPPP      PPPP  PPPPPPP", 
        "PPP       PPPP  PPPPPPP", 
        "PPP       PPPP  PPPPPPP", 
        "PPP       PPPP  PPPPPPP", 
        "PPP   PPPPP   PPPP  PPPPPPP", 
        "PPP          PPPP", 
        "PPP          PPPP", 
        "PPP          PPPP", 
        "PPP      PPPPPPPPPPPPPPPPPP", 
        "PPP      PPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP",], 
      'enemies': [(9, 38)]}, 
      1: {'level': [ 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           ", 
        "           E ", 
        "       PPPPPPPPPPPPPPPP", 
        "       PPPPPPPPPPPPPPPP", 
        "       PPPPPPPPPPPPPPPP", 
        "    PPPPP  PPPPPPPPPPPPPPPP", 
        "       PPPPPPPPPPPPPPPP", 
        "       PPPP   P", 
        "       PPPP   P", 
        "       PPPP  PPPPPPP", 
        "      PPPPPPPPPP  PPPPPPP", 
        "       PPPP  PPPPPPP", 
        "  PPPP     PPPP  PPPPPPP", 
        "       PPPP  PPPPPPP", 
        "       PPPP  PPPPPPP", 
        "       PPPP  PPPPPPP", 
        "PPPPP      PPPP  PPPPPPP", 
        "PPP     PPPPPPPPPPP  PPPPPPP", 
        "PPP       PPPP  PPPPPPP", 
        "PPP       PPPP  PPPPPPP", 
        "PPP    PPPPPPPP PPPP  PPPPPPP", 
        "PPP          PPPP", 
        "PPP          PPPP", 
        "PPP   PPPPP      PPPP", 
        "PPP   P   PPPPPPPPPPPPPPPPPP", 
        "PPP   P PPPPPPPPPPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP", 
        "PPPPPPPPPPPPPPP   PPPPPPPPPPPPPPPPPP",], 
      'enemies': [(9, 38), (18, 38), (15, 15)]}} 

class Scene(object): 
    def __init__(self): 
     pass 

    def render(self, screen): 
     raise NotImplementedError 

    def update(self): 
     raise NotImplementedError 

    def handle_events(self, events): 
     raise NotImplementedError 

class GameScene(Scene): 
    def __init__(self, levelno): 
     super(GameScene, self).__init__() 
     self.bg = Surface((32,32)) 
     self.bg.convert() 
     self.bg.fill(Color("#0094FF")) 
     up = left = right = False 
     self.entities = pygame.sprite.Group() 
     self.player = Player(5, 40) 
     self.player.scene = self 
     self.platforms = [] 

     self.levelno = levelno 

     levelinfo = levels[levelno] 
     self.enemies = [Enemy(*pos) for pos in levelinfo['enemies']] 

     level = levelinfo['level'] 
     total_level_width = len(level[0]) * 32 
     total_level_height = len(level) * 32 

     # build the level 
     x = 0 
     y = 0 
     for row in level: 
      for col in row: 
       if col == "P": 
        p = Platform(x, y) 
        self.platforms.append(p) 
        self.entities.add(p) 
       if col == "E": 
        e = ExitBlock(x, y) 
        self.platforms.append(e) 
        self.entities.add(e) 
       x += 32 
      y += 32 
      x = 0 

     self.camera = Camera(complex_camera, total_level_width, total_level_height) 
     self.entities.add(self.player) 
     for e in self.enemies: 
      self.entities.add(e) 

    def render(self, screen): 
     for y in range(20): 
      for x in range(25): 
       screen.blit(self.bg, (x * 32, y * 32)) 

     for e in self.entities: 
      screen.blit(e.image, self.camera.apply(e)) 

    def update(self): 
     pressed = pygame.key.get_pressed() 
     up, left, right = [pressed[key] for key in (K_UP, K_LEFT, K_RIGHT)] 
     self.player.update(up, left, right, self.platforms) 

     for e in self.enemies: 
      e.update(self.platforms) 

     self.camera.update(self.player) 

    def exit(self): 
     if self.levelno+1 in levels: 
      self.manager.go_to(GameScene(self.levelno+1)) 
     else: 
      self.manager.go_to(CustomScene("You win!")) 

    def die(self): 
     self.manager.go_to(CustomScene("You lose!")) 

    def handle_events(self, events): 
     for e in events: 
      if e.type == KEYDOWN and e.key == K_ESCAPE: 
       self.manager.go_to(TitleScene()) 

class CustomScene(object): 

    def __init__(self, text): 
     self.text = text 
     super(CustomScene, self).__init__() 
     self.font = pygame.font.SysFont('Arial', 56) 

    def render(self, screen): 
     # ugly! 
     screen.fill((0, 200, 0)) 
     text1 = self.font.render(self.text, True, (255, 255, 255)) 
     screen.blit(text1, (200, 50)) 

    def update(self): 
     pass 

    def handle_events(self, events): 
     for e in events: 
      if e.type == KEYDOWN: 
       self.manager.go_to(TitleScene()) 

class TitleScene(object): 

    def __init__(self): 
     super(TitleScene, self).__init__() 
     self.font = pygame.font.SysFont('Arial', 56) 
     self.sfont = pygame.font.SysFont('Arial', 32) 

    def render(self, screen): 
     # ugly! 
     screen.fill((0, 200, 0)) 
     text1 = self.font.render('Crazy Game', True, (255, 255, 255)) 
     text2 = self.sfont.render('> press space to start <', True, (255, 255, 255)) 
     screen.blit(text1, (200, 50)) 
     screen.blit(text2, (200, 350)) 

    def update(self): 
     pass 

    def handle_events(self, events): 
     for e in events: 
      if e.type == KEYDOWN and e.key == K_SPACE: 
       self.manager.go_to(GameScene(0)) 

class SceneMananger(object): 
    def __init__(self): 
     self.go_to(TitleScene()) 

    def go_to(self, scene): 
     self.scene = scene 
     self.scene.manager = self 

def main(): 
    pygame.init() 
    screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) 
    pygame.display.set_caption("ABCDEFGHIJKLMNOPQRSTUVWXYZ") 
    timer = pygame.time.Clock() 
    running = True 

    manager = SceneMananger() 

    while running: 
     timer.tick(60) 

     if pygame.event.get(QUIT): 
      running = False 
      return 
     manager.scene.handle_events(pygame.event.get()) 
     manager.scene.update() 
     manager.scene.render(screen) 
     pygame.display.flip() 

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): 
     try: 
      return target.rect.move(self.state.topleft) 
     except AttributeError: 
      return map(sum, zip(target, self.state.topleft)) 

    def update(self, target): 
     self.state = self.camera_func(self.state, target.rect) 

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(x*32, y*32, 32, 32) 

    def update(self, up, left, right, platforms): 
     if self.rect.top > 1440 or self.rect.top < 0: 
      self.scene.die() 
     if self.rect.left > 1408 or self.rect.right < 0: 
      self.scene.die() 
     if up: 
      if self.onGround: 
       self.yvel = 0 
       self.yvel -= 10 # only jump if on the ground 
     if left: 
      self.xvel = -10 
     if right: 
      self.xvel = 10 
     if not self.onGround: 
      self.yvel += 0.3 # only accelerate with gravity if in the air 
      if self.yvel > 80: self.yvel = 80 # max falling speed 
     if not(left or right): 
      self.xvel = 0 

     self.rect.left += self.xvel # increment in x direction 
     if 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): 
        self.scene.exit() 
        return False 
       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 
       if yvel < 0: 
        self.rect.top = p.rect.bottom 
     return True 

class Enemy(Entity): 
    def __init__(self, x, y): 
     Entity.__init__(self) 
     self.yVel = 0 
     self.xVel = 2 # start moving immediately 
     self.image = Surface((32,32)) 
     self.image.fill(Color("#00FF00")) 
     self.image.convert() 
     self.rect = Rect(x*32, y*32, 32, 32) 
     self.onGround = False 

    def update(self, platforms): 
     if not self.onGround: 
      self.yVel += 0.3 

     # no need for right_dis to be a member of the class, 
     # since we know we are moving right if self.xVel > 0 
     right_dis = self.xVel > 0 

     # create a point at our left (or right) feet 
     # to check if we reached the end of the platform 
     m = (1, 1) if right_dis else (-1, 1) 
     p = self.rect.bottomright if right_dis else self.rect.bottomleft 
     fp = map(sum, zip(m, p)) 

     # if there's no platform in front of us, change the direction 
     collide = any(p for p in platforms if p.rect.collidepoint(fp)) 
     if not collide: 
      self.xVel *= -1 

     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 xVel > 0: 
        self.rect.right = p.rect.left 
        self.xVel *= -1 # hit wall, so change direction 
       if xVel < 0: 
        self.rect.left = p.rect.right 
        self.xVel *= -1 # hit wall, so change direction 
       if yVel > 0: 
        self.rect.bottom = p.rect.top 
        self.onGround = True 
       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], pygame.SRCALPHA, 32) #makes blocks invisible for much better artwork 
     self.image = Surface((32,32)) #makes blocks visible for building levels 
     self.image.convert() 
     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 = Surface((32,32)) #makes blocks visible for building levels 
     self.image.convert() 
     self.rect = Rect(x, y, 32, 32) 




if __name__ == "__main__": 
    main() 
+0

これは非常に深いことを説明してくれてありがとう!これは本当に非常に役に立ち、私に多くのことを教えてくれました。私はあなたが壁に衝突するために使用した衝突検出について1つの質問があります。エンティティとの衝突を確認することでプレーヤーとの衝突を簡単にチェックできます。衝突がプレーヤーの場合は何かしますか? – user1758231

+0

@ user1758231簡単な方法は、プレーヤーの 'rect'を使って[' Rect.collidelist'](http://www.pygame.org/docs/ref/rect.html#Rect.collidelist)を使うことです。 'self.player.rect.collidelist(self.enemies内のeに対して正しい)...'のようなものが敵の矩形と衝突するかどうかを調べるために、 – sloth

0

私は、ゲームメニュー、レベルメニュー、ローディングパート、およびプレイパートを持つゲームを作成しました。
私のやり方は、ゲームのメインループにありました
私は、ゲームの「モード」が何であるかを判断するために一連のelif文を調べ、適切な処置を行いました。
非常にうまくいくように思えましたが、同じことを試してみることをお勧めします。

私のコードは本当に長いと分かりますが、#game loop(どこにctrl + fキーを押してください)と表示されている場合は、elifを見てモードを判断できます。お役に立てれば。

#basic stuff 
import pygame, sys, random 
pygame.init() 
window=pygame.display.set_mode((1500, 800), pygame.FULLSCREEN) 
winrect=window.get_rect() 

#colors 
GREEN=(19, 225, 30) 
BLUE=(41, 2, 245) 
YELLOW=(251, 240, 32) 
WHITE=(255, 255, 255) 
BLACK=(0, 0, 0) 
RED=(255, 0, 0) 

#text 
bigfont=pygame.font.SysFont('calibri', 75) 
font=pygame.font.SysFont('calibri', 40) 
texts={} 

so=bigfont.render('Ball Bounce', True, BLUE) 
rect=so.get_rect() 
rect.top=winrect.top+100 
rect.centerx=winrect.centerx 
texts['title']=[so, rect] 

so=font.render('Start', True, BLUE) 
rect=so.get_rect() 
so1=pygame.Surface((400, 50)) 
so2=pygame.Surface((400, 50)) 
rect1=so1.get_rect() 
so1.fill(YELLOW) 
so2.fill(RED) 
pygame.draw.rect(so1, BLACK, rect1, 5) 
pygame.draw.rect(so2, BLACK, rect1, 5) 
rect.center=rect1.center 
so1.blit(so, rect) 
so2.blit(so, rect) 
rect1.centerx=winrect.centerx 
rect1.top=texts['title'][1].top+300 
texts['start']=[so1, rect1, so2] 

so=bigfont.render('Levels', True, BLUE) 
rect=so.get_rect() 
rect.centerx=winrect.centerx 
rect.top=winrect.top+100 
texts['levels']=[so, rect] 

#levels [locked, unlocked, completed/mouseover, rect, state(locked, unlocked, completed)] 
levels=[] 
lock=pygame.image.load('images/lock.png').convert() 
lock=pygame.transform.scale(lock, (100, 100)) 
lock.set_colorkey(lock.get_at((1, 1))) 
for i in range(1, 21): 
    so=pygame.Surface((100, 100)) 
    so.fill(YELLOW) 
    rect=so.get_rect() 
    pygame.draw.rect(so, BLACK, rect, 5) 
    so1=pygame.Surface((100, 100)) 
    so1.fill(RED) 
    pygame.draw.rect(so1, BLACK, rect, 5) 
    text=font.render(str(i), True, BLUE) 
    textrect=text.get_rect() 
    textrect.center=rect.center 
    so.blit(text, textrect) 
    so1.blit(text, textrect) 
    locked=pygame.Surface((100, 100)) 
    locked.blit(so, rect) 
    locked.blit(lock, lock.get_rect()) 
    if i<=5: 
     rect.top=texts['levels'][1].bottom+25 
    elif i<=10: 
     rect.top=levels[0][3].bottom+50 
    elif i<=15: 
     rect.top=levels[7][3].bottom+50 
    else: 
     rect.top=levels[12][3].bottom+50 
    if i==1 or i==6 or i==11 or i==16: 
     rect.right=winrect.centerx-200 
    elif i==2 or i==7 or i==12 or i==17: 
     rect.right=winrect.centerx-75 
    elif i==3 or i==8 or i==13 or i==18: 
     rect.centerx=winrect.centerx 
    elif i==4 or i==9 or i==14 or i==19: 
     rect.left=winrect.centerx+75 
    else: 
     rect.left=winrect.centerx+200 
    if i==1: 
     levels.append([locked, so, so1, rect, 1]) 
    else: 
     levels.append([locked, so, so1, rect, 1]) 

#Wall class (0=horizontal, 1=vertical) 
class cwall(pygame.Rect): 
    'orientation (hor, vert), location, holesize, winrect' 
    def __init__(self, orientation, location, holesize, winrect): 
     self.orientation=orientation 
     if orientation==0: 
      self.height=5 
      self.width=winrect.width 
      self.centery=location 
     if orientation==1: 
      self.width=5 
      self.height=winrect.height 
      self.centerx=location 
     self.holesize=holesize 
     self.bbottomright=round(pygame.mouse.get_pos()[self.orientation]+self.holesize/2) 
     self.ttopleft=round(pygame.mouse.get_pos()[self.orientation]-self.holesize/2) 
    def update(self): 
     self.bbottomright=round(pygame.mouse.get_pos()[self.orientation]+self.holesize/2) 
     self.ttopleft=round(pygame.mouse.get_pos()[self.orientation]-self.holesize/2) 
     if self.bbottomright<self.holesize: 
      self.bbottomright=self.holesize 
     if self.ttopleft>self.right-self.holesize and self.orientation==0: 
      self.ttopleft=self.right-self.holesize 
     if self.ttopleft>self.bottom-self.holesize and self.orientation==1: 
      self.ttopleft=self.bottom-self.holesize 

#Ball Class 
class cball(pygame.Rect): 
    'diameter, speed, color, winrect' 
    def __init__(self, diameter, speed, color, winrect): 
     self.width=diameter 
     self.height=diameter 
     self.speed=speed 
     self.color=color 
     self.direction=random.randint(1, 4) 
     self.center=(random.randint(round(diameter/2), round(winrect.right-diameter/2)), random.randint(round(diameter/2), round(winrect.bottom-diameter/2))) 
    def update(self, winrect, walls): 
     if self.direction/2==round(self.direction/2): 
      self.right+=self.speed 
     else: 
      self.right-=self.speed 
     if self.direction<=2: 
      self.top+=self.speed 
     else: 
      self.top-=self.speed 
     for wall in walls: 
      if wall.collidepoint(self.center): 
       if wall.orientation==0 and (self.centerx<wall.ttopleft or self.centerx>wall.bbottomright): 
        if self.direction==1: 
         self.direction=3 
         self.bottom=wall.top 
        elif self.direction==2: 
         self.direction=4 
         self.bottom=wall.top 
        elif self.direction==3: 
         self.direction=1 
         self.top=wall.bottom 
        else: 
         self.direction=2 
         self.top=wall.bottom 
       elif wall.orientation==1 and (self.centery<wall.ttopleft or self.centery>wall.bbottomright): 
        if self.direction==1: 
         self.direction=2 
         self.left=wall.right 
        elif self.direction==2: 
         self.direction=1 
         self.right=wall.left 
        elif self.direction==3: 
         self.direction=4 
         self.left=wall.right 
        else: 
         self.direction=3 
         self.right=wall.left 
      elif wall.orientation==0: 
       if self.bottom>wall.top and self.centery<wall.top and (self.centerx<wall.ttopleft or self.centerx>wall.bbottomright): 
        if self.direction==1: 
         self.direction=3 
         self.bottom=wall.top 
        elif self.direction==2: 
         self.direction=4 
         self.bottom=wall.top 
       elif self.top<wall.bottom and self.centery>wall.bottom and (self.centerx<wall.ttopleft or self.centerx>wall.bbottomright): 
        if self.direction==3: 
         self.direction=1 
         self.top=wall.bottom 
        if self.direction==4: 
         self.direction=2 
         self.top=wall.bottom 
      else: 
       if self.left<wall.right and self.centerx>wall.right and (self.centery<wall.ttopleft or self.centery>wall.bbottomright): 
        if self.direction==1: 
         self.direction=2 
         self.left=wall.right 
        elif self.direction==3: 
         self.direction=4 
         self.left=wall.right 
       elif self.right>wall.left and self.centerx<wall.left and (self.centery<wall.ttopleft or self.centery>wall.bbottomright): 
        if self.direction==2: 
         self.direction=1 
         self.right=wall.left 
        if self.direction==4: 
         self.direction=3 
         self.right=wall.left 
     if self.top<0: 
      if self.direction==3: 
       self.direction=1 
       self.top=0 
      elif self.direction==4: 
       self.direction=2 
       self.topn=0 
     if self.bottom>winrect.bottom: 
      if self.direction==1: 
       self.direction=3 
       self.bottom=winrect.bottom 
      elif self.direction==2: 
       self.direction=4 
       self.bottom=winrect.bottom 
     if self.left<0: 
      if self.direction==1: 
       self.direction=2 
       self.left=0 
      elif self.direction==3: 
       self.direction=4 
       self.left=0 
     if self.right>winrect.right: 
      if self.direction==2: 
       self.direction=1 
       self.right=winrect.right 
      if self.direction==4: 
       self.direction=3 
       self.right=winrect.right 
     for box in boxes: 
      if box[0].collidepoint(self.center) and self.color==box[1]: 
       return True 
     return False 

#Game loop setup 
mode='title' 

#Game loop 
while True: 
    if mode=='title': 
     #event loop 
     for event in pygame.event.get(): 
      if event.type==pygame.QUIT: 
       pygame.quit() 
       sys.exit() 
      if event.type==pygame.MOUSEBUTTONDOWN: 
       if texts['start'][1].collidepoint(event.pos): 
        mode='levels' 
      if event.type==pygame.KEYDOWN: 
       if event.key==pygame.K_ESCAPE: 
        pygame.quit() 
        sys.exit() 
     #screen update 
     window.fill(GREEN) 
     mouse=pygame.mouse.get_pos() 
     if texts['start'][1].collidepoint(mouse): 
      window.blit(texts['start'][2], texts['start'][1]) 
     else: 
      window.blit(texts['start'][0], texts['start'][1]) 
     window.blit(texts['title'][0], texts['title'][1]) 
     pygame.display.update() 

    elif mode=='levels': 
     #event loop 
     for event in pygame.event.get(): 
      if event.type==pygame.QUIT: 
       pygame.quit() 
       sys.exit() 
      if event.type==pygame.MOUSEBUTTONDOWN: 
       for level in levels: 
        if level[3].collidepoint(event.pos) and level[4]!=0: 
         mode='loading' 
         loadinglevel=levels.index(level)+1 
      if event.type==pygame.KEYDOWN: 
       if event.key==pygame.K_ESCAPE: 
        pygame.quit() 
        sys.exit() 
     #screen update 
     window.fill(GREEN) 
     for level in levels: 
      if level[3].collidepoint(pygame.mouse.get_pos()) and level[4]==1: 
       window.blit(level[2], level[3]) 
      else: 
       window.blit(level[level[4]], level[3]) 
     window.blit(texts['levels'][0], texts['levels'][1]) 
     pygame.display.update() 

    elif mode=='loading': 
     if loadinglevel==1: 
      walls=[cwall(1, winrect.width/2, 100, winrect)] 
      balls=[] 
      for i in range(2): 
       balls.append(cball(20, 3, GREEN, winrect)) 
      for i in range(2): 
       balls.append(cball(20, 3, YELLOW, winrect)) 
      boxes=((pygame.Rect(0, 0, round(winrect.width/2), winrect.height), GREEN), (pygame.Rect(round(winrect.width/2), 0, round(winrect.width/2), winrect.height), YELLOW)) 
     elif loadinglevel==2: 
      walls=[cwall(1, winrect.width/2, 100, winrect)] 
      balls=[] 
      for i in range(4): 
       balls.append(cball(20, 3, GREEN, winrect)) 
      for i in range(4): 
       balls.append(cball(20, 3, YELLOW, winrect)) 
      boxes=((pygame.Rect(0, 0, round(winrect.width/2), winrect.height), GREEN), (pygame.Rect(round(winrect.width/2), 0, round(winrect.width/2), winrect.height), YELLOW)) 
     elif loadinglevel==3: 
      walls=[cwall(1, winrect.width/3, 100, winrect), cwall(1, 2*winrect.width/3, 100, winrect)] 
      balls=[] 
      for i in range(2): 
       balls.append(cball(20, 3, GREEN, winrect)) 
      for i in range(2): 
       balls.append(cball(20, 3, YELLOW, winrect)) 
      for i in range(2): 
       balls.append(cball(20, 3, BLUE, winrect)) 
      boxes=((pygame.Rect(0, 0, round(winrect.width/3), winrect.height), GREEN), (pygame.Rect(round(winrect.width/3), 0, round(winrect.width/3), winrect.height), YELLOW), 
        (pygame.Rect(round(2*winrect.width/3), 0, round(winrect.width/3), winrect.height), BLUE)) 
     elif loadinglevel==4: 
      walls=[cwall(1, winrect.width/3, 100, winrect), cwall(1, 2*winrect.width/3, 100, winrect)] 
      balls=[] 
      for i in range(4): 
       balls.append(cball(20, 3, GREEN, winrect)) 
      for i in range(4): 
       balls.append(cball(20, 3, YELLOW, winrect)) 
      for i in range(4): 
       balls.append(cball(20, 3, BLUE, winrect)) 
      boxes=((pygame.Rect(0, 0, round(winrect.width/3), winrect.height), GREEN), (pygame.Rect(round(winrect.width/3), 0, round(winrect.width/3), winrect.height), YELLOW), 
        (pygame.Rect(round(2*winrect.width/3), 0, round(winrect.width/3), winrect.height), BLUE)) 

     elif loadinglevel==7: 
      walls=[cwall(1, winrect.width/2, 100, winrect), cwall(0, winrect.height/2, 100, winrect)] 
      balls=[] 
      for i in range(2): 
       balls.append(cball(20, 3, GREEN, winrect)) 
      for i in range(2): 
       balls.append(cball(20, 3, YELLOW, winrect)) 
      for i in range(2): 
       balls.append(cball(20, 3, BLUE, winrect)) 
      for i in range(2): 
       balls.append(cball(20, 3, RED, winrect)) 
      boxes=((pygame.Rect(0, 0, round(winrect.width/2), round(winrect.height/2)), GREEN), 
        (pygame.Rect(0, round(winrect.height/2), round(winrect.width/2), round(winrect.height/2)), RED), 
        (pygame.Rect(round(winrect.width/2), 0, round(winrect.width/2), round(winrect.height/2)), YELLOW), 
        (pygame.Rect(round(winrect.width/2), round(winrect.height/2), round(winrect.width/2), round(winrect.height/2)), BLUE)) 
     elif loadinglevel==8: 
      walls=[cwall(1, winrect.width/2, 100, winrect), cwall(0, winrect.height/2, 100, winrect)] 
      balls=[] 
      for i in range(4): 
       balls.append(cball(20, 3, GREEN, winrect)) 
      for i in range(4): 
       balls.append(cball(20, 3, YELLOW, winrect)) 
      for i in range(4): 
       balls.append(cball(20, 3, BLUE, winrect)) 
      for i in range(4): 
       balls.append(cball(20, 3, RED, winrect)) 
      boxes=((pygame.Rect(0, 0, round(winrect.width/2), round(winrect.height/2)), GREEN), 
        (pygame.Rect(0, round(winrect.height/2), round(winrect.width/2), round(winrect.height/2)), RED), 
        (pygame.Rect(round(winrect.width/2), 0, round(winrect.width/2), round(winrect.height/2)), YELLOW), 
        (pygame.Rect(round(winrect.width/2), round(winrect.height/2), round(winrect.width/2), round(winrect.height/2)), BLUE)) 
     elif loadinglevel==5: 
      walls=[cwall(1, winrect.width/2, 100, winrect), cwall(0, winrect.height/2, 100, winrect)] 
      balls=[] 
      for i in range(10): 
       balls.append(cball(20, 3, RED, winrect)) 
      boxes=((pygame.Rect(0, 0, round(winrect.width/2), round(winrect.height/2)), RED), 
        (pygame.Rect(0, round(winrect.height/2), winrect.width, round(winrect.height/2)), WHITE), 
        (pygame.Rect(round(winrect.width/2), 0, round(winrect.width/2), winrect.height), WHITE)) 
     elif loadinglevel==6: 
      walls=[cwall(1, winrect.width/2, 100, winrect), cwall(0, winrect.height/2, 100, winrect)] 
      balls=[] 
      for i in range(20): 
       balls.append(cball(20, 3, RED, winrect)) 
      boxes=((pygame.Rect(0, 0, round(winrect.width/2), round(winrect.height/2)), RED), 
        (pygame.Rect(0, round(winrect.height/2), winrect.width, round(winrect.height/2)), WHITE), 
        (pygame.Rect(round(winrect.width/2), 0, round(winrect.width/2), winrect.height), WHITE)) 
     mode='playing' 
    elif mode=='playing': 
     while True: 
      #event loop 
      for event in pygame.event.get(): 
       if event.type==pygame.QUIT: 
        pygame.quit() 
        sys.exit() 
       if event.type==pygame.KEYDOWN: 
        if event.key==pygame.K_ESCAPE: 
         pygame.quit() 
         sys.exit() 
      #updates 
      updates=[] 
      for wall in walls: 
       wall.update() 
      for ball in balls: 
       updates.append(ball.update(winrect, walls)) 
      #Seeing if won 
      won=True 
      for update in updates: 
       if not update: 
        won=False 
        break 
      if won: 
       if levels[loadinglevel][4]==0: 
        levels[loadinglevel][4]=1 
       levels[loadinglevel-1][4]=2 
       mode='levels' 
       break 
      #blitting 
      window.fill(WHITE) 
      for box in boxes: 
       pygame.draw.rect(window, box[1], box[0]) 
      for wall in walls: 
       if wall.orientation==0: 
        pygame.draw.rect(window, BLACK, (wall.left, wall.top, wall.ttopleft, wall.height)) 
        pygame.draw.rect(window, BLACK, (wall.bbottomright, wall.top, wall.right-wall.bbottomright, wall.height)) 
       else: 
        pygame.draw.rect(window, BLACK, (wall.left, wall.top, wall.width, wall.ttopleft)) 
        pygame.draw.rect(window, BLACK, (wall.left, wall.bbottomright, wall.width, wall.bottom-wall.holesize)) 
      for ball in balls: 
       pygame.draw.circle(window, ball.color, ball.center, round(ball.width/2)) 
       pygame.draw.circle(window, BLACK, ball.center, round(ball.width/2), 2) 
      pygame.display.update() 
      pygame.time.Clock().tick(100) 
+0

読みやすさを向上させるためにレベルロードを別々の関数に組み込むことをお勧めします –

+0

@BartlomiejLewandowskiそれはおそらく助けになりますが、この質問に答えることを知らずにコードを作成しました。 – PygameNerd

+0

これは将来のためのちょっとしたアドバイスです:) –