Roll a Ball & Battle City

这是以前做过的两个小游戏,是根据unity官方教程来学习的,非常的简单。github下载地址在文末。

Roll a Ball:

控制一个球来回移动,碰撞旋转的cube可以消除,颜色可以根据自己的喜好来设定,Roll a Ball其实也不算个游戏,没有音效,只有简单的字体UI。不过camera可以随着球体的移动而移动。下面是截图。

Battle City:

双人游戏,W/S/A/D/J控制player1,UP/DOWN/LEFT/RIGHT/ENTER控制player2。值得说的是,坦克在移动时尾部会有灰尘效果,而坦克发射炮弹时,上面有点光源,且炮弹落到地面有炸裂效果,炸裂效果是由几张贴图生成的。炮弹对于对方坦克具有物理击飞效果。Battle City具有背景音效,炮弹音效等等,也具有文字UI。

两个游戏都是由C#来撰写游戏逻辑的。

Roll a Ball:

 1 using UnityEngine;
 2 using System.Collections;
 3
 4 public class CameraController : MonoBehaviour {
 5
 6     public GameObject player;
 7
 8     private Vector3 offset;
 9
10     // Use this for initialization
11     void Start () {
12         offset = transform.position - player.transform.position;
13     }
14
15     // Update is called once per frame
16     void LateUpdate () {
17         transform.position = player.transform.position + offset;
18     }
19 }

CameraController.cs

 1 using UnityEngine;
 2 using UnityEngine.UI;
 3 using System.Collections;
 4
 5 public class PlayerController : MonoBehaviour
 6 {
 7
 8     public float speed;
 9     public Text countText;
10     public Text winText;
11
12     private Rigidbody rb;
13
14     private int count;
15
16     void Start()
17     {
18         rb = GetComponent<Rigidbody>();
19         count = 0;
20         SetCountText();
21         winText.text = "";
22     }
23
24     void FixedUpdate()
25     {
26         float moveHorizontal = Input.GetAxis("Horizontal");
27         float moveVertical = Input.GetAxis("Vertical");
28
29         Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
30
31         rb.AddForce(movement * speed);
32     }
33
34     void OnTriggerEnter(Collider other)
35     {
36         if (other.gameObject.CompareTag("Pick up"))
37         {
38             other.gameObject.SetActive(false);
39             count = count + 1;
40             SetCountText();
41         }
42     }
43
44     void SetCountText()
45     {
46         countText.text = "Count: " + count.ToString();
47         if (count >= 16)
48         {
49             winText.text = "You Win!";
50         }
51     }
52 }

PlayerController.cs

 1 using UnityEngine;
 2 using System.Collections;
 3
 4 public class Rotator : MonoBehaviour {
 5
 6     // Update is called once per frame
 7     void Update () {
 8         transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
 9     }
10 }

Rotator.cs

Battle City:

  • Camera

      1 using UnityEngine;
      2
      3 public class CameraControl : MonoBehaviour
      4 {
      5     public float m_DampTime = 0.2f;
      6     public float m_ScreenEdgeBuffer = 4f;
      7     public float m_MinSize = 6.5f;
      8     [HideInInspector] public Transform[] m_Targets;
      9
     10
     11     private Camera m_Camera;
     12     private float m_ZoomSpeed;
     13     private Vector3 m_MoveVelocity;
     14     private Vector3 m_DesiredPosition;
     15
     16
     17     private void Awake()
     18     {
     19         m_Camera = GetComponentInChildren<Camera>();
     20     }
     21
     22
     23     private void FixedUpdate()
     24     {
     25         Move();
     26         Zoom();
     27     }
     28
     29
     30     private void Move()
     31     {
     32         FindAveragePosition();
     33
     34         transform.position = Vector3.SmoothDamp(transform.position, m_DesiredPosition, ref m_MoveVelocity, m_DampTime);
     35     }
     36
     37
     38     private void FindAveragePosition()
     39     {
     40         Vector3 averagePos = new Vector3();
     41         int numTargets = 0;
     42
     43         for (int i = 0; i < m_Targets.Length; i++)
     44         {
     45             if (!m_Targets[i].gameObject.activeSelf)
     46                 continue;
     47
     48             averagePos += m_Targets[i].position;
     49             numTargets++;
     50         }
     51
     52         if (numTargets > 0)
     53             averagePos /= numTargets;
     54
     55         averagePos.y = transform.position.y;
     56
     57         m_DesiredPosition = averagePos;
     58     }
     59
     60
     61     private void Zoom()
     62     {
     63         float requiredSize = FindRequiredSize();
     64         m_Camera.orthographicSize = Mathf.SmoothDamp(m_Camera.orthographicSize, requiredSize, ref m_ZoomSpeed, m_DampTime);
     65     }
     66
     67
     68     private float FindRequiredSize()
     69     {
     70         Vector3 desiredLocalPos = transform.InverseTransformPoint(m_DesiredPosition);
     71
     72         float size = 0f;
     73
     74         for (int i = 0; i < m_Targets.Length; i++)
     75         {
     76             if (!m_Targets[i].gameObject.activeSelf)
     77                 continue;
     78
     79             Vector3 targetLocalPos = transform.InverseTransformPoint(m_Targets[i].position);
     80
     81             Vector3 desiredPosToTarget = targetLocalPos - desiredLocalPos;
     82
     83             size = Mathf.Max (size, Mathf.Abs (desiredPosToTarget.y));
     84
     85             size = Mathf.Max (size, Mathf.Abs (desiredPosToTarget.x) / m_Camera.aspect);
     86         }
     87
     88         size += m_ScreenEdgeBuffer;
     89
     90         size = Mathf.Max(size, m_MinSize);
     91
     92         return size;
     93     }
     94
     95
     96     public void SetStartPositionAndSize()
     97     {
     98         FindAveragePosition();
     99
    100         transform.position = m_DesiredPosition;
    101
    102         m_Camera.orthographicSize = FindRequiredSize();
    103     }
    104 }

    CameraControl.cs

  • Managers

      1 using UnityEngine;
      2 using System.Collections;
      3 //using UnityEngine.SceneManagement;
      4 using UnityEngine.UI;
      5
      6 public class GameManager : MonoBehaviour
      7 {
      8     public int m_NumRoundsToWin = 5;
      9     public float m_StartDelay = 3f;
     10     public float m_EndDelay = 3f;
     11     public CameraControl m_CameraControl;
     12     public Text m_MessageText;
     13     public GameObject m_TankPrefab;
     14     public TankManager[] m_Tanks;
     15
     16
     17     private int m_RoundNumber;
     18     private WaitForSeconds m_StartWait;
     19     private WaitForSeconds m_EndWait;
     20 /*    private TankManager m_RoundWinner;
     21     private TankManager m_GameWinner;
     22 */
     23
     24     private void Start()
     25     {
     26         m_StartWait = new WaitForSeconds(m_StartDelay);
     27         m_EndWait = new WaitForSeconds(m_EndDelay);
     28
     29         SpawnAllTanks();
     30         SetCameraTargets();
     31
     32         StartCoroutine(GameLoop());
     33     }
     34
     35
     36     private void SpawnAllTanks()
     37     {
     38         for (int i = 0; i < m_Tanks.Length; i++)
     39         {
     40             m_Tanks[i].m_Instance =
     41                 Instantiate(m_TankPrefab, m_Tanks[i].m_SpawnPoint.position, m_Tanks[i].m_SpawnPoint.rotation) as GameObject;
     42             m_Tanks[i].m_PlayerNumber = i + 1;
     43             m_Tanks[i].Setup();
     44         }
     45     }
     46
     47
     48     private void SetCameraTargets()
     49     {
     50         Transform[] targets = new Transform[m_Tanks.Length];
     51
     52         for (int i = 0; i < targets.Length; i++)
     53         {
     54             targets[i] = m_Tanks[i].m_Instance.transform;
     55         }
     56
     57         m_CameraControl.m_Targets = targets;
     58     }
     59
     60
     61     private IEnumerator GameLoop()
     62     {
     63         yield return StartCoroutine(RoundStarting());
     64         yield return StartCoroutine(RoundPlaying());
     65         yield return StartCoroutine(RoundEnding());
     66
     67 /*        if (m_GameWinner != null)
     68         {
     69             SceneManager.LoadScene(0);
     70         }
     71         else
     72         {
     73             StartCoroutine(GameLoop());
     74         }
     75 */    }
     76
     77
     78     private IEnumerator RoundStarting()
     79     {
     80         yield return m_StartWait;
     81     }
     82
     83
     84     private IEnumerator RoundPlaying()
     85     {
     86         yield return null;
     87     }
     88
     89
     90     private IEnumerator RoundEnding()
     91     {
     92         yield return m_EndWait;
     93     }
     94
     95
     96     private bool OneTankLeft()
     97     {
     98         int numTanksLeft = 0;
     99
    100         for (int i = 0; i < m_Tanks.Length; i++)
    101         {
    102             if (m_Tanks[i].m_Instance.activeSelf)
    103                 numTanksLeft++;
    104         }
    105
    106         return numTanksLeft <= 1;
    107     }
    108
    109 /*
    110     private TankManager GetRoundWinner()
    111     {
    112         for (int i = 0; i < m_Tanks.Length; i++)
    113         {
    114             if (m_Tanks[i].m_Instance.activeSelf)
    115                 return m_Tanks[i];
    116         }
    117
    118         return null;
    119     }
    120
    121
    122     private TankManager GetGameWinner()
    123     {
    124         for (int i = 0; i < m_Tanks.Length; i++)
    125         {
    126             if (m_Tanks[i].m_Wins == m_NumRoundsToWin)
    127                 return m_Tanks[i];
    128         }
    129
    130         return null;
    131     }
    132
    133
    134     private string EndMessage()
    135     {
    136         string message = "DRAW!";
    137
    138         if (m_RoundWinner != null)
    139             message = m_RoundWinner.m_ColoredPlayerText + " WINS THE ROUND!";
    140
    141         message += "\n\n\n\n";
    142
    143         for (int i = 0; i < m_Tanks.Length; i++)
    144         {
    145             message += m_Tanks[i].m_ColoredPlayerText + ": " + m_Tanks[i].m_Wins + " WINS\n";
    146         }
    147
    148         if (m_GameWinner != null)
    149             message = m_GameWinner.m_ColoredPlayerText + " WINS THE GAME!";
    150
    151         return message;
    152     }
    153 */
    154
    155     private void ResetAllTanks()
    156     {
    157         for (int i = 0; i < m_Tanks.Length; i++)
    158         {
    159             m_Tanks[i].Reset();
    160         }
    161     }
    162
    163
    164     private void EnableTankControl()
    165     {
    166         for (int i = 0; i < m_Tanks.Length; i++)
    167         {
    168             m_Tanks[i].EnableControl();
    169         }
    170     }
    171
    172
    173     private void DisableTankControl()
    174     {
    175         for (int i = 0; i < m_Tanks.Length; i++)
    176         {
    177             m_Tanks[i].DisableControl();
    178         }
    179     }
    180 }

    GameManager.cs

     1 using System;
     2 using UnityEngine;
     3
     4 [Serializable]
     5 public class TankManager
     6 {
     7     public Color m_PlayerColor;
     8     public Transform m_SpawnPoint;
     9     [HideInInspector] public int m_PlayerNumber;
    10     [HideInInspector] public string m_ColoredPlayerText;
    11     [HideInInspector] public GameObject m_Instance;
    12     [HideInInspector] public int m_Wins;
    13
    14
    15     private TankMovement m_Movement;
    16     private TankShooting m_Shooting;
    17     private GameObject m_CanvasGameObject;
    18
    19
    20     public void Setup()
    21     {
    22         m_Movement = m_Instance.GetComponent<TankMovement>();
    23         m_Shooting = m_Instance.GetComponent<TankShooting>();
    24         m_CanvasGameObject = m_Instance.GetComponentInChildren<Canvas>().gameObject;
    25
    26         m_Movement.m_PlayerNumber = m_PlayerNumber;
    27         m_Shooting.m_PlayerNumber = m_PlayerNumber;
    28
    29         m_ColoredPlayerText = "<color=#" + ColorUtility.ToHtmlStringRGB(m_PlayerColor) + ">PLAYER " + m_PlayerNumber + "</color>";
    30
    31         MeshRenderer[] renderers = m_Instance.GetComponentsInChildren<MeshRenderer>();
    32
    33         for (int i = 0; i < renderers.Length; i++)
    34         {
    35             renderers[i].material.color = m_PlayerColor;
    36         }
    37     }
    38
    39
    40     public void DisableControl()
    41     {
    42         m_Movement.enabled = false;
    43         m_Shooting.enabled = false;
    44
    45         m_CanvasGameObject.SetActive(false);
    46     }
    47
    48
    49     public void EnableControl()
    50     {
    51         m_Movement.enabled = true;
    52         m_Shooting.enabled = true;
    53
    54         m_CanvasGameObject.SetActive(true);
    55     }
    56
    57
    58     public void Reset()
    59     {
    60         m_Instance.transform.position = m_SpawnPoint.position;
    61         m_Instance.transform.rotation = m_SpawnPoint.rotation;
    62
    63         m_Instance.SetActive(false);
    64         m_Instance.SetActive(true);
    65     }
    66 }

    TankManager.cs

  • Shell

     1 using UnityEngine;
     2
     3 public class ShellExplosion : MonoBehaviour
     4 {
     5     public LayerMask m_TankMask;
     6     public ParticleSystem m_ExplosionParticles;
     7     public AudioSource m_ExplosionAudio;
     8     public float m_MaxDamage = 100f;
     9     public float m_ExplosionForce = 1000f;
    10     public float m_MaxLifeTime = 2f;
    11     public float m_ExplosionRadius = 5f;
    12
    13
    14     private void Start()
    15     {
    16         Destroy(gameObject, m_MaxLifeTime);
    17     }
    18
    19
    20     private void OnTriggerEnter(Collider other)
    21     {
    22         // Find all the tanks in an area around the shell and damage them.
    23         Collider[] colliders = Physics.OverlapSphere(transform.position, m_ExplosionRadius, m_TankMask);
    24         for (int i = 0; i < colliders.Length; i++)
    25         {
    26             Rigidbody targetRigidbody = colliders[i].GetComponent<Rigidbody>();
    27
    28             if (!targetRigidbody)
    29                 continue;
    30
    31             targetRigidbody.AddExplosionForce(m_ExplosionForce, transform.position, m_ExplosionRadius);
    32             TankHealth targetHealth = targetRigidbody.GetComponent<TankHealth>();
    33
    34             if (!targetHealth)
    35                 continue;
    36
    37             float damage = CalculateDamage(targetRigidbody.position);
    38
    39             targetHealth.TakeDamage(damage);
    40         }
    41
    42         m_ExplosionParticles.transform.parent = null;
    43
    44         m_ExplosionParticles.Play();
    45
    46         m_ExplosionAudio.Play();
    47
    48         Destroy(m_ExplosionParticles.gameObject, m_ExplosionParticles.duration);
    49         Destroy(gameObject);
    50     }
    51
    52
    53     private float CalculateDamage(Vector3 targetPosition)
    54     {
    55         // Calculate the amount of damage a target should take based on it‘s position.
    56         Vector3 explosionToTarget = targetPosition - transform.position;
    57
    58         float explosionDistance = explosionToTarget.magnitude;
    59
    60         float relativeDistance = (m_ExplosionRadius - explosionDistance) / m_ExplosionRadius;
    61
    62         float damage = relativeDistance * m_MaxDamage;
    63
    64         damage = Mathf.Max(0f, damage);
    65
    66         return damage;
    67     }
    68 }

    ShellExplosion.cs

  • UI

     1 using UnityEngine;
     2
     3 public class UIDirectionControl : MonoBehaviour
     4 {
     5     public bool m_UseRelativeRotation = true;
     6
     7
     8     private Quaternion m_RelativeRotation;
     9
    10
    11     private void Start()
    12     {
    13         m_RelativeRotation = transform.parent.localRotation;
    14     }
    15
    16
    17     private void Update()
    18     {
    19         if (m_UseRelativeRotation)
    20             transform.rotation = m_RelativeRotation;
    21     }
    22 }

    UIDirectionControl.cs

  • UITank

     1 using UnityEngine;
     2 using UnityEngine.UI;
     3
     4 public class TankHealth : MonoBehaviour
     5 {
     6     public float m_StartingHealth = 100f;
     7     public Slider m_Slider;
     8     public Image m_FillImage;
     9     public Color m_FullHealthColor = Color.green;
    10     public Color m_ZeroHealthColor = Color.red;
    11     public GameObject m_ExplosionPrefab;
    12
    13     /*
    14     private AudioSource m_ExplosionAudio;
    15     private ParticleSystem m_ExplosionParticles;
    16     private float m_CurrentHealth;
    17     private bool m_Dead;
    18
    19
    20     private void Awake()
    21     {
    22         m_ExplosionParticles = Instantiate(m_ExplosionPrefab).GetComponent<ParticleSystem>();
    23         m_ExplosionAudio = m_ExplosionParticles.GetComponent<AudioSource>();
    24
    25         m_ExplosionParticles.gameObject.SetActive(false);
    26     }
    27
    28
    29     private void OnEnable()
    30     {
    31         m_CurrentHealth = m_StartingHealth;
    32         m_Dead = false;
    33
    34         SetHealthUI();
    35     }
    36     */
    37
    38     public void TakeDamage(float amount)
    39     {
    40         // Adjust the tank‘s current health, update the UI based on the new health and check whether or not the tank is dead.
    41     }
    42
    43
    44     private void SetHealthUI()
    45     {
    46         // Adjust the value and colour of the slider.
    47     }
    48
    49
    50     private void OnDeath()
    51     {
    52         // Play the effects for the death of the tank and deactivate it.
    53     }
    54 }

    TankHealth.cs

     1 using UnityEngine;
     2
     3 public class TankMovement : MonoBehaviour
     4 {
     5     public int m_PlayerNumber = 1;
     6     public float m_Speed = 12f;
     7     public float m_TurnSpeed = 180f;
     8     public AudioSource m_MovementAudio;
     9     public AudioClip m_EngineIdling;
    10     public AudioClip m_EngineDriving;
    11     public float m_PitchRange = 0.2f;
    12
    13     /*
    14     private string m_MovementAxisName;
    15     private string m_TurnAxisName;
    16     private Rigidbody m_Rigidbody;
    17     private float m_MovementInputValue;
    18     private float m_TurnInputValue;
    19     private float m_OriginalPitch;
    20
    21
    22     private void Awake()
    23     {
    24         m_Rigidbody = GetComponent<Rigidbody>();
    25     }
    26
    27
    28     private void OnEnable ()
    29     {
    30         m_Rigidbody.isKinematic = false;
    31         m_MovementInputValue = 0f;
    32         m_TurnInputValue = 0f;
    33     }
    34
    35
    36     private void OnDisable ()
    37     {
    38         m_Rigidbody.isKinematic = true;
    39     }
    40
    41
    42     private void Start()
    43     {
    44         m_MovementAxisName = "Vertical" + m_PlayerNumber;
    45         m_TurnAxisName = "Horizontal" + m_PlayerNumber;
    46
    47         m_OriginalPitch = m_MovementAudio.pitch;
    48     }
    49     */
    50
    51     private void Update()
    52     {
    53         // Store the player‘s input and make sure the audio for the engine is playing.
    54     }
    55
    56
    57     private void EngineAudio()
    58     {
    59         // Play the correct audio clip based on whether or not the tank is moving and what audio is currently playing.
    60     }
    61
    62
    63     private void FixedUpdate()
    64     {
    65         // Move and turn the tank.
    66     }
    67
    68
    69     private void Move()
    70     {
    71         // Adjust the position of the tank based on the player‘s input.
    72     }
    73
    74
    75     private void Turn()
    76     {
    77         // Adjust the rotation of the tank based on the player‘s input.
    78     }
    79 }

    TankMovement.cs

     1 using UnityEngine;
     2 using UnityEngine.UI;
     3
     4 public class TankShooting : MonoBehaviour
     5 {
     6     public int m_PlayerNumber = 1;
     7     public Rigidbody m_Shell;
     8     public Transform m_FireTransform;
     9     public Slider m_AimSlider;
    10     public AudioSource m_ShootingAudio;
    11     public AudioClip m_ChargingClip;
    12     public AudioClip m_FireClip;
    13     public float m_MinLaunchForce = 15f;
    14     public float m_MaxLaunchForce = 30f;
    15     public float m_MaxChargeTime = 0.75f;
    16
    17     /*
    18     private string m_FireButton;
    19     private float m_CurrentLaunchForce;
    20     private float m_ChargeSpeed;
    21     private bool m_Fired;
    22
    23
    24     private void OnEnable()
    25     {
    26         m_CurrentLaunchForce = m_MinLaunchForce;
    27         m_AimSlider.value = m_MinLaunchForce;
    28     }
    29
    30
    31     private void Start()
    32     {
    33         m_FireButton = "Fire" + m_PlayerNumber;
    34
    35         m_ChargeSpeed = (m_MaxLaunchForce - m_MinLaunchForce) / m_MaxChargeTime;
    36     }
    37     */
    38
    39     private void Update()
    40     {
    41         // Track the current state of the fire button and make decisions based on the current launch force.
    42     }
    43
    44
    45     private void Fire()
    46     {
    47         // Instantiate and launch the shell.
    48     }
    49 }

    TankShooting.cs

链接:https://github.com/yl-me/Game

时间: 2024-12-13 22:51:49

Roll a Ball & Battle City的相关文章

NYOJ 284 坦克大战 &amp;&amp; POJ 2312 Battle City (广搜+优先队列)

链接:click here~~ 题意: 描述 Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now. What we are discussing is a simple edition of this game. Given a map that consists of empty space

Battle City BFS+优先队列

Battle City Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now. What we are discussing is a simple edition of this game. Given a map that consists of empty spaces, rivers,

POJ 2312 Battle City(优先队列+BFS)

题目链接:http://poj.org/problem?id=2312 Battle City Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7085   Accepted: 2390 Description Many of us had played the game "Battle city" in our childhood, and some people (like me) even often pl

poj 2312 Battle City

题目连接 http://poj.org/problem?id=1840 Battle City Description Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now. What we are discussing is a simple edition of this game. Giv

poj 2312 Battle City【bfs+优先队列】

Battle City Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7579   Accepted: 2544 Description Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now. What we are d

poj2312 Battle City bfs

http://poj.org/problem?id=2312 Battle City Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6903   Accepted: 2336 Description Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it

POJ 题目2312 Battle City(BFS)

Battle City Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7208   Accepted: 2427 Description Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now. What we are d

Unity 官方案例 Roll a ball

终于找到免费科学上网的方法了,虽然 速度一般,但对于学习unity官方视频来说还行. 废话不多的说,这次学习官方案例 Roll a ball,就是控制小球在平台上吃食物,这么一个简单的游戏.对于unity的一些基本操作,我就不在博客中介绍了,所以还请各位朋友先学会unity的基本操作,几乎只需要知道unity的面板有几块,分别操作什么,怎么创建物体,脚本,以及给物体添加组件,就可以学习本博客了. 好,现在开始.先创建一个3D项目,名字就叫做 Roll a ball, 在Assert 目录下创建几

B - Battle City bfs+优先队列

来源poj2312 Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now. What we are discussing is a simple edition of this game. Given a map that consists of empty spaces, rivers, st