Unity游戏制作:2D弹球游戏 Pong(附完整项目)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Unity游戏制作:2D弹球游戏 Pong(附完整项目),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含8825字,纯文字阅读大概需要13分钟。
内容图文
介绍
这里,又来做弹球游戏了……(^_^)
之前自学了一段时间的 unity,还是先做一款 2D 的小游戏吧,运行效果如下:
目录
下载
下载地址:
Unity2D弹球游戏 可运行完整项目 0 积分
其他下载:
http://101.201.112.95/2021/Unity_Pong.zip
项目的结构,打开场景Pong文件,运行就可以了(2017.3开发的,更高版本应该可以兼容吧,还真没试过)
之前做了H5和Python版本的,【传送门】:
PyGame游戏制作: 弹球游戏Pong(附上Python完整代码)
项目制作过程
简单聊下制作过程吧,开发2D游戏也是第一次尝试。
一、拼界面
界面中包括6个显示元素,通过拖拽到了对于的位置上。分别是:
背景图片:bg
挡板图片:leftBlock、rightBlock
小球图片:ball
分数显示:leftScore、rightScore (使用的ugui的 text组件)
注意1:2D中图片单位与像素坐标比例为 1 : 100 (Pixels To Units)
上图中,3.7对于的像素概念是370
注意2:需要设置图片的前后遮挡关系order in layer,数值大的在顶层显示
下面会使用这些数值计算小球的运动以及碰撞(没用物理引擎...)
二、主程序Game.cs
整理下程序的制作思路。
1)显示初始化
首先、定义与界面相同的GameObject对象,并在Start函数中进行初始化(绑定下界面中的物体)
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)实现小球移动
定义移动速度变量、及单位像素比例变量(后面会多次用到)
????//单位与像素坐标比例为?1:?100?(Pixels?To?Units)
????private?float?pixelScale?=?100.0f;
????//小球移动速度和方向
????private?float?ballSpeed?=?10.0f;
????private?float?ballSpeedAngle?=?0.25f?*?Mathf.PI;
在Update函数中实现小球移动
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)挡板移动
这里以左侧挡板移动举例,在Update函数中,添加键盘的控制事件,并通过控制挡板的移动速度,实现效果。
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)小球碰撞墙壁
思路实际上就是计算小球的位置,改变小球的移动角度。
?? ?//小球碰撞到边缘后反弹
?? ?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)挡板与小球的碰撞
//左边挡板碰撞
//挡板的宽高分别是?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)更新得分
当小球碰到屏幕左右边缘时,进行得分显示更新
//左边得分
leftScoreNum?++;
leftScore.text?=?leftScoreNum.ToString?();
7)小球拖尾
在小球对象上,右键添加Trail即可,如下图操作:
完整代码
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;
}
}
}
内容总结
以上是互联网集市为您收集整理的Unity游戏制作:2D弹球游戏 Pong(附完整项目)全部内容,希望文章能够帮你解决Unity游戏制作:2D弹球游戏 Pong(附完整项目)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。