introducir
Toma, volvamos a jugar al pinball... (^_^)
Me he enseñado a mí mismo Unity por un tiempo, primero hagamos un juego 2D, el efecto de ejecución es el siguiente:
Tabla de contenido
Proceso de producción del proyecto.
2. El programa principal Game.cs
1) Inicialización de la pantalla
2) Darse cuenta del movimiento de la pelota
5) Colisión entre el deflector y la bola
descargar
enlace de descarga:
Unity2D juego de pinball ejecutable proyecto completo 0 créditos
Otras descargas:
http://101.201.112.95/2021/Unity_Pong.zip
La estructura del proyecto, abra el archivo Pong de la escena y ejecútelo (desarrollado en 2017.3, las versiones superiores deberían ser compatibles, aún no lo he probado)
Hice versiones H5 y Python antes, [Portal]:
Producción de juegos PyGame: juego de pinball Pong (se adjunta el código Python completo)
Producción de juegos HTML5: juego de pinball PONG (código completo adjunto)
Proceso de producción del proyecto.
Hablemos brevemente del proceso de producción, desarrollar un juego en 2D es también mi primer intento.
1. Interfaz
La interfaz incluye 6 elementos de visualización, que se arrastran a las posiciones correspondientes. Ellos son:
Imagen de fondo: bg
Imagen del bisel: bloque izquierdo, bloque derecho
Imagen de la pelota: pelota
Visualización de puntuación: LeftScore, RightScore (componente de texto de ugui utilizado)
Nota 1: La proporción de unidades de imagen a coordenadas de píxeles en 2D es 1: 100 (píxeles a unidades)
En la imagen de arriba, el concepto de píxel de 3.7 es 370
Nota 2: es necesario establecer el orden en la capa de la relación de oclusión frontal y posterior de la imagen, y el valor más grande se muestra en la capa superior
Lo siguiente usará estos valores para calcular el movimiento y la colisión de la pelota (sin motor de física...)
2. El programa principal Game.cs
Organizar las ideas de producción del programa.
1) Inicialización de la pantalla
Primero, defina el mismo objeto GameObject como interfaz e inicialícelo en la función Inicio (vincule los objetos en la interfaz)
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) Darse cuenta del movimiento de la pelota
Defina la variable de velocidad de movimiento y la variable de proporción de píxeles de la unidad (se usará muchas veces más adelante)
//单位与像素坐标比例为 1: 100 (Pixels To Units)
private float pixelScale = 100.0f;
//小球移动速度和方向
private float ballSpeed = 10.0f;
private float ballSpeedAngle = 0.25f * Mathf.PI;
Darse cuenta del movimiento de la pelota en la función Actualizar
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) movimiento del bisel
Aquí tomamos el movimiento del bisel izquierdo como ejemplo. En la función Actualizar, agregue eventos de control de teclado y controle la velocidad de movimiento del bisel para lograr el efecto.
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) La pelota golpea la pared
La idea es en realidad calcular la posición de la pelota y cambiar el ángulo de movimiento de la pelota.
//小球碰撞到边缘后反弹
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) Colisión entre el deflector y la 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) Actualizar puntaje
Cuando la pelota golpea los bordes izquierdo y derecho de la pantalla, actualice la pantalla de puntaje
//左边得分
leftScoreNum ++;
leftScore.text = leftScoreNum.ToString ();
7) Bola que se arrastra
En el objeto de la pelota, haga clic con el botón derecho para agregar Trail, como se muestra en la siguiente figura:
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;
}
}
}