GodotCourse/week2/exercise1_cannon.md

85 lines
3.1 KiB
Markdown
Raw Normal View History

2024-07-15 18:37:19 +00:00
## 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))
```