123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- using System;
- /// <summary>
- /// This component is responsible for moving and enemy and detecting when it has been captured,
- /// and/or gone off screen.
- /// </summary>
- [RequireComponent(typeof(PoolObject))]
- [RequireComponent(typeof(FollowTarget))]
- public class Enemy : Collidable, ILevelEditorGameEntity
- {
- public EnemyType type;
- public int points = 100;
- public SoundEvent[] caughtSounds;
- public SoundEvent goneThroughSound = SoundEvent.spermout;
- //These are used by the condom to align itself with the enemy
- public Vector3 hitOffset;
- protected bool captured;
- private PoolObject _poolObject;
- private bool _hasMultipleSineModifier;
- private bool _hasSineMovement;
- private FollowTarget _followTarget;
- public bool HasSineMovement { get { return _hasSineMovement; } }
- public bool HasMultipleSineModifier { get { return _hasMultipleSineModifier; } }
- public float scaleYFactor = 1; //0 would mean always from the center, 1 means it can vary through the screen's height
- const float MAX_POINTS_SCALE_FACTOR = 2;
- #region Unity Callbacks
- protected override void Awake()
- {
- base.Awake();
- _poolObject = GetComponent<PoolObject>();
- _followTarget = GetComponent<FollowTarget>();
- if (GetComponentsInChildren<SineMovement>().Length != 0)
- {
- _hasSineMovement = true;
- }
- MultipleSineModifier sineModifier = GetComponentInChildren<MultipleSineModifier>();
- if (sineModifier != null && sineModifier.phasors.Length > 1)
- {
- _hasMultipleSineModifier = true;
- }
- #if LEVEL_EDITOR
- if (!Pool.isSpawning)
- {
- NotificationCenter.Post(NotificationType.AddEnemyToLevelEditor, this);
- }
- #endif
- }
- #if LEVEL_EDITOR
- //Since the game designer can drag during level editing, we need to ensure this
- void Update()
- {
- Vector3 pos = transform.localPosition;
- pos.z = 0;
- transform.localPosition = pos;
- }
- #endif
-
- #endregion
- #region ILevelEditorGameEntity
- ushort ILevelEditorGameEntity.GetTypeForEncoding()
- {
- return (ushort)type;
- }
- LevelEditorGameEntityType ILevelEditorGameEntity.GetGameEntityType()
- {
- return LevelEditorGameEntityType.Enemy;
- }
- #endregion
- void CustomFixedUpdate()
- {
- //AVDebug.Log(RecordingManager.Ticks+" - "+name + ": "+transform.localPosition.x);
- //if it is captured let it go on a bit so that the condom linked with goes also off screen
- if (captured &&
- transform.localPosition.x > GameConstants.GAME_WIDTH * 3/2)
- {
- _poolObject.Despawn();
- }
- /// Note that the enemy's sprite's pivot is on the left. So when position of the enemy goes offscreen,
- /// it means it is not visible anymore
- if (!captured &&
- transform.localPosition.x > GameConstants.GAME_WIDTH)
- {
- _poolObject.Despawn();
- GoneThrough();
- }
- }
- public void OnCollisionWithCondom(CondomBase condom)
- {
- if (!captured)
- {
- CapturedByACondom(condom);
- }
- }
- #region NGUI Callbacks
- void OnPress(bool isPressed)
- {
- if (isPressed)
- {
- NotificationCenter.Post(NotificationType.Fire, new Vector2(Input.mousePosition.x, Input.mousePosition.y));
- }
- }
- #endregion
- #region Pool Messages
- protected virtual void OnSpawnMsg()
- {
- GetComponent<Collider>().enabled = true;
- captured = false;
- transform.rotation = Quaternion.identity;
- Logger.LogFlurryEvent("EnemySpawned", "Type", type.ToString());
- }
- #endregion
- #region Capturing Behaviours
- void CapturedByACondom(CondomBase condom)
- {
- //In the same frame it might have collided with another enemy
- if (condom.CanCaptureEnemy(this))
- {
- Logger.LogFlurryEvent("EnemyCaptured", "Type", type.ToString(), "CondomType", condom.type.ToString());
- captured = true;
- HitEvent hitEvent;
- hitEvent.hitObject = gameObject;
- hitEvent.projectile = condom;
- //AVDebug.Log(condom.name + " capture " +name+ " at tick "+RecordingManager.Ticks);
- NotificationCenter.Post(NotificationType.HitSomething, hitEvent);
- condom.CapturedEnemy(this);
- //disable the colliders. They won't hit anything else
- GetComponent<Collider>().enabled = false;
- GotHit();
- }
- }
- #endregion
- protected virtual void GoneThrough()
- {
- SoundManager.Play(goneThroughSound);
- Logger.LogFlurryEvent("EnemyGoneThrough", "Type", type.ToString());
- NotificationCenter.Post(NotificationType.EnemyGoneThrough, type);
- }
- public void Despawn()
- {
- _poolObject.Despawn();
- }
- public void Follow(Transform t)
- {
- BroadcastMessage("OnDisableMovementMsg");
- Vector3 offset = hitOffset;
- offset.x = -offset.x;
- _followTarget.SetTarget(t, offset);
- }
- public void GotHit()
- {
- SoundManager.PlayRandom(caughtSounds);
- int scaledPoints = GetScaledPointsAccordingToCapturePosition(points, transform.localPosition.x + hitOffset.x);
- ScoreChangeData scoreChangeData = new ScoreChangeData(ScoreChangeData.Source.Enemy, scaledPoints, transform.TransformPoint(hitOffset));
- NotificationCenter.Post(NotificationType.AddToScore, scoreChangeData);
- }
- /// <summary>
- /// This is to make the score more skill based, where we award players more if the capture it earlier or later.
- /// The scaleFactor ranges from MAX_POINTS_SCALE_FACTOR to 1 and back to MAX_POINTS_SCALE_FACTOR, with 1 when it
- /// is captured in the middle screen, and MAX_POINTS_SCALE_FACTOR at the edges
- /// </summary>
- /// <returns>
- /// The scaled points according to capture position.
- /// </returns>
- /// <param name='posX'>
- /// The local position in the x, 0 being on the left (just spawned), 1024 being on the right
- /// </param>
- public static int GetScaledPointsAccordingToCapturePosition(int points, float posX)
- {
- //normalising the x position to be between 0 and 1. 0 == left, 1 == right
- float x = Mathf.InverseLerp(0, GameConstants.GAME_WIDTH, posX);
- float scaleFactor;
- //if x is in the first in the first half, the scale factor should be 2 on the left, 1 in the middle of the screen
- if (x < 0.5f)
- {
- scaleFactor = Mathf.Lerp(MAX_POINTS_SCALE_FACTOR, 1, x*2);
- } else //the scale factor should be 1 in the middle and 2 on the right
- {
- scaleFactor = Mathf.Lerp(MAX_POINTS_SCALE_FACTOR, 1, (1-x) * 2);
- }
- AVDebug.Assert(scaleFactor >= 1 && scaleFactor <= MAX_POINTS_SCALE_FACTOR, "Scale factor is beyond expected range - "+scaleFactor);
- return (int)(points * scaleFactor);
- }
- }
|