Hello. In this video we will create real races in Construct 2. And more than ever, let’s go! So the first thing, of course, we need assets. And this time I really worried about it and found a free game kit to create a racing game. And where do you think I found it? On my favorite site with a bunch of various assets CraftPix.net Therefore, first of all, follow the link in the description and download this kit. Well, I have already downloaded and therefore we proceed to add all that we need on the scene. I think you can handle the process of placing the pictures yourself, so let’s skip comments on this step. So, that’s what I did. First, I created three layers, on the last one, under the name UI, I placed all the interface objects. More specifically, these are such decorative plates, two buttons. By clicking on the first one, we will stop and resume time, and the second will restart the level. And 4 texts. The first will display the current speed and the number of laps completed. The second will display Win or Lose depending on our result at the end. Well, the last two will show who came first, and who is the second. Also, the last three texts I put in the family, so that later it would be more convenient to work with them. There are no more objects on this layer, so we go to the map layer. Here, as you can see, I have placed absolutely all the objects graphically constituting our level. And what is more remarkable, all of these objects, both sprites and tiled backgrounds, have no behavior or variables. This is just an image. Well, the last Main layer consists mainly of solids. Yes, these violet tiled backgrounds have Solid behavior and as you understand, they are needed so that we could not leave the track. Also on this layer there is a green tiled background. We need it for classic fool protection, that is, in order to prevent reversing at the beginning of the race. It has a private variable ID for separation into first and second object. In addition to green and purple tiled backgrounds, there are also red tiled backgrounds and they work as dots, the path to which our opponent will constantly look for. As well as the green tiled background, red has a variable ID for point identification. The next object is decorative lights, they are on this layer so that the cars can pass under them, and not vice versa. Well, finally, our cars. Red has car behavior, and yellow- Pathfinding. Now let’s consider these behaviors in more detail. Let’s start with car behavior. It differs from the 8-direction in that it simulates steering, acceleration, braking, smooth rotation, and also allows you to drift. In general, fully loaded. Now let’s look at all the parameters of behavior in turn. The first is the maximum speed, well, here the name speaks for itself. The second is acceleration, everything is also clear here. But the slowdown in this behavior determines both the deceleration rate, that is, the car’s brake behavior and the braking speed without pressing any button. Therefore, in order to make everything beautiful, we will have to work on it later. The next parameter is Steer speed, it determines the speed with which our car turns. Next comes Drift recover. This is actually the parameter that allows us to drift. Here you need to pay attention to the fact that its value should not be greater than or equal to the speed of rotation, since under such conditions you will not succeed in any drift. Friction determines how much speed a machine will lose when it collides with a solid object. Respectively, 0- will not lose at all, 0.5- lose half, 1- stop completely. Set angle- allows or denies to change the angle of the object itself, that is, the angle of the sprite in this case. Well, the last parameter prohibits or allows standard control, that is, control of arrows. I think with this behavior everything is clear. I set it up like this. Also, pay attention to the fact that this car also has the ScrollTo behavior, so that the camera always follows this particular car. As well as 2 private variables, the first is responsible for the level of damage to the car, and the second determines what half of the circle the car is currently driving. But we’ll deal with this later. Now let’s go to the second car. It has Pathfinding behavior set, this behavior allows you to move objects along a certain route that does not need to be set in advance. Simply put, the behavior can calculate the shortest path to a point on the level, and we will use it accordingly to create the enemy’s artificial intelligence. Now let’s consider all the parameters of this behavior. The first parameter is Cell size, that is, for finding a path, this behavior divides the level into a grid, and this parameter just determines the size of a single cell in the same grid. And of course, the smaller the cell size, the larger the grid and the more accurately the path will be calculated. But at the same time, of course, more resources will be needed, and therefore time. The second parameter is Cell border, with this parameter you can adjust the number of cells occupied on the grid by the object of behavior itself. An example you see on the screen. There is nothing new to say about the next three parameters, this is maximum speed, acceleration and deceleration. Well, the last parameter allows or forbids the object to move along the diagonals. And for this project, I set up this behavior as follows. Well, and also the opponent’s sprite itself has two private variables. The first is responsible for how many laps were completed by this car. The second is responsible for the current path, but we’ll talk about it later. And before we go into the Event sheet, I almost forgot to say that the sprites of the cars must be rotated, as in the graphic editor itself, and at a level of 270 degrees. Because otherwise you get this. This is due to features of behavior. Well, now we go to the Event sheet. And the first thing we do is reassign the car control. And also add handbrake. To do this, we need a plugin keyboard, so we add it. Well, now create an event: if the keyboard->key is down->button W. That is, if we press and hold the W button, then the red car->Simulate control->Accelerate (that is, we begin to accelerate). And now we copy this event and change the W button to the A button, and the action on the Simulate control->Steer left. And once again we copy, and again we change, but already on button D, and the action on Steer right. The possibility of moving forward, left and right, we have done, now we will do the braking. Again, we copy the previous event, change the button to S, and the action to Brake, but if you remember, I set the Deceleration to 4000 in the parameters of the car’s behavior of our car. Now let’s see why I did it, and what will happen if we do not upgrade the last event. We start the preview and yes, let’s quickly add the On start of layout events and the Set visible->invisible text family action to it and the finish window is also invisible. Well, now we return to our car, and as you can see, if we press the W button, the car moves forward fairly quickly, and if we release, it also stops quickly. I set the deceleration to 4000 precisely for this inhibition, but here, of course, another problem arises. If we start to go back, then … well, you can see. Let’s go fix it. We fix this as follows: In the brake event, we add a new action. Car->Set deceleration->500. That is, when pressing the S button, we set the deceleration to 500, but this is naturally not enough, since at some point we need to return the deceleration value back to 4000. This moment will be the moment else, that is, ever, except if we go backwards. And of course, we add the action Set deceleration->4000. But that’s not all, buying one male Argo chain, second chain ….no, no, no, I mean that we don’t want the car to go back with its maximum speed, which will happen if we start the preview now. Let’s limit the speed of movement back to value, let it be 500. To do this, in the event of pressing the button back we add Another condition, that is, an additional condition: Our car->Compare speed ->if more than minus 500. Well, now from the control of the car we have to do only the hand brake. To do this, again, we create the event Keyboard->Key is down->spacebar->and immediately put an additional condition here: if the speed is greater than zero. We do this because, in the actions for this event, we will have a Brake action, which, under other conditions, accelerates the car in the opposite direction, that is, to a value that is less than 0. Well, we add to the action: Simulate control->Brake. And also we will set the Deceleration to 1500, so that the braking is sharp, but not much. So, we made the car control. We will not return to it soon, so we will create a group for it and hide all events. The next thing we do is the camera moving away depending on the speed of the car. We honestly steal this thing from the official example of the Driving game. We copy everything from here to our project, change it a bit, and now I will try to explain to you how it works. So, the first thing we have is a global variable called IntendedScale, that is, in Russian, the value of the narrowing, or rather the distance of the camera. And it takes the value in the first act of the event Every tick. This value is 1,2 minus car speed divided by 1000. What does it mean? 1,2- is the scale, 1- is the default level scale. And from this scale we subtract the value of the speed divided by 1000 so that these are thousandths, that is, the scale does not go into a minus. By the way, let’s change 1000 to 3000, since our car has a higher speed than in the example. This is what happens if we do not change this value. Yes, the variable “scale” will go to minus. And if the value is appropriate, then as you can see, at a maximum speed of 2000, the scale is 0.5. We have dealt with this. Now let’s consider the following steps. The new scale value is applied to our layers. The first action is called Set layer scale, that is, set the scale to a specific layer. This layer is the Map, that is, the one on which there are all objects except cars. The scale is applied to it using the special term lerp. Lerp is needed in order to smoothly change the value of something, that is, when writing this terms, we must specify three mandatory parameters. The first is the value of what needs to be changed. In this case, this is the LayerScale value, that is, the scale value of the Map layer. The second is how to change the value specified in the first parameter. This is the amount camera distance, that is, the value of our global variable, which varies depending on the speed. Well, the third parameter determines how fast the value will change. We have dealt with this. Now let’s consider the last action. It is necessary only in the case when, as in our example, the level is divided into layers. That is, this is an action that applies the same scaling as on the Map layer, but only to the Main layer with the cars. That’s how it’s done, kids. Well, while we are near the Every tick event, we’ll add an action to it, which will display the speed and number of the remaining laps in plain text on the screen. By the way about the laps, let’s add a global variable of the same name. Well, now the actions: Text->Set text->write speed->set an ampersand (to separate the text and system term), and write round (to round the speed to integers) ->and refer to the speed of our car in brackets. Then again we put the ampersand->open quotes->set a lot of spaces, since I was too lazy to create a second text for counting laps, and again we write round->colon->ampersand->our newly created variable Lap->ampersand again and / 2 since it will be necessary to drive only two laps. Well, since we started talking about laps, we’ll start counting the passed laps, as well as the finish and the results table. We create an event, and if the car touches our tiled background, which represents half of the lap, we also point to the tiled background, which marks the finish. We specify through the event Compare->Instance variable->ID variable is zero. And at the same time, the private variable Lap of the car must be equal to one. This means that we have completed half the lap and do not want to finish without having time to drive, and add action. First, we add one value to the global variable, which counts the completed laps. And secondly, we change the Lap variable of the car to zero, that is, we mean that we did not complete the first half of the lap so we cannot finish yet. Now let’s create the event that will determine whether we have completed half of the lap. If the car touches the green tiled background, and at the same time we specify which one we cross, and at the same time the private variable Lap of the car is zero, then we change it accordingly by one. We will also add an event that will count the opponent’s laps. And if the yellow car crosses the tiled background, whose ID is one (private variable ID of course, that is, this one), then it adds one value to the private variable Lap. Now, when the laps are counted, we will make the finish itself, that is, the end of the game. It will come when the global variable Lap becomes three, that is, when we complete the second lap. Add a sub-event to the event when we reach the finish, and if the global variable Lap is three, then we add the following actions: First, the Text family->set visible->visible. Secondly, this window->set visible->visible. Text showing speed and circles->invisible. These labels are also->invisible. Pause->Destroy button (so that we could not accidentally press it). And we will move the Replay button under the results. Set position, and specify the position where we want to move a button on the X and Y respectively, and System->Set time scale->set to zero, that is, to stop time. Also for showiness, let’s add a couple of effects to the Map layer. This will be Radial Blur and Grayscale. Well, add the following actions to the finish event. System->Set layer effect parameter->Layer 0->Effect Grayscale Parameter index 0, since we need to change the intensity parameter (Value), and set the value to 100. Well, we add the same action for the Blur effect, but the parameter index this time is equal to one. Also, do not forget to turn off both of these effects at the beginning of the level. To do this, copy these two actions into the On start of layout event and change their intensity value to 0. Now we just have to output the results from the finishing point. To do this, we will create such an uncomplicated event: System->Compare variable->if the global variable Lap is three, which means that we have passed two laps. And add a sub-event: Opponent’s Car->Compare variable->if the opponent’s private variable Lap is greater than or equal to the global variable, then this is the case when we lost. Therefore we add the following actions: Text 2->Set text->”You lose” Text 3->Set text->”1- Yellow”, Text 4->Set text->”2- You”. Well, now we copy this sub-event and change the conditions — if the opponent’s variable is less than the global variable, that is, the opponent has passed the third circle after us and we change the actions accordingly. We have successfully completed the finish, now we will make our car damaged when we hit an obstacle and this damage would affect its speed and acceleration. We add an event: if our car->On collision with another object->this object is our invisible solid. And at the same time, our car->Compare Speed (that is, we compare the speed of the car at the moment of collision) ->I set it to be greater than or equal to 300. But pay attention that the speed must be set taking into account the fact that it will decrease when colliding on the amount that you set in the Friction parameter of the Car behavior. That is, in this scenario, the event will work if the speed of car is approximately equal to about a thousand, and here we add a condition if the private variable Change of the car is less than or equal to 4, so that this variable cannot reach a value greater than five. We need exactly 5, since we have exactly this number of frames of animation. And now we add actions: First, we add one value to the Change variable of our car in order to change the speed and acceleration later, depending on it. Secondly, we immediately change the frame of the animation of the car, it will be equal to the degree of damage. For the effect, we also add the Shake action that the ScrollTo behavior of the car has. Well, we set the Set max speed of the car equal to this expression: 2000 (since this is our maximum speed) minus the degree of damage multiplied by 200, that is, if the damage is zero then 0 multiply by 200 will be 0, which means the car will go with the maximum speed. If the damage is equal to one, then 1 multiplied by 200 will be 200 and the car will already go at a speed of 1800. And so on. Well, in exactly the same way, we change our acceleration Set acceleration->350->minus Change->multiplied by 30. Everything as you can see is extremely simple. Now let’s make a bonus that will appear on the level, and if we collect it, it will restore our damage. To begin with, we organize its appearance. Add this action: System->Compare two values (that is, compare two variables). And we will compare the number of objects “bonus” at the level with zero. That is, if there is no bonus at the level, we picked it up, then such actions must take place: first, System->Wait->3 seconds (in order for the bonus to appear not immediately), and secondly, System->Create object ->Bonus->Layer 1->and write the desired coordinates. I have coordinates of this place. Well, so that such a disgrace does not occur: with the Trigger event once while true, we point out that this event should be executed once, when there is no bonus. Well, now let’s do so that we can pick up this bonus. Create an event: Our car->On collision with object->Bonus, then add the action Bonus->destroy->the variable Change of the car becomes zero. Well, here we copy these three actions in order to apply animation, speed and acceleration to the corresponding damage value. Well, in order to fully deal with the car we are driving, let’s add to it the effect of the smoke from the tires when turning at high speed. To do this, we first proceed to the animation of the car and add two new Image points to it in the places where the wheels are. Of course, do not forget to apply them to all frames of animation. Now we will create the smoke itself, it will be an object of a particle with these settings, of course, you can play with them yourself. And we go to the Event sheet and look for the group of events where we assigned control at the very beginning. And here we find the event where we turn left and right. We will add this sub-event to it: if our car->Compare speed (that is, if the car’s speed is greater than or equal), let it be 1300, then we add here the action our Сar->Spawn another object->our parts->layer 0. Please note that this is the layer, which is below the car, so that the smoke does not overlap the car and we indicate the first image point first and then the second. The same sub-event we insert in the event of pressing the handbrake. But the condition here is changed to: if the speed is greater than or equal to 400. Well, now we turn to creating the behavior of the opponent. For its automatic movement, as I said earlier, we will use the Pathfinding behavior and the Point object with the private variable ID that define different points. Create an event: if the opponent->On collision with->Point->here we add a sub-event: if Point->Compare variable->ID if equal to 1, if equal to 2, and if equal to 3. And we add an action to each of these sub-events: the opponent’s car->Set value->Path->equals 2, 3 and 1, respectively. Now let’s check what the variable path is equal to using the Compare variable event. Enemy car->Compare variable->Path->1, 2 and 3. And if it is equal to one, then we add a sub-event: if the private variable ID of the point is equal to one, that is, this is this point, then we add the action Enemy car->Find path (that is, find the way to) ->and specify point X point Y. We also add Trigger once to this sub-event, otherwise the car will not find the path, since it will recheck it every tick. Well, now we copy this action twice and change the conditions for checking the private variable ID point. And in order for car to move along the path, you need to add an event: Enemy car->On path found (that is, if the path is found) ->then the action Move along path, that is, go along the path. And that’s all, now our opponent will ride in a circle. This lesson is almost complete. We only need to activate the pause and restart buttons. We create an event: if the Mouse->On object clicked->button Pause->System->Set time scale->and here we write the expression- toggle. Specify the value of Time scale, set equal to 0/1. Now pressing the button one time will stop, pressing the second one will resume. And we create the same event for the restart button, just add another action. This action is Browser reload, that is, we completely restart the game. Well, that’s all, if you liked the video, then сlick the “Like” button and subscribe to my channel! Sometimes I still come to life. See you.