Update 2D physics platformer

This commit is contained in:
Aaron Franke
2020-02-03 03:08:00 -05:00
parent 375d5d13d2
commit 3eeba859b1
17 changed files with 143 additions and 156 deletions

View File

@@ -190,7 +190,7 @@ scale = 0.5
scale_random = 1.0
color = Color( 0.214844, 1, 0.392731, 1 )
[node name="Node" type="Node"]
[node name="Particles" type="Node"]
[node name="Fire" type="Particles2D" parent="."]
material = SubResource( 1 )

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=21 format=2]
[gd_scene load_steps=22 format=2]
[ext_resource path="res://Tileset.tres" type="TileSet" id=1]
[ext_resource path="res://coin/Coin.tscn" type="PackedScene" id=2]
@@ -8,14 +8,7 @@
[ext_resource path="res://player/Player.tscn" type="PackedScene" id=6]
[ext_resource path="res://enemy/Enemy.tscn" type="PackedScene" id=7]
[ext_resource path="res://background/ParallaxBg.tscn" type="PackedScene" id=8]
[ext_resource path="res://audio/music.ogg" type="AudioStream" id=9]
[sub_resource type="PhysicsMaterial" id=1]
friction = 0.0
@@ -53,7 +46,7 @@ friction = 0.0
[sub_resource type="PhysicsMaterial" id=12]
friction = 0.0
[node name="Stage" type="Node"]
[node name="Stage" type="Node2D"]
[node name="TileMap" type="TileMap" parent="."]
tile_set = ExtResource( 1 )
@@ -64,7 +57,8 @@ __meta__ = {
"_edit_lock_": true
}
[node name="Coins" type="Node" parent="."]
[node name="Coins" type="Node2D" parent="."]
editor/display_folded = true
[node name="Coin" parent="Coins" instance=ExtResource( 2 )]
position = Vector2( 672, 1179 )
@@ -192,7 +186,8 @@ position = Vector2( 4236.75, 541.058 )
[node name="Coin42" parent="Coins" instance=ExtResource( 2 )]
position = Vector2( 4172.75, 541.058 )
[node name="Props" type="Node" parent="."]
[node name="Props" type="Node2D" parent="."]
editor/display_folded = true
[node name="MovingPlatform" parent="Props" instance=ExtResource( 3 )]
position = Vector2( 1451.86, 742.969 )
@@ -219,7 +214,8 @@ position = Vector2( 927.698, 1120.81 )
position = Vector2( 251.684, 1045.6 )
physics_material_override = SubResource( 1 )
[node name="Enemies" type="Node" parent="."]
[node name="Enemies" type="Node2D" parent="."]
editor/display_folded = true
[node name="Enemy1" parent="Enemies" instance=ExtResource( 7 )]
position = Vector2( 834.664, 1309.6 )
@@ -277,3 +273,6 @@ size_flags_vertical = 0
text = "This is a simple demo on how to make a platformer game with Godot.\"This version uses physics and the 2D physics engine for motion and collision.\"\"The demo also shows the benefits of using the scene system, where coins,\"enemies and the player are edited separatedly and instanced in the stage.\"\"To edit the base tiles for the tileset, open the tileset_edit.tscn file and follow \"instructions.\""
autowrap = true
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
stream = ExtResource( 9 )
autoplay = true

View File

@@ -4,10 +4,7 @@
[ext_resource path="res://player/Player.tscn" type="PackedScene" id=2]
[ext_resource path="res://background/ParallaxBg.tscn" type="PackedScene" id=3]
[node name="Stage" type="Node"]
[node name="Stage2" type="Node2D"]
[node name="TileMap" type="TileMap" parent="."]
tile_set = ExtResource( 1 )
@@ -32,4 +29,3 @@ size_flags_horizontal = 2
size_flags_vertical = 0
text = "This is a simple demo on how to make a platformer game with Godot.\"This version uses physics and the 2D physics engine for motion and collision.\"\"The demo also shows the benefits of using the scene system, where coins,\"enemies and the player are edited separatedly and instanced in the stage.\"\"To edit the base tiles for the tileset, open the tileset_edit.tscn file and follow \"instructions.\""
autowrap = true

View File

@@ -2,7 +2,7 @@
[ext_resource path="res://tiles_demo.png" type="Texture" id=1]
[node name="Node" type="Node"]
[node name="TilesetEdit" type="Node2D"]
[node name="Floor" type="Sprite" parent="."]
texture = ExtResource( 1 )
@@ -156,4 +156,3 @@ text = "This scene serves as a tool for editing the tileset.
This will save a tileset. Saving over it will merge your changes.
Finally, the saved tileset resource (tileset.tres in this case), can be opened to be used into a TileMap node for editing a tile map."

View File

@@ -71,4 +71,3 @@ position = Vector2( 0, 225 )
texture = ExtResource( 6 )
centered = false
region_rect = Rect2( 0, 0, 800, 256 )

View File

@@ -105,6 +105,7 @@ emission_sphere_radius = 20.0
flag_disable_z = true
gravity = Vector3( 0, 0, 0 )
initial_velocity = 1.0
angular_velocity = 0.0191222
orbit_velocity = 0.0
orbit_velocity_random = 0.0
scale = 0.3
@@ -117,7 +118,7 @@ script = ExtResource( 1 )
texture = ExtResource( 2 )
hframes = 4
[node name="Anim" type="AnimationPlayer" parent="."]
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
autoplay = "spin"
anims/spin = SubResource( 1 )
anims/taken = SubResource( 2 )
@@ -139,5 +140,4 @@ texture = ExtResource( 4 )
[node name="Enabler" type="VisibilityEnabler2D" parent="."]
pause_particles = false
[connection signal="body_entered" from="." to="." method="_on_body_enter"]

View File

@@ -1,11 +1,8 @@
class_name Coin
extends Area2D
class_name Coin
# Member variables
var taken = false
func _on_body_enter( body ):
func _on_body_enter(body):
if not taken and body is Player:
($Anim as AnimationPlayer).play("taken")
($AnimationPlayer as AnimationPlayer).play("taken")

View File

@@ -117,6 +117,7 @@ flag_disable_z = true
spread = 180.0
gravity = Vector3( 0, 98, 0 )
initial_velocity = 322.73
angular_velocity = 1.5
orbit_velocity = 0.0
orbit_velocity_random = 0.0
scale = 2.4
@@ -133,7 +134,7 @@ position = Vector2( 16.2569, 11.0034 )
scale = Vector2( 23.5056, 10.8629 )
pause_particles = false
[node name="Anim" type="AnimationPlayer" parent="."]
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
anims/explode = SubResource( 2 )
anims/idle = SubResource( 3 )
anims/walk = SubResource( 4 )
@@ -179,4 +180,3 @@ stream = ExtResource( 4 )
[node name="SoundExplode" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource( 5 )

View File

@@ -1,53 +1,30 @@
class_name Enemy
extends RigidBody2D
class_name Enemy
# Member variables
const WALK_SPEED = 50
const STATE_WALKING = 0
const STATE_DYING = 1
# state machine
var state = STATE_WALKING
enum State {
WALKING,
DYING
}
var state = State.WALKING
var direction = -1
var anim = ""
onready var rc_left = $RaycastLeft
onready var rc_right = $RaycastRight
var Bullet = preload("res://player/bullet.gd")
func _die():
queue_free()
func _pre_explode():
#make sure nothing collides against this
$Shape1.queue_free()
$Shape2.queue_free()
$Shape3.queue_free()
# Stay there
mode = MODE_STATIC
($SoundExplode as AudioStreamPlayer2D).play()
func _bullet_collider(cc, s, dp):
mode = MODE_RIGID
state = STATE_DYING
s.set_angular_velocity(sign(dp.x) * 33.0)
set_friction(1)
cc.disable()
($SoundHit as AudioStreamPlayer2D).play()
onready var rc_left = $RaycastLeft
onready var rc_right = $RaycastRight
func _integrate_forces(s):
var lv = s.get_linear_velocity()
var new_anim = anim
if state == STATE_DYING:
if state == State.DYING:
new_anim = "explode"
elif state == STATE_WALKING:
elif state == State.WALKING:
new_anim = "walk"
var wall_side = 0.0
@@ -81,6 +58,31 @@ func _integrate_forces(s):
if anim != new_anim:
anim = new_anim
($Anim as AnimationPlayer).play(anim)
($AnimationPlayer as AnimationPlayer).play(anim)
s.set_linear_velocity(lv)
func _die():
queue_free()
func _pre_explode():
#make sure nothing collides against this
$Shape1.queue_free()
$Shape2.queue_free()
$Shape3.queue_free()
# Stay there
mode = MODE_STATIC
($SoundExplode as AudioStreamPlayer2D).play()
func _bullet_collider(cc, s, dp):
mode = MODE_RIGID
state = State.DYING
s.set_angular_velocity(sign(dp.x) * 33.0)
set_friction(1)
cc.disable()
($SoundHit as AudioStreamPlayer2D).play()

View File

@@ -3,7 +3,7 @@
[ext_resource path="res://platform/moving_platform.gd" type="Script" id=1]
[ext_resource path="res://platform/moving_platform.png" type="Texture" id=2]
[node name="Moving_platform" type="Node2D"]
[node name="MovingPlatform" type="Node2D"]
script = ExtResource( 1 )
[node name="Platform" type="RigidBody2D" parent="."]
@@ -14,4 +14,3 @@ texture = ExtResource( 2 )
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Platform"]
polygon = PoolVector2Array( -88, -24, 88, -24, 88, 24, -88, 24 )

View File

@@ -5,7 +5,7 @@
[sub_resource type="RectangleShape2D" id=1]
extents = Vector2( 100, 10 )
[node name="One_way_platform" type="StaticBody2D"]
[node name="OneWayPlatform" type="StaticBody2D"]
[node name="Sprite" type="Sprite" parent="."]
texture = ExtResource( 1 )
@@ -14,4 +14,3 @@ texture = ExtResource( 1 )
position = Vector2( 1.46304, -13.1672 )
shape = SubResource( 1 )
one_way_collision = true

View File

@@ -1,17 +1,14 @@
class_name MovingPlatform
extends Node2D
class_name MovingPlatform
# Member variables
export var motion = Vector2()
export var cycle = 1.0
var accum = 0.0
func _physics_process(delta):
accum += delta * (1.0 / cycle) * PI * 2.0
accum = fmod(accum, PI * 2.0)
accum += delta * (1.0 / cycle) * TAU
accum = fmod(accum, TAU)
var d = sin(accum)
var xf = Transform2D()

View File

@@ -80,7 +80,6 @@ shape = SubResource( 3 )
[node name="Timer" type="Timer" parent="."]
one_shot = true
[node name="Anim" type="AnimationPlayer" parent="."]
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
anims/shutdown = SubResource( 4 )
[connection signal="timeout" from="Timer" to="." method="disable"]

View File

@@ -229,7 +229,7 @@ local_coords = false
process_material = SubResource( 4 )
texture = ExtResource( 3 )
[node name="Anim" type="AnimationPlayer" parent="."]
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
anims/crouch = SubResource( 5 )
anims/falling = SubResource( 6 )
anims/falling_weapon = SubResource( 7 )
@@ -295,4 +295,3 @@ stream = ExtResource( 8 )
[node name="SoundJump" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource( 9 )

View File

@@ -1,17 +1,15 @@
class_name Bullet
extends RigidBody2D
class_name Bullet
# Member variables
var disabled = false
func _ready():
($Timer as Timer).start()
func disable():
if disabled:
return
($Anim as AnimationPlayer).play("shutdown")
disabled = true
($AnimationPlayer as AnimationPlayer).play("shutdown")
disabled = true

View File

@@ -1,30 +1,28 @@
class_name Player
extends RigidBody2D
class_name Player
# Character Demo, written by Juan Linietsky.
#
# Implementation of a 2D Character controller.
# This implementation uses the physics engine for
# controlling a character, in a very similar way
# than a 3D character controller would be implemented.
#
# Using the physics engine for this has the main advantages:
# - Easy to write.
# - Interaction with other physics-based objects is free
# - Only have to deal with the object linear velocity, not position
# - All collision/area framework available
#
# But also has the following disadvantages:
# - Objects may bounce a little bit sometimes
# - Going up ramps sends the chracter flying up, small hack is needed.
# - A ray collider is needed to avoid sliding down on ramps and
# undesiderd bumps, small steps and rare numerical precision errors.
# (another alternative may be to turn on friction when the character is not moving).
# - Friction cant be used, so floor velocity must be considered
# for moving platforms.
""" Character Demo, written by Juan Linietsky.
Implementation of a 2D Character controller.
This implementation uses the physics engine for
controlling a character, in a very similar way
than a 3D character controller would be implemented.
Using the physics engine for this has the main advantages:
- Easy to write.
- Interaction with other physics-based objects is free
- Only have to deal with the object linear velocity, not position
- All collision/area framework available
But also has the following disadvantages:
- Objects may bounce a little bit sometimes
- Going up ramps sends the chracter flying up, small hack is needed.
- A ray collider is needed to avoid sliding down on ramps and
undesiderd bumps, small steps and rare numerical precision errors.
(another alternative may be to turn on friction when the character is not moving).
- Friction cant be used, so floor velocity must be considered
for moving platforms. """
# Member variables
const WALK_ACCEL = 800.0
const WALK_DEACCEL = 800.0
const WALK_MAX_VELOCITY = 200.0
@@ -49,27 +47,6 @@ var shoot_time = 1e20
var Bullet = preload("res://player/Bullet.tscn")
var Enemy = preload("res://enemy/Enemy.tscn")
func _shot_bullet():
shoot_time = 0
var bi = Bullet.instance()
var ss
if siding_left:
ss = -1.0
else:
ss = 1.0
var pos = position + ($BulletShoot as Position2D).position * Vector2(ss, 1.0)
bi.position = pos
get_parent().add_child(bi)
bi.linear_velocity = Vector2(800.0 * ss, -80)
($Sprite/Smoke as Particles2D).restart()
($SoundShoot as AudioStreamPlayer2D).play()
add_collision_exception_with(bi) # Make bullet and this not collide
func _integrate_forces(s):
var lv = s.get_linear_velocity()
var step = s.get_step()
@@ -77,7 +54,7 @@ func _integrate_forces(s):
var new_anim = anim
var new_siding_left = siding_left
# Get the controls
# Get the controls.
var move_left = Input.is_action_pressed("move_left")
var move_right = Input.is_action_pressed("move_right")
var jump = Input.is_action_pressed("jump")
@@ -85,19 +62,13 @@ func _integrate_forces(s):
var spawn = Input.is_action_pressed("spawn")
if spawn:
var e = Enemy.instance()
var p = position
p.y = p.y - 100
e.position = p
get_parent().add_child(e)
call_deferred("_spawn_enemy_above")
# Deapply prev floor velocity
# Deapply prev floor velocity.
lv.x -= floor_h_velocity
floor_h_velocity = 0.0
# Find the floor (a contact with upwards facing collision normal)
# Find the floor (a contact with upwards facing collision normal).
var found_floor = false
var floor_index = -1
@@ -118,14 +89,14 @@ func _integrate_forces(s):
if found_floor:
airborne_time = 0.0
else:
airborne_time += step # Time it spent in the air
airborne_time += step # Time it spent in the air.
var on_floor = airborne_time < MAX_FLOOR_AIRBORNE_TIME
# Process jump
# Process jump.
if jumping:
if lv.y > 0:
# Set off the jumping flag if going down
# Set off the jumping flag if going down.
jumping = false
elif not jump:
stopping_jump = true
@@ -134,7 +105,7 @@ func _integrate_forces(s):
lv.y += STOP_JUMP_FORCE * step
if on_floor:
# Process logic when character is on floor
# Process logic when character is on floor.
if move_left and not move_right:
if lv.x > -WALK_MAX_VELOCITY:
lv.x -= WALK_ACCEL * step
@@ -148,14 +119,14 @@ func _integrate_forces(s):
xv = 0
lv.x = sign(lv.x) * xv
# Check jump
# Check jump.
if not jumping and jump:
lv.y = -JUMP_VELOCITY
jumping = true
stopping_jump = false
($SoundJump as AudioStreamPlayer2D).play()
# Check siding
# Check siding.
if lv.x < 0 and move_left:
new_siding_left = true
elif lv.x > 0 and move_right:
@@ -173,7 +144,7 @@ func _integrate_forces(s):
else:
new_anim = "run"
else:
# Process logic when the character is in the air
# Process logic when the character is in the air.
if move_left and not move_right:
if lv.x > -WALK_MAX_VELOCITY:
lv.x -= AIR_ACCEL * step
@@ -199,7 +170,7 @@ func _integrate_forces(s):
else:
new_anim = "falling"
# Update siding
# Update siding.
if new_siding_left != siding_left:
if new_siding_left:
($Sprite as Sprite).scale.x = -1
@@ -208,18 +179,45 @@ func _integrate_forces(s):
siding_left = new_siding_left
# Change animation
# Change animation.
if new_anim != anim:
anim = new_anim
($Anim as AnimationPlayer).play(anim)
($AnimationPlayer as AnimationPlayer).play(anim)
shooting = shoot
# Apply floor velocity
# Apply floor velocity.
if found_floor:
floor_h_velocity = s.get_contact_collider_velocity_at_position(floor_index).x
lv.x += floor_h_velocity
# Finally, apply gravity and set back the linear velocity
# Finally, apply gravity and set back the linear velocity.
lv += s.get_total_gravity() * step
s.set_linear_velocity(lv)
s.set_linear_velocity(lv)
func _shot_bullet():
shoot_time = 0
var bi = Bullet.instance()
var ss
if siding_left:
ss = -1.0
else:
ss = 1.0
var pos = position + ($BulletShoot as Position2D).position * Vector2(ss, 1.0)
bi.position = pos
get_parent().add_child(bi)
bi.linear_velocity = Vector2(800.0 * ss, -80)
($Sprite/Smoke as Particles2D).restart()
($SoundShoot as AudioStreamPlayer2D).play()
add_collision_exception_with(bi) # Make bullet and this not collide.
func _spawn_enemy_above():
var e = Enemy.instance()
e.position = position + 100 * Vector2.UP
get_parent().add_child(e)

View File

@@ -79,18 +79,23 @@ jump={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
]
}
move_left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
]
}
move_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
]
}
shoot={
@@ -98,6 +103,7 @@ shoot={
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":7,"pressure":0.0,"pressed":false,"script":null)
]
}
spawn={