using System.Collections; using System.Collections.Generic; using Photon.Pun; using UnityEngine; public class SnakeController : MonoBehaviourPunCallbacks { public GameManager gameManager; public Vector2 startOffset = new Vector3(-10,-10); public float movingInterval = 0.2f; public Vector2 curDirection = Vector3.right; public List snakePieces = new List(); public GameObject snakePiecePrefab; public int startingLength = 3; public Vector2 fieldSize= new Vector2(160,90); float moveTimer; public float topEdge => transform.position.y + fieldSize.y /2f; public float botEdge => transform.position.y - fieldSize.y /2f; public float leftEdge => transform.position.x - fieldSize.x /2f; public float rightEdge => transform.position.x + fieldSize.x /2f; void Start(){ snakePieces = new List(); for(int i=0; i < startingLength; i++){ Vector3 pos = ((Vector2)transform.position - startOffset)-(Vector2.right * i); GameObject newPiece = PhotonNetwork.Instantiate(snakePiecePrefab.name,pos, Quaternion.identity ); snakePieces.Add(newPiece.GetComponent()); } } bool kickstarted = false; void Update() { CheckHead(); if(isDead){return;} Move(); ProcessInput(); if(Input.GetKeyDown(KeyCode.Space)){ queueNewPiece=true; } } void ProcessInput(){ if(Input.GetKeyDown(KeyCode.RightArrow)){ ChangeDir(Vector2.right); }else if(Input.GetKeyDown(KeyCode.LeftArrow)){ ChangeDir(-Vector2.right); }else if(Input.GetKeyDown(KeyCode.UpArrow)){ ChangeDir(Vector2.up); }else if(Input.GetKeyDown(KeyCode.DownArrow)){ ChangeDir(-Vector2.up); } } List moveInputQueue =new List(); void ChangeDir(Vector2 newDir){ if(curDirection == -newDir){ return; } moveInputQueue.Add(newDir); // curDirection = newDir; } bool queueNewPiece = false; void Move(){ if(moveTimer > 0){ moveTimer-=Time.deltaTime; }else{ moveTimer = movingInterval; if(moveInputQueue.Count >0){ curDirection = moveInputQueue[0]; moveInputQueue.RemoveAt(0); } Vector2 curPosition = snakePieces[0].transform.position; Vector2 lastPosition = snakePieces[snakePieces.Count-1].transform.position; for(int i=snakePieces.Count-1; i>0; i--){ Vector3 dir = (snakePieces[i-1].transform.position - snakePieces[i].transform.position).normalized; snakePieces[i].direction = dir; snakePieces[i].isHead=false; snakePieces[i].transform.position = snakePieces[i-1].transform.position; snakePieces[i].transform.position = snakePieces[i].transform.position; } if(queueNewPiece){ GameObject newPiece = PhotonNetwork.Instantiate(snakePiecePrefab.name,lastPosition, Quaternion.identity ); snakePieces.Add(newPiece.GetComponent()); queueNewPiece=false; } snakePieces[0].transform.position = curPosition + curDirection; snakePieces[0].direction = curDirection; snakePieces[0].isHead=true; if(snakePieces[0].transform.position.x > rightEdge){ snakePieces[0].transform.position= new Vector2(leftEdge,snakePieces[0].transform.position.y); }else if(snakePieces[0].transform.position.x topEdge){ snakePieces[0].transform.position = new Vector2(snakePieces[0].transform.position.x, botEdge); }else if(snakePieces[0].transform.position.y < botEdge){ snakePieces[0].transform.position = new Vector2(snakePieces[0].transform.position.x, topEdge); } } } bool isDead = false; void CheckHead(){ Collider2D[] obstacles = Physics2D.OverlapCircleAll(snakePieces[0].transform.position, 0.25f); foreach(Collider2D obstacle in obstacles){ if(obstacle.GetComponent()!=null){ if(obstacle.transform == snakePieces[0].transform){ }else{ Debug.Log($"Crashed into {obstacle.name}", gameObject); isDead = true; } } if(obstacle.GetComponent()!=null){ queueNewPiece=true; gameManager.DestroyFruit(obstacle.transform.position); } } } private void OnDrawGizmos() { Gizmos.DrawWireCube(transform.position, new Vector3(fieldSize.x,fieldSize.y)); if(snakePieces.Count > 0){ Gizmos.DrawWireSphere(snakePieces[0].transform.position, 0.25f); } } }