代码拉取完成,页面将自动刷新
import os, codecs, json
from scene.scene import *
from scene.stage import *
from scene.level import levelDict
from scene.stage_rhythm import stageRhythm
from scene.stage_kingdomrush import stageKingdomRush
from scene.stage_kingdomrush2 import stageKingdomRush2
from res_config import *
from character.formation import *
from optparse import OptionParser
# os.environ['QT_MULTIMEDIA_PREFERRED_PLUGINS'] = 'windowsmediafoundation'
class loadResources(QThread): # 通过qthread异步加载游戏所有资源
percent = Signal(float)
loadFinish = Signal(dict)
loadStore = Signal(dict)
def __init__(self):
super(loadResources, self).__init__()
def run(self):
gameObjects = [
['tomb', tomb, tombFrames],
['goldenTomb', goldenTomb, goldenTombFrames],
['puff1', puff1, puffFrames],
['puff2', puff2, puffFrames],
['puff3', puff3, puffFrames],
['puff4', puff4, puffFrames],
['boom', boomCloud, boomCloudFrames],
['cherrybomb', cherryBombCloud, boomCloudFrames],
['bite', bite, biteFrames],
['cabbage', cabbage, cabbageFrames],
['butter', butter, butterFrames],
['melon', melon, melonFrames],
['wintermelon', wintermelon, wintermelonFrames],
['seckill', seckill, seckillFrames],
['dirt', dirt, dirtFrames],
['bowlingnut', bowlingnut, bowlingnutFrames],
['david', david, davidFrames],
['peashooter', peashooter, peashooterFrames],
['pea', pea, peaFrames],
['snowpeashooter', snowpeashooter, snowpeashooterFrames],
['snowpea', snowpea, snowpeaFrames],
['multipeashooter', multipeashooter, multipeashooterFrames],
['gatlingpeashooter', gatlingpeashooter, gatlingpeashooterFrames],
['smallshroom', smallshroom, smallshroomFrames],
['scaredyshroom', scaredyshroom, scaredyshroomFrames],
['largeshroom', largeshroom, largeshroomFrames],
['gloomshroom', gloomshroom, gloomshroomFrames],
['nut', nut, nutFrames],
['tallnut', tallnut, tallnutFrames],
['flamenut', flamenut, flamenutFrames],
['chomper', chomper, chomperFrames],
['cabbagepult', cabbagepult, cabbagepultFrames],
['cornpult', cornpult, cornpultFrames],
['melonpult', melonpult, melonpultFrames],
['wintermelonpult', wintermelonpult, wintermelonpultFrames],
['sunflower', sunflower, sunflowerFrames],
['twinsunflower', twinsunflower, twinsunflowerFrames],
['cherry', cherry, cherryFrames],
['pumpkin', pumpkin, pumpkinFrames],
['iceshroom', iceshroom, iceshroomFrames],
['lawnmower', lawnmower, lawnmowerFrames],
['zombie', zombie, zombieFrames],
['zombiedoor', zombieDoor, zombieDoorFrames],
['zombiepaper', zombiePaper, zombiePaperFrames],
['zombiepolevault', zombiePolevault, zombiePolevaultFrames],
['zombiefootball', zombieFootball, zombieFootballFrames],
['zombiegargantuar', zombieGargantuar, zombieGargantuarFrames],
['zombieimp', zombieImp, zombieImpFrames],
['zombiezamboni', zombiezamboni, zombiezamboniFrames],
['archer_lv1', archer_lv1, archer_lv1_frames],
['archer_lv2', archer_lv2, archer_lv2_frames],
['archer_lv3', archer_lv3, archer_lv3_frames],
['archer_lv4', archer_lv4, archer_lv4_frames],
['mage_lv1', mage_lv1, mage_lv1_frames],
['mage_lv2', mage_lv2, mage_lv2_frames],
['mage_lv3', mage_lv3, mage_lv3_frames],
['mage_lv4', mage_lv4, mage_lv4_frames],
['barrack_lv1', barrack_lv1, barrack_lv1_frames],
['soldier_lv1', soldier_lv1, soldier_lv1_Frames],
['barrack_lv2', barrack_lv2, barrack_lv2_frames],
['soldier_lv2', soldier_lv2, soldier_lv2_Frames],
['barrack_lv3', barrack_lv3, barrack_lv3_frames],
['soldier_lv3', soldier_lv3, soldier_lv3_Frames],
['barrack_lv4', barrack_lv4, barrack_lv4_frames],
['soldier_lv4', soldier_lv4, soldier_lv4_Frames],
['artillery_lv1', artillery_lv1, artillery_lv1_frames],
['artillery_lv2', artillery_lv2, artillery_lv2_frames],
['artillery_lv3', artillery_lv3, artillery_lv3_frames],
['artillery_lv4', artillery_lv4, artillery_lv4_frames],
['fireball', fireball, fireball_Frames],
['arrow', arrow, arrowFrames],
['magebolt', mageBolt, mageBoltFrames],
['mageray', mageRay, mageRayFrames],
['bomb_lv1', bombLV1, bombLV1Frames],
['bomb_lv2', bombLV2, bombLV2Frames],
['bomb_lv3', bombLV3, bombLV3Frames],
['bomb_lv4', bombLV4, bombLV4Frames],
['missile', missile, missileFrames],
['fireballParticle', fireballParticle, fireballFrames],
]
typeMap = {}
for index, gameObject in enumerate(gameObjects):
name, obj, func = gameObject
typeMap[name] = [obj, func()] # 实例化资源
self.percent.emit((index + 1) / len(gameObjects)) # 发送加载百分比
self.loadFinish.emit(typeMap)
self.loadStore.emit(typeMap)
class MainWindow(QMainWindow):
def __init__(self, option):
super(MainWindow, self).__init__()
self.setFixedSize(1000, 850)
try:
with codecs.open('config', 'r', encoding='utf8', errors='ignore') as f:
self.config = json.loads(f.read())
except:
self.config = {
'roomID': '',
'vol1': 1,
'vol2': 1,
'highDPI': False,
}
if not option.id:
self.roomID = self.config['roomID']
else:
self.roomID = option.id
self.version = option.version
self.setTitle('黄金矿工大战僵尸')
self.level = 1
self.plantCards = [['peashooter'], ['sunflower']]
self.brainMoney = [5, 100]
self.storeToken = {
SMALLSHROOMTOKEN: False, NUTTOKEN: False, CABBAGEPULTTOKEN: False, PUMPKINTOKEN: False, CHERRYTOKEN: False,
ICESHROOMTOKEN: False, GOLDENSHEILDTOKEN: False, DETONATOR: 0, POTIONTOKEN: False,
LASERTOKEN: False, ZOMBIEBOOKTOKEN: False, MINERTOKEN: False, LAWNMOWERTOKEN: False, LARGEHOOK: False,
}
self.notRefreshToken = [
SMALLSHROOMTOKEN, NUTTOKEN, CABBAGEPULTTOKEN, PUMPKINTOKEN, CHERRYTOKEN, ICESHROOMTOKEN, MINERTOKEN,
DETONATOR,
] # 每次重开都要重置
self.fps = 30 # 注意!!不要改动这个FPS 随着游戏开发它已经不止用来管理游戏帧率的了 千万不要随意改它 否则会影响到一大堆模块
self.gameStatus = 1
self.mainBGM = [QMediaPlayer(), 0, QMediaPlayer(), 0] # 初始化BGM音轨 第二个元素为循环播放时间点(ms)
self.mainBGM[0].setVolume(100 * self.config['vol1'])
self.mainBGM[2].setVolume(100 * self.config['vol1'])
self.mainBGM[0].mediaStatusChanged.connect(self.updateMainLoop)
self.voiceForce = QMediaPlayer() # 抢占式音效音轨
self.voiceForce.setVolume(60 * self.config['vol2'])
self.voices = [QMediaPlayer() for _ in range(10)] # 非抢占式音效音轨
for voice in self.voices:
voice.setVolume(40 * self.config['vol2'])
self.voiceChomp = [[], [], [], []] # 僵尸啃食时的音效音轨
for _ in range(5):
for index, sound in enumerate([chomp1, chomp2, chompSoft, gargantuar_thump]):
self.voiceChomp[index].append(QMediaPlayer())
self.voiceChomp[index][-1].setMedia(QUrl.fromLocalFile(sound))
self.voiceChomp[index][-1].setVolume(50 * self.config['vol2']) if index in [2, 3] \
else self.voiceChomp[index][-1].setVolume(20 * self.config['vol2'])
self.voiceShoot = []
for sound in [throw1, throw2, throw_snow, puff_sound, fume, big_chomp]: # 植物射击音效
self.voiceShoot.append(QMediaPlayer())
self.voiceShoot[-1].setMedia(QUrl.fromLocalFile(sound))
self.voiceShoot[-1].setVolume(30 * self.config['vol2'])
splatList = [splat1, splat2, splat3, shieldhit1, shieldhit2, '', '', frozen, boing, butter_sound, melonimpact1,
melonimpact2, bowlingimpact1, bowlingimpact2]
self.voiceSplat = [QMediaPlayer() for _ in range(len(splatList) * 5)] # 僵尸被击中时的音效
for voice in self.voiceSplat:
voice.setVolume(20 * self.config['vol2'])
for cnt, splat in enumerate(splatList):
for i in range(5):
self.voiceSplat[5 * cnt + i].setMedia(QUrl.fromLocalFile(splat))
self.voiceCatch = [QMediaPlayer() for _ in range(4)] # 抓到物品时的音效
for voice in self.voiceCatch:
voice.setVolume(60 * self.config['vol2'])
for cnt, catch in enumerate([catch_diamond, catch_item, catch_stone, floop]):
self.voiceCatch[cnt].setMedia(QUrl.fromLocalFile(catch))
self.voiceGulp = QMediaPlayer()
self.voiceGulp.setMedia(QUrl.fromLocalFile(gulp))
self.voiceGulp.setVolume(80 * self.config['vol2'])
self.voiceExplosion = [QMediaPlayer() for _ in range(3)] # TNT爆炸音效
self.voiceCherryBomb = [QMediaPlayer() for _ in range(3)] # 樱桃炸弹
for voice in self.voiceExplosion:
voice.setMedia(QUrl.fromLocalFile(explosion_sound))
voice.setVolume(40 * self.config['vol2'])
for voice in self.voiceCherryBomb:
voice.setMedia(QUrl.fromLocalFile(cherrybomb))
voice.setVolume(80 * self.config['vol2'])
self.voiceWave = [QMediaPlayer() for _ in range(2)]
for cnt, voice in enumerate([hugeWaveSound, finalWaveSound]):
self.voiceWave[cnt].setMedia(QUrl.fromLocalFile(voice))
self.voiceWave[cnt].setVolume([60, 60][cnt] * self.config['vol2'])
self.voicePoints = [[QMediaPlayer() for _ in range(5)] for _ in range(3)]
pickVoice = [points, pickCoin, pickDiamond]
for i in range(3):
for j in range(5):
self.voicePoints[i][j].setMedia(QUrl.fromLocalFile(pickVoice[i]))
self.voicePoints[i][j].setVolume(40 * self.config['vol2'])
self.mainBGM[0].setMedia(QUrl.fromLocalFile(bgm_start)) # 开始即播放起始音乐
self.mainStack = QStackedWidget() # 初始化主界面 用stack存储切换不同场景
self.mainStack.setStyleSheet('background-color:black')
self.setCentralWidget(self.mainStack)
self.startScene = startScene(self.fps) # 将主进程音频轨道传递给页面模块调用
self.startScene.switchNextScene.connect(self.switchToMenuScene)
self.mainStack.addWidget(self.startScene) # 启动动画页面
self.loadResources = loadResources() # 异步加载资源的QThread
self.loadResources.percent.connect(self.refreshProgressBar)
self.loadResources.loadFinish.connect(self.loadResourceFinish)
self.loadResources.loadStore.connect(self.initStore)
self.loadResources.start()
self.pauseMenu = PauseMenu(self, 400, 600)
self.pauseMenu.move(300, 200)
self.pauseMenu.hide()
self.pauseMenu.vol1.setValue(self.config['vol1'] * 100)
self.pauseMenu.vol1.value.connect(self.setBGMVol)
self.pauseMenu.vol2.setValue(self.config['vol2'] * 100)
self.pauseMenu.vol2.value.connect(self.setSFXVol)
self.pauseMenu.exit.clicked.connect(self.endGame)
self.pauseMenu.restartConfirmButton.clicked.connect(self.pauseMenu.hideCheckButton)
self.pauseMenu.restartConfirmButton.clicked.connect(self.restartGame)
self.menuScene = menuScene(self.fps)
self.menuScene.startClassicSignal.connect(self.startLevel)
self.menuScene.startLevel.connect(self.startLevel)
self.menuScene.startMini.connect(self.startMini)
self.mainStack.addWidget(self.menuScene)
self.storeScene = storeScene(self, self.storeToken, self.brainMoney)
self.storeScene.nextButton.clicked.connect(self.nextLevel)
self.mainStack.addWidget(self.storeScene)
# self.mainTimer = QTimer(self) # 主进程定时器 负责管理BGM循环 响应各种事件
# self.mainTimer.setInterval(10)
# self.mainTimer.timeout.connect(self.updateMainLoop)
# self.mainTimer.start()
def setBGMVol(self, value):
self.config['vol1'] = value
self.mainBGM[0].setVolume(100 * value)
if self.stage.hugeWaveToken:
self.mainBGM[2].setVolume(100 * value)
def setSFXVol(self, value):
self.config['vol2'] = value
self.voiceForce.setVolume(60 * value)
for voice in self.voices:
voice.setVolume(40 * value)
for i in range(5):
for index, sound in enumerate([chomp1, chomp2, chompSoft, gargantuar_thump]):
self.voiceChomp[index][i].setVolume(50 * value) if index in [2, 3] \
else self.voiceChomp[index][i].setVolume(20 * value)
for i in range(6): # 植物射击音效
self.voiceShoot[i].setVolume(30 * value)
for voice in self.voiceSplat:
voice.setVolume(20 * value)
for voice in self.voiceCatch:
voice.setVolume(60 * value)
self.voiceGulp.setVolume(80 * value)
for voice in self.voiceExplosion:
voice.setVolume(40 * value)
for voice in self.voiceCherryBomb:
voice.setVolume(80 * value)
for i in range(2):
self.voiceWave[i].setVolume(60 * value)
for i in range(3):
for j in range(5):
self.voicePoints[i][j].setVolume(40 * value)
def updateMainLoop(self, status):
if status in [QMediaPlayer.MediaStatus.EndOfMedia, QMediaPlayer.MediaStatus.LoadedMedia]:
if self.gameStatus == 1: # 音乐停止播放
self.mainBGM[0].setPosition(self.mainBGM[1]) # 回到循环点
self.mainBGM[0].play() # 没有暂停的情况下 主背景音一直循环
self.mainBGM[2].setPosition(self.mainBGM[3]) # 回到循环点
self.mainBGM[2].play() # 没有暂停的情况下 主背景音一直循环
def readBGM(self, bgm):
f = QFile(bgm)
f.open(QIODevice.ReadOnly)
return f.readAll()
def initStore(self, resources):
D, keyFrame = resources['david']
self.storeScene.resources = resources
self.storeScene.david = D(self.storeScene.background, self.fps)
self.storeScene.david.move(50, 70)
self.storeScene.david.statusDict = {i: keyFrame.statusDict[i] for i in keyFrame.statusDict.keys()}
self.storeScene.david.frames = keyFrame.statusDict['frames']
self.storeScene.david.timer.start()
# self.storeScene.addCard()
def restartGame(self):
self.pauseMenu.hide()
self.stage.exitGame()
self.startLevel(*self.lastLevelArgs)
# self.loadResourceFinish(self.resources)
# self.mainBGM[0].setMedia(QUrl.fromLocalFile(bgm_start)) # 切换至准备BGM
# self.mainBGM[1] = 0 # 设置循环点
# self.mainBGM[0].play()
# self.mainBGM[2].stop() # 停止鼓点
def endGame(self):
self.stage.exitGame()
self.loadResourceFinish(self.resources)
self.mainBGM[0].setMedia(QUrl.fromLocalFile(bgm_start)) # 切换至准备BGM
self.mainBGM[1] = 0 # 设置循环点
self.mainBGM[0].play()
self.mainBGM[2].stop() # 停止鼓点
def loadResourceFinish(self, resources):
self.setTitle('黄金矿工大战僵尸')
self.resources = resources
levelInfo = list(choice(levelDict[self.level]).values())
self.levelInfo = [self.level, self.brainMoney] + levelInfo + [self.plantCards, self.roomID, self.storeToken]
self.switchToMenuScene()
# self.switchToStoreScene()
def refreshProgressBar(self, percent):
self.startScene.brand.show()
# self.startScene.brand.resize(512 * percent, 512)
self.startScene.delta = int(512 * percent) - self.startScene.newBrandWidth
self.startScene.newBrandWidth = int(512 * percent)
def switchToMenuScene(self):
self.mainStack.setCurrentIndex(1)
self.menuScene.timer.start()
def switchToGameScene(self):
self.mainStack.setCurrentIndex(3) # 切换至场景
self.stage.groundAnimation_1.start() # 播放镜头平移查看僵尸动画
def switchToStoreScene(self):
try:
self.brainMoney[0] = self.stage.brain
self.brainMoney[1] = self.stage.money
self.roomID = self.stage.roomID
self.stage.exitGame()
except Exception as e:
print(str(e))
for token in self.storeToken:
if token not in self.notRefreshToken:
self.storeToken[token] = False
self.mainBGM[0].stop()
self.mainBGM[0].setMedia(QUrl.fromLocalFile(bgm_start)) # 切换至准备BGM
self.mainBGM[1] = 0 # 设置循环点
self.mainBGM[0].play()
self.storeScene.checkCard()
self.storeScene.addCard()
self.mainStack.setCurrentIndex(2) # 切换至商店场景
def nextLevel(self):
for card in self.storeScene.cards:
card.deleteLater()
self.storeScene.cards = []
self.plantCards = [['peashooter'], ['sunflower']]
for plant in ['smallshroom', 'nut', 'cabbagepult']:
token = {'smallshroom': SMALLSHROOMTOKEN, 'nut': NUTTOKEN, 'cabbagepult': CABBAGEPULTTOKEN}[plant]
if plant not in self.plantCards[0] and self.storeToken[token]:
self.plantCards[0].append(plant)
for plant in ['pumpkin', 'cherry', 'iceshroom']:
token = {'pumpkin': PUMPKINTOKEN, 'cherry': CHERRYTOKEN, 'iceshroom': ICESHROOMTOKEN}[plant]
if plant not in self.plantCards[1] and self.storeToken[token]:
self.plantCards[1].append(plant)
self.level += 1
levelInfo = list(choice(levelDict[self.level]).values())
self.levelInfo = [self.level, self.brainMoney] + levelInfo + [self.plantCards, self.roomID, self.storeToken]
self.startLevel()
def startMini(self, levelInfo):
self.startLevel(levelInfo + [self.storeToken], enableRoom=False, forceCards=True, returnMenu=True)
def startLevel(self, levelInfo=[], enableRoom=True, forceCards=False, returnMenu=False):
self.mainBGM[0].setMedia(QUrl.fromLocalFile(bgm_prepare)) # 切换至准备BGM
self.mainBGM[1] = 3600 # 设置循环点
self.mainBGM[0].play()
if not levelInfo:
levelInfo = self.levelInfo
if levelInfo[11] == RHYTHM:
self.stage = stageRhythm(self, self.fps, levelInfo)
elif levelInfo[11] == KINGDOMRUSH1:
self.stage = stageKingdomRush(self, self.fps, levelInfo)
elif levelInfo[11] == KINGDOMRUSH2:
self.stage = stageKingdomRush2(self, self.fps, levelInfo)
else:
self.stage = stageBasic(self, self.fps, levelInfo)
self.stage.resources = self.resources
self.stage.prepareZombies()
if forceCards:
self.stage.cards = levelInfo[12]
self.stage.prepareCards()
self.mainStack.addWidget(self.stage)
self.switchToGameScene()
try:
self.pauseMenu.resumeButton.clicked.disconnect(self.stage.pauseGame)
except:
pass
self.pauseMenu.resumeButton.clicked.connect(self.stage.pauseGame) # 绑定恢复游戏功能
self.stage.giftRank.nextButton.clicked.connect(self.switchToStoreScene) # 绑定商店按钮
self.stage.giftRank.restartButton.clicked.connect(self.restartGame)
if not enableRoom:
# self.stage.roomIDEdit.setEnabled(False)
self.stage.groundAnimation_1.finished.disconnect(self.stage.roomIDLabel.show)
self.stage.groundAnimation_1.finished.disconnect(self.stage.roomIDEdit.show)
if returnMenu:
self.stage.endReturnMenu = True
self.lastLevelArgs = [levelInfo, enableRoom, forceCards, returnMenu]
def setTitle(self, title):
self.setWindowTitle(f'{title} v{self.version}')
def closeEvent(self, QCloseEvent):
with codecs.open('config', 'w', encoding='utf8', errors='ignore') as f:
f.write(json.dumps(self.config, ensure_ascii=False))
self.close()
if __name__ == '__main__':
try:
with codecs.open('config', 'r', encoding='utf8', errors='ignore') as f:
highDPI = json.loads(f.read())['highDPI']
except:
highDPI = False
parser = OptionParser()
parser.add_option('-i', '--id', default=None, help='B站直播间房号')
parser.add_option('-v', '--version', default='0.5', help='版本')
option, args = parser.parse_args()
if highDPI:
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QApplication([])
app.setStyleSheet(open(qss, 'r').read())
QFontDatabase.addApplicationFont('res/font.ttf')
app.setFont(Font())
# app.setAttribute(Qt.AA_UseDesktopOpenGL)
mainWindow = MainWindow(option)
mainWindow.show()
app.exec_()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。