Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forest critters: Add animation frames for "turning" #81

Open
oliver-ruehl opened this issue Mar 27, 2017 · 4 comments
Open

Forest critters: Add animation frames for "turning" #81

oliver-ruehl opened this issue Mar 27, 2017 · 4 comments

Comments

@oliver-ruehl
Copy link
Contributor

oliver-ruehl commented Mar 27, 2017

Turning for NPCs look pretty ugly right now, because its just an instant "snap!".
What I would like to achieve is this:

  1. Slight pause before NPC is turning
  2. play 2 frame animation for turning
  3. continue walk
@YeOldeDM
Copy link

  1. The pause at the start could be part of the turning animation(?)
  2. The animationplayer should emit a "finished" signal when the animation is done

That would give you what you need to catch when to allow/disallow movement. I would have to look at the code for the NPCs (the red crabs from the demo?) to see the best approach. Probably a flag on the monster that disallows movement when TRUE. The function that initiates the animation will make it True, and the finished signal will make it False.

When I have the time I can monkey with the code and see how it works in practice. It shouldn't be too complex, but you never know...

@oliver-ruehl
Copy link
Contributor Author

Yes, its the crab monsters almost unchenged in my game

@YeOldeDM
Copy link

Yes, this should be do-able with minimal adjusting of the existing script.

Here's a rundown of the steps I take. All code is being done on forest_crawler.gd:

  • New animation for Turning: Add a callfunc track pointing to the enemy base node, at the end of the animation, add a key with the name "_done_turning"
  • declare new state constant STATE_TURNING = 2
  • check if current state is STATE_TURNING, convert that bool to int, which gives 0 or 1: var W = int(state!=STATE_TURNING)
  • line 80, where linear velocity for that frame is set, multiply by W: lv.x = direction*WALK_SPEED*W
  • whenever the integrate forces loop changes direction: direction = -direction, we define 'turn' as the new_anim and set state to STATE_TURNING: new_anim = "turn"; state = STATE_TURNING
  • define the _done_turning function which will set state back to STATE_WALKING

Here's what the script looks like with the changes:


extends RigidBody2D

# Member variables
const STATE_WALKING = 0
const STATE_DYING = 1
const STATE_TURNING = 2

var state = STATE_WALKING

var direction = -1
var anim = ""

var rc_left = null
var rc_right = null
var WALK_SPEED = 50


var bullet_class = preload("res://src/actors/player/bullet.gd")

var destroyed = false

func _die():
	destroyed = true
	queue_free()


func _pre_explode():
	# Stay there
	clear_shapes()
	set_mode(MODE_STATIC)
	get_node("sfx").play("cork_pop")



func _integrate_forces(s):
	var lv = s.get_linear_velocity()
	var new_anim = anim

	if (state == STATE_DYING):
		new_anim = "explode"
	elif (state == STATE_WALKING):
		new_anim = "walk"
		
		var wall_side = 0.0
		
		for i in range(s.get_contact_count()):
			var cc = s.get_contact_collider_object(i)
			var dp = s.get_contact_local_normal(i)
			
			if (cc):
				if (cc extends bullet_class and not cc.disabled):
					set_mode(MODE_RIGID)
					state = STATE_DYING
					#lv = s.get_contact_local_normal(i)*400
					s.set_angular_velocity(sign(dp.x)*33.0)
					set_friction(1)
					cc.disable()
					game.reset_bonus_score()
					get_node("sfx").play("punch")

					break
			
			if (dp.x > 0.9):
				wall_side = 1.0
			elif (dp.x < -0.9):
				wall_side = -1.0
		
		if (wall_side != 0 and wall_side != direction):
			direction = -direction
			get_node("sprite").set_scale(Vector2(-direction, 1))
			# set turning state
			new_anim = 'turn'
			state = STATE_TURNING
			
		if (direction < 0 and not rc_left.is_colliding() and rc_right.is_colliding()):
			direction = -direction
			get_node("sprite").set_scale(Vector2(-direction, 1))
			# set turning state
			new_anim = 'turn'
			state = STATE_TURNING
			
		elif (direction > 0 and not rc_right.is_colliding() and rc_left.is_colliding()):
			direction = -direction
			get_node("sprite").set_scale(Vector2(-direction, 1))
			# set turning state
			new_anim = 'turn'
			state = STATE_TURNING
		
		var W = int(state != STATE_TURNING)
		lv.x = direction*WALK_SPEED*W
	
	if(anim != new_anim):
		anim = new_anim
		get_node("anim").play(anim)
	
	s.set_linear_velocity(lv)


func _ready():
	rc_left = get_node("raycast_left")
	rc_right = get_node("raycast_right")

func _done_turning():
	state = STATE_WALKING

I tested it a little and it appears to be doing what it should.

@oliver-ruehl
Copy link
Contributor Author

OK I'll implement it soon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants