用C++实现游戏Crash Loyal, 包括AI部分，GUI库使用SDL.
Build collision avoidance for Crash Loyal, our home-brew clone of the popular mobile game Clash Loyale. In preparing for this game, you may want to get a copy of Clash Loyale (free on the Apple or Android store), and spend some time playing around with it, watching how different units interact when they try to move in to the same space.
Source code for Crash Loyal can be found here.
The game is still under development, and we may have updates that will be helpful to you. As new changes are merged into the master branch, we’ll let you know what changes were made. In the same vein, you may find bugs (including crashes). If you do, send a bug report to Arthur and me with as much information as you can include about how to reproduce them, so that we can work on getting them fixed.
The repository includes a Visual Studio 2019 solution. At this time, I don’t have a working solution for Mac development - Mac users may need to either get it compiling under Xcode, or find a PC to develop on.
Once you have the game running, the current interface allows you to drop swordsman by left- or right-clicking. You can drop smaller, faster-moving archers by holding left-shift while you left- or right-click.
Your task is to detect and handle collisions between the NPCs (i.e. swordsmen and archers) and:
- Other mobs
- The three towers at each end of the field
- The river
The hooks for handling collisions already exist in the Mob class (/CrashLoyal/src/Mob.h/cpp), and there are some comments with the label “// PROJECT 3: “ to help you figure out where to get started. More specifically, things you need to do include:
- Implement checkCollision(). Some hints:
- Units are squares.
- pos is the center of the square.
- GetSize() is the length of the side of the square
- The easiest way to check for a collision between two squares is to check whether both the difference in x and the difference in y are less than the average of the sizes. Similar math can help to figure out how far to bump them back.
- Extend checkCollision() so that it returns all mobs that are colliding, not just the first one found.
- Fair warning: Handling situations where there are lots of collisions can be a pain, because fixing one can create others. It doesn’t need to be perfect, but get it as good as you can.
- Something like
- Implement processCollision() so that it moves colliding mobs to a position where they are no longer colliding. Some details - you may not get all of these working, but the more, the better
- When units have different values from GetMass(), only the lighter (i.e. lower mass) unit should be moved by a collision - thus a heavy unit walking forward will push other units back. In Clash Royale, you can try watching the way a Golem pushes enemy units back as an example.
- When units have the same mass and are moving in approximately the same direction, the one in back should be pushed back, while the one in front continues at the same speed.
- When units have the same mass and are moving in approximately opposite directions, they should both be moved back a bit.
- If the direction of the impulse that is moving a unit back is straight up/down the screen, you might want to add a little bit of motion to the side, so that the faster unit can eventually get around the slower one. In Clash Royale, you can try watching a small unit (like a wizard) trying to get around a big unit (like a Golem) as an example.
- Get collisions working with the towers and the river, as well as other units.
- There are many ways to handle this, but one would be to handle the towers as Mobs that have infinite mass and don’t move, and the river as three Mobs that have infinite mass, don’t move, and are wider than they are tall (i.e. rectangles rather than squares).
- Right now, there’s a pathing bug where units that have selected an enemy target on the far side of the river move straight across instead of pathing to the bridge. Collision handling should prevent this from happening, although the unit may still get stuck on the river (or move sideways very slowly). Ultimately, most of the work for crossing at the bridge should come from the path planner, with collision handling just handling cases where units get bumped too far to the side.
There are at least three major changes that I foresee getting in in the near future, which you’ll need to integrate into your game:
- A fix to the pathing bug, so that units path across the bridge when their target is on the far side. We will likely also improve the target selection logic.
- Archers will have a greater range, which means that they’ll stop moving when they’re farther away from their target than is currently required.
- We will add giants. Giants are significantly larger (nearly as wide as the bridge), slow moving, have a very large mass (they push back both archers and swordsmen), and only attack towers (so they ignore any enemy swordsmen/archers that are in their way). This will create a number of new collision situations that don’t currently occur, including situations where smaller units are stuck behind the giant on the bridge, and situations where the giant pushes forward through enemy attackers.
Your deliverables should be checked into a Github repository, and a link sent to me and Arthur. The repo should include:
- All source code needed to compile and run the game.
- A written description of the approach you took, what works well, and what you might still like to improve.