public void ReturnSegmentsToCache() { // Return eaten/destroyed segments to the cache. SnakeSegment seg = this.head; SnakeSegment previousSeg = seg; SnakeSegment nextSegment = seg.NextSegment; // Sever connection to destroyed segments prior to calling destroy but AFTER hanging a pointer to the next // segment, in case previousSeg and seg are the same. previousSeg.NextSegment = null; // NOTE: Can't return snake head to the snake *body* cache. do { if (seg != this.head) { Managers.SnakeBodyCache.ReturnObject <SnakeBody>(seg.gameObject); } seg = nextSegment; if (seg == null) { break; } nextSegment = seg.NextSegment; } while (true); // Destroy head prefab and any attached objects - i.e. sprite animations. Destroy(this.head.gameObject); this.head = null; this.tail = null; this.length = 0; UpdateSpeed(); }
public void OnCollidedWithSnakeHead(SnakeSegment head) { for (int i = 0; i < m_CollisionListeners.Length; i++) { m_CollisionListeners[i].OnCollidedWithSnakeHead(head); } }
public override void SetSpriteDepth(int depth) { for (SnakeSegment segment = this.head; segment != null; segment = segment.NextSegment) { segment.SetSpriteDepth(depth); } }
protected override void CloseDoors() { SnakeSegment tail = this.Tail; if (tail == null) { return; } Direction tailDir = tail.CurrentDirection; if (tailDir == Direction.None) { return; } for (Direction direction = Direction.First; direction <= Direction.Last; ++direction) { if (direction == tailDir) { continue; } this.mazeController.CloseDoor(tail.transform.localPosition, direction); } }
private void SetSegmentSinusoidalPosition(SnakeSegment segment, Vector3 basePosition, float snakeSpeed) { SnakeTrail.SnakePosition lastCorner = this.trail.GetClosestCornerBehind(segment); float distanceInCellsSinceCorner = GetDistanceInCellsSinceLastCorner(segment, lastCorner.Position); float sinInterpolationPercent = GetInterpolationPercent(distanceInCellsSinceCorner); if (distanceInCellsSinceCorner < 0.5f) { // Calculate where based on sin we WANT to end up in half a tile. Vector3 sinPosition = GetSinusoidalPosition(segment, sinInterpolationPercent, basePosition); segment.transform.localPosition = sinPosition; float angleInterpolation = Mathf.Sqrt(distanceInCellsSinceCorner / 0.5f); Vector3 angles = InterpolateFacing(segment, lastCorner, angleInterpolation); segment.transform.eulerAngles = angles; } else { Vector3 sinPosition = GetSinusoidalPosition(segment, sinInterpolationPercent, basePosition); Vector3 sinAngles = GetSinusoidalAngle(segment, sinInterpolationPercent); segment.transform.localPosition = sinPosition; segment.transform.eulerAngles = sinAngles; } }
private Vector3 InterpolateFacing(SnakeSegment segment, SnakeTrail.SnakePosition lastCorner, float interpolation) { Vector3 firstDirectionVector = lastCorner.UnitVectorToPreviousPosition * -1.0f; Direction firstDirection = SerpentConsts.GetDirectionForVector(firstDirectionVector); Direction secondDirection = segment.CurrentDirection; Vector3 firstEulerAngles = SerpentConsts.RotationVector3[(int)firstDirection]; Vector3 secondEulerAngles = SerpentConsts.RotationVector3[(int)secondDirection]; // Compare the sign of the angles and make sure they are both positive or both negative to account for the circle. if (firstEulerAngles.z * secondEulerAngles.z < 0.0f) { // sign problem to do with west (90) and south (-180) if (firstEulerAngles.z < -90.0f) { firstEulerAngles *= -1.0f; } else { secondEulerAngles *= -1.0f; } } Vector3 currentEulerAngles = firstEulerAngles * (1.0f - interpolation) + secondEulerAngles * interpolation; return(currentEulerAngles); }
public void AddSegment() { /* ------------------------------------------ * 2.2 * ------------------------------------------ * The AddSegment method adds a segment to our snake. * * 1. First you need to store the last segment in our segments List * in a variable called lastSegment. We can access items in a List * the same way we access elements in an array. For instance * segments[0] will get the first item in the segments List. * You can use the segments.Count property to determine the number of * elements in the segments List. * * 2. Next we need to create the new Segment that we can add to the * segments List. We can store it in a variable called newSegment. * If you look at the constructor for SnakeSegment you will see we need * to specify the x and y position as well as a character that will represent * the segment visually. * The x and y positions should be the PrevX and PrevY positions of * the lastSegment. The character must be an 'o'. * * 3. use the segments.Add method to add the newSegment to the back of * the segments List. */ SnakeSegment lastSegment = segments[segments.Count]; SnakeSegment newSegment = new SnakeSegment(lastSegment.PrevX, lastSegment.PrevY, 'o'); segments.Add(newSegment); }
// Use this for initialization void Start() { segments = new GameObject[numSegments]; for (int i = 0; i < numSegments; i++) { //Transform parent = i > 0 ? segments[i - 1].transform : transform; Transform parent = transform; segments[i] = Instantiate(segmentPrefab, parent); segments[i].transform.localScale = new Vector3(1, 1, 1); SnakeSegment seg = segments[i].GetComponent <SnakeSegment>(); seg.id = i; seg.head = this; } head = Instantiate(headPrefab, segments[numSegments - 1].transform); head.transform.localPosition = new Vector3(0, 0, (oldSegmentLength + segmentLength) / 2); head.transform.localRotation = Quaternion.identity; head.transform.localScale = new Vector3(1, 1, 1); snakeHead = head.GetComponent <SnakeHead>(); stump1 = Instantiate(stumpPrefab, transform); stump1.GetComponent <SnakeStump>().head = this; stump1.SetActive(false); stump2 = Instantiate(stumpPrefab, transform); stump2.GetComponent <SnakeStump>().head = this; stump2.GetComponent <BoxCollider>().enabled = false; stump2.SetActive(false); ss = new SnakeSpline(this); state = State.WAITING; status = Status.ALIVE; cut = numSegments; t = 0; }
private void RemoveTailOfSnake() { var currentTail = tail; tail = currentTail.GetNext(); currentTail.RemoveTail(); currentSize--; }
void GrowSnake(bool isTail) { SnakeSegment tail = snake[snake.Count - 1]; Vector2 forwardDir = (snake[snake.Count - 2].position - tail.position).normalized; Vector2 position = tail.position - forwardDir * spacing; snake.Add(CreateBodyPart(position, tail, isTail)); }
private SnakeSegment HandleDirChangeDownToLeft(SnakeSegment currHead) { var newHead = m_SegmentPool.GetObject(); newHead.Rect.Init(currHead.Rect.LowerLeft + m_Width * Rect.VectorDirection(Direction.Up), currHead.Rect.LowerLeft); newHead.GridObj.Init(SquareOnRectOuter(currHead.GridObj.LowerLeft, newHead.Rect, Direction.Up), currHead.GridObj.LowerLeft); return(newHead); }
private SnakeSegment HandleDirChangeUpToRight(SnakeSegment currHead) { var newHead = m_SegmentPool.GetObject(); newHead.Rect.Init(currHead.Rect.UpperRight, currHead.Rect.UpperRight + m_Width * Rect.VectorDirection(Direction.Down)); newHead.GridObj.Init(currHead.GridObj.UpperRight, SquareOnRectOuter(currHead.GridObj.UpperRight, newHead.Rect, Direction.Down)); return(newHead); }
public float DistanceSquaredTo(SnakeSegment otherSegment) { Vector3 positionDiff = this.transform.localPosition - otherSegment.transform.localPosition; float distanceSq = positionDiff.sqrMagnitude; float radii = this.Radius + otherSegment.Radius; float radiiSq = radii * radii; return(distanceSq - radiiSq); }
/// <summary> /// Severs snake at segment. /// </summary> /// <returns><c>true</c>, if the snake should now die <c>false</c> otherwise.</returns> /// <param name="segment">Segment.</param> public bool SeverAtSegment(SnakeSegment segment) { SnakeSegment seg = this.head.NextSegment; SnakeSegment previousSeg; bool willDie = (segment == this.head || segment == seg); if (willDie) { seg = this.head; previousSeg = seg; } else { do { previousSeg = seg; seg = seg.NextSegment; if (seg == segment) { break; } } while (seg != null); previousSeg.NextSegment = null; } if (seg == null) { // error! return(false); } SnakeSegment nextSegment; do { nextSegment = seg.NextSegment; seg.ShrinkAndDie(); if (this.SnakeSegmentEaten != null) { this.SnakeSegmentEaten(this.Side, seg.gameObject.transform.localPosition); } seg = nextSegment; } while (seg != null); if (this.SnakeSegmentsChanged != null) { this.SnakeSegmentsChanged(this); } UpdateSpeed(); UpdateValues(); return(willDie); }
public void Grow() { // Create a new segment and have it follow the last segment SnakeSegment segment = Instantiate(this.segmentPrefab); segment.Follow(_segments[_segments.Count - 1], _segments.Count, _segments.Count + 1); // Add the segment to the end of the list _segments.Add(segment); }
private void MakeSegment(Vector2 direction) { nextPos += direction; SnakeSegment nextSegment = Instantiate(segment, nextPos, Quaternion.identity); AddSegmentToParent(nextSegment); head.setNext(nextSegment); head = nextSegment; currentSize++; }
private void Awake() { _head = GetComponent <SnakeSegment>(); if (_head == null) { _head = this.gameObject.AddComponent <SnakeSegment>(); _head.hideFlags = HideFlags.HideInInspector; } }
private void SetSegmentsRotation(Vector3 rotation) { SnakeSegment segment = this.head; while (segment != null) { segment.transform.eulerAngles = rotation; segment = segment.NextSegment; } }
private Vector3 GetSinusoidalPosition(SnakeSegment segment, float interpolationPercent, Vector3 basePosition) { float sidewaysDisplacement = GetSidewaysDisplacement(interpolationPercent); Direction currentDirection = segment.CurrentDirection; int intRightAngleDirection = ((int)currentDirection + 1) % (int)Direction.Count; Vector3 rightAngleUnitVector = SerpentConsts.DirectionVector3[intRightAngleDirection]; basePosition = basePosition + rightAngleUnitVector * sidewaysDisplacement; return(basePosition); }
private float GetLengthOfSinPeriod(SnakeSegment segment) { if (segment.CurrentDirection == Direction.N || segment.CurrentDirection == Direction.S) { return(2.0f * SerpentConsts.CellHeight); } else // W/E { return(2.0f * SerpentConsts.CellWidth); } }
public void ChangeColour(Color newColour) { this.colour = newColour; SnakeSegment segment = this.Head; while (segment != null) { segment.Colour = newColour; segment = segment.NextSegment; } }
public IEnumerator FlashDead(SnakeSegment snakeHead) { while (true) { yield return(new WaitForSeconds(0.5f)); HideSnake(snakeHead); yield return(new WaitForSeconds(0.5f)); ShowSnake(snakeHead); } }
protected void AddChild() { //Add child segment. If segement already has child, call is passed on until a childless sement is found if (child) { child.AddChild(); } else { grid = GameObject.Find("Grid"); child = Instantiate(this, this.transform.position, Quaternion.identity, grid.transform); } }
private void SetSegmentRotation(SnakeSegment bodySegment, SnakePosition position) { Direction dir = SerpentConsts.GetDirectionForVector(position.UnitVectorToPreviousPosition); if (dir == Direction.None) { return; } Direction oppositeDir = SerpentConsts.OppositeDirection[(int)dir]; bodySegment.CurrentDirection = oppositeDir; }
public override SegmentRender GetRenderSegment(SnakeSegment segment) { int i = Snake.Segments.Count - (int)Math.Round(StartTime); if (segment.Index == i) { return(SegmentRender.Fat); } else { return(SegmentRender.Normal); } }
//Burn enemies or anything that's tagged as burnable! private void OnTriggerEnter(Collider other) { if (other.tag == "Segment" && other.name[0] == 'E') //Destroy all of a snake { SnakeSegment enemySegment = other.GetComponent <SnakeSegment>(); GlobalStats.AddScore(10, other.transform.position); //Spawn death particles GameObject emitter = GameObject.Find("DeathParticleEmitter"); if (emitter) { Instantiate(emitter, other.transform.position, emitter.transform.rotation); } CoinObjective.CheckForObjective((int)CoinObjective.Objective.DESTROY_WITH_FIRE); Destroy(enemySegment.snakeOwner); } else if (other.tag == "Burnable" || other.tag == "BurnableNotSolid") { //Small chance for iceblocks to drop items if (other.name[0] == 'I') { if (Random.Range(0, 3) == 0) { GameObject newCollectableSpawner = Instantiate(itemSpawnerReference); newCollectableSpawner.transform.position = other.transform.position; Debug.Log("Thing spawned"); } } //Bonus points GlobalStats.AddScore(30, other.transform.position); //Spawn death particles GameObject emitter = GameObject.Find("DeathParticleEmitter"); if (emitter) { Instantiate(emitter, other.transform.position, emitter.transform.rotation); } CoinObjective.CheckForObjective((int)CoinObjective.Objective.DESTROY_WITH_FIRE); //Burn the object! (Spawn a special particle here?) Destroy(other.gameObject); } }
public override void Update(GameTime gameTime) { bool _gameOver = false; for (int i = snake.Children.Count - 1; i >= 0; i--) { SnakeSegment s = snake.Children[i] as SnakeSegment; for (int x = bullets.Children.Count - 1; x >= 0; x--) { Bullet b = bullets.Children[x] as Bullet; if (s.CollidesWith(b)) { score.Add(scoreSnakeHit); mushrooms.Add(new Mushroom(s.Position)); bullets.Remove(b); snake.Remove(s); } } for (int x = mushrooms.Children.Count - 1; x >= 0; x--) { Mushroom m = mushrooms.Children[x] as Mushroom; if (s.CollidesWith(m)) { s.Bounce(m.Position.X - s.Position.X); } } if (s.CollidesWith(player)) { _gameOver = true; } } if (_gameOver) { Reset(); } for (int i = bullets.Children.Count - 1; i >= 0; i--) { Bullet b = bullets.Children[i] as Bullet; for (int x = mushrooms.Children.Count - 1; x >= 0; x--) { Mushroom m = mushrooms.Children[x] as Mushroom; if (b.CollidesWith(m)) { score.Add(scoreMushroomHit); mushrooms.Remove(m); bullets.Remove(b); } } } base.Update(gameTime); }
// Loop through all segments and set their positions. public void PositionSegments(Snake snake) { SnakeHead head = snake.Head; float speed = snake.Speed; SetSegmentSinusoidalPosition(head, head.transform.localPosition, speed); SnakeSegment bodySegment = head.NextSegment; while (bodySegment != null) { SetSegmentSinusoidalPosition(bodySegment, bodySegment.transform.localPosition, speed); bodySegment = bodySegment.NextSegment; } }
private IReadOnlyCollection <Point> GetSnakePoints() { var list = new List <Point>(); SnakeSegment segment = _head; while (segment != null) { list.Add(segment.Position); segment = segment.Prev; } return(list); }
private void ConstructSnake(IEnumerable <Point> points) { _head = new SnakeSegment(points.First(), null, null); SnakeSegment tail = _head; foreach (var point in points.Skip(1)) { var segment = new SnakeSegment(point, null, tail); tail.Prev = segment; tail = segment; } _tail = tail; }
public void NotifySegmentUnderground(SnakeSegment segment) { if (IsCompletelyUnderground) { ReleasePath(); } }
public List<SnakeSegment> DetachSegmentsBehind (SnakeSegment segment) { var segmentIndex = Segments.IndexOf( segment ); var result = Segments.Skip(segmentIndex + 1).ToList(); Segments = Segments.Take( segmentIndex ).ToList(); return result; }