服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - Unity3D开发实战之五子棋游戏

Unity3D开发实战之五子棋游戏

2022-08-05 11:22雁回晴空 C#

这篇文章主要为大家详细介绍了Unity3D开发实战之五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

前言

经过前面《unity3d入门教程》系列讲解,再加上我们自己的探索,相信大家已经掌握了unity3d的相关知识和基本方法。本文将使用前面学到的知识,开发一款简单的五子棋程序。本文用到的东西其实不多,非常简单。在最后我们会把完整工程的源代码发布出来,以供初学者参考。先展示一下最后的运行效果吧。

Unity3D开发实战之五子棋游戏

1 准备工作

(1)开发环境:win10 + unity5.4.1

(2)图片素材准备:

黑棋子和白棋子

Unity3D开发实战之五子棋游戏Unity3D开发实战之五子棋游戏

棋盘

Unity3D开发实战之五子棋游戏

获胜提示图片

Unity3D开发实战之五子棋游戏

Unity3D开发实战之五子棋游戏

2 开发流程

上文提到的素材可以直接下载我们给出的这些图,也可以自己制作。注意黑白棋子要做成png格式,以保证显示的时候棋子四个角是透明的。将用到的图片素材导入到工程当中。新建一个场景,创建一个plane,作为maincamera的子物体。将棋盘贴图拖动到plane上,并且将plane正面面向摄像机。

Unity3D开发实战之五子棋游戏

再创建四个sphere,作为plane的子物体,分别命名为lefttop、righttop、leftbottom、rightbottom。然后把他们的meshrenderer勾选掉。这些球是为了计算棋子落点所设置的,所以需要把它们与棋盘的四个角点对准。

Unity3D开发实战之五子棋游戏

然后我们创建一个chess.cs脚本,绑定到maincamera上。脚本中包含了所有的功能。需要绑定的一些物体如图所示。

Unity3D开发实战之五子棋游戏

chess.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
using unityengine;
using system.collections;
 
public class chess : monobehaviour {
 
 //四个锚点位置,用于计算棋子落点
 public gameobject lefttop;
 public gameobject righttop;
 public gameobject leftbottom;
 public gameobject rightbottom;
 //主摄像机
 public camera cam;
 //锚点在屏幕上的映射位置
 vector3 ltpos;
 vector3 rtpos;
 vector3 lbpos;
 vector3 rbpos;
 
 vector3 pointpos;//当前点选的位置
 float gridwidth =1; //棋盘网格宽度
 float gridheight=1; //棋盘网格高度
 float mingriddis; //网格宽和高中较小的一个
 vector2[,] chesspos; //存储棋盘上所有可以落子的位置
 int[,] chessstate; //存储棋盘位置上的落子状态
 enum turn {black, white } ;
 turn chessturn; //落子顺序
 public texture2d white; //白棋子
 public texture2d black; //黑棋子
 public texture2d blackwin; //白子获胜提示图
 public texture2d whitewin; //黑子获胜提示图
 int winner = 0; //获胜方,1为黑子,-1为白子
 bool isplaying = true; //是否处于对弈状态
 void start () {
 chesspos = new vector2[15, 15];
 chessstate =new int[15,15];
 chessturn = turn.black;
 
 }
 
 void update () {
 
 //计算锚点位置
 ltpos = cam.worldtoscreenpoint(lefttop.transform.position);
 rtpos = cam.worldtoscreenpoint(righttop.transform.position);
 lbpos = cam.worldtoscreenpoint(leftbottom.transform.position);
 rbpos = cam.worldtoscreenpoint(rightbottom.transform.position);
 //计算网格宽度
 gridwidth = (rtpos.x - ltpos.x) / 14;
 gridheight = (ltpos.y - lbpos.y) / 14;
 mingriddis = gridwidth < gridheight ? gridwidth : gridheight;
 //计算落子点位置
 for (int i = 0; i < 15; i++)
 {
 for (int j = 0; j < 15; j++)
 {
 chesspos[i, j] = new vector2(lbpos.x + gridwidth * i, lbpos.y + gridheight * j);
 }
 }
 //检测鼠标输入并确定落子状态
 if (isplaying && input.getmousebuttondown(0))
 {
 pointpos = input.mouseposition;
 for (int i = 0; i < 15; i++)
 {
 for (int j = 0; j < 15; j++)
 {
 //找到最接近鼠标点击位置的落子点,如果空则落子
 if (dis(pointpos, chesspos[i, j]) < mingriddis / 2 && chessstate[i,j]==0)
 {
 //根据下棋顺序确定落子颜色
 chessstate[i, j] = chessturn == turn.black ? 1 : -1;
 //落子成功,更换下棋顺序
 chessturn = chessturn == turn.black ? turn.white : turn.black; 
 }
 }
 }
 //调用判断函数,确定是否有获胜方
 int re = result();
 if (re == 1)
 {
 debug.log("黑棋胜");
 winner = 1;
 isplaying = false;
 }
 else if(re==-1)
 {
 debug.log("白棋胜");
 winner = -1;
 isplaying = false;
 }
 }
 //按下空格重新开始游戏
 if (input.getkeydown(keycode.space))
 {
 for (int i = 0; i < 15; i++)
 {
 for (int j = 0; j < 15; j++)
 {
 chessstate[i, j] = 0;
 }
 }
 isplaying = true;
 chessturn = turn.black;
 winner = 0;
 }
 }
 //计算平面距离函数
 float dis(vector3 mpos, vector2 gridpos)
 {
 return mathf.sqrt(mathf.pow(mpos.x - gridpos.x, 2)+ mathf.pow(mpos.y - gridpos.y, 2));
 }
 
 void ongui()
 {
 //绘制棋子
 for(int i=0;i<15;i++)
 {
 for (int j = 0; j < 15; j++)
 {
 if (chessstate[i, j] == 1)
 {
 gui.drawtexture(new rect(chesspos[i,j].x-gridwidth/2, screen.height-chesspos[i,j].y-gridheight/2, gridwidth,gridheight),black);
 }
 if (chessstate[i, j] == -1)
 {
 gui.drawtexture(new rect(chesspos[i, j].x - gridwidth / 2, screen.height - chesspos[i, j].y - gridheight / 2, gridwidth, gridheight), white);
 }
 }
 }
 //根据获胜状态,弹出相应的胜利图片
 if (winner == 1)
 gui.drawtexture(new rect(screen.width * 0.25f, screen.height * 0.25f, screen.width * 0.5f, screen.height * 0.25f), blackwin);
 if (winner == -1)
 gui.drawtexture(new rect(screen.width * 0.25f, screen.height * 0.25f, screen.width * 0.5f, screen.height * 0.25f), whitewin);
 
 }
 //检测是够获胜的函数,不含黑棋禁手检测
 int result()
 {
 int flag = 0;
 //如果当前该白棋落子,标定黑棋刚刚下完一步,此时应该判断黑棋是否获胜
 if(chessturn == turn.white)
 {
 for (int i = 0; i < 11; i++)
 {
 for (int j = 0; j < 15; j++)
 {
 if (j < 4)
 {
 //横向
 if (chessstate[i, j] == 1 && chessstate[i, j + 1] == 1 && chessstate[i, j + 2] == 1 && chessstate[i, j + 3] == 1 && chessstate[i, j + 4] == 1)
 {
 flag = 1;
 return flag;
 }
 //纵向
 if (chessstate[i, j] == 1 && chessstate[i + 1, j] == 1 && chessstate[i + 2, j] == 1 && chessstate[i + 3, j] == 1 && chessstate[i + 4, j] == 1)
 {
 flag = 1;
 return flag;
 }
 //右斜线
 if (chessstate[i, j] == 1 && chessstate[i + 1, j + 1] == 1 && chessstate[i + 2, j + 2] == 1 && chessstate[i + 3, j + 3] == 1 && chessstate[i + 4, j + 4] == 1)
 {
 flag = 1;
 return flag;
 }
 //左斜线
 //if (chessstate[i, j] == 1 && chessstate[i + 1, j - 1] == 1 && chessstate[i + 2, j - 2] == 1 && chessstate[i + 3, j - 3] == 1 && chessstate[i + 4, j - 4] == 1)
 //{
 // flag = 1;
 // return flag;
 //}
 }
 else if (j >= 4 && j < 11)
 {
 //横向
 if (chessstate[i, j] == 1 && chessstate[i, j + 1] == 1 && chessstate[i, j + 2] == 1 && chessstate[i, j + 3] == 1 && chessstate[i, j + 4] == 1)
 {
 flag = 1;
 return flag;
 }
 //纵向
 if (chessstate[i, j] == 1 && chessstate[i + 1, j] == 1 && chessstate[i + 2, j] == 1 && chessstate[i + 3, j] == 1 && chessstate[i + 4, j] == 1)
 {
 flag = 1;
 return flag;
 }
 //右斜线
 if (chessstate[i, j] == 1 && chessstate[i + 1, j + 1] == 1 && chessstate[i + 2, j + 2] == 1 && chessstate[i + 3, j + 3] == 1 && chessstate[i + 4, j + 4] == 1)
 {
 flag = 1;
 return flag;
 }
 //左斜线
 if (chessstate[i, j] == 1 && chessstate[i + 1, j - 1] == 1 && chessstate[i + 2, j - 2] == 1 && chessstate[i + 3, j - 3] == 1 && chessstate[i + 4, j - 4] == 1)
 {
 flag = 1;
 return flag;
 }
 }
 else
 {
 //横向
 //if (chessstate[i, j] == 1 && chessstate[i, j + 1] == 1 && chessstate[i, j + 2] == 1 && chessstate[i, j + 3] == 1 && chessstate[i, j + 4] == 1)
 //{
 // flag = 1;
 // return flag;
 //}
 //纵向
 if (chessstate[i, j] == 1 && chessstate[i + 1, j] == 1 && chessstate[i + 2, j] == 1 && chessstate[i + 3, j] == 1 && chessstate[i + 4, j] == 1)
 {
 flag = 1;
 return flag;
 }
 //右斜线
 //if (chessstate[i, j] == 1 && chessstate[i + 1, j + 1] == 1 && chessstate[i + 2, j + 2] == 1 && chessstate[i + 3, j + 3] == 1 && chessstate[i + 4, j + 4] == 1)
 //{
 // flag = 1;
 // return flag;
 //}
 //左斜线
 if (chessstate[i, j] == 1 && chessstate[i + 1, j - 1] == 1 && chessstate[i + 2, j - 2] == 1 && chessstate[i + 3, j - 3] == 1 && chessstate[i + 4, j - 4] == 1)
 {
 flag = 1;
 return flag;
 }
 }
 
 }
 }
 for (int i = 11; i < 15; i++)
 {
 for (int j = 0; j < 11; j++)
 {
 //只需要判断横向
 if (chessstate[i, j] == 1 && chessstate[i, j + 1] == 1 && chessstate[i, j + 2] == 1 && chessstate[i, j + 3] == 1 && chessstate[i, j + 4] == 1)
 {
 flag = 1;
 return flag;
 }
 }
 }
 }
 //如果当前该黑棋落子,标定白棋刚刚下完一步,此时应该判断白棋是否获胜
 else if(chessturn == turn.black)
 {
 for (int i = 0; i < 11; i++)
 {
 for (int j = 0; j < 15; j++)
 {
 if (j < 4)
 {
 //横向
 if (chessstate[i, j] == -1 && chessstate[i, j + 1] == -1 && chessstate[i, j + 2] == -1 && chessstate[i, j + 3] == -1 && chessstate[i, j + 4] == -1)
 {
 flag = -1;
 return flag;
 }
 //纵向
 if (chessstate[i, j] == -1 && chessstate[i + 1, j] == -1 && chessstate[i + 2, j] == -1 && chessstate[i + 3, j] == -1 && chessstate[i + 4, j] == -1)
 {
 flag = -1;
 return flag;
 }
 //右斜线
 if (chessstate[i, j] == -1 && chessstate[i + 1, j + 1] == -1 && chessstate[i + 2, j + 2] == -1 && chessstate[i + 3, j + 3] == -1 && chessstate[i + 4, j + 4] == -1)
 {
 flag = -1;
 return flag;
 }
 //左斜线
 //if (chessstate[i, j] == -1 && chessstate[i + 1, j - 1] == -1 && chessstate[i + 2, j - 2] == -1 && chessstate[i + 3, j - 3] == -1 && chessstate[i + 4, j - 4] == -1)
 //{
 // flag = -1;
 // return flag;
 //}
 }
 else if (j >= 4 && j < 11)
 {
 //横向
 if (chessstate[i, j] == -1 && chessstate[i, j + 1] == -1 && chessstate[i, j + 2] == -1 && chessstate[i, j + 3] == -1 && chessstate[i, j + 4] ==- 1)
 {
 flag = -1;
 return flag;
 }
 //纵向
 if (chessstate[i, j] == -1 && chessstate[i + 1, j] == -1 && chessstate[i + 2, j] == -1 && chessstate[i + 3, j] == -1 && chessstate[i + 4, j] == -1)
 {
 flag = -1;
 return flag;
 }
 //右斜线
 if (chessstate[i, j] == -1 && chessstate[i + 1, j + 1] == -1 && chessstate[i + 2, j + 2] == -1 && chessstate[i + 3, j + 3] == -1 && chessstate[i + 4, j + 4] == -1)
 {
 flag = -1;
 return flag;
 }
 //左斜线
 if (chessstate[i, j] == -1 && chessstate[i + 1, j - 1] == -1 && chessstate[i + 2, j - 2] == -1 && chessstate[i + 3, j - 3] == -1 && chessstate[i + 4, j - 4] == -1)
 {
 flag = -1;
 return flag;
 }
 }
 else
 {
 //横向
 //if (chessstate[i, j] == -1 && chessstate[i, j + 1] ==- 1 && chessstate[i, j + 2] == -1 && chessstate[i, j + 3] == -1 && chessstate[i, j + 4] == -1)
 //{
 // flag = -1;
 // return flag;
 //}
 //纵向
 if (chessstate[i, j] == -1 && chessstate[i + 1, j] ==- 1 && chessstate[i + 2, j] ==- 1 && chessstate[i + 3, j] ==- 1 && chessstate[i + 4, j] == -1)
 {
 flag = -1;
 return flag;
 }
 //右斜线
 //if (chessstate[i, j] == -1 && chessstate[i + 1, j + 1] == -1 && chessstate[i + 2, j + 2] == -1 && chessstate[i + 3, j + 3] == -1 && chessstate[i + 4, j + 4] == -1)
 //{
 // flag = -1;
 // return flag;
 //}
 //左斜线
 if (chessstate[i, j] == -1 && chessstate[i + 1, j - 1] == -1 && chessstate[i + 2, j - 2] == -1 && chessstate[i + 3, j - 3] == -1 && chessstate[i + 4, j - 4] == -1)
 {
 flag = -1;
 return flag;
 }
 }
 }
 }
 for (int i = 11; i < 15; i++)
 {
 for (int j = 0; j < 11; j++)
 {
 //只需要判断横向
 if (chessstate[i, j] == -1 && chessstate[i, j + 1] == -1 && chessstate[i, j + 2] == -1 && chessstate[i, j + 3] == -1 && chessstate[i, j + 4] == -1)
 {
 flag = -1;
 return flag;
 }
 }
 }
 }
 return flag;
 }
}

运行效果截图:

Unity3D开发实战之五子棋游戏

Unity3D开发实战之五子棋游戏

小结

本程序实现了五子棋的基本功能,纯属娱乐而作。暂时没有加入各种ui、网络模块等。本程序经过了简单的测试,没有什么问题,如果大家在使用的时候发现有什么bug,请联系我改正,谢谢。

下面是工程源码下载地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/zzlyw/article/details/54345250

延伸 · 阅读

精彩推荐
  • C#c#基础系列之值类型和引用类型的深入理解

    c#基础系列之值类型和引用类型的深入理解

    这篇文章主要给大家介绍了关于c#基础系列之值类型和引用类型的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学...

    大菜11552022-03-01
  • C#C#正则过滤HTML标签并保留指定标签的方法

    C#正则过滤HTML标签并保留指定标签的方法

    这篇文章主要介绍了C#正则过滤HTML标签并保留指定标签的方法,涉及C#针对页面HTML元素正则匹配与替换相关操作技巧,需要的朋友可以参考下...

    蓝色水6752022-01-11
  • C#使用代理模式来进行C#设计模式开发的基础教程

    使用代理模式来进行C#设计模式开发的基础教程

    这篇文章主要介绍了使用代理模式来进行C#设计模式开发的基础教程,代理模式主张在客户端和目标对象中间建立中介来降低程序设计的耦合度,需要的朋友可...

    saville10842021-11-14
  • C#C# this关键字的四种用法

    C# this关键字的四种用法

    这篇文章主要为大家详细介绍了C# this关键字的四种用法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    天碼亦行空10322021-12-13
  • C#Unity实现旋转扭曲图像特效

    Unity实现旋转扭曲图像特效

    这篇文章主要为大家详细介绍了Unity实现旋转扭曲图像特效,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    图形小菜鸡11882022-03-11
  • C#C# 开发(创蓝253)手机短信验证码接口的实例

    C# 开发(创蓝253)手机短信验证码接口的实例

    下面小编就为大家分享一篇C# 开发(创蓝253)手机短信验证码接口的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    C#教程网3742022-02-17
  • C#基于C#的电视台节目表接口调用代码

    基于C#的电视台节目表接口调用代码

    这篇文章主要介绍了基于C#的电视台节目表接口调用代码的相关资料,需要的朋友可以参考下...

    C#教程网7022021-11-26
  • C#使用C#的正则表达式验证中文字符(实例代码)

    使用C#的正则表达式验证中文字符(实例代码)

    本文通过实例代码给大家介绍了使用C#的正则表达式验证中文字符的方法,需要的的朋友参考下吧...

    Adonay6182022-01-17