2D冒险游戏

思考并回答以下问题:

编写控制玩家移动的脚本

PlayerControl.cs

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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;

public class PlayerControl : MonoBehaviour
{
public enum FACEDIRECTION
{
FACELEFT = -1,
FACERIGHT = 1
}

// Player对象面对的方向是左还是右?
public FACEDIRECTION Facing = FACEDIRECTION.FACERIGHT;

// 哪些对象的tag被标记为ground
public LayerMask GroundLayer;

// 对刚体的引用
private Rigidbody2D ThisBody = null;

// 对transform组件的引用
private Transform ThisTransform = null;

// 对脚本碰撞体的引用
public CircleCollider2D FeetCollider = null;

// 我们碰到地面了吗?
public bool isGrounded = false;

// 主要输入轴
public string HorzAxis = "Horizontal";
public string JumpButton = "Jump";

// 速度变量
public float MaxSpeed = 50f;
public float JumpPower = 600
public float JumpTimeOut = 1f;

// 我们现在可以跳了吗?
private bool CanJump = true;

// 我们可以控制游戏角色了吗?
public bool CanControl = true;

public static PlayerControl PlayerInstance = null;

private static float _Health = 100f;

public static float Health
{
get
{
return _Health;
}
set
{
_Health = value;

// 如果死亡的话,游戏也就结束了
if(_Health <= 0)
Die();
}
}

void Awake()
{
// 获取transform组件和rigidbody组件
ThisBody = GetComponent<Rigidbody2D>();
ThisTransform = GetComponent<Transform>();

// 设置静态实例
PlayerInstance = this;
}

// 返回一个布尔值,玩家在地面上吗?
private bool GetGrounded()
{
// 检测地面
Vector2 CircleCenter = new Vector2(ThisTransform.position.x, ThisTransform.position.y) + FeetCollider.offset;

Collider2D[] HitColliders = Physics2D.OverlapCircleAll(CircleCenter, FeetCollider.radius, GroundLayer);

if(HitColliders.Length > 0) return true;

return false;
}

// 调转角色方向
private void FlipDirection()
{
Facing = (FACEDIRECTION) ((int)Facing * -1f);

Vector3 LocalScale = ThisTransform.localScale;
LocalScale.x *= -1f;
ThisTransform.localScale = LocalScale;
}

// 跳跃
private void Jump()
{
// 如果我们在地面上的话,就跳跃
if(!isGrounded || !CanJump) return;

// 跳跃
ThisBody.AddForce(Vector2.up * JumpPower);
CanJump = false;
Invoke("ActivateJump", JumpTimeOut);
}

// 在指定时间结束后激活允许跳跃变量
// 禁止第一次跳跃未结束时就二次起跳
private void ActivateJump()
{
CanJump = true;
}

void FixedUpdate()
{
// 如果我们不能控制角色,就退出
if(!CanControl || Health <= 0f)
return;

// 更新grounded变量状态
isGrounded = GetGrounded();
float Horz = CrossPlatformInputManager.GetAxis(HorzAxis);
ThisBody.AddForce(Vector2.right * Horz * MaxSpeed);

if(CrossPlatformInputManager.GetButton(JumpButton))
Jump();

// 对速度进行限制
ThisBody.velocity = new Vector2(Mathf.Clamp(ThisBody.velocity.x, -MaxSpeed, MaxSpeed), Mathf.Clamp(ThisBody.velocity.y, -Mathf.Infinity, JumpPower));

// 如果需要的话就调转方向
if( (Horz < 0f && Facing != FACEDIRECTION.FACELEFT) || (Horz > 0f && Facing != FACEDIRECTION.FACERIGHT) )
FlipDirection();
}

void OnDestroy()
{
PlayerInstance = null;
}

// 杀死玩家的功能
static void Die()
{
Destroy(PlayerControl.PlayerInstance.gameObject);
}

// 重置Player
public static void Reset()
{
Health = 100f;
}
}

移动的平台

PingPongMotion.cs

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
using UnityEngine;
using System.Collections;

public class PingPongMotion : MonoBehaviour
{
private Transform ThisTransform = null;

private Vector3 OrigPos = Vector3.zero;

public Vector3 MoveAxes = Vector2.zero;

public float Distance = 3f;

void Awake()
{
ThisTransform = GetComponent<Transform>();

OrigPos = ThisTransform.position;
}

void Update()
{
ThisTransform.position = OrigPos + MoveAxes * Mathf.PingPong(Time.time, Distance);
}
}

死亡区域

KillZone.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using UnityEngine;
using System.Collections;

public class KillZone : MonoBehaviour
{
public float Damage = 100f;

void OnTriggerStay2D(Collider2D other)
{
if (!other.CompareTag("Player")) return;

if (PlayerControl.PlayerInstance != null)
PlayerControl.Health -= Damage * Time.deltaTime;
}
}

用户界面中的生命值条

HealthBar.cs

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
using UnityEngine;
using System.Collections;

public class HealthBar : MonoBehaviour
{
private RectTransform ThisTransform = null;

public float MaxSpeed = 10f;

void Awake()
{
ThisTransform = GetComponent<RectTransform>();
}

void Start()
{
if(PlayerControl.PlayerInstance != null)
ThisTransform.sizeDelta = new Vector2(Mathf.Clamp(PlayerControl.Health, 0, 100), ThisTransform.sizeDelta.y);
}

void Update()
{
float HealthUpdate = 0f;

if (PlayerControl.PlayerInstance != null)
HealthUpdate = Mathf.MoveTowards(ThisTransform.rect.width, PlayerControl.Health, MaxSpeed);

ThisTransform.sizeDelta = new Vector2(Mathf.Clamp(HealthUpdate, 0, 100), ThisTransform.sizeDelta.y);
}
}

炮弹和伤害

Mover.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;
using System.Collections;

public class Mover : MonoBehaviour
{
public float Speed = 10f;

private Transform ThisTransform = null;

void Awake()
{
ThisTransform = GetComponent<Transform>();
}

void Update()
{
ThisTransform.position += ThisTransform.forward * Speed * Time.deltaTime;
}
}

Ammo.cs

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
using UnityEngine;
using System.Collections;

public class Ammo : MonoBehaviour
{
public float Damage = 100f;

public float LifeTime = 1f;

void Start()
{
Invoke("Die", LifeTime);
}

void OnTriggerEnter2D(Collider2D other)
{
if(!other.CompareTag("Player")) return;

PlayerControl.Health -= Damage;
}

public void Die()
{
Destroy(gameObject);
}
}

CollideDestroy.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using UnityEngine;
using System.Collections;

public class CollideDestroy : MonoBehaviour
{
public string TagCompare = string.Empty;

void OnTriggerEnter2D(Collider2D other)
{
if (!other.CompareTag(TagCompare)) return;

Destroy(gameObject);
}
}

炮塔和炮弹

AmmoSpawner.cs

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
using UnityEngine;
using System.Collections;

public class AmmoSpawner : MonoBehaviour
{
public GameObject AmmoPrefab = null;

private Transform ThisTransform = null;

public Vector2 TimeDelayRange = Vector2.zero;

public float AmmoLifeTime = 2f;

public float AmmoSpeed = 4f;

public float AmmoDamage = 100f;

void Awake()
{
FireAmmo();
}

public void FireAmmo()
{
GameObject Obj = Instantiate(AmmoPrefab, ThisTransform.position, ThisTransform.rotation) as GameObject;

Ammo AmmoComp = Obj.GetComponent<Ammo>();
Mover MoveCamp = Obj.GetComponent<Mover>();

AmmoComp.LifeTime = AmmoLifeTime;
AmmoComp.Damage = AmmoDamage;
AmmoComp.Speed = AmmoSpeed;

Invoke("FireAmmo", Random.Range(TimeDelayRange.x, TimeDelayRange.y));
}
}

NPC和任务系统

QuestManager.cs

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
using UnityEngine;
using System.Collections;

[System.Serializable]
public class Quest
{
public enum QUESTSTATUS
{
UNASSIGNED = 0,
ASSIGNED = 1,
COMPLETE = 2
}

public QUESTSTATUS Status = QUESTSTATUS.UNASSIGNED;

public string QuestName = string.Empty;
}

public class QuestManager : MonoBehaviour
{
public Quest[] Quests;
private static QuestManager SingletonInstance = null;

public static QuestManager ThisInstance
{
get
{
if( SingletonInstance == null)
{
GameObject QuestObject = new GameObject("Default");
SingletonInstance = QuestObject.AddComponent<QuestManager>();
}
return SingletonInstance;
}
}

void Awake()
{
if(SingletonInstance)
{
DestroyImmediate(gameObject);
return;
}
SingletonInstance = this;
DontDestroyOnLoad(gameObject);
}

public static Quest.QUESTSTATUS GetQuestStatus(string QuestName)
{
foreach(Quest Q in ThisInstance.Quests)
{
if(Q.QuestName.Equals(QuestName))
return Q.Status;
}

return Quest.QUESTSTATUS.UNASSIGNED;
}

public static void SetQuestStatus(string QuestName, Quest.QUESTSTATUS NewStatus)
{
foreach(Quest Q in ThisInstance.Quests)
{
if(Q.QuestName.Equals(QuestName))
{
Q.Status = NewStatus;
return;
}
}
}

public static void Reset()
{
if(ThisInstance == null) return;

foreach(Quest Q in ThisInstance.Quests)
Q.Status = Quest.QUESTSTATUS.UNASSIGNED;
}
}

QuestGiver.cs

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
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class QuestGiver : MonoBehaviour
{
public string QuestName = string.Empty;

public Text Captions = null;

public string[] CaptionText;

void OnTriggerEnter2D(Collider2D other)
{
if (!other.CompareTag("Player")) return;

Quest.QUESTSTATUS Status = QuestManager.GetQuestStatus(QuestName);

Captions.text = CaptionText[(int) Status];
}

void OnTriggerExit2D(Collider2D other)
{
Quest.QUESTSTATUS Status = QuestManager.GetQuestStatus(QuestName);

if (Status == Quest.QUESTSTATUS.UNASSIGNED)
QuestManager.SetQuestStatus(QuestName, Quest.QUESTSTATUS.ASSIGNED);

if(Status == Quest.QUESTSTATUS.COMPLETE)
SceneManager.LoadScene(5);
}
}

QuestItem.cs

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
using UnityEngine;
using System.Collections;

public class QuestItem : MonoBehaviour
{
public string QuestName;
private AudioSource ThisAudio = null;
private SpriteRenderer ThisRenderer = null;

private Collider2D ThisCollider = null;

void Awake()
{
ThisAudio = GetComponent<AudioSource>();
ThisRenderer = GetComponent<SpriteRenderer>();
ThisCollider = GetComponent<Collider2D>();
}

void Start()
{
gameObject.SetActive(false);

if (QuestManager.GetQuestStatus(QuestName) == Quest.QUESTSTATUS.ASSIGNED)
gameObject.SetActive(true);
}

void OnTriggerEnter2D(Collider2D other)
{
if(!other.CompareTag("Player")) return;

if(!gameObject.activeSelf) return;

QuestManager.SetQuestStatus(QuestName, Quest.QUESTSTATUS.COMPLETE);

ThisRenderer.enabled = ThisCollider.enabled = false;

if (ThisAudio != null) ThisAudio.Play();
}
}
0%