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
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() |