design sketch:
Idea: the core of the snake playing method is that players control one box to eat another box. The box they eat becomes their own body and moves with the previous box. The more they eat, the faster they will be. At the end of the game, judge whether they hit the wall or their own body
1, Scene layout
1. Camera settings
Modify camera parameters: set ClearFlags to SolidColor to display the scene in the game in pure color, set Projection to Orthographic orthogonal camera, and size to set the size of camera angle of view
2. Scene setting
Set the game background, four walls, snake heads and food components and properties, as well as a UI interface for game failure and score display.
① Background image: create a new 2D object -- > Sprite, name GameBG, set the picture wizard, and adjust the scale size to 30 * 30
Fence Wall: set the Tag tag, set the collision box for the Wall (used to judge the death of hitting the Wall), copy the three fences and adjust the size position
② Snake head snake player adds rigid body Rigidbody2D and boxcolorer2d components. Here, note that the Gravity Scale of 2D rigid body components is set to 0 (gravity is not required for plane movement) and the adjustment position xy is 0.5 (why to adjust to 0.5 will be explained below)
③ Create food: the FoodPool is used as an object pool for storing food, create food, add BoxColider2D component, set Tag to food (for collision detection), and adjust the position xy to 0.5 like snake head
Why should snakehead and food set position to 0.5?
Because the snake and food we created are rectangles with a scale of 1 * 1, we need to set its initial position to 0.5 (i.e. half the size of scale/2) if we want it to move with the scene box. In fact, we don't need to set Xiaobian. It's a little obsessive-compulsive. It's good-looking, hehe
④ set UI interface
Create an empty object UIManager as a node container to store components, Text in the upper left corner is the score, RefreshPanel game failure background UI, create a new Text as the game failure Text, and a Button as the restart Button.
2, Function realization
1. First create the snake movement function and create a new script playermovement All functions of CS greedy snake are put in this script
Snake eating function:
① The movement of the snake is automatic. We only need to control the direction of the snake's left, right or up and down movement,
② When the snake moves to the left (or down), we can't operate the snake to move to the right (or left).
③ The snake head eats the food when it triggers the food, and the game ends when it triggers the wall or its own body
Understand the mobile mode, let's start writing functions.
using System.Collections; using System.Collections.Generic; using UnityEngine; //Direction type public enum DirectionType { Horizontal, Vertical } public class PlayerMovement : MonoBehaviour { public static Vector3 direction = new Vector3(1, 0, 0);//Moving direction public float currentTimespeed; //Current movement speed (the smaller the time, the faster the speed. Here I use time to speed up) public float timerSpeedRatio;//Time subtracted from each meal (i.e. snake acceleration) float timer;//For time calculation bool isDie = false;//Death int foodnumber = 0;//Amount of food eaten //Food object pool public FoodData foodPrefab; public Transform foodPool; //The snake container is used to store the food eaten and become the body public Transform snakePool; //Game map public Transform GameBG; void Start() { //Initialize timer timer = currentTimespeed; //Initialization location transform.position = new Vector3(0.5f, 0.5f, 1); } void Update() { //Player movement float h = Input.GetAxis("Horizontal"); float V = Input.GetAxis("Vertical"); //Judge the moving direction if (h != 0) { SetDirection(DirectionType.Horizontal, h); } if (V != 0) { SetDirection(DirectionType.Vertical, V); } //Move not executed if (!isDie) { Move(); } } //Modify direction private void SetDirection(DirectionType directionType, float _direction) { //Judge horizontal left-right movement or vertical up-down movement float value = _direction > 0 ? 1f : -1f; //Judge the direction type and set the moving direction switch (directionType) { case DirectionType.Horizontal: if (direction.x==0) { direction = new Vector2(value, 0); } break; case DirectionType.Vertical: if (direction.y==0) { direction = new Vector2(0, value); } break; default: break; } } //move private void Move() { timer -= Time.deltaTime; if (timer < 0) { //Perform move GetComponent<FoodData>().Move(transform.position + direction); timer = currentTimespeed; } } //Detection (requires FoodData and UIManager scripts) void OnTriggerEnter2D(Collider2D col) { //Judge whether it triggered the wall or yourself if (col.transform.tag.Equals("Wall") || col.transform.tag.Equals("Player")) { //death isDie = true; UIManager.uiMagr.DieUI(); } //food if (col.transform.tag.Equals("Food")) { //Judge whether the greedy snake has a body if (snakePool.childCount > 0) { col.transform.GetComponent<FoodData>().SetDataInt(snakePool.GetChild(snakePool.childCount - 1).GetComponent<FoodData>()); } if (snakePool.childCount <= 0) { col.transform.GetComponent<FoodData>().SetDataInt(GetComponent<FoodData>()); } col.transform.SetParent(snakePool); if (col.transform== snakePool.GetChild(0)) { col.transform.tag = "Untagged"; } else { col.transform.tag = "Player"; } //Create food CreatFood(); //accelerate currentTimespeed -= timerSpeedRatio; if (currentTimespeed<=0.1f) { currentTimespeed = 0.1f; } //UI foodnumber++; UIManager.uiMagr.SetNumber(foodnumber); } } //Create food public void CreatFood() { //Base value float basePos = 0.5f; int h_value = (int)(GameBG.localScale.x / 2); int v_value = (int)(GameBG.localScale.y / 2); int h = Random.Range(-h_value, h_value + 1); int v = Random.Range(-v_value, v_value + 1); Vector2 pos = new Vector2(h + 0.5f, v + 0.5f); if (pos.x > 15) { pos = new Vector2(h_value - 0.5f, pos.y); } if (pos.y > 15) { pos = new Vector2(pos.x, v_value - 0.5f); } GetFood(0).position = pos; } //Get food public Transform GetFood(int index) { Transform food; if (index <= foodPool.childCount) { food = Instantiate(foodPrefab.transform, foodPool); } else { food = foodPool.GetChild(index); } return food; } }
There are detailed explanations in the code. Copying the code directly will cause problems because fooddata is required CS and uimanager Methods in CS script
Set the initial properties of greedy snake
2. Create the food (and body) attribute script FoodData , drag the script to snake player and food
This food script becomes the body of a snake after being eaten by a snake.
Function introduction:
① The basic attribute is the position information before moving, the upper level object and the lower level object.
② When the food is eaten, the last body of the snake should be obtained as its upper level. After the upper level moves, the next level moves to the position before the upper level moves
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FoodData : MonoBehaviour { public Vector3 oldPos;//Record last move public FoodData parentObj;//Get the previous body part attribute of the body part (used to move the next box to the position of the previous box when the greedy snake moves) public FoodData newObj;//Record the next body part property (for the next move after the body moves). void Start() { } // Update is called once per frame void Update() { } //Get the last object (called when food is eaten) public void SetDataInt(FoodData obj) { parentObj = obj; //Set the newobj of the previous object as itself parentObj.newObj = this; //The food was eaten and turned white transform.GetComponent<SpriteRenderer>().color = Color.white; //Location initialization transform.position = parentObj.oldPos; } //Move (used to move the next object after the current object is moved) public void Move() { //Record the last moving position (this value is required for the next object to move) oldPos=transform.position; //modify location transform.position = parentObj.oldPos; //Execute the move command of the next object if (newObj!=null) { newObj.Move(); } } //Movement (the snake's head needs to be transmitted) public void Move(Vector3 pos) { oldPos = transform.position; //modify location transform.position = pos; if (newObj != null) { newObj.Move(); } } }
3. Script UIManager CS drag to empty object UIManager
using System.Collections; using System.Collections.Generic; using UnityEngine.UI; using UnityEngine; using UnityEngine.SceneManagement;//Reference is required when loading the scene public class UIManager : MonoBehaviour { public static UIManager uiMagr; public Text number_txt;//fraction public Button refreshBtn;//Restart button public Transform dieUI;//Game failure panel void Start() { //initialization uiMagr = this; dieUI.gameObject.SetActive(false); refreshBtn.onClick.AddListener(Refresh); } // Update is called once per frame void Update() { //Press esc to exit the program if (Input.GetKeyDown(KeyCode.Escape)) { Application.Quit(); } } //Modify score value public void SetNumber(int value) { number_txt.text = value.ToString(); } //Show death UI public void DieUI() { dieUI.gameObject.SetActive(true); } //Refresh void Refresh() { //Reload scene SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); } }
Project package https://pan.baidu.com/s/1JzgD-E5H8bJU7RTq5aVOqw Extraction code: syq1