本文介绍了pygame更改级别-由列表制成的级别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,我是pygame的新手。我使用了以下示例:
该示例显示了如何应对碰撞,从列表和移动中创建关卡。一个很好的初学者例子。
我已经对其进行了修改,因此它应该能够更改级别。我尝试删除绘制后的矩形,但我不知道。
我有一个问题,我无法更改代码中的级别:

Hello i am new in pygame. And i have used this example: http://pygame.org/project/1061/The example shows how to chack for collision, make a level from a list and movement. A great beginner example.I have modified it so it should be able to change level. I have tried deleting the rects once drawn but i can't figure that out.I have the problem that i can't change the level in my code:

import os
import random
import pygame

# Class for the orange dude
    class Player(object):

    def __init__(self, pos):
        players.append(self)
        self.rect = pygame.Rect(pos[0], pos[1], 16, 16)

    def move(self, dx, dy):

        # Move each axis separately. Note that this checks for collisions both times.
        if dx != 0:
            self.move_single_axis(dx, 0)
        if dy != 0:
            self.move_single_axis(0, dy)

    def move_single_axis(self, dx, dy):

    # Move the rect
        self.rect.x += dx
        self.rect.y += dy

    # If you collide with a wall, move out based on velocity
        for wall in walls:
            if self.rect.colliderect(wall.rect):
                if dx > 0: # Moving right; Hit the left side of the wall
                    self.rect.right = wall.rect.left
                if dx < 0: # Moving left; Hit the right side of the wall
                    self.rect.left = wall.rect.right
                if dy > 0: # Moving down; Hit the top side of the wall
                    self.rect.bottom = wall.rect.top
                if dy < 0: # Moving up; Hit the bottom side of the wall
                    self.rect.top = wall.rect.bottom

# Nice class to hold a wall rect
class Wall(object):

    def __init__(self, pos):
        walls.append(self)
        self.rect = pygame.Rect(pos[0], pos[1], 16, 16)

class Finish(object):

    def __init__(self, pos):
        finishes.append(self)
        self.rect = pygame.Rect(pos[0], pos[1], 16, 16)

# Variables
currentLevel = 1

# Initialise pygame
pygame.init()

# Set up the display
pygame.display.set_caption("Change level")
screen = pygame.display.set_mode((320, 240))

clock = pygame.time.Clock()
walls = [] # List to hold the walls
players = []
finishes = []

# Holds the level layout in a list of strings.
if currentLevel == 1:

    level = [
    "WWWWWWWWWWWWWWWWWWWW",
    "W                  W",
    "W  P      WWWWWW   W",
    "W   WWWW       W   W",
    "W   W        WWWW  W",
    "W WWW  WWWW        W",
    "W   W     W W      W",
    "W   W     W   WWW WW",
    "W   WWW WWW   W W  W",
    "W     W   W   W W  W",
    "WWW   W   WWWWW W  W",
    "W W      WW        W",
    "W W   WWWW   WWW   W",
    "W     W   F    W   W",
    "WWWWWWWWWWWWWWWWWWWW",
    ]
    # Parse the level string above
    x = y = 0
    for row in level:
        for col in row:
            if col == "W":
                Wall((x, y))
            if col == "P":
                Player((x, y))
            if col == "F":
                Finish((x, y))
            x += 16
        y += 16
        x = 0
if currentLevel == 2:

    level = [
    "WWWWWWWWWWWWWWWWWWWW",
    "W                  W",
    "W                  W",
    "W   WWWWWWWWWWWWW  W",
    "W                  W",
    "W         P        W",
    "W                  W",
    "W   WWWWWWWWWWWWW  W",
    "W                  W",
    "W   WWWWWWWWWWWWW  W",
    "W                  W",
    "W         F        W",
    "W                  W",
    "W                  W",
    "WWWWWWWWWWWWWWWWWWWW",
    ]

    # Parse the level string above
    x = y = 0
    for row in level:
        for col in row:
            if col == "W":
                Wall((x, y))
            if col == "P":
                Player((x, y))
            if col == "F":
                Finish((x, y))
            x += 16
        y += 16
        x = 0

running = True
while running:

    clock.tick(60)

    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False
        if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
            running = False

    # Move the player if an arrow key is pressed
    key = pygame.key.get_pressed()
    if key[pygame.K_LEFT]:
        player.move(-2, 0)
    if key[pygame.K_RIGHT]:
        player.move(2, 0)
    if key[pygame.K_UP]:
        player.move(0, -2)
    if key[pygame.K_DOWN]:
        player.move(0, 2)

    # Just added this to make it slightly fun ;)
    for player in players:
        for finish in finishes:
            if player.rect.colliderect(finish.rect):
                currentLevel = 2 # Doesn't work

    # Draw the scene
    screen.fill((0, 0, 0))
    for wall in walls:
        pygame.draw.rect(screen, (255, 255, 255), wall.rect)
    for player in players:
        pygame.draw.rect(screen, (255, 200, 0), player.rect)
    for finish in finishes:
        pygame.draw.rect(screen, (0, 200, 0), finish.rect)
    pygame.display.flip()


推荐答案

您只需更改 currentLevel 变量,但您实际上从未更改过 walls players 完成列表(此时仅执行 while 循环内的代码)。

You just change the currentLevel variable, but you never actually change the walls, players and finishes lists (only the code inside the while loop is executed at this time).

解决此问题的一种非常简单的方法是将加载关卡的代码放入函数中,并在玩家到达关卡末尾时调用它,例如:

A very simple way to solve this issue is to put the code that "loads" the level into a function and call it when the player reaches the end of the level, e.g.:

import os
import random
import pygame

# Class for the orange dude
class Player(object):

    def __init__(self, pos):
        self.rect = pygame.Rect(pos[0], pos[1], 16, 16)

    def move(self, dx, dy):

        # Move each axis separately. Note that this checks for collisions both times.
        if dx != 0:
            self.move_single_axis(dx, 0)
        if dy != 0:
            self.move_single_axis(0, dy)

    def move_single_axis(self, dx, dy):

    # Move the rect
        self.rect.x += dx
        self.rect.y += dy

    # If you collide with a wall, move out based on velocity
        for wall in walls:
            if self.rect.colliderect(wall.rect):
                if dx > 0: # Moving right; Hit the left side of the wall
                    self.rect.right = wall.rect.left
                if dx < 0: # Moving left; Hit the right side of the wall
                    self.rect.left = wall.rect.right
                if dy > 0: # Moving down; Hit the top side of the wall
                    self.rect.bottom = wall.rect.top
                if dy < 0: # Moving up; Hit the bottom side of the wall
                    self.rect.top = wall.rect.bottom

# Nice class to hold a wall rect
class Wall(object):

    def __init__(self, pos):
        self.rect = pygame.Rect(pos[0], pos[1], 16, 16)

class Finish(object):

    def __init__(self, pos):
        self.rect = pygame.Rect(pos[0], pos[1], 16, 16)

# Variables
currentLevel = 0

# Initialise pygame
pygame.init()

# Set up the display
pygame.display.set_caption("Change level")
screen = pygame.display.set_mode((320, 240))

clock = pygame.time.Clock()

levels = [[
    "WWWWWWWWWWWWWWWWWWWW",
    "W                  W",
    "W  P      WWWWWW   W",
    "W   WWWW       W   W",
    "W   W        WWWW  W",
    "W WWW  WWWW        W",
    "W   W     W W      W",
    "W   W     W   WWW WW",
    "W   WWW WWW   W W  W",
    "W     W   W   W W  W",
    "WWW   W   WWWWW W  W",
    "W W      WW        W",
    "W W   WWWW   WWW   W",
    "W     W   F    W   W",
    "WWWWWWWWWWWWWWWWWWWW",
    ],
    [
    "WWWWWWWWWWWWWWWWWWWW",
    "W                  W",
    "W                  W",
    "W   WWWWWWWWWWWWW  W",
    "W                  W",
    "W         P        W",
    "W                  W",
    "W   WWWWWWWWWWWWW  W",
    "W                  W",
    "W   WWWWWWWWWWWWW  W",
    "W                  W",
    "W         F        W",
    "W                  W",
    "W                  W",
    "WWWWWWWWWWWWWWWWWWWW",
    ]]

def load_level(level):
    walls = []
    players = []
    finishes = []

    # Parse the level string above
    x = y = 0
    for row in levels[level]:
        for col in row:
            if col == "W":
                walls.append(Wall((x, y)))
            if col == "P":
                players.append(Player((x, y)))
            if col == "F":
                finishes.append(Finish((x, y)))
            x += 16
        y += 16
        x = 0
    return walls, players, finishes

walls, players, finishes = load_level(currentLevel)
running = True
while running:

    clock.tick(60)

    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False
        if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
            running = False

    # Move the player if an arrow key is pressed
    key = pygame.key.get_pressed()
    if key[pygame.K_LEFT]:
        player.move(-2, 0)
    if key[pygame.K_RIGHT]:
        player.move(2, 0)
    if key[pygame.K_UP]:
        player.move(0, -2)
    if key[pygame.K_DOWN]:
        player.move(0, 2)

    # Just added this to make it slightly fun ;)
    for player in players:
        for finish in finishes:
            if player.rect.colliderect(finish.rect):
                currentLevel += 1
                walls, players, finishes = load_level(currentLevel)

    # Draw the scene
    screen.fill((0, 0, 0))
    for wall in walls:
        pygame.draw.rect(screen, (255, 255, 255), wall.rect)
    for player in players:
        pygame.draw.rect(screen, (255, 200, 0), player.rect)
    for finish in finishes:
        pygame.draw.rect(screen, (0, 200, 0), finish.rect)
    pygame.display.flip()

这篇关于pygame更改级别-由列表制成的级别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 02:42