Produção de jogos Unity: jogo de pinball 2D Pong (com projeto completo)

introduzir

Aqui, vamos jogar pinball de novo...(^_^)

Eu aprendi Unity sozinho por um tempo, vamos fazer um jogo 2D primeiro, o efeito de execução é o seguinte:

Índice

download

Processo de produção do projeto

1. Interface

2. O programa principal Game.cs

1) Inicialização da tela

2) Perceba o movimento da bola

3) Movimento do bisel

4) A bola bate na parede

5) Colisão entre o defletor e a bola

6) Atualizar pontuação

7) Bola para trás

código completo


download

Link para Download:

Projeto completo executável do jogo de pinball Unity2D   0 créditos

Outros downloads:

http://101.201.112.95/2021/Unity_Pong.zip

 

A estrutura do projeto, abra o arquivo Pong da cena e execute-o (desenvolvido em 2017.3, versões superiores devem ser compatíveis, ainda não testei)

 

Eu fiz versões H5 e Python antes, [Portal]:

Produção do jogo PyGame: jogo de pinball Pong (o código Python completo está anexado)

Produção de jogos HTML5: jogo de pinball PONG (código completo anexado)

 

 

Processo de produção do projeto

Vamos falar brevemente sobre o processo de produção. Desenvolver um jogo 2D também é minha primeira tentativa.

1. Interface

A interface inclui 6 elementos de exibição, que são arrastados para as posições correspondentes. Eles são:

Imagem de fundo: bg

Imagem da moldura: leftBlock, rightBlock

imagem da bola: bola

Exibição de pontuação: leftScore, rightScore (componente de texto do ugui usado)

 

Observação 1: A proporção de unidades de imagem para coordenadas de pixel em 2D é 1: 100 (Pixels para unidades)

Na foto acima, o conceito de pixel de 3,7 é 370

 

Nota 2: É necessário definir a ordem na camada da relação de oclusão frontal e traseira da imagem, e o valor maior é exibido na camada superior

O seguinte usará esses valores para calcular o movimento e a colisão da bola (sem motor de física...)

 

 

2. O programa principal Game.cs

Organizar as ideias de produção do programa.

1) Inicialização da tela

Primeiro, defina o mesmo objeto GameObject da interface e inicialize-o na função Start (vincule os objetos na interface)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Game : MonoBehaviour {

  //挡板
    private GameObject leftBlock;
    private GameObject rightBlock;

    //小球
    private GameObject ball;

    //左右得分 ugui text
    private Text leftScore;
    private Text rightScore;

    void Start () {
        Application.targetFrameRate = 60; //关掉垂直同步后,设置帧频

        leftBlock = GameObject.Find ("leftBlock");
        rightBlock = GameObject.Find ("rightBlock");

        ball = GameObject.Find ("ball");

        leftScore = GameObject.Find ("leftScore").GetComponent<Text> ();
        rightScore = GameObject.Find ("rightScore").GetComponent<Text> ();

    }

 

2) Perceba o movimento da bola

Defina a variável de velocidade de movimento e a variável de proporção de unidade de pixel (será usada muitas vezes mais tarde)

    //单位与像素坐标比例为 1: 100 (Pixels To Units)
    private float pixelScale = 100.0f;

    //小球移动速度和方向
    private float ballSpeed = 10.0f;
    private float ballSpeedAngle = 0.25f * Mathf.PI;

Perceba o movimento da bola na função Atualizar

void Update() {

	//计算小球移动速度(极坐标计算)
	float speedY = Mathf.Cos(ballSpeedAngle) * ballSpeed / pixelScale;
	float speedX = Mathf.Sin (ballSpeedAngle) * ballSpeed / pixelScale;

	//小球移动
	Vector2 ballPosition = ball.transform.position;
	ballPosition.x += speedX;
	ballPosition.y += speedY;
	ball.transform.position = ballPosition;

}

 

3) Movimento do bisel

Aqui, tomamos como exemplo o movimento do painel esquerdo.Na função Atualizar, adicione eventos de controle do teclado e controle a velocidade de movimento do painel para obter o efeito.

void Update() {

	//按下按键
	if (Input.GetKeyDown (KeyCode.W)) {  
		Debug.Log("您按下了W键");  
		leftMoveSpeed = 0.08f;
	}  

	if (Input.GetKeyDown (KeyCode.S)) {  
		Debug.Log("您按下了S键");  
		leftMoveSpeed = -0.08f;
	}  

	//抬起按键  
	if (Input.GetKeyUp (KeyCode.W))  
	{  
		Debug.Log("您抬起了W键");  
		leftMoveSpeed = 0.0f;
	}  

	if (Input.GetKeyUp (KeyCode.S))  
	{  
		Debug.Log("您抬起了S键");  
		leftMoveSpeed = 0.0f;

	//左右挡板移动
	Vector2 leftBlockPosition = leftBlock.transform.position;
	leftBlockPosition.y += leftMoveSpeed;
	//碰到边缘处理
	if (leftBlockPosition.y > 2.5f) {
		leftBlockPosition.y = 2.5f;
	}
	//碰到边缘处理
	if (leftBlockPosition.y < -2.5f) {
		leftBlockPosition.y = -2.5f;
	}
	leftBlock.transform.position = leftBlockPosition;

}

 

4) A bola bate na parede

A ideia é realmente calcular a posição da bola e mudar o ângulo de movimento da bola.

    //小球碰撞到边缘后反弹
    if (ballPosition.x > 400 / pixelScale) { //右侧
        ballSpeedAngle = -ballSpeedAngle;
    }
    if (ballPosition.x < -400 / pixelScale) { //左侧
        ballSpeedAngle = -ballSpeedAngle;
    }
    if (ballPosition.y > 300 / pixelScale) { //上侧
        ballSpeedAngle = -(ballSpeedAngle - Mathf.PI);
    }
    if (ballPosition.y < -300 / pixelScale) { //下侧
        ballSpeedAngle = -(ballSpeedAngle - Mathf.PI);
    }

 

5) Colisão entre o defletor e a bola

	//左边挡板碰撞
	//挡板的宽高分别是 20、100像素,所以计算碰撞区域时,按照宽高一半进行计算
	if (ballPosition.x < leftBlockPosition.x + 10 / pixelScale && ballPosition.x > leftBlockPosition.x - 10 / pixelScale
		&& ballPosition.y < leftBlockPosition.y + 50 / pixelScale && ballPosition.y > leftBlockPosition.y - 50 / pixelScale) {

		//碰撞上了
                   
	}

 

6) Atualizar pontuação

Quando a bola atingir as bordas esquerda e direita da tela, atualize a exibição do placar

    //左边得分
 	leftScoreNum ++;
	leftScore.text = leftScoreNum.ToString ();

 

7) Bola para trás

No objeto bola, clique com o botão direito do mouse para adicionar Trilha, conforme a figura abaixo:

 

código completo

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Game : MonoBehaviour {

	//挡板
	private GameObject leftBlock;
	private GameObject rightBlock;

	//小球
	private GameObject ball;

	//左右得分 ugui text
	private Text leftScore;
	private Text rightScore;

	//单位与像素坐标比例为 1: 100 (Pixels To Units)
	private float pixelScale = 100.0f;

	//小球移动速度和方向
	private float ballSpeed = 10.0f;
	private float ballSpeedAngle = 0.25f * Mathf.PI;

	//左右挡板的移动速度
	private float leftMoveSpeed = 0.0f;
	private float rightMoveSpeed = 0.0f;

	private int leftScoreNum = 0;
	private int rightScoreNum = 0;

	// Use this for initialization
	void Start () {

		Application.targetFrameRate = 60; //关掉垂直同步后,设置帧频

		leftBlock = GameObject.Find ("leftBlock");
		rightBlock = GameObject.Find ("rightBlock");

		ball = GameObject.Find ("ball");

		leftScore = GameObject.Find ("leftScore").GetComponent<Text> ();
		rightScore = GameObject.Find ("rightScore").GetComponent<Text> ();

	}
	
	// Update is called once per frame
	void Update () {

		//## 小球移动
		//计算小球移动速度(极坐标计算)
		float speedY = Mathf.Cos(ballSpeedAngle) * ballSpeed / pixelScale;
		float speedX = Mathf.Sin (ballSpeedAngle) * ballSpeed / pixelScale;

		//小球移动
		Vector2 ballPosition = ball.transform.position;
		ballPosition.x += speedX;
		ballPosition.y += speedY;
		ball.transform.position = ballPosition;

		//小球碰撞到边缘后反弹
		if (ballPosition.x > 400 / pixelScale) {
			ballSpeedAngle = -ballSpeedAngle;
			//左边得分
			leftScoreNum ++;
			leftScore.text = leftScoreNum.ToString ();
		}
		if (ballPosition.x < -400 / pixelScale) {
			ballSpeedAngle = -ballSpeedAngle;
			//右边得分
			rightScoreNum ++;
			rightScore.text = rightScoreNum.ToString ();
		}
		if (ballPosition.y > 300 / pixelScale) {
			ballSpeedAngle = -(ballSpeedAngle - Mathf.PI);
		}
		if (ballPosition.y < -300 / pixelScale) {
			ballSpeedAngle = -(ballSpeedAngle - Mathf.PI);
		}


		//左右挡板移动
		Vector2 leftBlockPosition = leftBlock.transform.position;
		leftBlockPosition.y += leftMoveSpeed;
		//碰到边缘处理
		if (leftBlockPosition.y > 2.5f) {
			leftBlockPosition.y = 2.5f;
		}
		//碰到边缘处理
		if (leftBlockPosition.y < -2.5f) {
			leftBlockPosition.y = -2.5f;
		}
		leftBlock.transform.position = leftBlockPosition;


		Vector2 rightBlockPosition = rightBlock.transform.position;
		rightBlockPosition.y += rightMoveSpeed;
		//碰到边缘处理
		if (rightBlockPosition.y > 2.5f) {
			rightBlockPosition.y = 2.5f;
		}
		if (rightBlockPosition.y < -2.5f) {
			rightBlockPosition.y = -2.5f;
		}
		rightBlock.transform.position = rightBlockPosition;


		//### 左挡板控制 ###
		//按下按键
		if (Input.GetKeyDown (KeyCode.W)) {  
			Debug.Log("您按下了W键");  
			leftMoveSpeed = 0.08f;
		}  

		if (Input.GetKeyDown (KeyCode.S)) {  
			Debug.Log("您按下了S键");  
			leftMoveSpeed = -0.08f;
		}  

		//抬起按键  
		if (Input.GetKeyUp (KeyCode.W))  
		{  
			Debug.Log("您抬起了W键");  
			leftMoveSpeed = 0.0f;
		}  

		if (Input.GetKeyUp (KeyCode.S))  
		{  
			Debug.Log("您抬起了S键");  
			leftMoveSpeed = 0.0f;
		} 


		//### 右挡板控制 ###
		//按下按键
		if (Input.GetKeyDown (KeyCode.UpArrow)) {  
			rightMoveSpeed = 0.08f;
		}  

		if (Input.GetKeyDown (KeyCode.DownArrow)) {   
			rightMoveSpeed = -0.08f;
		}  

		//抬起按键  
		if (Input.GetKeyUp (KeyCode.UpArrow)) {  
			rightMoveSpeed = 0.0f;
		}  

		if (Input.GetKeyUp (KeyCode.DownArrow)) {  
			rightMoveSpeed = 0.0f;
		} 

		//### 计算小球与挡板的碰撞 ###
		//左边挡板碰撞
		bool isLeftBlockCrash = false;
		//挡板的宽高分别是 20、100像素,所以计算碰撞区域时,按照宽高一半进行计算
		if (ballPosition.x < leftBlockPosition.x + 10 / pixelScale && ballPosition.x > leftBlockPosition.x - 10 / pixelScale
		    && ballPosition.y < leftBlockPosition.y + 50 / pixelScale && ballPosition.y > leftBlockPosition.y - 50 / pixelScale) {

			Debug.Log ("crash");
			if (isLeftBlockCrash == false) {
				if (speedX < 0) {
					ballSpeedAngle = (leftBlockPosition.y - ballPosition.y) / 50.0f * pixelScale + Mathf.PI / 2.0f;

				}
				isLeftBlockCrash = true;
			}
		
		} else {
			isLeftBlockCrash = false;
		}

		//右边挡板碰撞
		bool isRightBlockCrash = false;
		//挡板的宽高分别是 20、100像素,所以计算碰撞区域时,按照宽高一半进行计算
		if (ballPosition.x < rightBlockPosition.x + 10 / pixelScale && ballPosition.x > rightBlockPosition.x - 10 / pixelScale
			&& ballPosition.y < rightBlockPosition.y + 50 / pixelScale && ballPosition.y > rightBlockPosition.y - 50 / pixelScale) {

			Debug.Log ("crash");
			if (isRightBlockCrash == false) {
				if (speedX > 0) {
					ballSpeedAngle =  Mathf.PI * 3 / 2 - (rightBlockPosition.y - ballPosition.y) / 50.0f * pixelScale;

				}
				isRightBlockCrash = true;
			}

		} else {
			isRightBlockCrash = false;
		}



	}
}

 

Acho que você gosta

Origin blog.csdn.net/fujian87232/article/details/115321853
Recomendado
Clasificación