123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- extends RigidBody2D
- # 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.
- var anim=""
- var siding_left=false
- var jumping=false
- var stopping_jump=false
- var shooting=false
- var WALK_ACCEL = 800.0
- var WALK_DEACCEL= 800.0
- var WALK_MAX_VELOCITY= 200.0
- var GRAVITY = 700.0
- var AIR_ACCEL = 200.0
- var AIR_DEACCEL= 200.0
- var JUMP_VELOCITY=460
- var STOP_JUMP_FORCE=900.0
- var MAX_FLOOR_AIRBORNE_TIME = 0.15
- var airborne_time=1e20
- var shoot_time=1e20
- var MAX_SHOOT_POSE_TIME = 0.3
- var bullet = preload("res://bullet.xml")
- var floor_h_velocity=0.0
- var enemy
- func _integrate_forces(s):
- var lv = s.get_linear_velocity()
- var step = s.get_step()
-
- var new_anim=anim
- var new_siding_left=siding_left
-
- # 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")
- var shoot = Input.is_action_pressed("shoot")
- var spawn = Input.is_action_pressed("spawn")
-
- if spawn:
- var e = enemy.instance()
- var p = get_pos()
- p.y = p.y - 100
- e.set_pos(p)
- get_parent().add_child(e)
-
- #deapply prev floor velocity
- lv.x-=floor_h_velocity
- floor_h_velocity=0.0
-
-
- # Find the floor (a contact with upwards facing collision normal)
- var found_floor=false
- var floor_index=-1
-
- for x in range(s.get_contact_count()):
- var ci = s.get_contact_local_normal(x)
- if (ci.dot(Vector2(0,-1))>0.6):
- found_floor=true
- floor_index=x
-
- # A good idea when impementing characters of all kinds,
- # Compensates for physics imprecission, as well as human
- # reaction delay.
-
- if (shoot and not shooting):
- shoot_time=0
- var bi = bullet.instance()
- var ss
- if (siding_left):
- ss=-1.0
- else:
- ss=1.0
- var pos = get_pos() + get_node("bullet_shoot").get_pos()*Vector2(ss,1.0)
- bi.set_pos(pos)
- get_parent().add_child(bi)
- bi.set_linear_velocity( Vector2(800.0*ss,-80) )
- get_node("sprite/smoke").set_emitting(true)
- get_node("sound").play("shoot")
- PS2D.body_add_collision_exception(bi.get_rid(),get_rid()) # make bullet and this not collide
- else:
- shoot_time+=step
-
-
- if (found_floor):
- airborne_time=0.0
- else:
- airborne_time+=step #time it spent in the air
-
- var on_floor = airborne_time < MAX_FLOOR_AIRBORNE_TIME
- # Process jump
- if (jumping):
- if (lv.y>0):
- #set off the jumping flag if going down
- jumping=false
- elif (not jump):
- stopping_jump=true
-
- if (stopping_jump):
- lv.y+=STOP_JUMP_FORCE*step
-
- if (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
- elif (move_right and not move_left):
- if (lv.x < WALK_MAX_VELOCITY):
- lv.x+=WALK_ACCEL*step
- else:
- var xv = abs(lv.x)
- xv-=WALK_DEACCEL*step
- if (xv<0):
- xv=0
- lv.x=sign(lv.x)*xv
-
- #Check jump
- if (not jumping and jump):
- lv.y=-JUMP_VELOCITY
- jumping=true
- stopping_jump=false
- get_node("sound").play("jump")
-
- #check siding
-
- if (lv.x < 0 and move_left):
- new_siding_left=true
- elif (lv.x > 0 and move_right):
- new_siding_left=false
- if (jumping):
- new_anim="jumping"
- elif (abs(lv.x)<0.1):
- if (shoot_time<MAX_SHOOT_POSE_TIME):
- new_anim="idle_weapon"
- else:
- new_anim="idle"
- else:
- if (shoot_time<MAX_SHOOT_POSE_TIME):
- new_anim="run_weapon"
- else:
- new_anim="run"
- else:
-
- # 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
- elif (move_right and not move_left):
- if (lv.x < WALK_MAX_VELOCITY):
- lv.x+=AIR_ACCEL*step
- else:
- var xv = abs(lv.x)
- xv-=AIR_DEACCEL*step
- if (xv<0):
- xv=0
- lv.x=sign(lv.x)*xv
-
- if (lv.y<0):
- if (shoot_time<MAX_SHOOT_POSE_TIME):
- new_anim="jumping_weapon"
- else:
- new_anim="jumping"
- else:
- if (shoot_time<MAX_SHOOT_POSE_TIME):
- new_anim="falling_weapon"
- else:
- new_anim="falling"
-
- #Update siding
-
- if (new_siding_left!=siding_left):
- if (new_siding_left):
- get_node("sprite").set_scale( Vector2(-1,1) )
- else:
- get_node("sprite").set_scale( Vector2(1,1) )
-
- siding_left=new_siding_left
-
- #Change animation
- if (new_anim!=anim):
- anim=new_anim
- get_node("anim").play(anim)
-
- shooting=shoot
- # Apply floor velocity
- if (found_floor):
- floor_h_velocity=s.get_contact_collider_velocity_at_pos(floor_index).x
- lv.x+=floor_h_velocity
-
-
-
-
- #Finally, apply gravity and set back the linear velocity
- lv+=s.get_total_gravity()*step
- s.set_linear_velocity(lv)
-
-
-
-
- func _ready():
- # Initalization here
- # if !Globals.has_singleton("Facebook"):
- # return
- # var Facebook = Globals.get_singleton("Facebook")
- # var link = Globals.get("facebook/link")
- # var icon = Globals.get("facebook/icon")
- # var msg = "I just sneezed on your wall! Beat my score and Stop the Running nose!"
- # var title = "I just sneezed on your wall!"
- # Facebook.post("feed", msg, title, link, icon)
- enemy = ResourceLoader.load("res://enemy.xml")
- pass
|