推箱子游戏不会推动新的水平 - Python - Pygame
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了推箱子游戏不会推动新的水平 - Python - Pygame相关的知识,希望对你有一定的参考价值。
我正在用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 + "
"
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
我在你的代码中看到很多问题。
你在crate
创建mainloop
crate = Crate("@", 2, 4)
但它创建了局部变量和
crate.setCol(5)
crate.setRow(3)
改变这个本地crate
的位置(顺便说一下:它是错误的位置 - 它必须是col = 4,row = 2)
其他函数使用全球crate
与col=0
,row=5
,因为它是在第一级结束时的crate
位置。
如果你删除
crate = Crate("@", 2, 4)
然后
crate.setCol(5)
crate.setRow(3)
将改变全球crate
(或在global crate
中添加main()
)
--
移动元素还有其他问题,但是......你必须自己找到它;)你有四个函数moveSobDown
,moveSobUp
,moveSobLeft
,moveSobRight
,它们应该几乎相同,但它们不是。
--
顺便说一句:你在迷宫中有错误的字符 - 你使用''
(空字符)但它必须是' '
(空格)所以第二级被错误绘制而你有“隐形”墙。
以上是关于推箱子游戏不会推动新的水平 - Python - Pygame的主要内容,如果未能解决你的问题,请参考以下文章
POJ1475(Pushing Boxes)--bbffss
《算法竞赛进阶指南》0x25广度优先搜索 推箱子游戏 双重BFS