Vorherige Artikel:
Verbesserungen des Klettersystems ab Satz 2 und mehr
Fügen Sie der Playerszene einen RayCast2D-Knoten hinzu.
So sieht mein Charakter aus. Fügen Sie RayCast am Anfang des Pfeils hinzu.
Im Allgemeinen werde ich den gesamten Code meines Charakters zeigen und versuchen, ihn so klar wie möglich zu kommentieren.
# , .
extends KinematicBody2D
signal timer_ended # _process
const UP_VECTOR: Vector2 = Vector2(0, -1) #
const GRAVITY: int = 40 #
const MOVE_SPEED: int = 100 #
const JUMP_POWER: int = 480 #
const CLIMB_SPEED: int = 40 #
const WALL_JUMP_SPEED: int = 80 #
enum States {ON_FLOOR, ON_WALL} # , 2
onready var ray_cast: Object = $RayCast2D # .
var velocity: Vector2 = Vector2.ZERO # .
var walls: Array = [false, false, false] # . , , .
var timer_enabled: bool = false #
var climbing: bool = false # ,
var is_wall_jump: bool = false # ,
var is_double_jump: bool = true #
var right_pressed: float = 0 # ,
var left_pressed: float = 0
var timer: float = 0 #
var prev_direction: float = 0 # .
var direction: float = 0 # .
var keys: int = 0 # . ,
var current_state: int = States.ON_FLOOR #
func _ready():
ray_cast.add_exception($WallLeft) # ray_cast
ray_cast.add_exception($WallRight)
ray_cast.add_exception(self)
func _process(_delta: float) -> void: # _process
if timer > 0 or timer_enabled:
timer -= _delta # _delta
if timer <= 0 and timer_enabled:
timer_enabled = false
timer = 0 #
emit_signal("timer_ended") # .
if self.direction != 0:
self.ray_cast.cast_to *= -1
self.prev_direction = self.direction # 0
func _physics_process(_delta: float) -> void:
self.control_character()
self.pause_opened() # -
if (!self.climbing): # ,
if (!self.is_wall_jump): # self.velocity.y
self.velocity.y += GRAVITY
else: # 4
self.velocity.y += float(GRAVITY) / 4
self.velocity = self.move_and_slide(self.velocity, UP_VECTOR) # self.velocity
func check_states() -> void:
if self.is_on_floor():
self.current_state = States.ON_FLOOR
is_double_jump = true
elif self.is_on_wall():
self.current_state = States.ON_WALL
is_double_jump = true
elif self.is_on_floor() and self.is_on_wall():
self.current_state = States.ON_WALL
func fall() -> void:
self.velocity.y += GRAVITY
func update_controls(): # "" ""
if !is_wall_jump: # -
self.left_pressed = Input.get_action_strength("ui_left")
self.right_pressed = Input.get_action_strength("ui_right")
func control_character() -> void: #
check_states() #
update_controls() #
self.interact_with() # +
match current_state:
States.ON_WALL:
self.climb()
self.move()
if !climbing:
self.jump()
self.fall()
self.wall_jump()
# States.IN_AIR: #
# self.jump()
# self.move()
# self.fall()
States.ON_FLOOR:
self.jump()
self.move()
func climb():
if (walls[0] or walls[2]): # - self.climbing = "ui_climb".
self.climbing = Input.is_action_pressed("ui_climb")
else: #
self.climbing = false
func climb_up() -> void: #
self.velocity.y = (CLIMB_SPEED)
func climb_down() -> void: #
self.velocity.y = (-CLIMB_SPEED)
func move() -> void: # . ,
self.direction = self.right_pressed - self.left_pressed
if (self.climbing and !self.is_wall_jump):
if self.walls[0]: #
if direction > 0: # -
climb_up()
elif direction < 0: # -
climb_down()
else: #
self.velocity.y = 0
elif self.walls[2]: # ,
if direction < 0:
climb_up()
elif direction > 0:
climb_down()
else:
self.velocity.y = 0
# else: # ,
# self.velocity.y = 0
else: #
self.velocity.x = self.direction * float(MOVE_SPEED) * (1 + (float(self.is_wall_jump) / 2))
if !(climbing): #
if direction == 0:
$AnimatedSprite.flip_h = (-self.prev_direction >= 0)
$AnimatedSprite.play("idle")
else:
$AnimatedSprite.flip_h = direction < 0
$AnimatedSprite.play("run")
return
func jump() -> void: #
if Input.is_action_just_pressed("ui_accept"):
if is_on_floor():
self.velocity.y = -JUMP_POWER
if !is_on_floor() and is_double_jump:
is_double_jump = false
self.velocity.y = -JUMP_POWER
func wall_jump() -> void:
if Input.is_action_just_pressed("ui_accept") and Input.is_action_pressed("ui_climb"):
self.is_wall_jump = true
self.velocity.y = -JUMP_POWER
if walls[0]:
self.timer = 0.3
self.timer_enabled = true
self.right_pressed = 1 # -
yield(self, "timer_ended") #
self.right_pressed = Input.get_action_strength("ui_right")
#
elif walls[2]:
self.timer = 0.3
self.timer_enabled = true
self.left_pressed = 1 # -
yield(self, "timer_ended")
self.left_pressed = Input.get_action_strength("ui_left")
#
self.is_wall_jump = false #
func interact_with() -> void: #
if Input.is_action_pressed("ui_use"): #
var coll: Object = self.ray_cast.get_collider() #
if coll: # null
if coll.has_method("open"): # ,
use_key(coll)
elif coll.has_method("interact"):
use_object(coll)
func use_object(collider: Object) -> void: #
collider.interact(self) #
func use_key(collider: Object) -> void: # .
if self.keys > 0: #
collider.open() #
self.keys -= 1 #
func key_picked_up():
self.keys += 1
func _on_WallRight_body_entered(_body): # .
if (_body.name != self.name): # - -
self.walls[2] = true # walls true false.
func _on_WallRight_body_exited(_body): #
self.walls[2] = false #
func _on_WallLeft_body_entered(_body): #
if (_body.name != self.name): #
self.walls[0] = true #
func _on_WallLeft_body_exited(_body): #
self.walls[0] = false #
func dead():
# $Particles2D.emitting = true # -
LevelMgr.goto_scene("res://scenes/dead_screen/dead_screen.tscn") # .
func pause_opened(): #
if Input.is_action_just_pressed("ui_cancel"): #
$PositionResetter/WindowDialog.popup_centered()
Fazit
Im Moment ist dies der aktuellste Zeichencode, den ich gerade erstellt habe. Aufgrund der Tatsache, dass der Code vollständig fertig ist, muss ich nichts separat hinzufügen. Und da ich die Lektionen über Fallen in einem separaten Zyklus genommen habe, habe ich auch nichts zu den Beispielen für die Verwendung des Interaktionssystems zu sagen. Ich habe mich auch gefragt, was Sie im nächsten Teil lieber herausfinden möchten, und im Folgenden eine Umfrage vorgestellt, die Ideen für Mechaniker enthält, die mir in den Sinn gekommen sind. Danke fürs Lesen und bis zum nächsten Mal.