We have everything we need to build towers, but this game is all about demolition. The player would become bored if all they had was TNT to destroy the towers. We are going to utilize some more physics functions and create some new equipment: a Wrecking Ball and a Magnetic Crane.
Let's start with the Wrecking Ball as we have already built a large portion of it. We will utilize the Chain and Anchor and add a Ball to it.
spr_WreckingBall
, and load Chapter 6/Sprites/WreckingBall.png
with Remove Background checked. Center the origin and click on OK.obj_WreckingBall
, and apply the spr_WreckingBall
as its Sprite.-100
.50
.5
.0
.scr_Anchor_Create
and add the following code at the end of the script:ball = instance_create(chain[9].x +24, y, obj_WreckingBall); physics_joint_revolute_create(chain[9], ball , chain[9].x, chain[9].y, -30, 30, true, 0, 0, false, false);
Here we are creating a Wrecking Ball at the end of the Chain, with a 24 pixel offset so it is positioned correctly. We then add a Revolute Joint between the last link in the Chain and the Wrecking Ball with a rotational limit of 30 degrees in either direction.
obj_Pillar_Parent
and adding an obj_WreckingBall
event, and attaching scr_Pillar_Destroy
. As all Pillars and Debris are parented to the object, they will all respond to this event.obj_Pillar_Glass
, obj_Pillar_Wood
, and obj_Pillar_Steel
, and add an obj_WreckingBall
event with scr_Pillar_BreakApart
attached. If a parent object and one of its children both have the same type of event, be it collision, step, or whatever, the child's event will be executed and the parent's event will be ignored.Sandbox
and place an instance of obj_Anchor
in the room, just off to the right of the existing Pillars. We can also remove the TNT as we do not need it for this test. The setup should look like the following screenshot:phy_active
variable to false for each instance we want to stop. Reopen scr_Anchor_Create
and apply this change for the Wrecking Ball and every Chain. The entire script can be seen in the following code:for (i = 1; i < 10; i++) { chain[i] = instance_create(x+(i * 16), y, obj_ChainLink); chain[i].phy_active = false; } physics_joint_revolute_create(self, chain[1], self.x, self.y, 0, 0, false, 0, 0, false, false); for (i = 1; i < 9; i++) { physics_joint_revolute_create(chain[i], chain[i+1], chain[i].x, chain[i].y, -20, 20, true, 0, 0, false, false); } ball = instance_create(chain[9].x +24, y, obj_WreckingBall); ball.phy_active = false; physics_joint_revolute_create(chain[9], ball , chain[9].x, chain[9].y, -30, 30, true, 0, 0, false, false);
scr_Anchor_Activate
, and for testing purposes, attach it to a Space event under Key Press.for (i = 1; i < 10; i++) { chain[i].phy_active = true; } ball.phy_active = true;
When this script is run, a simple for
loop activates every Chain, and then the Wrecking Ball.
Our third piece of demolition equipment will be a Magnetic Crane. This Crane will drop down and pick up any small Pillar and Debris made from Steel. It will then raise itself back up with whatever it has collected.
spr_Magnet
, and load Chapter 6/Sprites/Magnet.png
with Remove Background checked. Center the origin, and click on OK.obj_Magnet
, and assign spr_Magnet
as the Sprite.50
.0
, as we don't want them affecting the magnet's movement.obj_Pillar_Parent
for collision purposes. We still need to be able to have that ability, but we want magnetic attraction to be unique to a few objects. To do this, we can parent the Debris to any object that has obj_Pillar_Parent
as its parent. Let's set the Parent for all Steel Debris to obj_Pillar_Steel_Small
.scr_Pillar_Steel_Create
and add the following line of code at the end of the script:isCollected = false;
scr_Magnet_Step
, and attach it to a Step event in obj_Magnet
.if (phy_active) { if (instance_exists(obj_Pillar_Steel_Small)) { with (obj_Pillar_Steel_Small) { if (!isCollected) { myMagnet = instance_nearest(x,y,obj_Magnet) myDist = point_distance(phy_position_x, phy_position_y, myMagnet.x, myMagnet.y); myDir = point_direction(phy_position_x, phy_position_y, myMagnet.x, myMagnet.y); if (myDist < 200 && myDir > 60 && myDir < 120) { physics_apply_impulse(x, y, 0, -2000) } } } } }
We start by seeing whether the magnet is active and can begin collecting scrap metal. Next, we check if there are any small Steel Pillars, or anything parented to it, in the world. If there are instances in existence, we apply code directly to them through a with
statement. If the instance has not been collected, we find the nearest Magnet, see how far away it is, and in what direction. When checking for the X and Y coordinates of an object in a physics game, we need to use the phy_position_x
and phy_position_y
values to accurately know where they are in the world space. Next, we see if the instance is within the magnetic range, and whether it is underneath the Magnet. If it is, we apply a strong impulse upwards, which will make it move towards the Magnet.
scr_Magnet_Collsion
, and attach it to an obj_Pillar_Steel_Small
event in obj_Magnet
.physics_joint_prismatic_create(id, other, x, y, 0, 1, 0, 0, true, 0, 0, false, false); other.isCollected = true;
Here we are making a Prismatic Joint with the magnet and the instance that collides with it. The first two parameters are the two instances that are to be joined, followed by where in the world they are connected. The fifth and sixth parameters are the direction it can move in, and in this case it is vertical only. The next three are the limits of the movement. We don't want it to move, so we set the min/max values to zero. The limits do need to be enabled, otherwise they won't lift with the Magnet. The following three are for whether there is a motor to move this joint. The final parameter is for collision with the objects which we want to avoid. Once the joint has been created, we then set the collected variable to false
.
spr_CraneBase
, and load Chapter 6/Sprites/CraneBase.png
with Remove Background checked. Center the origin and click on OK.obj_CraneBase
, and apply spr_CraneBase
as the Sprite.0
. All other properties can be left at their default values.scr_CraneBase_Create
, and attach it to a Create event.magnet = instance_create(x, y+160, obj_Magnet); magnet.phy_active = false; crane = physics_joint_prismatic_create(id, magnet, x, y, 0, 1, -128, 128, true, 100000, 20000, true, false);
We are creating the Magnet well below the crane base and have deactivated it from the physics world. We then apply a Prismatic Joint between the two instances. This time we are allowing for 128 pixels of movement in a vertical direction. We are also running a motor, so that the Magnet can move up and down on its own. The maximum force the motor can apply is 100000
and we have the motor dropping the Magnet at a motor speed of 20000
. As you can see, the values we are using are extremely high and the reason for this is to make sure that the heavy magnet can lift plenty of Steel Debris.
scr_CraneBase_Activate
, and for testing purposes, attach it to the Space event under Key Press.magnet.phy_active = true; alarm[0] = 5 * room_speed;
We want the magnet to drop down first, so we make it active in the physics world. We are using an alarm set for five seconds, which will raise the Magnet back up.
scr_CraneBase_Alarm0
and attach it to an Alarm 0 event.physics_joint_set_value(crane, phy_joint_motor_speed, -20000);
We are setting the value for the motor speed to go up at a value of -20000
. Again, we are using a very large number to ensure it goes back up with the additional weight of the Pillar Debris.
scr_CraneBase_Draw
, and apply it to a Draw event.draw_self(); draw_set_color(c_dkgray); draw_line_width(x, y, magnet.x, magnet.y-16, 8);
Whenever a Draw event is used, it overrides the drawing of the default Sprite for the object. Therefore, we use draw_self
to correct that override. Next we set a color to use, here we are using a default dark gray color, and then we draw an 8 pixel wide line between the crane base and the top of the magnet.
Sandbox
. Place the instance off to the left-hand side of the existing Pillars. Also add a few instances of Debris and the small Steel Pillar as can be seen in the following screenshot:3.141.37.10