Type Game / 打字游戏

游戏展示

Type Game

游戏开发

创建 2D/3D 游戏

创建 2D 游戏 (TypeGame2D.sence)。

虽然是 2D 游戏,这里也可以用 3D Object,其中 Plane3D > Plane(Gameplay.sence)。

设置分辨率

Standalone(1024x768)

导入资源

Resources / 打字游戏文本

创建新文件夹,Resources

  • Project
    • Assets
      • Create
        • Folder: Resources
      • Resources
        • “xxx.txt”

BG / 背景

拖入 BG 背景

Bottom 碰撞检测

2D

  • Hirearchy
    • Create Empty: Bottom
  • Inspector
    • Tag: Bottom
    • Rect Transform
      • Position
        • Y: -5.18
    • Box Collider 2D
      • Is Trigger: True
      • Size
        • X: 26
        • Y: 0.15

3D

  • Hirearchy
    • Create
      • 3D
        • Plane
  • Inspector
    • Rect Transform
      • Position
        • Y: -6.54
      • Scale
        • X: 2
        • Y: 1
        • Z: 0.1

确保能发生碰撞

Scripts

创建新文件夹,Scripts,脚本都是 2D/3D Object 通用。

  • Project
    • Assets
      • Create
        • Folder: Scripts
      • Scripts
        • Create
          • C# Script
            • WordController # word 控制器
            • WordSwapner # word 生成器
            • GameController # UI 检测碰撞

WordController

1
using UnityEngine;
2
3
public class WordController : MonoBehaviour
4
{
5
    public float mytimer = 1f;
6
    public float gravity = -10f;
7
    public GUISkin skin;
8
9
    private int position; 
10
    private string showString;
11
    private string word; // "Hello"
12
    private string preWord; // match pre "He"
13
    private string postWord; // match post "llo"
14
    private string hitColor = "#00ff00";
15
    private string hitChar;
16
    private string defaultColor = "#ffffff";
17
    private Vector3 transformPos3D;
18
    private Vector2 transformPos2D;
19
    private Transform myTransform;
20
    private Camera mainCamera;
21
    private bool isBlow;
22
    private string explain;
23
    private int lengthChange;
24
    private bool oncecal;
25
26
    void Start()
27
    {
28
        oncecal = false;
29
        word = WordSwapner.instance.word;
30
        explain = WordSwapner.instance.explain;
31
        position = -1;
32
        mainCamera = Camera.main;
33
        myTransform = this.transform;
34
        isBlow = false;
35
        lengthChange = word.Length * 10;
36
    }
37
38
    void Update()
39
    {
40
        Physics.gravity = new Vector3(0, gravity, 0);
41
42
        if (!isBlow)
43
        {
44
            if (position == -1)
45
            {
46
                showString = word;
47
            }
48
            if (Input.anyKeyDown)
49
            {
50
                position++;
51
            }
52
            if (Input.GetKeyDown(KeyCode.A))
53
            {
54
                hitChar = "a";
55
            }
56
            if (Input.GetKeyDown(KeyCode.B))
57
            {
58
                hitChar = "b";
59
            }
60
            if (Input.GetKeyDown(KeyCode.C))
61
            {
62
                hitChar = "c";
63
            }
64
            if (Input.GetKeyDown(KeyCode.D))
65
            {
66
                hitChar = "d";
67
            }
68
            if (Input.GetKeyDown(KeyCode.E))
69
            {
70
                hitChar = "e";
71
            }
72
            if (Input.GetKeyDown(KeyCode.F))
73
            {
74
                hitChar = "f";
75
            }
76
            if (Input.GetKeyDown(KeyCode.G))
77
            {
78
                hitChar = "g";
79
            }
80
            if (Input.GetKeyDown(KeyCode.H))
81
            {
82
                hitChar = "h";
83
            }
84
            if (Input.GetKeyDown(KeyCode.I))
85
            {
86
                hitChar = "i";
87
            }
88
            if (Input.GetKeyDown(KeyCode.J))
89
            {
90
                hitChar = "j";
91
            }
92
            if (Input.GetKeyDown(KeyCode.K))
93
            {
94
                hitChar = "k";
95
            }
96
            if (Input.GetKeyDown(KeyCode.L))
97
            {
98
                hitChar = "l";
99
            }
100
            if (Input.GetKeyDown(KeyCode.M))
101
            {
102
                hitChar = "m";
103
            }
104
            if (Input.GetKeyDown(KeyCode.N))
105
            {
106
                hitChar = "n";
107
            }
108
            if (Input.GetKeyDown(KeyCode.O))
109
            {
110
                hitChar = "o";
111
            }
112
            if (Input.GetKeyDown(KeyCode.P))
113
            {
114
                hitChar = "p";
115
            }
116
            if (Input.GetKeyDown(KeyCode.Q))
117
            {
118
                hitChar = "q";
119
            }
120
            if (Input.GetKeyDown(KeyCode.R))
121
            {
122
                hitChar = "r";
123
            }
124
            if (Input.GetKeyDown(KeyCode.S))
125
            {
126
                hitChar = "s";
127
            }
128
            if (Input.GetKeyDown(KeyCode.T))
129
            {
130
                hitChar = "t";
131
            }
132
            if (Input.GetKeyDown(KeyCode.U))
133
            {
134
                hitChar = "u";
135
            }
136
            if (Input.GetKeyDown(KeyCode.V))
137
            {
138
                hitChar = "v";
139
            }
140
            if (Input.GetKeyDown(KeyCode.W))
141
            {
142
                hitChar = "w";
143
            }
144
            if (Input.GetKeyDown(KeyCode.X))
145
            {
146
                hitChar = "x";
147
            }
148
            if (Input.GetKeyDown(KeyCode.Y))
149
            {
150
                hitChar = "y";
151
            }
152
            if (Input.GetKeyDown(KeyCode.Z))
153
            {
154
                hitChar = "z";
155
            }
156
            if (Input.GetKeyDown(KeyCode.Keypad0) || Input.GetKeyDown(KeyCode.Alpha0))
157
            {
158
                hitChar = "0";
159
            }
160
            if (Input.GetKeyDown(KeyCode.Keypad1) || Input.GetKeyDown(KeyCode.Alpha1))
161
            {
162
                hitChar = "1";
163
            }
164
            if (Input.GetKeyDown(KeyCode.Keypad2) || Input.GetKeyDown(KeyCode.Alpha2))
165
            {
166
                hitChar = "2";
167
            }
168
            if (Input.GetKeyDown(KeyCode.Keypad3) || Input.GetKeyDown(KeyCode.Alpha3))
169
            {
170
                hitChar = "3";
171
            }
172
            if (Input.GetKeyDown(KeyCode.Keypad4) || Input.GetKeyDown(KeyCode.Alpha4))
173
            {
174
                hitChar = "4";
175
            }
176
            if (Input.GetKeyDown(KeyCode.Keypad5) || Input.GetKeyDown(KeyCode.Alpha5))
177
            {
178
                hitChar = "5";
179
            }
180
            if (Input.GetKeyDown(KeyCode.Keypad6) || Input.GetKeyDown(KeyCode.Alpha6))
181
            {
182
                hitChar = "6";
183
            }
184
            if (Input.GetKeyDown(KeyCode.Keypad7) || Input.GetKeyDown(KeyCode.Alpha7))
185
            {
186
                hitChar = "7";
187
            }
188
            if (Input.GetKeyDown(KeyCode.Keypad8) || Input.GetKeyDown(KeyCode.Alpha8))
189
            {
190
                hitChar = "8";
191
            }
192
            if (Input.GetKeyDown(KeyCode.Keypad9) || Input.GetKeyDown(KeyCode.Alpha9))
193
            {
194
                hitChar = "9";
195
            }
196
            if (Input.GetKeyDown(KeyCode.Space))
197
            {
198
                hitChar = " ";
199
            }
200
            if (Input.GetKeyDown(KeyCode.Minus))
201
            {
202
                hitChar = "-";
203
            }
204
            if (Input.GetKeyDown(KeyCode.Period))
205
            {
206
                hitChar = ".";
207
            }
208
            if (Input.GetKeyDown(KeyCode.Return))
209
            {
210
                hitChar = "Return";
211
            }
212
213
            if (position < WordSwapner.instance.midBreak)
214
            {    
215
                position = -1;
216
                return;
217
            }
218
219
            if ((position >= 0) && (position < word.Length))
220
            {
221
                preWord = word.Substring(0, position + 1);
222
                postWord = word.Substring(position + 1);
223
224
                if (!word.Substring(position, 1).ToLower().Equals(hitChar))
225
                {
226
                    position = -1;
227
                    WordSwapner.instance.midBreak = -1;
228
                }
229
                else
230
                {
231
                    WordSwapner.instance.midBreak = position;
232
233
                    showString = "<color=" + hitColor + ">" + preWord + "</color><color=" + defaultColor + ">" + postWord + "</color>";
234
                }
235
                return;
236
            }
237
        }
238
239
        if (position >= word.Length - 1)
240
        {
241
            if (hitChar.Equals("Return"))
242
            {
243
                WordSwapner.instance.midBreak = -1;
244
245
                if (!oncecal)
246
                {
247
                    lengthChange = explain.Length * 15;
248
                    oncecal = true;
249
                }
250
                showString = "<color=white>" + explain + "</color>";
251
252
                mytimer -= Time.deltaTime * 2;
253
254
                if (mytimer <= 0 && !isBlow)
255
                {
256
                    isBlow = true;
257
                    GameController.instance.score += 1;
258
259
                    if (GameController.instance.score > GameController.instance.highScore)
260
                    {
261
                        GameController.instance.highScore = GameController.instance.score;
262
                    }
263
                }
264
            }
265
        }
266
    }
267
268
    void OnGUI()
269
    {
270
        GUI.skin = skin;
271
        transformPos3D = transform.position;
272
        transformPos2D = mainCamera.WorldToScreenPoint(transformPos3D);
273
        transformPos2D = new Vector2(transformPos2D.x, Screen.height - transformPos2D.y);
274
275
        if (!isBlow)
276
        {
277
            GUI.Box(new Rect(transformPos2D.x, transformPos2D.y, lengthChange*3, 64), showString);   
278
        }
279
        else
280
        {
281
            Destroy(this.gameObject, 1);
282
        }
283
    }
284
}

WordSwapner

1
using System.IO;
2
using UnityEngine;
3
4
public class WordSwapner : MonoBehaviour
5
{
6
    public Transform wordTransform;
7
    private Transform myTransform;
8
    public TextAsset txt;
9
10
    public static WordSwapner instance; 
11
    private string txtLine;
12
    public string word; 
13
    public string explain;
14
    
15
    private float interval; 
16
    private string[] txtData;
17
    public int midBreak;
18
19
    void Start()
20
    {
21
        instance = this;
22
        myTransform = this.transform;
23
24
        txtData = txt.text.Split('\n');
25
    }
26
27
    void Update()
28
    {
29
        interval -= Time.deltaTime;
30
        if (interval <= 0)
31
        {
32
            txtLine = txtData[Random.Range(0, txtData.Length)];
33
            word = txtLine.Split('|')[0].TrimEnd();
34
            explain = txtLine.Split('|')[1].TrimStart();
35
            Instantiate(wordTransform, new Vector3(myTransform.position.x + Random.Range(-4, 4), myTransform.position.y, myTransform.position.z), Quaternion.identity);
36
            interval = 3.5f;
37
        }
38
    }
39
}

GameController

1
using UnityEngine;
2
using UnityEngine.SceneManagement;
3
4
public class GameController : MonoBehaviour
5
{
6
    public int life;
7
    public static GameController instance;
8
    public int score; 
9
    public int highScore;
10
    public GUISkin skin;
11
    private bool esc;
12
13
    void Start()
14
    {
15
        Time.timeScale = 1;
16
        //life = 10;
17
        instance = this;
18
        highScore = PlayerPrefs.GetInt("HiScore");
19
    }
20
21
    void Update()
22
    {
23
        esc |= Input.GetKeyDown(KeyCode.Escape);
24
    }
25
26
    private void OnTriggerEnter2D(Collider2D collision)
27
    {
28
        Debug.Log("OnTriggerEnter2D");
29
        if (collision.CompareTag("Word"))
30
        {
31
            if (life > 0)
32
            {
33
                life -= 1;
34
                WordSwapner.instance.midBreak = -1;
35
                Destroy(collision.gameObject);
36
            }
37
        }
38
    }
39
40
    void OnTriggerEnter(Collider other)        
41
    {
42
        if (other.CompareTag("Word"))
43
        {   
44
            if (life > 0)
45
            {
46
                life -= 1;
47
                WordSwapner.instance.midBreak = -1;   
48
                Destroy(other.gameObject);
49
            }
50
        }
51
    }
52
53
    void OnGUI()
54
    {
55
        GUI.skin = skin;
56
        GUI.Label(new Rect(20, 20, 300, 100), "High Score: " + highScore);
57
        GUI.Label(new Rect(Screen.width - 220, 20, 200, 100), "Score: " + score);
58
        GUI.Label(new Rect(Screen.width - 220, Screen.height - 120, 200, 100), "Life:" + life);
59
60
        if (esc && life != 0)
61
        {
62
            Time.timeScale = 0;
63
            if (GUI.Button(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 50, 200, 100), "Resume"))
64
            {
65
                esc = false;
66
                Time.timeScale = 1;
67
            }
68
        }
69
70
        if (life == 0)
71
        {
72
            esc = true;
73
            Time.timeScale = 0;
74
75
            if (score > highScore)
76
            {
77
                PlayerPrefs.SetInt("HiScore", highScore);
78
                GUI.Label(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 300, 400, 100), "Awesome!");
79
            }
80
81
            if (GUI.Button(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 50, 400, 100), "Restart"))
82
            {
83
                RestartGame();
84
            }
85
86
            if (GUI.Button(new Rect(Screen.width / 2 - 200, Screen.height / 2 + 100, 400, 100), "Quit"))
87
            {
88
                Application.Quit();
89
            }
90
        }
91
    }
92
93
    void RestartGame()
94
    {
95
        SceneManager.LoadScene(
96
            SceneManager.GetActiveScene().name);
97
    }
98
}

小结

2D 游戏的制作可以参照之前的 《Box Tower / 堆箱塔》,也可以用 3D 实现 2D 效果。

下载

游戏

Release: https://github.com/GameDevLog/GameDevLogTemplete/releases

源码

GitHub: https://github.com/GameDevLog/GameDevLogTemplete

本文标题:Type Game / 打字游戏

文章作者:iOSDevLog

发布时间:2019年12月09日 - 17:35:04

最后更新:2019年12月19日 - 14:28:00

原始链接:https://game.iosdevlog.com/2019/12/09/Type-Game/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

iOSDevLog wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!