DownhillAutoscroller.tscn changes
This commit is contained in:
parent
dd148ba02a
commit
6fec533222
File diff suppressed because one or more lines are too long
|
@ -177,7 +177,7 @@ const UNIT_SPRITES = {
|
|||
}
|
||||
|
||||
const UNIT_TYPE_MOVE_SPEEDS = {
|
||||
UnitType.PLAYER: 6,
|
||||
UnitType.PLAYER: 5,
|
||||
UnitType.NPC: 3,
|
||||
}
|
||||
|
||||
|
@ -187,8 +187,8 @@ const UNIT_TYPE_JUMP_SPEEDS = {
|
|||
|
||||
const SCALE_FACTOR = 2.4
|
||||
const GRID_SIZE = 20 # pixels
|
||||
const GRAVITY = 30
|
||||
const MAX_FALL_SPEED = -12
|
||||
const GRAVITY = 10
|
||||
const MAX_FALL_SPEED = -9
|
||||
const ACCELERATION = 35
|
||||
const QUANTUM_DIST = 0.001
|
||||
const SPAWN_DISTANCE = 10
|
||||
|
|
|
@ -9,10 +9,11 @@ extends Node
|
|||
class_name GameScene
|
||||
|
||||
export var tile_set_name: String
|
||||
export var camera_h_offset : float = 1
|
||||
const Constants = preload("res://Scripts/Constants.gd")
|
||||
const Unit = preload("res://Scripts/Unit.gd")
|
||||
const UNIT_DIRECTORY = {
|
||||
Constants.UnitType.NPC: preload("res://Units/NPC.tscn"),
|
||||
Constants.UnitType.NPC: preload("res://Units/DownhillAutoscrollerNPC.tscn"),
|
||||
}
|
||||
|
||||
# positions to unit string
|
||||
|
@ -62,9 +63,9 @@ func _ready():
|
|||
func _process(delta):
|
||||
# visual effects
|
||||
if (player.facing == Constants.Direction.RIGHT):
|
||||
player_cam.offset_h = 1
|
||||
player_cam.offset_h = camera_h_offset
|
||||
else:
|
||||
player_cam.offset_h = -1
|
||||
player_cam.offset_h = -camera_h_offset
|
||||
|
||||
read_paused()
|
||||
if not paused:
|
||||
|
|
|
@ -12,6 +12,7 @@ var colliders = []
|
|||
# if unit's move vector has at least one of these directional components,
|
||||
# do the collision check
|
||||
var collision_into_direction_arrays = [] # nested array
|
||||
var collider_to_map_elem_type = {}
|
||||
|
||||
var unit_collision_bounds = {} # maps unit type to [upper, lower, left, right]
|
||||
|
||||
|
@ -68,64 +69,70 @@ func init_stage_grid(tilemap : TileMap):
|
|||
break
|
||||
match map_elem_type:
|
||||
Constants.MapElemType.SQUARE:
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.DOWN, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.LEFT, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.RIGHT, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.DOWN, 1, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.LEFT, 1, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.RIGHT, 1, map_elem_type)
|
||||
Constants.MapElemType.SLOPE_LEFT:
|
||||
try_insert_collider(
|
||||
Vector2(stage_x, stage_y),
|
||||
Vector2(stage_x + 1, stage_y + 1),
|
||||
[Constants.Direction.RIGHT, Constants.Direction.DOWN]
|
||||
[Constants.Direction.RIGHT, Constants.Direction.DOWN],
|
||||
map_elem_type
|
||||
)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.LEFT, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.LEFT, 1, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1, map_elem_type)
|
||||
Constants.MapElemType.SLOPE_RIGHT:
|
||||
try_insert_collider(
|
||||
Vector2(stage_x, stage_y + 1),
|
||||
Vector2(stage_x + 1, stage_y),
|
||||
[Constants.Direction.LEFT, Constants.Direction.DOWN]
|
||||
[Constants.Direction.LEFT, Constants.Direction.DOWN],
|
||||
map_elem_type
|
||||
)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.RIGHT, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.RIGHT, 1, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1, map_elem_type)
|
||||
Constants.MapElemType.SMALL_SLOPE_LEFT_1:
|
||||
try_insert_collider(
|
||||
Vector2(stage_x, stage_y),
|
||||
Vector2(stage_x + 1, stage_y + .5),
|
||||
[Constants.Direction.RIGHT, Constants.Direction.DOWN]
|
||||
[Constants.Direction.RIGHT, Constants.Direction.DOWN],
|
||||
map_elem_type
|
||||
)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.LEFT, .5)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.LEFT, .5, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1, map_elem_type)
|
||||
Constants.MapElemType.SMALL_SLOPE_LEFT_2:
|
||||
try_insert_collider(
|
||||
Vector2(stage_x, stage_y + .5),
|
||||
Vector2(stage_x + 1, stage_y + 1),
|
||||
[Constants.Direction.RIGHT, Constants.Direction.DOWN]
|
||||
[Constants.Direction.RIGHT, Constants.Direction.DOWN],
|
||||
map_elem_type
|
||||
)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.RIGHT, .5)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.LEFT, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.RIGHT, .5, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.LEFT, 1, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1, map_elem_type)
|
||||
Constants.MapElemType.SMALL_SLOPE_RIGHT_1:
|
||||
try_insert_collider(
|
||||
Vector2(stage_x, stage_y + .5),
|
||||
Vector2(stage_x + 1, stage_y),
|
||||
[Constants.Direction.LEFT, Constants.Direction.DOWN]
|
||||
[Constants.Direction.LEFT, Constants.Direction.DOWN],
|
||||
map_elem_type
|
||||
)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.RIGHT, .5)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.RIGHT, .5, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1, map_elem_type)
|
||||
Constants.MapElemType.SMALL_SLOPE_RIGHT_2:
|
||||
try_insert_collider(
|
||||
Vector2(stage_x, stage_y + 1),
|
||||
Vector2(stage_x + 1, stage_y + .5),
|
||||
[Constants.Direction.LEFT, Constants.Direction.DOWN]
|
||||
[Constants.Direction.LEFT, Constants.Direction.DOWN],
|
||||
map_elem_type
|
||||
)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.RIGHT, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.LEFT, .5)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.RIGHT, 1, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.LEFT, .5, map_elem_type)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.UP, 1, map_elem_type)
|
||||
Constants.MapElemType.LEDGE:
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.DOWN, 1)
|
||||
insert_grid_collider(stage_x, stage_y, Constants.Direction.DOWN, 1, map_elem_type)
|
||||
|
||||
func insert_grid_collider(stage_x, stage_y, direction : int, fractional_height : float):
|
||||
func insert_grid_collider(stage_x, stage_y, direction : int, fractional_height : float, map_elem_type : int):
|
||||
var check_colliders = []
|
||||
var insert_colliders = []
|
||||
var point_a : Vector2
|
||||
|
@ -143,9 +150,9 @@ func insert_grid_collider(stage_x, stage_y, direction : int, fractional_height :
|
|||
Constants.Direction.RIGHT:
|
||||
point_a = Vector2(stage_x, stage_y + (1 * fractional_height))
|
||||
point_b = Vector2(stage_x, stage_y)
|
||||
try_insert_collider(point_a, point_b, [direction])
|
||||
try_insert_collider(point_a, point_b, [direction], map_elem_type)
|
||||
|
||||
func try_insert_collider(point_a : Vector2, point_b : Vector2, directions : Array):
|
||||
func try_insert_collider(point_a : Vector2, point_b : Vector2, directions : Array, map_elem_type : int):
|
||||
if directions.size() == 1:
|
||||
# aligned with grid
|
||||
for i in range(len(colliders)):
|
||||
|
@ -157,6 +164,7 @@ func try_insert_collider(point_a : Vector2, point_b : Vector2, directions : Arra
|
|||
return
|
||||
colliders.append([point_a, point_b])
|
||||
collision_into_direction_arrays.append(directions)
|
||||
collider_to_map_elem_type[[point_a, point_b]] = map_elem_type
|
||||
|
||||
func are_inverse_directions(d1, d2):
|
||||
return ((d1 == Constants.Direction.LEFT and d2 == Constants.Direction.RIGHT)
|
||||
|
@ -205,6 +213,10 @@ func reangle_grounded_move(unit : Unit):
|
|||
unit.pos.y = intersects_results[1].y + Constants.QUANTUM_DIST
|
||||
unit.last_contacted_ground_collider = collider
|
||||
reangle_move(unit, collider, true)
|
||||
# slope acceleration for DownhillAutoscroller:
|
||||
# set the player's last_contacted_map_elem_type field
|
||||
if unit is DownhillAutoscrollerPlayer:
|
||||
unit.last_contacted_map_elem_type = collider_to_map_elem_type[collider]
|
||||
if !has_ground_collision:
|
||||
reangle_move(unit, unit.last_contacted_ground_collider, true)
|
||||
unit.set_unit_condition(Constants.UnitCondition.IS_ON_GROUND, false)
|
||||
|
@ -249,6 +261,11 @@ func check_collision(unit : Unit, collider, collision_into_directions, delta):
|
|||
# landed on ground, horizontal component to become magnitude
|
||||
unit.v_speed = 0
|
||||
reangle_move(unit, collider, false)
|
||||
|
||||
# slope acceleration for DownhillAutoscroller:
|
||||
# set the player's last_contacted_map_elem_type field
|
||||
if unit is DownhillAutoscrollerPlayer:
|
||||
unit.last_contacted_map_elem_type = collider_to_map_elem_type[collider]
|
||||
else:
|
||||
if collider[0].x == collider[1].x:
|
||||
# vertical wall collision
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
extends Player
|
||||
|
||||
class_name DownhillAutoscrollerPlayer
|
||||
|
||||
export var min_speed : float = 2
|
||||
export var max_speed : float = 10
|
||||
export var player_initiated_acceleration : float = 6
|
||||
|
||||
var last_contacted_map_elem_type : int = Constants.MapElemType.SQUARE
|
||||
|
||||
func process_unit(delta, time_elapsed : float):
|
||||
# always be movin'
|
||||
facing = Constants.Direction.RIGHT
|
||||
actions[Constants.ActionType.MOVE] = true
|
||||
|
||||
# Fine tune the player's speed
|
||||
|
||||
if get_current_action() == Constants.UnitCurrentAction.RECOILING:
|
||||
target_move_speed = min_speed
|
||||
else:
|
||||
# override player input so that leftward movement is deceleration,
|
||||
# right movement is acceleration
|
||||
if scene.input_table[Constants.PlayerInput.LEFT][scene.I_T_PRESSED]:
|
||||
target_move_speed = move_toward(target_move_speed, min_speed, player_initiated_acceleration * delta)
|
||||
else:
|
||||
if not get_condition(Constants.UnitCondition.IS_ON_GROUND, true):
|
||||
if (target_move_speed < Constants.UNIT_TYPE_MOVE_SPEEDS[unit_type]
|
||||
and scene.input_table[Constants.PlayerInput.RIGHT][scene.I_T_PRESSED]):
|
||||
target_move_speed = move_toward(target_move_speed, Constants.UNIT_TYPE_MOVE_SPEEDS[unit_type], player_initiated_acceleration * delta)
|
||||
else:
|
||||
# shallow slope: arctan(.5) = 27 degrees, sin(27) = 0.45
|
||||
# steep slope: sin(45) = 0.71
|
||||
var ground_influenced_acceleration = 0
|
||||
var is_decel : bool = false
|
||||
if (last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_RIGHT_1
|
||||
or last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_RIGHT_2
|
||||
or last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_LEFT_1
|
||||
or last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_LEFT_2):
|
||||
ground_influenced_acceleration = Constants.GRAVITY * 0.45
|
||||
if (last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_LEFT_1
|
||||
or last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_LEFT_2):
|
||||
is_decel = true
|
||||
elif (last_contacted_map_elem_type == Constants.MapElemType.SLOPE_RIGHT
|
||||
or last_contacted_map_elem_type == Constants.MapElemType.SLOPE_LEFT):
|
||||
ground_influenced_acceleration = Constants.GRAVITY * 0.71
|
||||
if last_contacted_map_elem_type == Constants.MapElemType.SLOPE_LEFT:
|
||||
is_decel = true
|
||||
if is_decel or ground_influenced_acceleration == 0:
|
||||
var end_speed
|
||||
if ground_influenced_acceleration == 0:
|
||||
# flat ground
|
||||
if scene.input_table[Constants.PlayerInput.RIGHT][scene.I_T_PRESSED]:
|
||||
end_speed = max(target_move_speed, Constants.UNIT_TYPE_MOVE_SPEEDS[unit_type])
|
||||
else:
|
||||
end_speed = target_move_speed
|
||||
else:
|
||||
# incline
|
||||
if scene.input_table[Constants.PlayerInput.RIGHT][scene.I_T_PRESSED]:
|
||||
end_speed = Constants.UNIT_TYPE_MOVE_SPEEDS[unit_type]
|
||||
else:
|
||||
end_speed = min_speed
|
||||
if target_move_speed < end_speed:
|
||||
target_move_speed = move_toward(target_move_speed, end_speed, player_initiated_acceleration * delta)
|
||||
else:
|
||||
target_move_speed = move_toward(target_move_speed, end_speed, ground_influenced_acceleration * delta)
|
||||
else:
|
||||
var acceleration = ground_influenced_acceleration
|
||||
if scene.input_table[Constants.PlayerInput.RIGHT][scene.I_T_PRESSED]:
|
||||
acceleration = max(acceleration, player_initiated_acceleration)
|
||||
if target_move_speed < max_speed:
|
||||
target_move_speed = move_toward(target_move_speed, max_speed, acceleration * delta)
|
||||
|
||||
.process_unit(delta, time_elapsed)
|
||||
|
||||
# treat all collisions as right-side collisions
|
||||
func hit(dir : int):
|
||||
# Unit.gd implementation override
|
||||
hit_queued = true
|
||||
hit_dir = Constants.Direction.RIGHT
|
||||
|
||||
# Player.gd implementation
|
||||
set_unit_condition_with_timer(Constants.UnitCondition.IS_INVINCIBLE)
|
||||
start_flash()
|
||||
set_action(Constants.ActionType.RECOIL)
|
||||
set_current_action(Constants.UnitCurrentAction.RECOILING)
|
||||
set_unit_condition(Constants.UnitCondition.MOVING_STATUS, Constants.UnitMovingStatus.IDLE)
|
||||
|
||||
# override super class's RECOIL_PUSHBACK
|
||||
func handle_recoil():
|
||||
if not hit_queued:
|
||||
return
|
||||
hit_queued = false
|
||||
# skip recoil pushback logic, since target_move_speed is already
|
||||
# set to min_speed
|
|
@ -1,5 +1,7 @@
|
|||
extends NPCUnit
|
||||
|
||||
class_name NPCExample
|
||||
|
||||
|
||||
func before_tick():
|
||||
if scene.rng.randf() < 0.5:
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
extends NPCExample
|
||||
|
||||
|
||||
func before_tick():
|
||||
pass
|
|
@ -0,0 +1,39 @@
|
|||
[gd_scene load_steps=7 format=2]
|
||||
|
||||
[ext_resource path="res://Units/DownhillAutoscrollerNPC.gd" type="Script" id=1]
|
||||
[ext_resource path="res://Graphics/Units/NPC.png" type="Texture" id=2]
|
||||
[ext_resource path="res://Graphics/Animations/NPCWalk.tres" type="SpriteFrames" id=3]
|
||||
[ext_resource path="res://Graphics/Units/NPCJump2.png" type="Texture" id=4]
|
||||
[ext_resource path="res://Graphics/Units/NPCJump1.png" type="Texture" id=5]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=1]
|
||||
extents = Vector2( 6, 14 )
|
||||
|
||||
[node name="NPC" type="Area2D"]
|
||||
collision_mask = 2
|
||||
script = ExtResource( 1 )
|
||||
unit_type = 1
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
position = Vector2( 0, -14 )
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="Idle" type="Sprite" parent="."]
|
||||
visible = false
|
||||
texture = ExtResource( 2 )
|
||||
offset = Vector2( 0, -15 )
|
||||
|
||||
[node name="Jump1" type="Sprite" parent="."]
|
||||
visible = false
|
||||
texture = ExtResource( 5 )
|
||||
offset = Vector2( 0, -15 )
|
||||
|
||||
[node name="Jump2" type="Sprite" parent="."]
|
||||
visible = false
|
||||
texture = ExtResource( 4 )
|
||||
offset = Vector2( 0, -15 )
|
||||
|
||||
[node name="Walk" type="AnimatedSprite" parent="."]
|
||||
visible = false
|
||||
frames = ExtResource( 3 )
|
||||
offset = Vector2( 0, -15 )
|
|
@ -0,0 +1,47 @@
|
|||
[gd_scene load_steps=8 format=2]
|
||||
|
||||
[ext_resource path="res://Scripts/Units/DownhillAutoscrollerPlayer.gd" type="Script" id=1]
|
||||
[ext_resource path="res://Graphics/Units/Player.png" type="Texture" id=2]
|
||||
[ext_resource path="res://Graphics/Units/PlayerJump2.png" type="Texture" id=3]
|
||||
[ext_resource path="res://Graphics/Units/PlayerJump1.png" type="Texture" id=4]
|
||||
[ext_resource path="res://Graphics/Animations/PlayerWalk.tres" type="SpriteFrames" id=5]
|
||||
[ext_resource path="res://Graphics/Units/PlayerRecoil.png" type="Texture" id=6]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=1]
|
||||
extents = Vector2( 6, 14 )
|
||||
|
||||
[node name="Player" type="Area2D"]
|
||||
z_index = 1
|
||||
collision_layer = 0
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
position = Vector2( 0, -14 )
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="Idle" type="Sprite" parent="."]
|
||||
visible = false
|
||||
texture = ExtResource( 2 )
|
||||
offset = Vector2( 0, -15 )
|
||||
|
||||
[node name="Walk" type="AnimatedSprite" parent="."]
|
||||
visible = false
|
||||
frames = ExtResource( 5 )
|
||||
offset = Vector2( 0, -15 )
|
||||
|
||||
[node name="Jump1" type="Sprite" parent="."]
|
||||
visible = false
|
||||
texture = ExtResource( 4 )
|
||||
offset = Vector2( 0, -15 )
|
||||
|
||||
[node name="Jump2" type="Sprite" parent="."]
|
||||
visible = false
|
||||
texture = ExtResource( 3 )
|
||||
offset = Vector2( 0, -15 )
|
||||
|
||||
[node name="Recoil" type="Sprite" parent="."]
|
||||
visible = false
|
||||
texture = ExtResource( 6 )
|
||||
offset = Vector2( 0, -15 )
|
||||
|
||||
[connection signal="area_entered" from="." to="." method="_on_Player_area_entered"]
|
|
@ -9,11 +9,21 @@
|
|||
config_version=4
|
||||
|
||||
_global_script_classes=[ {
|
||||
"base": "Player",
|
||||
"class": "DownhillAutoscrollerPlayer",
|
||||
"language": "GDScript",
|
||||
"path": "res://Scripts/Units/DownhillAutoscrollerPlayer.gd"
|
||||
}, {
|
||||
"base": "Node",
|
||||
"class": "GameScene",
|
||||
"language": "GDScript",
|
||||
"path": "res://Scripts/GameScene.gd"
|
||||
}, {
|
||||
"base": "NPCUnit",
|
||||
"class": "NPCExample",
|
||||
"language": "GDScript",
|
||||
"path": "res://Scripts/Units/NPCExample.gd"
|
||||
}, {
|
||||
"base": "Unit",
|
||||
"class": "NPCUnit",
|
||||
"language": "GDScript",
|
||||
|
@ -30,7 +40,9 @@ _global_script_classes=[ {
|
|||
"path": "res://Scripts/Unit.gd"
|
||||
} ]
|
||||
_global_script_class_icons={
|
||||
"DownhillAutoscrollerPlayer": "",
|
||||
"GameScene": "",
|
||||
"NPCExample": "",
|
||||
"NPCUnit": "",
|
||||
"Player": "",
|
||||
"Unit": ""
|
||||
|
|
Loading…
Reference in New Issue