public void ChangeDirection(Direction newDirection) { SnakeHead head = ((SnakeHead)this.Pieces[0]); int[] newDirChanges = Utillity.GetCoordDiffByDirection(newDirection); if (this.Pieces.Count > 1) { if (head.X + newDirChanges[0] != this.Pieces[1].X && head.Y + newDirChanges[1] != this.Pieces[1].Y) { head.Facing = newDirection; } } else { head.Facing = newDirection; } }
public void MoveForward() { SnakeHead head = (SnakeHead)this.Pieces[0]; int[] dirChange = Utillity.GetCoordDiffByDirection(head.Facing); int xChange = dirChange[0]; int yChange = dirChange[1]; int nextHeadX = head.X + xChange; int nextHeadY = head.Y + yChange; if (nextHeadX < Program.WindowWidth - 1 && nextHeadY < Program.WindowHeight && nextHeadX > 0 && nextHeadY > 0) { //check collisions //NOTE TO FUTURE ME! //It appears doing this loop with a foreach causes the Logic thread to crash //as Enumerators don't like it when the thing they are enumerating changes. for (int i = 0; i < Program.Food.Count; i++) { Food food = Program.Food[i]; if (food.X == nextHeadX && food.Y == nextHeadY) { Program.Logic.EatFoodAtLocation(nextHeadX, nextHeadY, this); } } //if (this.AnyPieceAtCoords(head.X, head.Y)) Program.Logic.GameOver(); for (int i = 1; i < this.Pieces.Count; i++) { if (nextHeadX == this.Pieces[i].X && nextHeadY == this.Pieces[i].Y) { Program.Logic.GameOver(); } } //first, update the previous coords //shift the closest previous coord to the latest this.PreviousTailCoords[1] = this.PreviousTailCoords[0]; //and now, set the new closest previous coord this.PreviousTailCoords[0] = new int[] { this.Pieces[this.Pieces.Count - 1].X, this.Pieces[this.Pieces.Count - 1].Y }; //move the last body piece to the position of the next last and so on, finally move the head. //it seems counter intuitive, I know, but if you do it head first, all the pieces bunch up together, //as the latter pieces have to move to the former pieces, and if the former piece has already moved, //the latter will just be exactly where the former piece moved to, as I discovered during the creation //of the previous iteration. //theoretically you could reference a copy but that's really messy, prone to bugs and inefficient if (this.Pieces.Count > 1) { for (int i = this.Pieces.Count - 1; i > 0; i--) { this.Pieces[i].X = this.Pieces[i - 1].X; this.Pieces[i].Y = this.Pieces[i - 1].Y; } } //finally, move the head Program.DebugLog($"New Head X: {nextHeadX}, New Head Y: {nextHeadY}"); head.X = nextHeadX; head.Y = nextHeadY; } else { //Game over if you crash into a wall Program.Logic.GameOver(); } }