155 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			GDScript
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			GDScript
		
	
	
	
	
	
class_name Player extends CharacterBody2D
 | 
						|
 | 
						|
 | 
						|
const SPEED = 300.0
 | 
						|
const JUMP_VELOCITY = -400.0
 | 
						|
var direction:float = 0
 | 
						|
@export var BUMP_POWER = 100
 | 
						|
enum FaceDirection{LEFT, RIGHT}
 | 
						|
var facing:FaceDirection = FaceDirection.RIGHT
 | 
						|
enum State{IDLE,JUMP,FALLING,RUNNING,SHOVE}
 | 
						|
var current_state:State = State.IDLE
 | 
						|
 | 
						|
@onready var right_cast = $RightCast
 | 
						|
@onready var left_cast = $LeftCast
 | 
						|
var pushTarget:RigidBody2D
 | 
						|
var pushEnabled:bool = false
 | 
						|
@onready var right_spawn = $RightSpawn
 | 
						|
@onready var left_spawn = $LeftSpawn
 | 
						|
 | 
						|
@export var acceleration:int = 900
 | 
						|
@onready var jump_buffer_timer = $JumpBufferTimer
 | 
						|
var upJump:bool = false
 | 
						|
 | 
						|
@export var hard_gravity:float =1.5
 | 
						|
@onready var player_graphic = $PlayerGraphic
 | 
						|
 | 
						|
func _physics_process(delta):
 | 
						|
	# Get the input direction and handle the movement/deceleration.
 | 
						|
	# As good practice, you should replace UI actions with custom gameplay actions.
 | 
						|
	handle_input()
 | 
						|
	handle_movement(delta)
 | 
						|
	update_states()
 | 
						|
	update_animation()
 | 
						|
	move_and_slide()
 | 
						|
	handle_collisions()
 | 
						|
 | 
						|
func update_states()->void:
 | 
						|
	#Create a state machine
 | 
						|
	match current_state:
 | 
						|
		#scenarios
 | 
						|
		State.JUMP when velocity.y > 0:
 | 
						|
			current_state = State.FALLING
 | 
						|
		State.FALLING when is_on_floor():
 | 
						|
			if velocity.x == 0:
 | 
						|
				current_state = State.IDLE
 | 
						|
			else:
 | 
						|
				current_state = State.RUNNING
 | 
						|
		State.IDLE when velocity.x !=0:
 | 
						|
			current_state = State.RUNNING
 | 
						|
		State.RUNNING when velocity.x ==0:
 | 
						|
			current_state = State.IDLE
 | 
						|
				
 | 
						|
func update_animation()->void:
 | 
						|
	match current_state:
 | 
						|
		State.IDLE:
 | 
						|
			player_graphic.play("idle")		
 | 
						|
		State.JUMP:
 | 
						|
			if upJump:
 | 
						|
				player_graphic.play("jump")	
 | 
						|
		State.FALLING:
 | 
						|
			player_graphic.play("fall")
 | 
						|
		State.RUNNING:
 | 
						|
			player_graphic.play("run")
 | 
						|
		State.SHOVE:
 | 
						|
			player_graphic.play("shove")
 | 
						|
			
 | 
						|
func handle_input()->void:
 | 
						|
	# Handle jump.
 | 
						|
	if Input.is_action_just_pressed("jump") and is_on_floor():
 | 
						|
		#velocity.y = JUMP_VELOCITY
 | 
						|
		jump_buffer_timer.start()
 | 
						|
	direction = Input.get_axis("moveLeft", "moveRight")
 | 
						|
	if direction <0:
 | 
						|
		facing=FaceDirection.LEFT
 | 
						|
		player_graphic.flip_h = true
 | 
						|
	if direction >0:
 | 
						|
		facing=FaceDirection.RIGHT
 | 
						|
		player_graphic.flip_h = false
 | 
						|
		
 | 
						|
	if Input.is_action_just_pressed("shove") && pushEnabled:
 | 
						|
		print("I want to shove")
 | 
						|
		var shoveDirection:int
 | 
						|
		match facing:
 | 
						|
			FaceDirection.RIGHT:
 | 
						|
				shoveDirection = 1
 | 
						|
			FaceDirection.LEFT:
 | 
						|
				shoveDirection = -1
 | 
						|
		current_state = State.SHOVE
 | 
						|
		pushTarget.apply_central_impulse(Vector2(shoveDirection,0)*700)
 | 
						|
	if Input.is_action_just_pressed("shoot"):
 | 
						|
		print("Ima shoot")
 | 
						|
		match facing:
 | 
						|
			FaceDirection.RIGHT:
 | 
						|
				print("shoot right")
 | 
						|
				%SceneManager.makeBullet(right_spawn.global_transform, 700)
 | 
						|
			FaceDirection.LEFT:
 | 
						|
				print("shoot left")
 | 
						|
				%SceneManager.makeBullet(left_spawn.global_transform, -700)
 | 
						|
	if Input.is_action_just_pressed("chuck"):
 | 
						|
		print("ima chuck a grenade")
 | 
						|
		match facing:
 | 
						|
			FaceDirection.RIGHT:
 | 
						|
				%SceneManager.makeGrenade(right_spawn.global_transform, 1)
 | 
						|
			FaceDirection.LEFT:
 | 
						|
				%SceneManager.makeGrenade(left_spawn.global_transform, -1)
 | 
						|
				
 | 
						|
func handle_movement(_delta)->void:
 | 
						|
	if direction ==0:
 | 
						|
		velocity.x = move_toward(velocity.x, 0, acceleration*_delta)
 | 
						|
	else:
 | 
						|
		velocity.x = move_toward(velocity.x, SPEED*direction, acceleration*_delta)
 | 
						|
	
 | 
						|
	if current_state == State.JUMP: 
 | 
						|
		#apply normal velocity
 | 
						|
		velocity += get_gravity() * _delta
 | 
						|
	else:
 | 
						|
		velocity += get_gravity() * hard_gravity * _delta
 | 
						|
			
 | 
						|
	if is_on_floor() && jump_buffer_timer.time_left>0:
 | 
						|
		velocity.y = JUMP_VELOCITY 
 | 
						|
		current_state = State.JUMP
 | 
						|
		upJump = true
 | 
						|
		jump_buffer_timer.stop()
 | 
						|
		
 | 
						|
func handle_collisions()->void:
 | 
						|
	#handle world reactions
 | 
						|
	for i in get_slide_collision_count():
 | 
						|
		var c = get_slide_collision(i)
 | 
						|
		if c.get_collider() is RigidBody2D:
 | 
						|
			c.get_collider().apply_central_impulse(-c.get_normal() * BUMP_POWER)
 | 
						|
	
 | 
						|
	if right_cast.is_colliding() && facing==FaceDirection.RIGHT:
 | 
						|
		var collider = right_cast.get_collider()
 | 
						|
		#check if this is okay
 | 
						|
		if collider is Node && collider is RigidBody2D && collider.is_in_group("pushable"):
 | 
						|
			pushTarget = collider
 | 
						|
			pushEnabled = true
 | 
						|
			
 | 
						|
	if left_cast.is_colliding() && facing==FaceDirection.LEFT:
 | 
						|
		var collider = left_cast.get_collider()
 | 
						|
		if collider is Node && collider is RigidBody2D && collider.is_in_group("pushable"):
 | 
						|
			pushTarget = collider
 | 
						|
			pushEnabled = true
 | 
						|
		 
 | 
						|
	if not right_cast.is_colliding() && not left_cast.is_colliding():
 | 
						|
		pushEnabled = false
 | 
						|
 | 
						|
 | 
						|
func _on_animation_finished():
 | 
						|
	match current_state:
 | 
						|
		State.JUMP:
 | 
						|
			upJump=false
 | 
						|
		State.SHOVE:
 | 
						|
			current_state = State.IDLE
 |