diff --git a/README.md b/README.md index 931dd1c..8562281 100644 --- a/README.md +++ b/README.md @@ -73,11 +73,11 @@ python main.py ``` cmd git clone https://github.com/wszqkzqk/pypvz.git cd pypvz -nuitka --mingw --standalone --onefile --show-progress --show-memory --output-dir=out --windows-icon-from-ico=pypvz.ico --include-data-dir=resources=resources --include-data-file=C:\Users\17265\AppData\Local\Programs\Python\Python310\Lib\site-packages\pygame\libogg-0.dll=libogg-0.dll --include-data-file=C:\Users\17265\AppData\Local\Programs\Python\Python310\Lib\site-packages\pygame\libopus-0.dll=libopus-0.dll --include-data-file=C:\Users\17265\AppData\Local\Programs\Python\Python310\Lib\site-packages\pygame\libopusfile-0.dll=libopusfile-0.dll --windows-disable-console main.py + nuitka --mingw64 --standalone --onefile --show-progress --show-memory --output-dir=out --windows-icon-from-ico=pypvz.ico --include-data-dir=resources=resources --include-data-file=C:\Users\17265\AppData\Local\Programs\Python\Python310\Lib\site-packages\pygame\libogg-0.dll=libogg-0.dll --include-data-file=C:\Users\17265\AppData\Local\Programs\Python\Python310\Lib\site-packages\pygame\libopus-0.dll=libopus-0.dll --include-data-file=C:\Users\17265\AppData\Local\Programs\Python\Python310\Lib\site-packages\pygame\libopusfile-0.dll=libopusfile-0.dll --include-data-file=C:\Users\17265\AppData\Local\Programs\Python\Python310\Lib\site-packages\pygame\libvorbisfile-3.dll=libvorbisfile-3.dll --include-data-file=C:\Users\17265\AppData\Local\Programs\Python\Python310\Lib\site-packages\pygame\libvorbis-0.dll=libvorbis-0.dll --windows-disable-console main.py ``` * 其中`C:\Users\17265\AppData\Local\Programs\Python\Python310\Lib\site-packages\pygame\xxx.dll`应当替换为`xxx.dll`实际所在路径 -* 由于仅复制了`opus`的解码器,故要求所有背景音乐都要以opus编码 +* 由于仅复制了`opus`与`vorbis`的解码器,故要求所有背景音乐都要以opus或vorbis编码 可执行文件生成路径为`./out/main.exe` @@ -150,6 +150,7 @@ nuitka --mingw --standalone --onefile --show-progress --show-memory --output-dir * 吹走 * 增加部分音效 * 如爆炸、打击等 + * 自0.6.9已实现部分 ## 截屏 diff --git a/resources/sound/bigchomp.ogg b/resources/sound/bigchomp.ogg new file mode 100644 index 0000000..f9d436b Binary files /dev/null and b/resources/sound/bigchomp.ogg differ diff --git a/resources/sound/bomb.ogg b/resources/sound/bomb.ogg new file mode 100644 index 0000000..9b95445 Binary files /dev/null and b/resources/sound/bomb.ogg differ diff --git a/resources/sound/bowlingimpact.ogg b/resources/sound/bowlingimpact.ogg new file mode 100644 index 0000000..77eb5d6 Binary files /dev/null and b/resources/sound/bowlingimpact.ogg differ diff --git a/resources/sound/buttonclick.ogg b/resources/sound/buttonclick.ogg new file mode 100644 index 0000000..9ebaa90 Binary files /dev/null and b/resources/sound/buttonclick.ogg differ diff --git a/resources/sound/evillaugh.ogg b/resources/sound/evillaugh.ogg new file mode 100644 index 0000000..37b10f1 Binary files /dev/null and b/resources/sound/evillaugh.ogg differ diff --git a/resources/sound/mushroomWakeup.ogg b/resources/sound/mushroomWakeup.ogg new file mode 100644 index 0000000..7e5c368 Binary files /dev/null and b/resources/sound/mushroomWakeup.ogg differ diff --git a/resources/sound/potatomine.ogg b/resources/sound/potatomine.ogg new file mode 100644 index 0000000..d9fc4b4 Binary files /dev/null and b/resources/sound/potatomine.ogg differ diff --git a/resources/sound/scream.ogg b/resources/sound/scream.ogg new file mode 100644 index 0000000..1097567 Binary files /dev/null and b/resources/sound/scream.ogg differ diff --git a/resources/sound/squashHmm.ogg b/resources/sound/squashHmm.ogg new file mode 100644 index 0000000..5b154ca Binary files /dev/null and b/resources/sound/squashHmm.ogg differ diff --git a/resources/sound/tap.ogg b/resources/sound/tap.ogg new file mode 100644 index 0000000..77657fd Binary files /dev/null and b/resources/sound/tap.ogg differ diff --git a/source/component/plant.py b/source/component/plant.py index 90a4110..97bd92a 100755 --- a/source/component/plant.py +++ b/source/component/plant.py @@ -1,5 +1,6 @@ import random import pygame as pg +import os from .. import tool from .. import constants as c @@ -31,7 +32,7 @@ class Car(pg.sprite.Sprite): if self.state == c.IDLE: self.state = c.WALK # 播放音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "carWalking.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "carWalking.ogg")).play() def draw(self, surface): surface.blit(self.image, self.rect) @@ -112,9 +113,9 @@ class Bullet(pg.sprite.Sprite): # 播放子弹爆炸音效 if self.name == c.BULLET_FIREBALL: - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "firepea.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "firepea.ogg")).play() else: - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "bulletExplode.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "bulletExplode.ogg")).play() def draw(self, surface): surface.blit(self.image, self.rect) @@ -501,6 +502,8 @@ class CherryBomb(Plant): self.bomb_timer = self.current_time elif (self.current_time - self.bomb_timer) > 500: self.health = 0 + # 播放爆炸音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "bomb.ogg")).play() else: if (self.current_time - self.animate_timer) > 100: self.frame_index += 1 @@ -564,6 +567,8 @@ class Chomper(Plant): def attacking(self): if self.frame_index == (self.frame_num - 3): + # 播放吞的音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "bigchomp.ogg")).play() self.zombie_group.remove(self.attack_zombie) if (self.frame_index + 1) == self.frame_num: self.setDigest() @@ -658,6 +663,8 @@ class PotatoMine(Plant): self.changeFrames(self.explode_frames) elif (self.current_time - self.bomb_timer) > 500: self.health = 0 + # 播放音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "potatomine.ogg")).play() class Squash(Plant): @@ -709,6 +716,8 @@ class Squash(Plant): self.state = c.ATTACK # 攻击状态下生命值无敌 self.health = float('inf') + # 锁定目标时播放音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "squashHmm.ogg")).play() def attacking(self): if self.squashing: @@ -792,6 +801,8 @@ class Jalapeno(Plant): self.frame_index += 1 if self.frame_index >= self.frame_num: self.health = 0 + # 播放爆炸音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "bomb.ogg")).play() return self.animate_timer = self.current_time else: @@ -1110,6 +1121,8 @@ class RedWallNutBowling(Plant): self.changeFrames(self.explode_frames) elif (self.current_time - self.explode_timer) > 500: self.health = 0 + # 播放爆炸音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "bomb.ogg")).play() def animation(self): if (self.current_time - self.animate_timer) > self.animate_interval: @@ -1197,6 +1210,8 @@ class CoffeeBean(Plant): plant.state = c.IDLE plant.setIdle() plant.changeFrames(plant.idle_frames) + # 播放唤醒音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "mushroomWakeup.ogg")).play() self.mapContent[c.MAP_PLANT].remove(self.name) self.kill() diff --git a/source/component/zombie.py b/source/component/zombie.py index 85ea948..85bad44 100755 --- a/source/component/zombie.py +++ b/source/component/zombie.py @@ -1,4 +1,5 @@ import pygame as pg +import os from random import randint from .. import tool from .. import constants as c @@ -279,7 +280,7 @@ class Zombie(pg.sprite.Sprite): def setIceSlow(self): # 在转入冰冻减速状态时播放冰冻音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "freeze.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "freeze.ogg")).play() # when get a ice bullet damage, slow the attack or walk speed of the zombie self.ice_slow_timer = self.current_time @@ -420,7 +421,7 @@ class Zombie(pg.sprite.Sprite): self.changeFrames(self.attack_frames) # 播放啃咬音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "zombieAttack.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "zombieAttack.ogg")).play() def setDie(self): self.state = c.DIE diff --git a/source/state/level.py b/source/state/level.py index 9314563..54d9be8 100644 --- a/source/state/level.py +++ b/source/state/level.py @@ -73,10 +73,6 @@ class Level(tool.State): elif self.map_data[c.BACKGROUND_TYPE] in {c.BACKGROUND_POOL}: self.bgm = 'poolLevel.opus' - pg.mixer.music.stop() - pg.mixer.music.load(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "music", self.bgm)) - pg.mixer.music.play(-1, 0) - def setupBackground(self): img_index = self.map_data[c.BACKGROUND_TYPE] self.background_type = img_index @@ -195,7 +191,7 @@ class Level(tool.State): self.numZombie = len(self.waveZombies) # 第一波刚刚刷出来的时候播放音效 if self.waveNum == 1: - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "zombieComing.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "zombieComing.ogg")).play() return else: if ((current_time - self.waveTime >= 45000) or (self.bar_type != c.CHOOSEBAR_STATIC and current_time - self.waveTime >= 25000)): @@ -204,7 +200,7 @@ class Level(tool.State): self.waveZombies = self.waves[self.waveNum - 1] self.numZombie = len(self.waveZombies) # 一大波时播放音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "hugeWaveApproching.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "hugeWaveApproching.ogg")).play() return elif ((current_time - self.waveTime >= 43000) or (self.bar_type != c.CHOOSEBAR_STATIC and current_time - self.waveTime >= 23000)): self.showHugeWaveApprochingTime = current_time @@ -282,13 +278,26 @@ class Level(tool.State): self.state = c.CHOOSE self.panel = menubar.Panel(menubar.cards_to_choose, self.map_data[c.INIT_SUN_NAME]) + # 播放选卡音乐 + pg.mixer.music.stop() + pg.mixer.music.load(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "music", "chooseYourSeeds.opus")) + pg.mixer.music.play(-1, 0) + def choose(self, mouse_pos, mouse_click): if mouse_pos and mouse_click[0]: self.panel.checkCardClick(mouse_pos) if self.panel.checkStartButtonClick(mouse_pos): self.initPlay(self.panel.getSelectedCards()) + # 播放点击音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "tap.ogg")).play() def initPlay(self, card_list): + + # 播放bgm + pg.mixer.music.stop() + pg.mixer.music.load(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "music", self.bgm)) + pg.mixer.music.play(-1, 0) + self.state = c.PLAY if self.bar_type == c.CHOOSEBAR_STATIC: self.menubar = menubar.MenuBar(card_list, self.map_data[c.INIT_SUN_NAME]) @@ -521,12 +530,16 @@ class Level(tool.State): self.showLittleMenu = False # 继续播放音乐 pg.mixer.music.unpause() + # 播放点击音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "buttonclick.ogg")).play() elif self.checkRestartClick(mouse_pos): self.done = True self.next = c.LEVEL pg.mixer.music.stop() pg.mixer.music.load(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "music", self.bgm)) pg.mixer.music.play(-1, 0) + # 播放点击音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "buttonclick.ogg")).play() elif self.checkMainMenuClick(mouse_pos): self.done = True self.next = c.MAIN_MENU @@ -535,6 +548,8 @@ class Level(tool.State): pg.mixer.music.stop() pg.mixer.music.load(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "music", "intro.opus")) pg.mixer.music.play(-1, 0) + # 播放点击音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "buttonclick.ogg")).play() return if (c.ZOMBIE_LIST in self.map_data.keys()) and self.map_data[c.SPAWN_ZOMBIES] == c.SPAWN_ZOMBIES_LIST: @@ -592,7 +607,7 @@ class Level(tool.State): self.menubar.increaseSunValue(sun.sun_value) clickedSun = True # 播放收集阳光的音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "collectSun.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "collectSun.ogg")).play() # 拖动植物或者铲子 if not self.drag_plant and mouse_pos and mouse_click[0] and not clickedSun: @@ -601,7 +616,7 @@ class Level(tool.State): self.setupMouseImage(result[0], result[1]) clickedCardsOrMap = True # 播放音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "clickCard.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "clickCard.ogg")).play() elif self.drag_plant: if mouse_click[1]: self.removeMouseImage() @@ -622,12 +637,14 @@ class Level(tool.State): if self.checkLittleMenuClick(mouse_pos): # 暂停 显示菜单 self.showLittleMenu = True + # 播放点击音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "buttonclick.ogg")).play() elif self.checkShovelClick(mouse_pos): self.drag_shovel = not self.drag_shovel if not self.drag_shovel: self.removeMouseImagePlus() # 播放点击铲子的音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "shovel.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "shovel.ogg")).play() elif self.drag_shovel: # 移出这地方的植物 self.shovelRemovePlant(mouse_pos) @@ -786,7 +803,7 @@ class Level(tool.State): self.removeMouseImage() # 播放种植音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "plant.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "plant.ogg")).play() def setupHintImage(self): pos = self.canSeedPlant(self.plant_name) @@ -889,6 +906,8 @@ class Level(tool.State): # 注意:以上语句为通用处理,以后加入了铁门僵尸需要单独设置直接冲撞就直接杀死 # 可以给坚果保龄球设置attacked属性,如果attacked就秒杀(setDamage的攻击类型此时设置为COMMMON)铁门 plant.changeDirection(i) + # 播放撞击音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "bowlingimpact.ogg")).play() elif plant.name == c.REDWALLNUTBOWLING: if plant.state == c.IDLE: plant.setAttack() @@ -952,7 +971,7 @@ class Level(tool.State): def freezeZombies(self, plant): # 播放冻结音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "freeze.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "freeze.ogg")).play() for i in range(self.map_y_len): for zombie in self.zombie_groups[i]: @@ -997,7 +1016,7 @@ class Level(tool.State): zombie.setDamage(1800, damageType=c.ZOMBIE_RANGE_DAMAGE) else: # 用铲子移除植物时播放音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "plant.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "plant.ogg")).play() # 避免僵尸在用铲子移除植物后还在原位啃食 plant.health = 0 @@ -1131,12 +1150,13 @@ class Level(tool.State): self.next = c.GAME_VICTORY self.done = True # 播放胜利音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "win.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "win.ogg")).play() elif self.checkLose(): self.next = c.GAME_LOSE self.done = True # 播放失败音效 - pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "lose.ogg")) + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "lose.ogg")).play() + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "scream.ogg")).play() def drawMouseShow(self, surface): if self.hint_plant: diff --git a/source/state/mainmenu.py b/source/state/mainmenu.py index 99c6fe9..7a2cb88 100644 --- a/source/state/mainmenu.py +++ b/source/state/mainmenu.py @@ -1,4 +1,5 @@ import pygame as pg +import os from .. import tool from .. import constants as c from . import level @@ -108,6 +109,9 @@ class Menu(tool.State): self.adventure_clicked = True self.adventure_timer = self.adventure_start = self.current_time self.persist[c.GAME_MODE] = c.MODE_ADVENTURE + # 播放进入音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "evillaugh.ogg")).play() + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "lose.ogg")).play() return False # 点击到按钮,修改转态的done属性 @@ -125,6 +129,8 @@ class Menu(tool.State): # 确实小游戏还是用的level # 因为目前暂时没有生存模式和解谜模式,所以暂时设置为这样 self.persist[c.GAME_MODE] = c.MODE_LITTLEGAME + # 播放点击音效 + pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "buttonclick.ogg")).play() def update(self, surface, current_time, mouse_pos, mouse_click): self.current_time = self.game_info[c.CURRENT_TIME] = current_time