推箱子游戏不会推动新的水平 - Python - Pygame

问题描述 投票:-3回答:1

我正在用Python设计一个推箱子克隆(Pygame)

当向右移动1个板条箱3个位置,击中黑色空间,并将您移动到下一个级别时,游戏工作正常。但在第二级,当试图移动1个箱子UP 1位置时,箱子反而移动到位置3向下和1向左。

我在这里想念的是什么? :(

下面的代码,或完整的代码与媒体下载https://www.dropbox.com/s/7whgt1duvlpwleb/Sokoban%204.9.zip?dl=0

------------- Main Class --------------------

#import classes
#from maze3 import Maze
from amaze import Maze
from crate import Crate
from Sobokan import Sobokan
"""from maze2 import Maze
from maze3 import Maze
from maze4 import Maze
from maze5 import Maze"""
#add pygame imports
import random, sys, copy, os, pygame
from pygame.locals import *
maze = Maze()
#maze2 = maze.leveltwo()
sob = Sobokan("^", 5, 1)
crate = Crate("@", 0, 0)

FPS = 30                    # frames per second to update the screen
WINWIDTH = 800              # width of the program's window, in pixels
WINHEIGHT = 800           # height in pixels
HALF_WINWIDTH = int(WINWIDTH / 2) #you need to know 1/2 sizes so you can
HALF_WINHEIGHT = int(WINHEIGHT / 2) #place things centrally
# The total width and height of each tile in pixels.
TILEWIDTH = 64
TILEHEIGHT = 64
TILEFLOORHEIGHT = 64
BRIGHTBLUE = (  0, 170, 255)
WHITE      = (255, 255, 255)
BGCOLOR = BRIGHTBLUE
#A dictionary of the images used.  You can then use#floor, wall etc
#in place of the whole pathname
IMAGESDICT = {'floor': pygame.image.load("Images/flooring.png"),
              'wall': pygame.image.load("Images/wall.png"),
              'box': pygame.image.load("Images/hoost.png"),
              'sob': pygame.image.load("Images/Sapp.gif"),
              'spacer': pygame.image.load("Images/spacer.jpg") }
TILEMAPPING = { '#':IMAGESDICT['wall'],
                ' ':IMAGESDICT['floor'],
                '@':IMAGESDICT['box'],
                '/':IMAGESDICT['spacer'],
                '^':IMAGESDICT['sob']}
pygame.init()
FPSCLOCK = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WINWIDTH, WINHEIGHT))
pygame.display.set_caption('Sobokan v 1.00')
BASICFONT = pygame.font.Font('freesansbold.ttf', 18)
score = 0
def moveSobLeft():
    x = maze.getCharAtPos(sob.getRow(), sob.getCol() - 1)
    y = maze.getCharAtPos(sob.getRow(), sob.getCol() - 2)
    r = maze.getCharAtPos(sob.getRow(), sob.getCol() - 1)

    print "x/y init works"
    if x == "#":
        print "You have hit a wall, you cannot move!"
    elif x == " ":
        print "This is a space!"
        sob.moveLeft()
        maze.placeSob(sob.getChar(), sob.getRow(), sob.getCol())
        maze.clearAtPos(sob.getRow(), sob.getCol()+1)
    elif (x == "@" and y == " "):
        print "You have collided with a sprout, the sprout will move away now"
        crate.pushboxleft()
        print "crate pushed right"
        #this is pretty much the only thing that changes the blit of the crate.
        maze.placecrate("@",crate.getRow()+1, crate.getcol()-2)
        print "crate placed"
        maze.clearAtPos(crate.getRow(), crate.getcol()+1)
        print "old crate cleared"
        sob.moveLeft()
        print "Player moved right"
        maze.placeSob(sob.getChar(), sob.getRow(), sob.getCol())
        print "Player placed"
        maze.clearAtPos(sob.getRow(), sob.getCol()+1)
        print "old player cleared"
    elif (x == "@" and y == "#"):
        print "You have hit a sprout, but the sprout is trapped!"
    else:
            pass

    print maze.GetBoxes()



def moveSobRight():
    global score
    x = maze.getCharAtPos(sob.getRow(), sob.getCol() + 1)
    y = maze.getCharAtPos(sob.getRow(), sob.getCol() + 2)
    r = maze.getCharAtPos(sob.getRow(), sob.getCol() + 1)

    print "x/y init works"
    if x == "#":
        print "You have hit a wall, you cannot move!"
    elif x == " ":
        print "This is a space!"
        sob.moveRight()
        maze.placeSob(sob.getChar(), sob.getRow(), sob.getCol())
        maze.clearAtPos(sob.getRow(), sob.getCol()-1)
    elif (x == "@" and y == " "):
        print "You have collided with a sprout, the sprout will move away now"
        crate.pushboxright()
        print "crate pushed right"
        #this is pretty much the only thing that changes the blit of the crate.
        maze.placecrate("@",crate.getRow()+1, crate.getcol()+2)
        print "crate placed"
        maze.clearAtPos(crate.getRow(), crate.getcol()-1)
        print "old crate cleared"
        sob.moveRight()
        print "Player moved right"
        maze.placeSob(sob.getChar(), sob.getRow(), sob.getCol())
        print "Player placed"
        maze.clearAtPos(sob.getRow(), sob.getCol()-1)
        print "old player cleared"
    elif (x == "@" and y == "#"):
        print "You have hit a sprout, but the sprout is trapped!"
    elif (x == "@" and y == "/"):
        print "You have pushed a crate on to a diamond, free point to you!"
        crate.pushboxright()
        print "crate pushed right"
        #this is pretty much the only thing that changes the blit of the crate.
        maze.placecrate("@",crate.getRow()+1, crate.getcol()+2)
        print "crate placed"
        maze.clearAtPos(crate.getRow(), crate.getcol()-1)
        print "old crate cleared"
        sob.moveRight()
        print "Player moved right"
        maze.placeSob(sob.getChar(), sob.getRow(), sob.getCol())
        print "Player placed"
        maze.clearAtPos(sob.getRow(), sob.getCol()-1)
        print "old player cleared"
        score = score + 1
        print "Score: " +str(score)




    else:
            pass



def moveSobUp():
    print "Key up"
    c1 = crate.getRow()
    c2 = crate.getcol()

    z = sob.getCol()
    w = sob.getRow()
    x = maze.getCharAtPos(sob.getRow()-1, sob.getCol())
    y = maze.getCharAtPos(sob.getRow()-2, sob.getCol())
    print "x/y init works"
    if x == "#":
        print "You have hit a wall, you cannot move!"
    elif x == " ":
        print "This is a space!"
        sob.moveUp()
        maze.placeSob("^", w-1, z)
        print "player should be placed"
        maze.clearAtPos(w, z)
        print "player should be cleared"
    elif (x == "@" and y == " "):
        print "You have collided with a sprout, the sprout will move away now"
        #move crate
        crate.pushboxup()
        maze.clearAtPos(c1,c2)
        maze.placecrate("@",c1 - 1,c2)
        #move sob
        sob.moveUp()
        maze.clearAtPos(sob.getRow(),sob.getCol())
        maze.placeSob(sob.getChar,sob.getRow() - 1,sob.getCol())


def moveSobDown():

    #moving sob down
    #Check he can move
    x = maze.getCharAtPos(sob.getRow()+1, sob.getCol())
    y = maze.getCharAtPos(sob.getRow()+2, sob.getCol())
    print "crate row : " + str(crate.getRow)
    print "Crate Col : " + str(crate.getcol)
    if x == "#":
        print "You have hit a wall, you cannot move!"
    elif x == " ":
        print "This is a space!"
        sob.moveDown()
        maze.placeSob(sob.getChar(), sob.getRow(), sob.getCol())
        maze.clearAtPos(sob.getRow() -1, sob.getCol())
    elif (x == "@" and y == " "):
            print "This is a box!"
            #move the box first and then the man!
            crate.pushboxdown()
            sob.moveDown
            #place the crate in the maze in the new position
            maze.placecrate("@", crate.getRow()+1,crate.getcol())
            maze.placeSob(sob.getChar(),sob.getRow()+1,sob.getCol())
            maze.clearAtPos(crate.getRow() - 1,crate.getcol())


            maze.clearAtPos(sob.getRow()-1,sob.getCol())
            #then move the man
            #then place the man in the maze
            #then clear original position
            maze.pushBox()

            sob.moveDown()
            maze.clearAtPos(sob.getRow() - 1, sob.getCol())
            maze.placeSob(sob.getChar(), sob.getRow(), sob.getCol())
    print maze.toString()
    print sob.toString()
def main():
    global FPSCLOCK, DISPLAYSURF, IMAGESDICT, TILEMAPPING, BASICFONT, score
    maze.placeSob('^', 5,1)
    print maze.toString()
    drawMap(maze)
    while True:
                #thread 1 - look for an action
        for event in pygame.event.get(): # event handling loop
            if event.type == QUIT:
                # Player clicked the "X" at the corner of the window.
                terminate()
            elif event.type == KEYDOWN:
                if event.key == K_RIGHT:
                    moveSobRight()
                elif event.key == K_LEFT:
                    moveSobLeft()
                elif event.key == K_UP:
                    moveSobUp()
                elif event.key == K_DOWN:
                    moveSobDown()
                elif event.key == K_SPACE:
                    restart()
                else:
                    pass
            mapNeedsRedraw = True
        if score == 1:

            score = 0
            maze.leveltwo()
            maze.clearAtPos(5,1)
            maze.placeSob('^', 5,1)
            maze.clearAtPos(1,2)
            maze.placecrate('@',2,4)
            crate = Crate("@", 2, 4)
            #do i need multiple crates for .setcrate ?
            maze.placecrate("@",2,4)
            sob.setRow(5)
            sob.setCol(1)




        #thread 2: redraw the screen
        DISPLAYSURF.fill(BGCOLOR) #draws the turquoise background
        #if something has changed, redraw....
        if mapNeedsRedraw:

                mapSurf = drawMap(maze)



                #mapsurf =
            #elif score == 3:
                #mapsurf = drawmap(maze3)
            #elif score == 4:
                #mapsurf = drawmap(maze4)
            #elif score == 5:
                #mapsurf = drawmap(maze5)

        mapNeedsRedraw = False
        mapSurfRect = mapSurf.get_rect()
        mapSurfRect.center = (HALF_WINWIDTH, HALF_WINHEIGHT)
        # Draw the map on the DISPLAYSURF object.
        DISPLAYSURF.blit(mapSurf, mapSurfRect)
        pygame.display.update() # draw DISPLAYSURF to the screen.
        FPSCLOCK.tick()
def drawMap(maze):
    #draw the tile sprites onto this surface.
    #this creates the visual map!
    mapSurfWidth = maze.getWidth() * TILEWIDTH
    mapSurfHeight = maze.getHeight() * TILEHEIGHT
    mapSurf = pygame.Surface((mapSurfWidth, mapSurfHeight))
    mapSurf.fill(BGCOLOR)
    for h in range(maze.getHeight()):
        for w in range(maze.getWidth()):
            thisTile = pygame.Rect((w * TILEWIDTH, h * TILEFLOORHEIGHT, TILEWIDTH, TILEHEIGHT))
            if maze.getCharAtPos(h, w) in TILEMAPPING:
                #checks in the TILEMAPPING directory above to see if there is a
                #matching picture, then renders it
                baseTile = TILEMAPPING[maze.getCharAtPos(h,w)]
            # Draw the tiles for the map.
            mapSurf.blit(baseTile, thisTile)
    return mapSurf
def restart():
    maze.__init__()
    sob.setRow(4)
    sob.setCol(1)
    maze.placeSob(sob.getChar(), sob.getRow(), sob.getCol())
    drawMap(maze)

def text(text,textcolour):
    smalltext = pygame.font.font('freesansbold.ttf',20)
    largetext = pygame.font.font('freesansbold.ttf',20)
    titletextsurf,titletextrect = maketextobjs(text,largetext,textcolour)
    titletextrect.center = (int(maze.getwidth / 2),int(maze.getHeight / 2))
    DISPLAYSURF.blit(titletextsurf,titletextrect)
    typtextsurf,typetextrect = maketextobjs("press key to continue",smalltext,white)
    typtextrect.center = (int(maze.getwidth/2),int(maze.getHeight/2)+75)

def terminate():
    #shutdown routine
    pygame.quit()
    sys.exit()
if __name__ == '__main__':
    main()

-------------迷宫级-------------------------

class Maze:
    """2D Maze for the player to play the game in"""

    def __init__(self):
    """the maze constructor
    (none) -> none
    start by declaring attributes"""
        self.maze = [['#','#','#','#','#','#','#'],
                       ['#',' ','@',' ',' ','/','#'],
                       ['#',' ',' ','#',' ','#','#'],
                       ['#',' ',' ','#',' ',' ','#'],
                       ['#',' ',' ','#','',' ','#'],
                       ['#',' ',' ','#','#','#','#'],
                       ['#','#','#','#','#','#','#']]
        self.width = 7
        self.height = 7
        self.box = 1

    def toString(self):
    """prints out the maze
    (none) -> none"""
        printme = ""
        for i in range (0,len(self.maze)):
            for j in self.maze[i]:
                printme = printme + j
            printme = printme + "\n"
        return printme

    def placeSob (self, Sob_char, row, column):
    """places a Sobokan at a specified row and column in the maze
    (char, int, int) -> none
    >>>placeSob("$", 2, 2)
    NoneType"""
        self.maze[row][column] = Sob_char

    def placecrate (self, crate_char, row, column):
    """places a Sobokan at a specified row and column in the maze
    (char, int, int) -> none
    >>>placeSob("$", 2, 2)
    NoneType"""
        self.maze[row][column] = crate_char


    def clearAtPos(self, row, col):
        self.maze[row][col] = " "


    def getCharAtPos(self, row, col):
        """This is a very important method as it allows you to check for
        walls and boxes
        >>>getCharAtPos(0,0)
        '#'"""
        return self.maze[row][col]

    def pushBox(self):
            self.box -= 1

    def getWidth(self):
        return self.width

    def getHeight(self):
        return self.height
    def getCurrentMaze(self):
        return self.maze

    def leveltwo(self):
        self.maze = [['#','#','#','#','#','#','#'],
                       ['#',' ',' ',' ',' ','/','#'],
                       ['#',' ',' ',' ','@','#','#'],
                       ['#','#','',' ',' ',' ','#'],
                       ['#',' ',' ',' ','',' ','#'],
                       ['#','^',' ',' ',' ','#','#'],
                       ['#','#','#','#','#','#','#']]
        self.width = 7
        self.height = 7
        self.box = 1
        return self.maze

    def GetBoxes(self):
        return self.box

---------------推箱子班---------------------------

class Sobokan:
    #add attributes for sobokan character
    def __init__(self, x, r, c):
        """Constructor for sobokan. Needs to pass in values
        for the character representing sobokan, row and column
        >>> sobokan("$", 2, 3)
        NoneType"""
        self.char = x
        self.row = r
        self.col = c
        self.box = 0
    def toString(self):
        info = "Sobokan " + self.char + " at row " + str(self.row) + " and column " + str(self.col)
        info = info +  " has pushed " + str(self.box) + " boxes today."
        return info
    def getRow(self):
        return self.row
    def getCol(self):
        return self.col
    def getChar(self):
        return self.char
    def setRow(self, r):
        self.row = r
    def setCol(self, c):
        self.col = c
    def moveRight(self):
        self.col += 1
    def moveLeft(self):
        self.col -= 1
    def moveUp(self):
        self.row -=1
    def moveDown(self):
        self.row +=1
    def pushBox(self):
        self.box += 1
    def pushboxup(self):
        self.row -= 1
    def pushboxdown(self):
        self.row += 1
    def pushboxleft(self):
        self.col -= 1
    def pushboxright(self):
        self.col += 1

----------- Crate Class --------------------------

class Crate:
    #add attributes for sobokan character
    def __init__(self, x, r, c):
        """Constructor for sobokan. Needs to pass in values
        for the character representing sobokan, row and column
        >>> crate("@", 2, 3)
        NoneType"""
        self.char = x
        self.row = r
        self.col = c
        self.box = 0
    def toString(self):
        info = "crate " + self.char + " at row " + str(self.row) + " and column " + str(self.col)
        info = info +  " has been pushed " + str(self.box) + " times today."
        return info

    def pushboxup(self):
        self.row -= 1
    def pushboxdown(self):
        self.row += 1
    def pushboxleft(self):
        self.col -= 1
    def pushboxright(self):
        self.col += 1

    def getRow(self):
        return self.row

    def getcol(self):
        return self.col

    def setCol(self, c):
        self.col = c

    def setRow(self, r):
        self.row = r

我很确定问题就在这里......(MoveSobUp)

def moveSobUp():
    print "Key up"
    c1 = crate.getRow()
    c2 = crate.getcol()

    z = sob.getCol()
    w = sob.getRow()
    x = maze.getCharAtPos(sob.getRow()-1, sob.getCol())
    y = maze.getCharAtPos(sob.getRow()-2, sob.getCol())
    print "x/y init works"
    if x == "#":
        print "You have hit a wall, you cannot move!"
    elif x == " ":
        print "This is a space!"
        sob.moveUp()
        maze.placeSob("^", w-1, z)
        print "player should be placed"
        maze.clearAtPos(w, z)
        print "player should be cleared"
    elif (x == "@" and y == " "):
        print "You have collided with a sprout, the sprout will move away now"
        #move crate
        crate.pushboxup()
        maze.clearAtPos(c1,c2)
        maze.placecrate("@",c1 - 1,c2)
        #move sob
        sob.moveUp()
        maze.clearAtPos(sob.getRow(),sob.getCol())
        maze.placeSob(sob.getChar,sob.getRow() - 1,sob.getCol())

或者在这里......(Maze.leveltwo)

def leveltwo(self):

        self.maze = [['#','#','#','#','#','#','#'],
                       ['#',' ',' ',' ',' ','/','#'],
                       ['#',' ',' ',' ','@','#','#'],
                       ['#','#','',' ',' ',' ','#'],
                       ['#',' ',' ',' ','',' ','#'],
                       ['#','^',' ',' ',' ','#','#'],
                       ['#','#','#','#','#','#','#']]
        self.width = 7
        self.height = 7
        self.box = 1
        return self.maze
python pygame maze
1个回答
0
投票

我在你的代码中看到很多问题。

你在crate创建mainloop

crate = Crate("@", 2, 4)

但它创建了局部变量和

crate.setCol(5)
crate.setRow(3)

改变这个本地crate的位置(顺便说一下:它是错误的位置 - 它必须是col = 4,row = 2)

其他函数使用全球cratecol=0row=5,因为它是在第一级结束时的crate位置。

如果你删除

crate = Crate("@", 2, 4)

然后

crate.setCol(5)
crate.setRow(3)

将改变全球crate

(或在global crate中添加main()

--

移动元素还有其他问题,但是......你必须自己找到它;)你有四个函数moveSobDownmoveSobUpmoveSobLeftmoveSobRight,它们应该几乎相同,但它们不是。

--

顺便说一句:你在迷宫中有错误的字符 - 你使用''(空字符)但它必须是' '(空格)所以第二级被错误绘制而你有“隐形”墙。

© www.soinside.com 2019 - 2024. All rights reserved.