diff --git a/week2/exercise1_cannon.md b/week2/exercise1_cannon.md new file mode 100644 index 0000000..03102ed --- /dev/null +++ b/week2/exercise1_cannon.md @@ -0,0 +1,84 @@ +## Exercise 1: Projectiles + +There are several ways we can create projectiles in Godot. To choose the right one we need to think about how the projectiles should behave. Consider the following: + +* Should there be a limited number of projectiles? +* What happens to projectiles that leave the viewing area? +* Should shots ricochet? +* Do projectiles need momentum, acceleration, deceleration? + +Depending on what we need the projectiles to do, we could choose a body type for them. + +### Area Node Bullet + +The area node is probably the simplest way to achieve a projectile. Areas can receive signals when a child collision shape intersects another collision shape (so they know when they have hit something). + +An area node also inherits a Transform, with a position property that can be written to. + +``` +extends Area2D + +var speed = 750 + +func setSpeed(speedVal): + speed = speedVal + +func _physics_process(delta): + position += transform.x * speed * delta + +func _on_body_entered(body): + # blast the body? + if body.is_in_group("boxes"): + body.queue_free() + queue_free() +``` + +Now to use our bullet we need to be able to create the bullet and position it with code. This is called instantiation. + +To be able to instantiate a scene in Godot we must pre-load it. + +`var bullet = preload("res://scenes/bullet.tscn")` + +We can now create as many isntances of the bullet as we wish! + +But be careful! When we add our bullet to the world, we want to add it at the global scope - not at the scope of the character. Otherwise, when the character moves the bullet will move with them. + +``` +if Input.is_action_just_pressed("blast"): + var mybullet = bullet.instantiate() + mybullet.setSpeed(-BLAST_SPEED if faceLeft else BLAST_SPEED) + owner.add_child(mybullet) + mybullet.transform = markerLeft.global_transform if faceLeft else markerRight.global_transform +``` + +### RigidBody Missile + +For our next example, we will create our projectile from a RigidBody so that it can react via physics to the environment. + +One thing to note about RigidBodies is that they do not by default hear collision signals. This is a performance consideration, and usually this is a good thing, but in the case of our missile we want the RigidBody to know about the collision. + +For this reason in the inspector we will need to turn on collision_monitor and set a value in max_collision_objects. After this, we will be able to detect collisions. + +``` +extends RigidBody2D + +func _on_body_entered(body): + # check here to see if the thing should explode + print("missile hit something") + + if body.is_in_group("boxes"): + body.queue_free() + if not body.is_in_group("player"): + queue_free() +``` + +As before, we need to think about instantiation of the missile. Depending on the direction the player is facing, we could either apply a negative or a positive impulse to the RigidBody. + +``` +if Input.is_action_just_pressed("blast"): + var myMissile = missile.instantiate() + owner.add_child(myMissile) + myMissile.transform = markerLeft.global_transform if faceLeft else markerRight.global_transform + var missileForce = -600 if faceLeft else 600 + myMissile.apply_impulse(Vector2(missileForce,10), Vector2(0, 0)) +```