diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a1507a5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +.qtcreator/ \ No newline at end of file diff --git a/Grazy Dave.wav b/Grazy Dave.wav new file mode 100644 index 0000000..9c6b2bf Binary files /dev/null and b/Grazy Dave.wav differ diff --git a/PVZ.pro b/PVZ.pro index 6156ae7..ae01968 100644 --- a/PVZ.pro +++ b/PVZ.pro @@ -26,7 +26,10 @@ CONFIG += c++11 SOURCES += \ main.cpp \ + sound.cpp \ sunflower.cpp \ + threepeater.cpp \ + utils.cpp \ zombie.cpp \ plant.cpp \ wallnut.cpp \ @@ -52,7 +55,10 @@ SOURCES += \ screenzombie.cpp HEADERS += \ + sound.h \ sunflower.h \ + threepeater.h \ + utils.h \ zombie.h \ plant.h \ wallnut.h \ @@ -88,3 +94,6 @@ RESOURCES += \ RC_ICONS += \ PVZ.ico + +DISTFILES += \ + Grazy Dave.mp3 diff --git a/PVZ.pro.user b/PVZ.pro.user index 66b1fb6..de513c6 100644 --- a/PVZ.pro.user +++ b/PVZ.pro.user @@ -1,20 +1,20 @@ - + EnvironmentId - {503846c8-0b0d-4554-84a9-73a1fb985722} + {0cb542d5-0db5-4958-9618-d7fb4952c045} ProjectExplorer.Project.ActiveTarget - 0 + 0 ProjectExplorer.Project.EditorSettings + true true - false true Cpp @@ -28,552 +28,323 @@ QmlJSGlobal - 2 + 2 UTF-8 false 4 false + 0 80 true true 1 + 0 + false true false - 0 + 2 true true 0 8 true + false 1 true true true + *.md, *.MD, Makefile false + true + true ProjectExplorer.Project.PluginSettings - - -fno-delayed-template-parsing - - true + + true + false + true + true + true + true + + false + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 8 + true + + + + true + + 0 ProjectExplorer.Project.Target.0 - Desktop Qt 5.12.2 MinGW 32-bit - Desktop Qt 5.12.2 MinGW 32-bit - qt.qt5.5122.win32_mingw73_kit - 1 - 0 - 0 + Desktop + true + Desktop Qt 5.15.0 MinGW 64-bit + Desktop Qt 5.15.0 MinGW 64-bit + qt.qt5.5150.win64_mingw81_kit + 0 + 0 + 0 - C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_32_bit-Debug + 0 + C:\Users\Rdemi\Desktop\C++PRO\PVZ-master\build\Desktop_Qt_5_15_0_MinGW_64_bit-Debug + C:/Users/Rdemi/Desktop/C++PRO/PVZ-master/build/Desktop_Qt_5_15_0_MinGW_64_bit-Debug true - qmake - QtProjectManager.QMakeBuildStep - true - false - false - false + true - Make - Qt4ProjectManager.MakeStep - - false - - - false - 2 + 2 Build - + Build ProjectExplorer.BuildSteps.Build true - Make - Qt4ProjectManager.MakeStep - - true clean - - false - 1 + 1 Clean - + Clean ProjectExplorer.BuildSteps.Clean 2 false + + false - Debug Debug Qt4ProjectManager.Qt4BuildConfiguration - 2 - true - - - C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_32_bit-Release - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - - false - false - true - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - false + 0 + 0 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy - 2 - Build - - ProjectExplorer.BuildSteps.Build + 1 + + false + ProjectExplorer.DefaultDeployConfiguration - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean + 1 + + true + true + 0 + true + + + 2 + + false + -e cpu-cycles --call-graph "dwarf,4096" -F 250 - ProjectExplorer.BuildSteps.Clean + Qt4ProjectManager.Qt4RunConfiguration: + C:/Users/Rdemi/Desktop/C++PRO/PVZ-master/PVZ.pro + false + + true + true + true + %{RunConfig:Executable:Path} - 2 - false - - Release - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - - C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_32_bit-Profile - - - true - qmake - - QtProjectManager.QMakeBuildStep - true - - false - true - true - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Build - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Profile - Profile - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true + 1 + 2 - 3 + 1 - 0 - 部署 - + 0 + Deploy + Deploy ProjectExplorer.BuildSteps.Deploy 1 - Deploy Configuration - + + false ProjectExplorer.DefaultDeployConfiguration - 1 - + 1 - false - false - 1000 - + true true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 + 0 true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - + + 2 - PVZ + false + -e cpu-cycles --call-graph "dwarf,4096" -F 250 - Qt4ProjectManager.Qt4RunConfiguration:C:/Users/33400/Documents/Qt/PVZ/PVZ.pro - PVZ.pro - - 3768 - false + Qt4ProjectManager.Qt4RunConfiguration: + C:/Users/Rdemi/Desktop/C++PRO/PVZ-master/PVZ.pro + false + true true - false - false true - - C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_32_bit-Release + %{RunConfig:Executable:Path} - 1 + 1 ProjectExplorer.Project.Target.1 - Desktop Qt 5.12.2 MinGW 64-bit - Desktop Qt 5.12.2 MinGW 64-bit - qt.qt5.5122.win64_mingw73_kit - 0 - 0 - 0 + Desktop + true + Desktop Qt 5.15.1 MinGW 64-bit + Desktop Qt 5.15.1 MinGW 64-bit + qt.qt5.5151.win64_mingw81_kit + 0 + 0 + 0 - C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_64_bit-Debug + 0 + C:\Users\Rdemi\Desktop\C++PRO\PVZ-master\build\Desktop_Qt_5_15_1_MinGW_64_bit-Debug + C:/Users/Rdemi/Desktop/C++PRO/PVZ-master/build/Desktop_Qt_5_15_1_MinGW_64_bit-Debug true - qmake - QtProjectManager.QMakeBuildStep - true - false - false - false + true - Make - Qt4ProjectManager.MakeStep - - false - - - false - 2 + 2 Build - + Build ProjectExplorer.BuildSteps.Build true - Make - Qt4ProjectManager.MakeStep - - true clean - - false - 1 + 1 Clean - + Clean ProjectExplorer.BuildSteps.Clean 2 false + + false - Debug Debug Qt4ProjectManager.Qt4BuildConfiguration - 2 - true - - - C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_64_bit-Release - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - - false - false - true - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Build - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - - C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_64_bit-Profile - - - true - qmake - - QtProjectManager.QMakeBuildStep - true - - false - true - true - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - false + 0 + 0 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy - 2 - Build - - ProjectExplorer.BuildSteps.Build + 1 + + false + ProjectExplorer.DefaultDeployConfiguration - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean + 1 + + true + true + 0 + true + + + 2 + + false + -e cpu-cycles --call-graph "dwarf,4096" -F 250 - ProjectExplorer.BuildSteps.Clean + Qt4ProjectManager.Qt4RunConfiguration: + C:/Users/Rdemi/Desktop/C++PRO/PVZ-master/PVZ.pro + false + true + true + true + C:/Users/Rdemi/Desktop/C++PRO/PVZ-master/build/Desktop_Qt_5_15_1_MinGW_64_bit-Debug - 2 - false - - Profile - Profile - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true + 1 + 2 - 3 + 1 - 0 - 部署 - + 0 + Deploy + Deploy ProjectExplorer.BuildSteps.Deploy 1 - Deploy Configuration - + + false ProjectExplorer.DefaultDeployConfiguration - 1 - + 1 - false - false - 1000 - + true true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 + 0 true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - + + 2 - - Custom Executable + false + -e cpu-cycles --call-graph "dwarf,4096" -F 250 - ProjectExplorer.CustomExecutableRunConfiguration - - 3768 - false + Qt4ProjectManager.Qt4RunConfiguration: + C:/Users/Rdemi/Desktop/C++PRO/PVZ-master/PVZ.pro + false true - false - false + true true - - + C:/Users/Rdemi/Desktop/C++PRO/PVZ-master/build/Desktop_Qt_5_15_1_MinGW_64_bit-Debug - 1 + 1 ProjectExplorer.Project.TargetCount - 2 - - - ProjectExplorer.Project.Updater.FileVersion - 20 + 2 Version - 20 + 22 diff --git a/PVZ.pro.user.503846c.4.9-pre1 b/PVZ.pro.user.503846c.4.9-pre1 new file mode 100644 index 0000000..66b1fb6 --- /dev/null +++ b/PVZ.pro.user.503846c.4.9-pre1 @@ -0,0 +1,579 @@ + + + + + + EnvironmentId + {503846c8-0b0d-4554-84a9-73a1fb985722} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.12.2 MinGW 32-bit + Desktop Qt 5.12.2 MinGW 32-bit + qt.qt5.5122.win32_mingw73_kit + 1 + 0 + 0 + + C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_32_bit-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_32_bit-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_32_bit-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + 部署 + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy Configuration + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + PVZ + + Qt4ProjectManager.Qt4RunConfiguration:C:/Users/33400/Documents/Qt/PVZ/PVZ.pro + PVZ.pro + + 3768 + false + true + true + false + false + true + + C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_32_bit-Release + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.12.2 MinGW 64-bit + Desktop Qt 5.12.2 MinGW 64-bit + qt.qt5.5122.win64_mingw73_kit + 0 + 0 + 0 + + C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_64_bit-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_64_bit-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + C:/Users/33400/Documents/Qt/build-PVZ-Desktop_Qt_5_12_2_MinGW_64_bit-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + 部署 + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy Configuration + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + Custom Executable + + ProjectExplorer.CustomExecutableRunConfiguration + + 3768 + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 20 + + + Version + 20 + + diff --git a/README.md b/README.md index d8a9d88..fc5c5f8 100644 --- a/README.md +++ b/README.md @@ -431,3 +431,4 @@ void Button::mousePressEvent(QGraphicsSceneMouseEvent *event) 2. 在不支持可视化编程的框架下如何高效开发? 必须对`Qt`有较深入了解,并且对每个物体的坐标心中有数,反复调试。 + diff --git a/audios/bomb.wav b/audios/bomb.wav new file mode 100644 index 0000000..df8ea3e Binary files /dev/null and b/audios/bomb.wav differ diff --git a/audios/bucket.wav b/audios/bucket.wav new file mode 100644 index 0000000..9778a47 Binary files /dev/null and b/audios/bucket.wav differ diff --git a/audios/car.wav b/audios/car.wav new file mode 100644 index 0000000..6d8f03f Binary files /dev/null and b/audios/car.wav differ diff --git a/audios/sunclick.wav b/audios/sunclick.wav new file mode 100644 index 0000000..840e4a3 Binary files /dev/null and b/audios/sunclick.wav differ diff --git a/basiczombie.cpp b/basiczombie.cpp index c8d1736..0eab57a 100644 --- a/basiczombie.cpp +++ b/basiczombie.cpp @@ -2,13 +2,19 @@ BasicZombie::BasicZombie() { + hp = 270; atk = 100 * 33 / 1000; speed = 80.0 * 33 / 1000 / 4.7; + state=Zombie::move; + + zomImg[attack]=":/images/ZombieAttack.gif"; if (qrand() % 2) - setMovie(":/images/ZombieWalk1.gif"); + zomImg[state]=":/images/ZombieWalk1.gif"; else - setMovie(":/images/ZombieWalk2.gif"); + zomImg[state]=":/images/ZombieWalk2.gif"; + + setMovie(zomImg[state]); } void BasicZombie::advance(int phase) @@ -18,9 +24,9 @@ void BasicZombie::advance(int phase) update(); if (hp <= 0) { - if (state < 2) + if (state!=Zombie::die) { - state = 2; + state = Zombie::die; setMovie(":/images/ZombieDie.gif"); setHead(":/images/ZombieHead.gif"); } @@ -33,20 +39,17 @@ void BasicZombie::advance(int phase) { Plant *plant = qgraphicsitem_cast(items[0]); plant->hp -= atk; - if (state != 1) + if (state != Zombie::attack) { - state = 1; - setMovie(":/images/ZombieAttack.gif"); + state = Zombie::attack; + setMovie(zomImg[state]); } return; } - if (state) + if (state!=Zombie::move) { - state = 0; - if (qrand() % 2) - setMovie(":/images/ZombieWalk1.gif"); - else - setMovie(":/images/ZombieWalk2.gif"); + state = Zombie::move; + setMovie(zomImg[state]); } setX(x() - speed); } diff --git a/basiczombie.h b/basiczombie.h index db69b4b..b45138a 100644 --- a/basiczombie.h +++ b/basiczombie.h @@ -7,6 +7,7 @@ class BasicZombie : public Zombie { public: + const static int blood=270; BasicZombie(); void advance(int phase) override; }; diff --git a/bucketzombie.cpp b/bucketzombie.cpp index e63bbcc..1ce3ccf 100644 --- a/bucketzombie.cpp +++ b/bucketzombie.cpp @@ -5,7 +5,11 @@ BucketZombie::BucketZombie() hp = 1370; atk = 100 * 33 / 1000; speed = 80.0 * 33 / 1000 / 4.7; - setMovie(":/images/BucketZombieWalk.gif"); + state=Zombie::move; + zomImg[move]=":/images/BucketZombieWalk.gif"; + zomImg[attack]=":/images/BucketZombieAttack.gif"; + name="bucket"; + setMovie(zomImg[move]); } void BucketZombie::advance(int phase) @@ -15,9 +19,9 @@ void BucketZombie::advance(int phase) update(); if (hp <= 0) { - if (state < 2) + if (state!=Zombie::die) { - state = 2; + state=Zombie::die; setMovie(":/images/ZombieDie.gif"); setHead(":/images/ZombieHead.gif"); } @@ -25,22 +29,28 @@ void BucketZombie::advance(int phase) delete this; return; } + //变成普通僵尸 + if(hp<=BasicZombie::blood){ + Utils::turnNormalZoombie(this); + } + QList items = collidingItems(); if (!items.isEmpty()) { Plant *plant = qgraphicsitem_cast(items[0]); plant->hp -= atk; - if (state != 1) + if (state!=Zombie::attack) { - state = 1; - setMovie(":/images/BucketZombieAttack.gif"); + state=Zombie::attack; + setMovie(zomImg[state]); + } return; } - if (state) + if (state!=Zombie::move) { - state = 0; - setMovie(":/images/BucketZombieWalk.gif"); + state = Zombie::move; + setMovie(zomImg[state]); } setX(x() - speed); } diff --git a/bucketzombie.h b/bucketzombie.h index f65a917..1367c88 100644 --- a/bucketzombie.h +++ b/bucketzombie.h @@ -3,12 +3,18 @@ #include "zombie.h" #include "plant.h" - +#include "basiczombie.h" +#include "utils.h" +#include class BucketZombie : public Zombie { public: BucketZombie(); void advance(int phase) override; + +; + + }; #endif // BUCKETZOMBIE_H diff --git a/cherrybomb.cpp b/cherrybomb.cpp index 50e5bb6..978d47a 100644 --- a/cherrybomb.cpp +++ b/cherrybomb.cpp @@ -4,7 +4,9 @@ CherryBomb::CherryBomb() { atk = 1800; hp = 300; + setMovie(":/images/CherryBomb.gif"); + sound=new Sound(":/audios/bomb.wav"); } QRectF CherryBomb::boundingRect() const @@ -17,12 +19,15 @@ void CherryBomb::advance(int phase) if (!phase) return; update(); + if (hp <= 0) delete this; else if (state == 0 && movie->currentFrameNumber() == movie->frameCount() - 1) { state = 1; + setMovie(":/images/Boom.gif"); + sound->playOnlyOne(); QList items = collidingItems(); foreach (QGraphicsItem *item, items) { diff --git a/cherrybomb.h b/cherrybomb.h index b947e0c..71d8ca8 100644 --- a/cherrybomb.h +++ b/cherrybomb.h @@ -3,7 +3,8 @@ #include "plant.h" #include "zombie.h" - +#include +#include "sound.h" class CherryBomb : public Plant { public: diff --git a/conezombie.cpp b/conezombie.cpp index 6ca8638..1ec5c4b 100644 --- a/conezombie.cpp +++ b/conezombie.cpp @@ -1,10 +1,15 @@ #include "conezombie.h" +#include "utils.h" + ConeZombie::ConeZombie() { hp = 640; atk = 100 * 33 / 1000; speed = 80.0 * 33 / 1000 / 4.7; + + zomImg[move]=":/images/ConeZombieWalk.gif"; + zomImg[attack]=":/images/ConeZombieAttack.gif"; setMovie(":/images/ConeZombieWalk.gif"); } @@ -15,9 +20,9 @@ void ConeZombie::advance(int phase) update(); if (hp <= 0) { - if (state < 2) + if (state!=die) { - state = 2; + state = die; setMovie(":/images/ZombieDie.gif"); setHead(":/images/ZombieHead.gif"); } @@ -25,22 +30,29 @@ void ConeZombie::advance(int phase) delete this; return; } + + if(hp<=BasicZombie::blood){ + Utils::turnNormalZoombie(this); + } + + + QList items = collidingItems(); if (!items.isEmpty()) { Plant *plant = qgraphicsitem_cast(items[0]); plant->hp -= atk; - if (state != 1) + if (state != attack) { - state = 1; - setMovie(":/images/ConeZombieAttack.gif"); + state = attack; + setMovie(zomImg[attack]); } return; } - if (state) + if (state!=move) { - state = 0; - setMovie(":/images/ConeZombieWalk.gif"); + state = move; + setMovie(zomImg[move]); } setX(x() - speed); } diff --git a/conezombie.h b/conezombie.h index b2db361..2e17ef7 100644 --- a/conezombie.h +++ b/conezombie.h @@ -3,7 +3,7 @@ #include "zombie.h" #include "plant.h" - +#include "basiczombie.h" class ConeZombie : public Zombie { public: diff --git a/footballzombie.cpp b/footballzombie.cpp index 9b2efa9..76f2619 100644 --- a/footballzombie.cpp +++ b/footballzombie.cpp @@ -1,10 +1,17 @@ #include "footballzombie.h" +#include "utils.h" + FootballZombie::FootballZombie() { hp = 1670; atk = 100 * 33 / 1000; speed = 80.0 * 33 / 1000 / 2.5; + + + zomImg[move]=":/images/FootballZombieWalk.gif"; + zomImg[attack]=":/images/FootballZombieAttack.gif"; + zomImg[die]=":/images/FootballZombieDie.gif"; setMovie(":/images/FootballZombieWalk.gif"); } @@ -15,10 +22,10 @@ void FootballZombie::advance(int phase) update(); if (hp <= 0) { - if (state < 2) + if (state !=die) { - state = 2; - setMovie(":/images/FootballZombieDie.gif"); + state = die; + setMovie(zomImg[die]); setHead(":/images/ZombieHead.gif"); } @@ -26,22 +33,27 @@ void FootballZombie::advance(int phase) delete this; return; } + + if(hp<=BasicZombie::blood){ + Utils::turnNormalZoombie(this); + } + QList items = collidingItems(); if (!items.isEmpty()) { Plant *plant = qgraphicsitem_cast(items[0]); plant->hp -= atk; - if (state != 1) + if (state !=attack) { - state = 1; - setMovie(":/images/FootballZombieAttack.gif"); + state = attack; + setMovie(zomImg[state]); } return; } - if (state) + if (state!=move) { - state = 0; - setMovie(":/images/FootballZombieWalk.gif"); + state = move; + setMovie(zomImg[state]); } setX(x() - speed); } diff --git a/footballzombie.h b/footballzombie.h index 7ea2204..0a663be 100644 --- a/footballzombie.h +++ b/footballzombie.h @@ -3,7 +3,7 @@ #include "zombie.h" #include "plant.h" - +#include "basiczombie.h" class FootballZombie : public Zombie { public: diff --git a/images.qrc b/images.qrc index 217c8e3..d00b201 100644 --- a/images.qrc +++ b/images.qrc @@ -45,5 +45,10 @@ images/ScreenZombieAttack.gif images/ScreenZombieWalk.gif images/ZombiesWon.png + images/Threepeater.gif + audios/bomb.wav + audios/bucket.wav + audios/car.wav + audios/sunclick.wav diff --git a/images/Threepeater.gif b/images/Threepeater.gif new file mode 100644 index 0000000..97398e4 Binary files /dev/null and b/images/Threepeater.gif differ diff --git a/main.cpp b/main.cpp index d2644b6..6de3e74 100644 --- a/main.cpp +++ b/main.cpp @@ -8,5 +8,6 @@ int main(int argc, char *argv[]) w.setFixedSize(900, 600); w.setWindowTitle("植物大战僵尸"); w.show(); + return a.exec(); } diff --git a/mainwindow.cpp b/mainwindow.cpp index 41891ad..a3486bc 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,5 +1,13 @@ #include "mainwindow.h" - +/** + * @brief MainWindow::MainWindow + * @param parent + * 窗口大小:900*600 + * scene大小:900*600(不带边框) + * view大小:902*602 + * view大小超过窗口大小会被裁剪 + * + */ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { qsrand(uint(QTime(0,0,0).secsTo(QTime::currentTime()))); diff --git a/map.h b/map.h index bdaf765..2f66545 100644 --- a/map.h +++ b/map.h @@ -7,6 +7,13 @@ #include "shovel.h" #include +/** + * @brief The Map class + * 用来处理一些拖拉事件的类 + * 可以拖放植物以及铲子 + */ + + class Map : public Other { public: @@ -15,6 +22,7 @@ class Map : public Other void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void dragEnterEvent(QGraphicsSceneDragDropEvent *event) override; void dragLeaveEvent(QGraphicsSceneDragDropEvent *event) override; + void dropEvent(QGraphicsSceneDragDropEvent *event) override; private: bool dragOver; diff --git a/mower.cpp b/mower.cpp index fc250c3..e07a527 100644 --- a/mower.cpp +++ b/mower.cpp @@ -1,9 +1,10 @@ #include "mower.h" - +#include "utils.h" Mower::Mower() { flag = false; speed = 270.0 * 33 / 1000; + sound=new Sound(":/audios/car.wav"); } QRectF Mower::boundingRect() const @@ -29,9 +30,11 @@ void Mower::advance(int phase) if (!phase) return; update(); + QList items = collidingItems(); if (!items.empty()) { + if(sound!=nullptr) sound->playOnlyOne(); flag = true; foreach (QGraphicsItem *item, items) { diff --git a/other.cpp b/other.cpp index 3aadadf..8295f61 100644 --- a/other.cpp +++ b/other.cpp @@ -1,6 +1,11 @@ #include "other.h" Other::Other() +{ + sound=nullptr; +} + +Other::~Other() { } @@ -9,3 +14,4 @@ int Other::type() const { return Type; } + diff --git a/other.h b/other.h index 616b4b3..c78b4a9 100644 --- a/other.h +++ b/other.h @@ -4,13 +4,18 @@ #include #include #include - +#include +#include "sound.h" class Other : public QGraphicsItem { public: enum { Type = UserType + 3}; + Sound *sound;//音频 + Other(); + ~Other(); int type() const override; + }; #endif // OTHER_H diff --git a/pea.cpp b/pea.cpp index 480b3da..9e58cc7 100644 --- a/pea.cpp +++ b/pea.cpp @@ -6,6 +6,7 @@ Pea::Pea(int attack, bool flag) snow = flag; atk = attack; speed = 360.0 * 33 / 1000; + } QRectF Pea::boundingRect() const @@ -23,7 +24,7 @@ void Pea::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidg bool Pea::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const { Q_UNUSED(mode) - return other->type() == Zombie::Type && qFuzzyCompare(other->y(), y()) && qAbs(other->x() - x()) < 15; + return other->type() == Zombie::Type && qAbs(other->y()-y())<10 && qAbs(other->x() - x()) < 15; } void Pea::advance(int phase) @@ -38,6 +39,11 @@ void Pea::advance(int phase) zombie->hp -= atk; if (snow && zombie->speed > 0.55) zombie->speed /= 2; + if(zombie->name=="bucket"&&zombie->stage!=Zombie::droped){ + Sound *s=new Sound(":/audios/bucket.wav"); + s->playOnlyOne(); + + } delete this; return; } diff --git a/plant.cpp b/plant.cpp index 9fdd981..929c548 100644 --- a/plant.cpp +++ b/plant.cpp @@ -4,11 +4,13 @@ Plant::Plant() { movie = nullptr; + sound = nullptr; atk = counter = state = time = 0; } Plant::~Plant() { + delete movie; } @@ -42,3 +44,5 @@ void Plant::setMovie(QString path) movie = new QMovie(path); movie->start(); } + + diff --git a/plant.h b/plant.h index 7a545f8..3849121 100644 --- a/plant.h +++ b/plant.h @@ -5,12 +5,14 @@ #include #include #include - +#include +#include "sound.h" class Plant : public QGraphicsItem { public: - int hp; - int state; + int hp;//血量 + int state;//状态量 + Sound *sound;//音频 enum { Type = UserType + 1}; Plant(); ~Plant() override; @@ -19,11 +21,12 @@ class Plant : public QGraphicsItem bool collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const override; int type() const override; void setMovie(QString path); + protected: - QMovie *movie; - int atk; - int counter; - int time; + QMovie *movie;//帧片段 + int atk;//技能攻击力 + int counter;//定时器 + int time;//冷却时间 }; #endif // PLANT_H diff --git a/screenzombie.cpp b/screenzombie.cpp index 35d6b23..82da298 100644 --- a/screenzombie.cpp +++ b/screenzombie.cpp @@ -1,10 +1,14 @@ #include "screenzombie.h" +#include "utils.h" + ScreenZombie::ScreenZombie() { hp = 1370; atk = 100 * 33 / 1000; speed = 80.0 * 33 / 1000 / 4.7; + zomImg[move]=":/images/ScreenZombieWalk.gif"; + zomImg[attack]=":/images/ScreenZombieAttack.gif"; setMovie(":/images/ScreenZombieWalk.gif"); } @@ -15,9 +19,9 @@ void ScreenZombie::advance(int phase) update(); if (hp <= 0) { - if (state < 2) + if (state !=die) { - state = 2; + state = die; setMovie(":/images/ZombieDie.gif"); setHead(":/images/ZombieHead.gif"); } @@ -25,22 +29,27 @@ void ScreenZombie::advance(int phase) delete this; return; } + + if(hp<=BasicZombie::blood){ + Utils::turnNormalZoombie(this); + } + QList items = collidingItems(); if (!items.isEmpty()) { Plant *plant = qgraphicsitem_cast(items[0]); plant->hp -= atk; - if (state != 1) + if (state !=attack) { - state = 1; - setMovie(":/images/ScreenZombieAttack.gif"); + state = attack; + setMovie(zomImg[state]); } return; } - if (state) + if (state!=move) { - state = 0; - setMovie(":/images/ScreenZombieWalk.gif"); + state = move; + setMovie(zomImg[state]); } setX(x() - speed); } diff --git a/screenzombie.h b/screenzombie.h index c5202b0..7a96d73 100644 --- a/screenzombie.h +++ b/screenzombie.h @@ -3,7 +3,7 @@ #include "zombie.h" #include "plant.h" - +#include "basiczombie.h" class ScreenZombie : public Zombie { public: diff --git a/shop.cpp b/shop.cpp index 15d5b30..a52abb4 100644 --- a/shop.cpp +++ b/shop.cpp @@ -1,8 +1,12 @@ #include "shop.h" + + + + Shop::Shop() { - sun = 200; + sun = 500; counter = 0; time = int(7.0 * 1000 / 33); Card *card = nullptr; @@ -56,7 +60,7 @@ void Shop::addPlant(QString s, QPointF pos) case 0: plant = new SunFlower; break; case 1: - plant = new Peashooter; break; + plant = new Threeepeater; break; case 2: plant = new CherryBomb; break; case 3: diff --git a/shop.h b/shop.h index d56d3e1..dbebe0d 100644 --- a/shop.h +++ b/shop.h @@ -13,7 +13,7 @@ #include "potatomine.h" #include "repeater.h" #include "basiczombie.h" - +#include "threepeater.h" class Shop : public Other { public: diff --git a/sound.cpp b/sound.cpp new file mode 100644 index 0000000..b533078 --- /dev/null +++ b/sound.cpp @@ -0,0 +1,26 @@ +#include "sound.h" + + +Sound::Sound(QString path) { + played_count=0; + setLoopCount(1); + setSource(QUrl::fromLocalFile(path)); + connect(this,&QSoundEffect::playingChanged,[this](){ + if (!this->isPlaying()) { + + this->deleteLater(); // 安全删除 + } + }); + +} + +void Sound::playOnlyOne() +{ + if(played_count!=0)return; + played_count++; + play(); +} + + + + diff --git a/sound.h b/sound.h new file mode 100644 index 0000000..573a458 --- /dev/null +++ b/sound.h @@ -0,0 +1,14 @@ +#ifndef SOUND_H +#define SOUND_H +#include +class Sound :public QSoundEffect +{ +public: + Sound(QString path); + int played_count; + void playOnlyOne(); + + +}; + +#endif // SOUND_H diff --git a/sun.cpp b/sun.cpp index ec6a201..56a792e 100644 --- a/sun.cpp +++ b/sun.cpp @@ -11,6 +11,7 @@ Sun::Sun() movie = new QMovie(":/images/Sun.gif"); movie->start(); setAcceptedMouseButtons(Qt::LeftButton); + sound=new Sound(":/audios/sunclick.wav"); } Sun::Sun(QPointF pos) @@ -23,6 +24,7 @@ Sun::Sun(QPointF pos) movie = new QMovie(":/images/Sun.gif"); movie->start(); setAcceptedMouseButtons(Qt::LeftButton); + sound=new Sound(":/audios/sunclick.wav"); } Sun::~Sun() @@ -49,7 +51,9 @@ void Sun::mousePressEvent(QGraphicsSceneMouseEvent *event) Shop *shop = qgraphicsitem_cast(scene()->items(QPointF(300, 15))[0]); shop->sun += 25; counter = time; + sound->playOnlyOne(); event->setAccepted(true); + } void Sun::advance(int phase) @@ -57,6 +61,7 @@ void Sun::advance(int phase) if (!phase) return; update(); + if (++counter >= time) delete this; else if (y() < dest.y()) diff --git a/sunflower.cpp b/sunflower.cpp index 1fb2bb7..08b0da4 100644 --- a/sunflower.cpp +++ b/sunflower.cpp @@ -5,6 +5,8 @@ SunFlower::SunFlower() { hp = 300; time = int(10.0 * 1000 / 33); + + setMovie(":/images/SunFlower.gif"); } diff --git a/sunflower.h b/sunflower.h index baf75ce..1ff0492 100644 --- a/sunflower.h +++ b/sunflower.h @@ -3,11 +3,12 @@ #include "plant.h" #include "sun.h" - +#include class SunFlower : public Plant { public: SunFlower(); + void advance(int phase) override; }; diff --git a/threepeater.cpp b/threepeater.cpp new file mode 100644 index 0000000..a2336f0 --- /dev/null +++ b/threepeater.cpp @@ -0,0 +1,44 @@ +#include "threepeater.h" + +Threeepeater::Threeepeater() { + atk=25; + hp=300; + time=int(1.4*1000/33); + setMovie(":/images/Threepeater.gif"); + +} +void Threeepeater::advance(int phase) +{ + if (!phase) + return; + update(); + if (hp <= 0) + delete this; + else if (++counter >= time) + { + counter = 0; + if (!collidingItems().isEmpty()) + { + for(int i=-1;i<=1;i++){ + double xx=x()+32; + double yy=y()+i*100; + if(yy>=0&&yy<=600){ + Pea *pea=new Pea(atk); + pea->setX(xx); + pea->setY(yy); + scene()->addItem(pea); + + } + } + + + return; + } + } +} + +bool Threeepeater::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const +{ + Q_UNUSED(mode) + return other->type() == Zombie::Type && fabs(other->y()-this->y())<100; +} diff --git a/threepeater.h b/threepeater.h new file mode 100644 index 0000000..acec723 --- /dev/null +++ b/threepeater.h @@ -0,0 +1,14 @@ +#ifndef THREEPEATER_H +#define THREEPEATER_H +#include "plant.h" +#include "zombie.h" +#include "pea.h" +class Threeepeater:public Plant +{ +public: + Threeepeater(); + void advance(int phase) override; + bool collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const override; +}; + +#endif // THREEPEATER_H diff --git a/utils.cpp b/utils.cpp new file mode 100644 index 0000000..ead5266 --- /dev/null +++ b/utils.cpp @@ -0,0 +1,23 @@ +#include "sound.h" +#include "utils.h" +#include +Utils::Utils() { + + + +} + +void Utils::turnNormalZoombie(Zombie *zombie) +{ + if(zombie->stage==Zombie::droped)return; + zombie->stage=Zombie::droped; + + QMap zomImg=zombie->zomImg; + zomImg[Zombie::move]=":/images/ZombieWalk1.gif"; + zomImg[Zombie::attack]=":/images/ZombieAttack.gif"; + zomImg[Zombie::die]=":/images/ZombieDie.gif"; + if(zombie->state==Zombie::move) zombie->setMovie(zomImg[Zombie::move]); + if(zombie->state==Zombie::attack) zombie->setMovie(zomImg[Zombie::attack]); +} + + diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..27af7a3 --- /dev/null +++ b/utils.h @@ -0,0 +1,15 @@ +#ifndef UTILS_H +#define UTILS_H + +#include "sound.h" +#include "zombie.h" +#include +class Utils +{ +public: + Utils(); + static void turnNormalZoombie(Zombie *zombie); + +}; + +#endif // UTILS_H diff --git a/zombie.cpp b/zombie.cpp index 6f6cb99..c582ef9 100644 --- a/zombie.cpp +++ b/zombie.cpp @@ -7,6 +7,9 @@ Zombie::Zombie() movie = head = nullptr; hp = atk = state = 0; speed = 0.0; + name=""; + + } Zombie::~Zombie() diff --git a/zombie.h b/zombie.h index ea8b797..58c8ae2 100644 --- a/zombie.h +++ b/zombie.h @@ -5,15 +5,19 @@ #include #include #include - +#include class Zombie : public QGraphicsItem { public: - int hp; + int hp;//僵尸血量 int atk; - int state; - qreal speed; + int state;//行进状态 + int stage;//僵尸阶段 + qreal speed;//行进速度 + QString name;//僵尸名字 + QMapzomImg; enum { Type = UserType + 2}; + enum {attack,move,die,hurt,droped}; Zombie(); ~Zombie() override; QRectF boundingRect() const override; @@ -25,6 +29,7 @@ class Zombie : public QGraphicsItem protected: QMovie *movie; QMovie *head; + }; #endif // ZOOMBIE_H