GDSCRIPT player - YeOldeDM/Pgeki GitHub Wiki
back to Code-Objects
Physics integration and logic for the all-important Player object.
extends RigidBody2D
#########################################
# Basic Character Motion #
# based on the Demo by Juan Linietsky #
#########################################
# Mob Spawner #
var mob = preload('res://brub.xml')
# Spear preload #
var spear = preload('res://spear.xml')
# Character States #
var animation = ''
var facing = 1
# State Switches #
var is_jumping = false
var did_jump = false
var stopping_jump=false
var did_step = 0
var did_shoot=false
var is_hit=false
# timers #
var hit_timer=0
var hit_timelimit=3.0
# Movement Variables #
var WALK_ATK = 300.0
var WALK_DEC = 300.0
var WALK_MAX_SPEED = 60.0
var AIR_ATK = 150.0
var AIR_DEC = 75.0
var JUMP_VELOCITY = 130
var STOP_JUMP_FORCE = 900.0
var MAX_FLOOR_AIRBORNE_TIME = 0.15
var airborne_time = 1e20
var floor_h_velocity = 0.0
var SPEAR_SPEED = 325.0
var SPEAR_DROP = -35
var respawn_point = Vector2(100,50)
#################################
# Custom physics integration #
#################################
func _integrate_forces(state):
var lv = state.get_linear_velocity() #our current velocity
var step = state.get_step() #time delta
var new_animation = animation
var new_facing = facing
# GET INPUT #
###############
var move_left = Input.is_action_pressed('move_left')
var move_right = Input.is_action_pressed('move_right')
var action = Input.is_action_pressed('action')
var jump = Input.is_action_pressed('jump')
var respawn = Input.is_action_pressed('respawn')
#Deapply prev floor velocity
lv.x -= floor_h_velocity
floor_h_velocity = 0.0
# SPEAR THROWING #
####################
if (action and not did_shoot):
var bullet = spear.instance()
var pos = get_pos()
bullet.set_pos(pos)
get_parent().add_child(bullet)
if facing == -1: #Rotate if facing left
bullet.set_rot(deg2rad(180.0))
#set spear velocity
bullet.set_linear_velocity( Vector2(SPEAR_SPEED*facing, SPEAR_DROP))
#add us as a collision exception
#keeps us from shooting ourself in the foot ;)
PS2D.body_add_collision_exception(bullet.get_rid(),get_rid())
#rate of fire switch
did_shoot = true
# FLOOR COLLISION #
#####################
var found_floor=false
var floor_index = -1
for x in range(state.get_contact_count()):
var ci = state.get_contact_local_normal(x)
if (ci.dot(Vector2(0,-1))>0.6): #check slope for 'floor'
found_floor = true
floor_index = x
#We have landed on the floor
if (found_floor):
if (airborne_time > 0):
get_node('sound').play('land')
airborne_time=0.0
if (did_jump and not jump):
did_jump = false
#We are airborne
else:
airborne_time+=step #time we spent in the air
#if we are airborne for a moment, we are no longer on_floor
var on_floor = airborne_time < MAX_FLOOR_AIRBORNE_TIME
# JUMPING #
#############
if(is_jumping):
if (lv.y>0):
#set off the jumping flag if we're going down
is_jumping=false
elif (not jump):
#we let go of jump, so make us drop (Metroid-style)
stopping_jump=true
if (stopping_jump):
#push us downward if we are stop_jumping
lv.y += STOP_JUMP_FORCE*step
# ON-FLOOR LOGIC #
####################
if (on_floor):
#we are moving left
if (move_left and not move_right):
if(lv.x > -WALK_MAX_SPEED): #throttle control
lv.x += -WALK_ATK*step #apply velocity
#we are moving right
elif(move_right and not move_left):
if(lv.x < WALK_MAX_SPEED): #throttle control
lv.x += WALK_ATK*step #apply velocity
#we are not moving, so decelerate
else:
var xv = abs(lv.x)
xv -= WALK_DEC*step
if (xv<0):
xv=0
lv.x=sign(lv.x)*xv
# Trigger Jump
if (not is_jumping and not did_jump and jump):
lv.y=-JUMP_VELOCITY #Apply velocity
is_jumping=true #switch: we are jumping
stopping_jump=false #switch: we are not stop-jumping
did_jump = true #switch: we did jump (and cannot again until we release the command)
get_node('sound').play('jump') #boing!
# Get/Set Facing
# -1 = facing left
# 1 = facing right
if (lv.x < 0 and move_left):
new_facing = -1
elif (lv.x > 0 and move_right):
new_facing = 1
#Set animation
if (is_jumping):
new_animation='jumping'
elif(abs(lv.x)<0.1):
new_animation='idle'
else:
new_animation='running'
# IN-AIR LOGIC #
##################
else:
#moving right in mid-air
if(move_left and not move_right):
if(lv.x > -WALK_MAX_SPEED): #throttle control
lv.x -= AIR_ATK*step #set velocity
#moving left in mid-air
elif(move_right and not move_left):
if(lv.x < WALK_MAX_SPEED): #throttle control
lv.x += AIR_ATK*step #seet velocity
#not moving in mid-air, so decelerate
else:
var xv = abs(lv.x)
xv -= AIR_DEC*step
if (xv<0):
xv=0
lv.x=sign(lv.x)*xv
# Set Animation
if(lv.y<0):
new_animation='jumping'
else:
new_animation='falling'
#Update sprite scale to reflect new facing
if(new_facing!=facing):
var sc = Vector2(-facing,1)
get_node('sprite').set_scale(sc)
facing = new_facing
# Play Animation
if (new_animation!=animation):
animation=new_animation
get_node('animator').play(animation)
# Play footstep SFX based on running animation
if (animation == 'running'):
var frame = get_node('sprite').get_frame()
if(frame == 4 or frame == 9) and did_step != frame: #Pgeki puts a foot down on frame #4 & #9
get_node('sound').play('footstep')
did_step = frame
# APPLY VELOCITIES TO OUR RIGIDBODY #
#######################################
if(found_floor):
#(not certain exactly what this does. it's important though!
floor_h_velocity = state.get_contact_collider_velocity_at_pos(floor_index).x
lv.x += floor_h_velocity
#Finally, apply gravity and set back the linear velocity
lv += state.get_total_gravity()*step
state.set_linear_velocity(lv)
# Hook for spear script:
# Our spear is freed, so we can fire another
func done_shooting():
did_shoot = false
#################################
# I Get Hit by Something! #
#################################
func get_hit(origin):
if not is_hit: #if we're not already hit
var life = get_node('/root/globals').LIFE #get global Life value
if(life>0): #if we are not dead yet..
life -= 1 #lose some life (should be an argument)
get_node('/root/globals').LIFE = life #set global Life value
# kick-back from damage
var target_pos = origin.get_pos() #position of origin
var my_pos = get_pos() #my position
var vect = target_pos - my_pos #Vector between the two
vect.y = abs(vect.y) #ensure 'upward' kick
set_linear_velocity(-vect*8) #set velocity inverted
#call draw function to HUD Hearts
get_node('/root/Root/hud/hearts')._draw_hearts()
#switch: we are hit, and invulnerable for a moment
is_hit=true
func _ready():
# Initialize
set_process(true)
func _process(delta):
# DEV HACK: Teleport to initial scene position
if Input.is_action_pressed('respawn'):
set_pos(respawn_point)
#DEV HACK: Spawn a Blub in front of you
if Input.is_action_pressed('DEV_spawn_blub'):
var guy = mob.instance()
var pos = get_pos()
pos.x += 10*facing
pos.y -= 5
guy.set_pos(pos)
get_parent().add_child(guy)
# Handle hit timer if we are hit
if is_hit:
hit_timer += delta
if hit_timer >= hit_timelimit:
hit_timer=0
is_hit=false