我希望得到一些我在pygame上工作的第三场比赛的帮助。我按照以下方式加载了图像和声音,以及“宝石”和“宝石”。将是空气,土,火和水的经典元素。如何播放相应的水声文件,例如,当匹配3个或更多水精灵时?不需要任何游戏代码的帮助,只是为了在图像和音频文件之间建立关联以及如何播放它们,而匹配元素!= []'。谢谢。
# Directions
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
# Space to the sides of grid
XMARGIN = int((WIDTH - ELEMENTSIZE * GRIDWIDTH) / 2)
YMARGIN = int((HEIGHT - ELEMENTSIZE * GRIDHEIGHT) / 2)
EMPTY_SPACE = -1
ROWABOVEBOARD = 'row above board'
# Colours
AIR = pygame.Color(145, 129, 129)
FIRE = pygame.Color(255, 123, 0)
WATER = pygame.Color(93, 118, 245)
EARTH = pygame.Color(22, 136, 0)
ELECTRIC = pygame.Color(22, 204, 0)
SMOKE = pygame.Color(222, 222, 222)
ICE = pygame.Color(234, 231, 255)
METAL = pygame.Color(105, 105, 105)
BLOOD = pygame.Color(222, 7, 7)
# FPS controller
fpsController = pygame.time.Clock()
def main():
global FPSCLOCK, BOARDRECTS, ELEMENTIMAGES, SOUNDS, PLAYSURF, BASICFONT
# Basic set up
pygame.init()
FPSCLOCK = pygame.time.Clock()
PLAYSURF = pygame.display.set_mode((WIDTH, HEIGHT))
BASICFONT = pygame.font.Font('freesansbold.ttf', 36)
# Load images
ELEMENTIMAGES = []
for i in range(1, NUMELEMENTS+1):
elementImage = pygame.image.load('element%s.jpg' % i)
if elementImage.get_size() != (ELEMENTSIZE, ELEMENTSIZE):
elementImage = pygame.transform.smoothscale(elementImage, (ELEMENTSIZE, ELEMENTSIZE))
ELEMENTIMAGES.append(elementImage)
# Load sounds
SOUNDS = {}
SOUNDS['bad swap'] = pygame.mixer.Sound('badswap.wav')
SOUNDS['match'] = []
for i in range(NUMMATCHSOUNDS):
SOUNDS['match'].append(pygame.mixer.Sound('elementsound%s.wav' % i))
# Rect objects for board space conversions
BOARDRECTS = []
for x in range(GRIDWIDTH):
BOARDRECTS.append([])
for y in range(GRIDHEIGHT):
r = pygame.Rect((XMARGIN + (x * ELEMENTSIZE),
YMARGIN + (y * ELEMENTSIZE),
ELEMENTSIZE, ELEMENTSIZE))
BOARDRECTS[x].append(r)
while True:
runGame()
def runGame():
# Board initialisation
gameBoard = getBlankBoard()
score = 0
fillBoardAndAnimate(gameBoard, [], score) # Drop initial elements
# Initialise new game variables
firstSelectedElement = None
lastMouseDownX = None
lastMouseDownY = None
gameIsOver = False
lastScoreDeduction = time.time()
clickContinueTextSurf = None
# Main game loop
while True:
clickedSpace = None
for event in pygame.event.get(): # Event handling
if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == KEYUP and event.key == K_BACKSPACE:
return # new game
elif event.type == MOUSEBUTTONUP:
if gameIsOver:
return # click to start new game
if event.pos == (lastMouseDownX, lastMouseDownY):
clickedSpace = checkForElementClick(event.pos)
else:
firstSelectedElement = checkForElementClick((lastMouseDownX, lastMouseDownY))
clickedSpace = checkForElementClick(event.pos)
if not firstSelectedElement or not clickedSpace:
firstSelectedElement = None
clickedSpace = None
elif event.type == MOUSEBUTTONDOWN:
lastMouseDownX, lastMouseDownY = event.pos
if clickedSpace and not firstSelectedElement:
firstSelectedElement = clickedSpace
elif clickedSpace and firstSelectedElement:
firstSwappingElement, secondSwappingElement = getSwappingElements(gameBoard, firstSelectedElement, clickedSpace)
if firstSwappingElement == None and secondSwappingElement == None:
# If both are None, elements are not adjacent
firstSelectedElement = None
continue
# Swap animation
boardCopy = getBoardCopyMinusElements(gameBoard, (firstSwappingElement, secondSwappingElement))
animateMovingElements(boardCopy, [firstSwappingElement, secondSwappingElement], [], score)
# Swap elements in the board
gameBoard[firstSwappingElement['x']][firstSwappingElement['y']] = secondSwappingElement['imageNum']
gameBoard[secondSwappingElement['x']][secondSwappingElement['y']] = firstSwappingElement['imageNum']
# See if this is a match
matchedElements = findMatchingElements(gameBoard)
if matchedElements == []:
# No match - swap back
SOUNDS['bad swap'].play()
animateMovingElements(boardCopy, [firstSwappingElement, secondSwappingElement], [], score)
gameBoard[firstSwappingElement['x']][firstSwappingElement['y']] = firstSwappingElement['imageNum']
gameBoard[secondSwappingElement['x']][secondSwappingElement['y']] = secondSwappingElement['imageNum']
else:
# A match
scoreAdd = 0
while matchedElements != []:
points = []
for elementSet in matchedElements:
scoreAdd += (10 + (len(elementSet) - 3) * 10)
for element in elementSet:
gameBoard[element[0]][element[1]] = EMPTY_SPACE
points.append({'points': scoreAdd,
'x': element[0] * ELEMENTSIZE + XMARGIN,
'y': element[1] * ELEMENTSIZE + YMARGIN})
score += scoreAdd
# Drop new elements
fillBoardAndAnimate(gameBoard, points, score)
# Check for new matches
matchedElements = findMatchingElements(gameBoard)
firstSelectedElement = None
if not canMakeMove(gameBoard):
gameIsOver = True
# Draw the board
PLAYSURF.fill(BGCOLOUR)
drawBoard(gameBoard)
if firstSelectedElement != None:
highlightSpace(firstSelectedElement['x'], firstSelectedElement['y'])
if gameIsOver:
if clickContinueTextSurf == None:
clickContinueTextSurf = BASICFONT.render('Final Score: %s (Click to continue)' % (score), 1, GAMEOVERCOLOUR, GAMEOVERBGCOLOUR)
clickContinueTextRect = clickContinueTextSurf.get_rect()
clickContinueTextRect.center = int(WIDTH / 2), int(HEIGHT / 2)
PLAYSURF.blit(clickContinueTextSurf, clickContinueTextRect)
elif score > 0 and time.time() - lastScoreDeduction > DEDUCTSPEED:
# score drops over time
score -= 1
lastScoreDeduction = time.time()
drawScore(score)
pygame.display.update()
FPSCLOCK.tick(FPS)
def getSwappingElements(board, firstXY, secondXY):
# If the elements at the (X, Y) coordinates of the two elements are adjacent,
# then their 'direction' keys are set to the appropriate direction
# value to be swapped with each other.
# Otherwise, (None, None) is returned.
firstElement = {'imageNum': board[firstXY['x']][firstXY['y']],
'x': firstXY['x'],
'y': firstXY['y']}
secondElement = {'imageNum': board[secondXY['x']][secondXY['y']],
'x': secondXY['x'],
'y': secondXY['y']}
highlightedElement = None
if firstElement['x'] == secondElement['x'] + 1 and firstElement['y'] == secondElement['y']:
firstElement['direction'] = LEFT
secondElement['direction'] = RIGHT
elif firstElement['x'] == secondElement['x'] - 1 and firstElement['y'] == secondElement['y']:
firstElement['direction'] = RIGHT
secondElement['direction'] = LEFT
elif firstElement['y'] == secondElement['y'] + 1 and firstElement['x'] == secondElement['x']:
firstElement['direction'] = UP
secondElement['direction'] = DOWN
elif firstElement['y'] == secondElement['y'] - 1 and firstElement['x'] == secondElement['x']:
firstElement['direction'] = DOWN
secondElement['direction'] = UP
else:
# These elements are not adjacent and can't be swapped.
return None, None
return firstElement, secondElement
def getBlankBoard():
# Create and return a blank board data structure.
board = []
for x in range(GRIDWIDTH):
board.append([EMPTY_SPACE] * GRIDHEIGHT)
return board
def canMakeMove(board):
# Return True if the board is in a state where a matching
# move can be made on it. Otherwise return False.
# The patterns in oneOffPatterns represent elements that are configured
# in a way where it only takes one move to make a triplet.
oneOffPatterns = (((0,1), (1,0), (2,0)),
((0,1), (1,1), (2,0)),
((0,0), (1,1), (2,0)),
((0,1), (1,0), (2,1)),
((0,0), (1,0), (2,1)),
((0,0), (1,1), (2,1)),
((0,0), (0,2), (0,3)),
((0,0), (0,1), (0,3)))
# The x and y variables iterate over each space on the board.
# If we use + to represent the currently iterated space on the
# board, then this pattern: ((0,1), (1,0), (2,0))refers to identical
# elements being set up like this:
#
# +A
# B
# C
#
# That is, element A is offset from the + by (0,1), element B is offset
# by (1,0), and element C is offset by (2,0). In this case, element A can
# be swapped to the left to form a vertical three-in-a-row triplet.
#
# There are eight possible ways for the elements to be one move
# away from forming a triple, hence oneOffPattern has 8 patterns.
for x in range(GRIDWIDTH):
for y in range(GRIDHEIGHT):
for pat in oneOffPatterns:
# check each possible pattern of "match in next move" to
# see if a possible move can be made.
if (getElementAt(board, x+pat[0][0], y+pat[0][1]) == \
getElementAt(board, x+pat[1][0], y+pat[1][1]) == \
getElementAt(board, x+pat[2][0], y+pat[2][1]) != None) or \
(getElementAt(board, x+pat[0][1], y+pat[0][0]) == \
getElementAt(board, x+pat[1][1], y+pat[1][0]) == \
getElementAt(board, x+pat[2][1], y+pat[2][0]) != None):
return True # return True the first time you find a pattern
return False
def drawMovingElement(element, progress):
# Draw an element sliding in the direction that its 'direction' key
# indicates. The progress parameter is a number from 0 (just
# starting) to 100 (slide complete).
movex = 0
movey = 0
progress *= 0.01
if element['direction'] == UP:
movey = -int(progress * ELEMENTSIZE)
elif element['direction'] == DOWN:
movey = int(progress * ELEMENTSIZE)
elif element['direction'] == RIGHT:
movex = int(progress * ELEMENTSIZE)
elif element['direction'] == LEFT:
movex = -int(progress * ELEMENTSIZE)
basex = element['x']
basey = element['y']
if basey == ROWABOVEBOARD:
basey = -1
pixelx = XMARGIN + (basex * ELEMENTSIZE)
pixely = YMARGIN + (basey * ELEMENTSIZE)
r = pygame.Rect( (pixelx + movex, pixely + movey, ELEMENTSIZE, ELEMENTSIZE) )
PLAYSURF.blit(ELEMENTIMAGES[element['imageNum']], r)
def pullDownAllElements(board):
# pulls down elements on the board to the bottom to fill in any gaps
for x in range(GRIDWIDTH):
elementsInColumn = []
for y in range(GRIDHEIGHT):
if board[x][y] != EMPTY_SPACE:
elementsInColumn.append(board[x][y])
board[x] = ([EMPTY_SPACE] * (GRIDHEIGHT - len(elementsInColumn))) + elementsInColumn
def getElementAt(board, x, y):
if x < 0 or y < 0 or x >= GRIDWIDTH or y >= GRIDHEIGHT:
return None
else:
return board[x][y]
def getDropSlots(board):
# Creates a "drop slot" for each column and fills the slot with a
# number of elements that that column is lacking. This function assumes
# that the elements have been gravity dropped already.
boardCopy = copy.deepcopy(board)
pullDownAllElements(boardCopy)
dropSlots = []
for i in range(GRIDWIDTH):
dropSlots.append([])
# count the number of empty spaces in each column on the board
for x in range(GRIDWIDTH):
for y in range(GRIDHEIGHT-1, -1, -1): # start from bottom, going up
if boardCopy[x][y] == EMPTY_SPACE:
possibleElements = list(range(len(ELEMENTIMAGES)))
for offsetX, offsetY in ((0, -1), (1, 0), (0, 1), (-1, 0)):
# Narrow down the possible elements we should put in the
# blank space so we don't end up putting an two of
# the same elements next to each other when they drop.
neighborElement = getElementAt(boardCopy, x + offsetX, y + offsetY)
if neighborElement != None and neighborElement in possibleElements:
possibleElements.remove(neighborElement)
newElement = random.choice(possibleElements)
boardCopy[x][y] = newElement
dropSlots[x].append(newElement)
return dropSlots
答案 0 :(得分:0)
这只是部分答案,以展示我在评论中建议的内容。我不确定你的gameBoard
实际上是什么样的,所以你必须根据需要调整代码。
我在这个例子中使用了一个只填充字符串的电路板(你也可以使用常量WATER = 1
,FIRE = 2
等或枚举。声音在字典中,元素作为键。如果你有一个匹配,找出它是哪个元素,然后使用它从dict中获取相关的声音并播放它。
ELEMENT_SOUNDS = {
'water': WATER_SOUND,
'fire': FIRE_SOUND,
}
board = [
['water', 'fire', 'water'],
['fire', 'water', 'fire'],
['water', 'water', 'water'],
]
if match:
# Figure out the kind of the matching element 'water' in this case.
element_kind = 'water'
ELEMENT_SOUNDS[element_kind].play()