Placeholder Image

字幕列表 影片播放

  • hello and welcome to the final part of my code it yourself worm.

  • Siri's this gun.

  • It'll be a little bit different.

  • How you usually do the videos because I've got the last part of this video is a full battle.

  • Royal off the worms.

  • Fighting each other on this video is really going to be about the aye aye strategy that I've developed to get them to do that.

  • Now, Fundamentally, I've not changed very much from the previous video in this series.

  • I've added a prettier looking sky, and I've added a countdown timer on health.

  • But Andi, there are teams of worms, but I'm not going to go into very much detail like a usually would about how all of that's done.

  • Instead, we're going to focus on the A I.

  • The Cody Self Worms game has now become quite a large project.

  • In fact, there's about 1000 lines of code, but please believe me when I say most of the code you have seen in the previous two videos, I've not made any changes to the create map function.

  • I've not made any changes to the pearl in noise function.

  • I've not made any changes to the boom function.

  • And I've made one slight change to the sea physics object class, which is the inclusion off this damage function, which we'll see later.

  • I've also made no changes to the camera tracking all the firing weapon routines, and I've made absolutely no changes at all to the physics engine.

  • So let's have a quick look at the C team class on this class is really just a rapper for a vector off worm objects on the specters called back members on those two functions this class provides, and one is his team alive, which just iterated through all of the members in the vector and checks to see if their health is greater than zero.

  • If any of the worms have a health that is greater than zero, then the team is still alive.

  • It's still available to take part in combat.

  • On the second function is get Next member, which returns a pointer to a sea worm object on DTH.

  • This function goes through the vector one by one and wraps around, so this way we can work out which worms turn.

  • It is given a particular team, and of course, we don't want it to choose worms, which aren't healthy.

  • And you might be thinking, Well, if a worm dies wise, it's still a member of the team.

  • Well, the object still exists.

  • What I've decided to do is George as a gravestone instead of a worm.

  • And if we look in the drawer, function off the sea worm object we can see is playable.

  • This flag is directly set by the health of the words.

  • If it's greater than zero, the worm is playable.

  • Then we draw the worm using the drawer partial spite routine, as we did in the previous video.

  • We also take this opportunity to draw the health bar underneath, which is just scrolling through the health values, setting pixels beneath the worm.

  • We use the drawer partial spite routine because the single sprite ass it's this game uses contains all four team colors individually, George and it also contains for tombstones with the team colors marked on them.

  • So if the worm isn't playable, instead of drawing the worms right, we draw the tombstones bright.

  • So a team is just a collection of worms.

  • Let's take that off now.

  • The previous video looked at using state machines to govern the order of play, and we're still doing that here.

  • The only difference is the allocate units has now been filled in.

  • Previously.

  • It was blank, and it's in this state that we can set the number of teams or the number of worms per team that we want, and we can play with these numbers as long as we don't have more than four teams on.

  • The first thing that we do is work out.

  • How much space does each team and worm need?

  • Because we want the Team City be deployed in a team, But the worms, we don't want them all to be on top of each other.

  • We want to deploy them next to each other in their teams.

  • So once we calculated the spacing, we create a team object, and then we add worms to it at the appropriate location Organ.

  • See here where we're taking the vector of teams were taking the vector of members for that team, and we're pushing the worm to the back of that vector.

  • So it's really just two nested four loops, creating all the teams and worms, and it's quite nice.

  • So, for example, if I chose to have two teams but 10 worms per team.

  • We could easily do that and see what it looks like.

  • And there were two big teams you may notice.

  • I've added the ability to zoom in and zoom out when the user presses the tab key that this was quite useful.

  • See could see the overall state of play.

  • Let me just put it back to four teams of four.

  • So I'm going to continue with my strategy of closing up the things that we don't need to see.

  • That start play State is where the action happens on.

  • It will remain in this state until one of two things has happened.

  • The player has fired the weapon, which we saw in the previous video or the turn.

  • Time has expired.

  • So in the a news update function now I'm decreasing the turn time from 15 seconds just by subtracting every lapse time from it.

  • And in fact, we can see that here.

  • The other major change to the state machine is tthe e camera mode state.

  • This state was responsible for controlling the camera following the object of interest on it did so until the physics engine settled and then returned back to start play.

  • But we're also now waiting for the physics engine to settle and then choosing the next object of interest.

  • So if we've got teams of worms, it goes between one team, then to the next, and then it goes to the next worm within that team, etcetera, etcetera.

  • So once the physics engine is stable, we can assume the action has stopped and it's time to choose the next team on worm to play.

  • So to do this, I just increment the current team counter and I make sure that that wraps around the number of teams that are playing.

  • So we're always going between zero on the maximum number of teams minus one.

  • But I'm also making sure that when I increased the team counter that that current team is alive, do they actually have the ability to play?

  • If they don't, it just goes around and increments again.

  • It will keep doing this now.

  • This leaves us with a situation where the next team to play could be the same as the current scene that is playing, and in this case that means there must only be that one team left therefore that team has one, so we look for that specifically.

  • If current team is equal to old team, then we go into the game over state.

  • However, we want one of the teams to be controlled by the player on all of the teams to be controlled by the A.

  • I and I've designated that team.

  • Zero is the player team there, the red ones.

  • So if the current team is the player team, we enable player control and we disable computer control as opposed to the eye team, where we disable the player control and enable the computer control.

  • Once they're selected, a new worm object to follow.

  • We set it is the object under control and we tell the camera to track it.

  • We reset the term time back to 15 on.

  • I've set here the zoom out flag to be false because that will make it sure that the camera zooms in on the worm that is currently under control and we go back to the start Play ST Let's just briefly look at how the zoom out function works.

  • If we're not zoomed out, then we draw, as we did in video, to the only difference here is I've made the sky a Grady int instead of just a fixed science color.

  • And as before, thee objects draw themselves and draw across her to indicate in which direction they are aiming.

  • However, if we have zoomed out, then we re scale the sampling points for the map, and we draw the whole map on the single screen again.

  • I need code to draw the gray tinted sky, and the objects go on draw themselves.

  • But we can't just get them to draw themselves natively.

  • We have to do some clever offsetting to get them to draw them in the right location.

  • Because remember, now we're looking at the whole map on the screen, and we also need to indicate that we want them to be drawn at a smaller scale.

  • So I've modified the drawer function to include a flag, which we set to true for when we're in zoomed out mode.

  • If we just briefly look at the drawer function for the missile object, it uses the drawer wife remodel function, as it did before.

  • But if the zoomed out flag is set to true, then it fixes the scaling factor to North 0.5 instead off the radius, which was set before so drawing the landscape, we can check that off to at the top of the screen.

  • I'm drawing health bars that represent the total health off the team on.

  • I'm calculating this in a very trivial way.

  • I'm just iterating through all of the team members on accumulating their health, and I used the fill function to draw a colored rectangle in the team colors, the appropriate length across the screen.

  • The countdown timer in the corner was a seven segment display on this code.

  • Believe it or not, generates that seven segment display for us.

  • And you might be thinking, What is that?

  • Well, on the discord server, we've had lots of little challenges where we try to do some code Gulf on.

  • This was the minimal amount of code required to draw a seven segment display using the council game engine.

  • I've decided to leave it in its gulf form because, well, it looks cool, and it's little intellectual curiosity for any of those that do look at the source code for this project.

  • So with all that out, the way we can now focus on the real content of this video, which is the artificial intelligence or AI I I decided early on that the A I shouldn't be allowed to cheat.

  • So I'm going to restrict the eye to using the same controls that the player can use on the one that many.

  • So there was a MME left, aim right, jump on fire.

  • And if you remember, you hold down fire to energize the weapon.

  • And when you release it, it takes the energy level and applies.

  • That is a velocity on because I've restricted the eye to using just the controls that the player can use.

  • This means I don't have to make any changes to the physics engine or any other part of the game.

  • All I need to do is send the control signals to the engine that already exists.

  • And just like we controlled the game with the state machine, I'm going to create another state machine just for controlling the I.

  • May I.

  • State machine consists off six states on going to start in this one, which is the choose strategy state in this state.

  • The worm is going to decide where it should walk to, and it basically rolls the dice to choose between one of three options.

  • Option one is to walk away from teammates.

  • Option two is to walk towards the middle of the map.

  • An option three is to just do nothing at all if the worm chooses Option one.

  • This is quite a defensive strategy because it tries to resist having clumps of worms together.

  • So when the missile hits, it's only likely to damage one worm rather than whole cluster of the same team.

  • Option two is quite an aggressive strategy, because being in the middle of the map gives you the advantage of being able to hit most of the targets elsewhere on the map.

  • But it does mean you're more exposed to being hit by other worms.

  • On Option three.

  • Do nothing means the worm just sits where it is and simply takes aim and fires.

  • Depending on which strategy is selected, we can choose a location, which is the target for the A.

  • I tow walk, too, which leads directly into our next state, which is our walk state.

  • When we're in the walk, state will continue walking until we have reached that target position or will stay in that state to carry on walking on.

  • Making the worms walk is quite easy because they can only jump.

  • So all we need to do is set a jumping angle based on the direction we want the worm to walk in.

  • So it'll either be positive or negative on.

  • We set our jump flag, too true.

  • Once the worm is in its new location, it's Next state is to choose a target.

  • And my strategy for choosing a target is simply going to be choose a team which is not yours on Choose the worm with the most health on that team.

  • Now, of course, we're going to have to examine the mathematics of how the trajectory and the projectile stuff works on.

  • I'll do that just after we finished looking at this state machine.

  • But one of the byproducts of that mathematics is whether it is possible for the worm to hit its target.

  • And if it isn't, the worm needs to move towards its target, which means we need to go into a second walk state, which, just like the previous work state, has the option of staying in that state until it satisfies that criteria on that criteria is that it is in position, sufficient enough to hit the target on as before, Tow walk.

  • We simply set the angle to be positive or negative, and we set the jump flag.

  • Too.

  • True.

  • Once the worm is in a position where it knows it can hit its target, the next two states are really just animation states that make it look good for the player.

  • So the first is a.

  • The worm has to move its cursor to the correct angle in order to hit its target.

  • And in a similar way to walk, they're two exits to this state.

  • One is target angle is correct, and while it's not correct, it can sit in its own state.

  • Adjusting the cursor for that worm using the name left a name right flex once its lines over the cursor with the angle that it needs in order to hit the target.

  • It then enters the fire state on, just as we did with aimed their two ways to exit this state.

  • Firstly, the target energy required is met or state loops back on itself, issuing the fire flag.

  • Once the worm has fired its weapon, it has finished.

  • The game will move into the camera mode state, and eventually a new worm will be chosen.

  • So we want to make sure that the A I goes back into its two strategy state.

  • But what I'd like to emphasize here is that at no point does the aye aye do anything that the player can't do.

  • It only uses the same set of commands jump, aim and fire.

  • So how do we determine the angle that the A I worm should aim for in order to hit a target?

  • Well, let's make an assumption that the worm under control exists at 00 in a two D plane on the target worm exists somewhere relative to 00 within that plate.

  • This gives us a change in elevation on a change in range.

  • I'm going to draw a line between these two points.

  • We know in our physics simulation that all of the projectors will follow a parabolic trajectory, and what we want to find is the angle that we should aim the cursor in orders for the projectile to follow that trajectory and hit that point.

  • This is actually quite complex on their two unknowns.

  • One is the angle and the second is the muzzle velocity?

  • A what velocity do we fire the projectile out?

  • And to make this simpler, the I will always fire its projectile at a fixed velocity.

  • Well, it's looking through the maths For this project, I discovered this excellent Wikipedia page, which is projectile motion.

  • And about halfway down the page, there's an interesting article angle theater required to hit Coordinate, Tex, Why on this is precisely what we're looking for.

  • And it gives us this really nice formula, but rather curiously, It doesn't say how this formula is derived, but the formula contains all of the relevant parts that we need.

  • We've got V, which is our muzzle velocity.

  • How fast is the projectile fired?

  • We've got G, which is gravity.

  • In this case, that's a constant set in our physics engine.

  • On.

  • We've got X on.

  • Why, which is the target offset location here next.

  • Why?

  • But I don't like just using a formula without knowing where it comes from.

  • And when I look at this formula, I see a lot of similarities to the quadratic equation formula which hopefully you remember from high school.

  • Now, in previous videos, I would have happily derived this for you, but I did actually find this a little tricky.

  • After a little bit of searching, I found this excellent video presented by Physics E.

  • H, where he steps through the deprivation line by line.

  • I've included a link to this in the notes below, but lo and behold, it turns out to be a quadratic equation.

  • Fancy that.

  • So rather than me just reinventing the wheel, I thoroughly recommend you go and have a look at that video.

  • It's excellent.

  • He's a very enthusiastic guy.

  • He describes it wonderfully.

  • Well, it's better than I could do it.

  • And so go take a look.

  • And so this equation uses only values that we know and generates the result that we want.

  • But it also has one interesting byproduct which we can use to position the worms.

  • And that is we want to make sure that this remains rial, i e.

  • It doesn't become a new imaginary number when it's all calculated, and we can do that by making sure that the highlighted party is always positive.

  • So if we test that this is positive first and it is then we know that there is a sensible solution for theater However, if this is not positive, then the worm isn't close enough.

  • There is no known solution.

  • There is no theater, which a projectile could be fired out.

  • That will hit the target worm, so we'll move the worm forwards towards the target.

  • And so our walk towards target state.

  • It's constantly reevaluating whether calculating theater is possible, and if it isn't the worm keeps walking towards the target as soon as it becomes possible, it can then move on to the AIM state.

  • So let's have a look at the code for the state machine.

  • For the A.

  • I.

  • My first state is assess environment or to strategy on.

  • In this case, it just chooses a random number between zero and two.

  • However, it's in this state that you could probably have the most fun about giving intelligence to your worms.

  • Mine is quite crude, and they play Defensive Option is perhaps the most sophisticated in that it creates a field of influence that decides what the worm should do next.

  • But of course, these states could be governed by other outside influences, such as how much health is the worm got.

  • You know, if it's low health and it should play defensive.

  • It also doesn't study the environment in any particular way.

  • Doesn't look to see well, there's an obstacle that can't pass or there are too many worms in one cluster.