Öoo
|Word count:705|Reading time:3min|Post View:
前言
项目已经传到 github 上了 https://github.com/zong4/Ooo,不过目前的功能还需要测试,可能会有 bug。

PlayerController
简单实现一下移动,放炸弹,引爆炸弹的功能,并且留下了一些可变参数。
这里没有设置成空中不能移动,一方面是会引出新的 bug,一方面是我忘记了游戏里是什么样的了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| public class PlayerController : MonoBehaviour { public float moveSpeed = 3f;
private Foot _foot; public GameObject bombPrefab; public int maxBombs = 2; private readonly List<Bomb> _bombs = new List<Bomb>();
private void Start() { _foot = transform.GetComponentInChildren<Foot>();
if (!bombPrefab) { Debug.LogError("Bomb Prefab is not assigned in the inspector."); } }
private void Update() { Move();
if ((Input.GetKeyDown(KeyCode.J) || Input.GetMouseButtonDown(0)) && _foot.touchTag is "Ground" or "Bomb" && _bombs.Count < maxBombs) { if (bombPrefab) { var oldPosition = transform.position; transform.position = new Vector3(transform.position.x, transform.position.y + bombPrefab.transform.localScale.y, transform.position.z); _bombs.Add(Instantiate(bombPrefab, oldPosition, Quaternion.identity).GetComponent<Bomb>()); } }
if ((Input.GetKeyDown(KeyCode.K) || Input.GetMouseButtonDown(1)) && _bombs.Count > 0) { _bombs[0].Explode(); _bombs.RemoveAt(0); } }
private void Move() {
var moveInput = new Vector3(Input.GetAxis("Horizontal"), 0, 0); transform.Translate(moveInput * (Time.deltaTime * moveSpeed)); } }
|
一般平台游戏都需要单独的脚部检测,通过稍微缩小一点判定框可以减少很多 bug。
用 Gizmos 显示了一下爆炸范围,方便 debug。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Foot : MonoBehaviour { public string touchTag;
private void OnCollisionEnter2D(Collision2D collision) { touchTag = collision.gameObject.tag; }
private void OnCollisionExit2D() { touchTag = null; } }
|
Bomb
游戏中是十字形爆炸,所以这边就用两个矩形检测,配合 hashset 去重。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| public class Bomb : MonoBehaviour { public float explosionWidth = 3f; public float explosionHeight = 1f; public float explosionForce = 5f;
public void Explode() { CheckExplosionRange(); Destroy(gameObject); }
private void CheckExplosionRange() { var hashSet = new HashSet<Rigidbody2D>();
{ var results = new Collider2D[10]; var size = Physics2D.OverlapBoxNonAlloc(transform.position, new Vector2(explosionWidth * transform.localScale.x - 0.1f, explosionHeight * transform.localScale.y - 0.1f), 0f, results, LayerMask.GetMask("Player", "Bomb"));
for (var i = 0; i < size; i++) { hashSet.Add(results[i].GetComponent<Rigidbody2D>()); } }
{ var results = new Collider2D[10]; var size = Physics2D.OverlapBoxNonAlloc(transform.position, new Vector2(explosionHeight * transform.localScale.x, explosionWidth * transform.localScale.y), 0f, results, LayerMask.GetMask("Player", "Bomb"));
for (var i = 0; i < size; i++) { hashSet.Add(results[i].GetComponent<Rigidbody2D>()); } }
foreach (var rigidbody2D1 in hashSet) { if (rigidbody2D1.CompareTag("Bomb")) { rigidbody2D1.bodyType = RigidbodyType2D.Dynamic; }
var direction = Vector3.zero; if (rigidbody2D1.position.y > transform.position.y + 0.1f) { direction = new Vector3(0f, 1f, 0f); } else if (rigidbody2D1.position.y < transform.position.y - 0.1f) { direction = new Vector3(0f, -1f, 0f); } else if (rigidbody2D1.position.x > transform.position.x + 0.1f) { direction = new Vector3(1f, 0f, 0f); } else if (rigidbody2D1.position.x < transform.position.x - 0.1f) { direction = new Vector3(-1f, 0f, 0f); }
rigidbody2D1.AddForce(direction * explosionForce, ForceMode2D.Impulse); } }
private void OnCollisionEnter2D(Collision2D other) { if (other.gameObject.CompareTag("Ground")) { transform.GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Kinematic; } }
private void OnDrawGizmosSelected() { Gizmos.color = Color.red; Gizmos.DrawWireCube(transform.position, new Vector2(explosionWidth, explosionHeight)); Gizmos.DrawWireCube(transform.position, new Vector2(explosionHeight, explosionWidth)); } }
|