You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
6.8 KiB

import pygame
import sys
from os import path
from map import list
from pygame import mixer
import math
pygame.init()
screen = pygame.display.set_mode((560, 560), 0, 0)
pygame.display.set_caption('推箱子游戏')
boxList = []
ballList = []
wallList = []
peopleDir = {'x': 0, 'y': 0}
clock = pygame.time.Clock()
def initData(level):
boxList.clear()
ballList.clear()
wallList.clear()
data = list[level]
index = -1
for i in range(0, 16):
for j in range(0, 16):
index += 1
item = data[index]
if item == 1:
wallList.append(1)
else:
wallList.append(0)
if item == 2:
ballList.append(2)
else:
ballList.append(0)
if item == 3:
boxList.append(3)
else:
boxList.append(0)
if item == 4:
peopleDir['x'] = j
peopleDir['y'] = i
class GameApp:
level = 0 # 第一关
map = None
background = None
wall = None
ball = None
box = None
down_people = None
left_people = None
right_people = None
up_people = None
direction = 'down'
levelFont = None
ballNum = 0
def __init__(self):
self.loadFile()
icon = pygame.image.load(self.resolve('img/down.png'))
pygame.display.set_icon(icon)
mixer.music.load(self.resolve('img/background.wav'))
self.levelFont = pygame.font.Font(self.resolve('img/msyh.ttc'), 20)
mixer.music.play(-1)
self.runGame()
def loadFile(self):
self.background = pygame.image.load(self.resolve('img/bg.jpg'))
self.wall = pygame.image.load(self.resolve('img/wall.png'))
self.ball = pygame.image.load(self.resolve('img/ball.png'))
self.box = pygame.image.load(self.resolve('img/box.png'))
self.down_people = pygame.image.load(self.resolve('img/down.png'))
self.left_people = pygame.image.load(self.resolve('img/left.png'))
self.right_people = pygame.image.load(self.resolve('img/right.png'))
self.up_people = pygame.image.load(self.resolve('img/up.png'))
def resolve(self, filename):
dirName = path.dirname(__file__)
return dirName + '/' + filename
def renderLevel(self):
levelText = self.levelFont.render(''+str(self.level+1)+'', True, (0, 0, 0))
screen.blit(levelText, (490, 5))
def renderPeople(self, i, j):
if self.direction == 'down':
screen.blit(self.down_people, (j*35-7, i*35-27))
if self.direction == 'left':
screen.blit(self.left_people, (j*35-7, i*35-27))
if self.direction == 'right':
screen.blit(self.right_people, (j*35-7, i*35-27))
if self.direction == 'up':
screen.blit(self.up_people, (j*35-7, i*35-27))
def renderData(self):
index = -1
for i in range(0, 16):
for j in range(0, 16):
index+=1
if wallList[index] == 1:
screen.blit(self.wall, (j*35, i*35 - 13))
if ballList[index] == 2:
self.ballNum+=1
screen.blit(self.ball, (j*35 + 2, i*35 + 2))
if boxList[index] == 3:
screen.blit(self.box, (j*35, i*35 - 11))
if peopleDir['x'] == j and peopleDir['y'] == i:
self.renderPeople(i, j)
def hasGo(self, preItem, nextItem, preIndex, nextIndex, x, y):
if preItem == 0 or preItem == 2:
peopleDir['x'] = x
peopleDir['y'] = y
return True
if preItem == 3: # 推箱子走路
if nextItem == 0 or nextItem == 2:
boxList[preIndex] = 0
boxList[nextIndex] = 3
peopleDir['x'] = x
peopleDir['y'] = y
self.checkGameover(nextIndex)
self.checkWin()
return True
return False
def checkGameover(self, nextIndex):
y = math.floor(nextIndex/16)
x = nextIndex%16
preItem = 0
if ballList[nextIndex] != 2:
checkList = [
wallList[(y-1)*16 + x],
wallList[y*16 + x-1],
wallList[(y+1)*16 + x],
wallList[y*16 + x+1],
wallList[(y-1)*16 + x]
]
for item in checkList:
if item == 0:
preItem = 0
elif item == 1 and preItem == 0:
preItem = 1
elif item == 1 and preItem == 1: # 如果相邻是两面墙及失败了
self.level = 0
initData(self.level)
break
def checkWin(self):
index = -1
winNum = 0
self.ballNum = 0
for i in range(0, 16):
for j in range(0, 16):
index+=1
if ballList[index] == 2:
self.ballNum+=1
if (boxList[index] == 3):
winNum+=1
if self.ballNum == winNum:
self.level+=1
initData(self.level)
def pushData(self, type):
x = peopleDir['x']
y = peopleDir['y']
curIndex = y*16+x
if type == 'left':
preIndex = y*16+x-1
nextIndex = y*16+x-2
preItem = max([boxList[preIndex], ballList[preIndex], wallList[preIndex]])
nextItem = max([boxList[nextIndex], ballList[nextIndex], wallList[nextIndex]])
if self.hasGo(preItem, nextItem, preIndex, nextIndex, x-1, y):
self.direction = 'left'
if type == 'right':
preIndex = y*16+x+1
nextIndex = y*16+x+2
preItem = max([boxList[preIndex], ballList[preIndex], wallList[preIndex]])
nextItem = max([boxList[nextIndex], ballList[nextIndex], wallList[nextIndex]])
if self.hasGo(preItem, nextItem, preIndex, nextIndex, x+1, y):
self.direction = 'right'
if type == 'up':
preIndex = (y-1)*16+x
nextIndex = (y-2)*16+x
preItem = max([boxList[preIndex], ballList[preIndex], wallList[preIndex]])
nextItem = max([boxList[nextIndex], ballList[nextIndex], wallList[nextIndex]])
if self.hasGo(preItem, nextItem, preIndex, nextIndex, x, y-1):
self.direction = 'up'
if type == 'down':
preIndex = (y+1)*16+x
nextIndex = (y+2)*16+x
preItem = max([boxList[preIndex], ballList[preIndex], wallList[preIndex]])
nextItem = max([boxList[nextIndex], ballList[nextIndex], wallList[nextIndex]])
if self.hasGo(preItem, nextItem, preIndex, nextIndex, x, y+1):
self.direction = 'down'
def runGame(self):
while True:
clock.tick(300)
screen.fill((0, 0, 0))
screen.blit(self.background, (0, 0))
self.renderData()
self.renderLevel()
for event in pygame.event.get():
if event.type == pygame.QUIT: # 如果单击关闭窗口,则退出
pygame.quit() # 退出pygame
sys.exit() # 退出系统
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
self.pushData('left')
if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
self.pushData('right')
if event.key == pygame.K_DOWN or event.key == pygame.K_s:
self.pushData('down')
if event.key == pygame.K_UP or event.key == pygame.K_w:
self.pushData('up')
pygame.display.update()
if __name__ == '__main__':
initData(0)
GameApp()