基于Unity3D的科普游戏设计与实现
2023-09-20赵佳乔凤天
赵佳 乔凤天
摘 要 以Unity3D作为游戏引擎,设计开发一款有关化学基本仪器使用的卡牌配对的科普类教育游戏。该游戏可作为一种科普工具,能够帮助学习者了解基本化学仪器的使用。详细介绍游戏制作的流程以及主要功能的实现,呈现游戏最后实现的效果图,将科普知识融入游戏当中,增强学习的趣味性和游戏的科普性。
关键词 Unity3D;教育游戏;科普游戏;卡牌配对;化学仪器
中图分类号:TP317.6 文献标识码:B
文章编号:1671-489X(2023)10-0038-05
Design and Implementation of Science Game Based on Unity3D: Taking Basic Chemical In-struments as Example//ZHAO Jia,QIAO Feng-tian
Abstract Using Unity3D as the game engine, this paper designed and developed a popular science edu-cation game about the card pairing of basic chemical instruments, which can be used as a popular science tool to help learners understand the use of basic chemical instruments. This article details the pro-cess of game production and the implementation of the main functions, and presents the final effect diagram of the game. The integration of popular science knowledge into the game enhances the fun of learning and the popularity of the game.
Key words Unity3D; education game; science games; card matching; chemical instrument
Authors address Teacher Education Institute, The Capital Normal University, Beijing, China, 100037
0 引言
近年來,游戏已被应用到教学领域,游戏和教学的融合程度越来越高,游戏化学习成为一种越来越普遍和受欢迎的学习方式,已经慢慢被教师和家长所接受。以科普为目的的科普类教育游戏也应运而生,它作为一种教育资源,本身所具有的娱乐性功能吸引了不少的学习者。此外,科普活动的教育目标不只是科学知识,还包括科学方法与科学精神,游戏化的实现手段使公众在学习了解科学知识本身的同时,全方面地锻炼沟通实践等能力[1]。相比于传统科普教育方式的枯燥和晦涩难懂,以游戏化的方式呈现科普知识,能够增强科普过程中的趣味性以及学习者和科普知识之间的互动性。
科普游戏作为教育游戏的一种,从字面上了解,就是以知识科普为目的的教育游戏。但截至目前,国内还没有对“科普游戏”作出明确的定义。刘玉花等[2]提出了“科普网游”的广义概念和狭义概念。周忠和认为,科普游戏要符合游戏的四大特征:目标、规则、反馈、自愿参与。科普游戏不能离开科学的核心,还要有趣味,没有科学的所谓科普游戏都是伪科普游戏,而科普游戏没有了游戏的趣味和设定就不是游戏[3]。不容置疑的是,科普游戏的真正目的是寓教于乐,要将科普知识植入游戏当中,使学习者在与游戏的交互过程中潜移默化地学到知识,提高能力。
尽管科普游戏对于促进学习具有重大意义,但并未引起国内游戏行业的足够重视。目前,国内的科普游戏主要用在科普场馆,受众面严重受限,而且,无论是在理论上还是在实践上,国内科普游戏的发展与国外相比都存在较大的差距。科普游戏在不断发展的过程中,逐渐暴露出它所存在的一些问题,比如科普游戏的娱乐性与教育性的平衡问题,很多游戏设计者都不能完美解决这一问题,一般都会出现两个极端:有些科普游戏过分注重知识的科普性,附加了太多的教育元素,因而使它沦为了一个纯粹的教育工具,像游戏“心理游戏”规定在有限时间内将给出的4张牌通过加减乘除计算得到结果24,整个游戏过程非常枯燥,且具有一定的难度;还有一部分科普游戏过分注重游戏的娱乐性,附加了太多的游戏元素,从而使它沦为了一个纯粹的游戏软件。诸如此类的问题一直困扰着科普游戏的开发者,而正确的科普游戏旨在使学习者在轻松愉悦且具有一定教育意义的游戏环境中获取知识,锻炼能力,增强技能。
本研究基于Unity3D游戏引擎,遵循游戏开发的系统性、实用性、艺术性等特点,设计并开发了一款面向小学高年级学生的有关基本化学仪器使用的卡牌配对类的科普游戏,该游戏具有一定的辅助教学的功能,能够使学习过程变得简单有趣,可以满足向学生科普知识的基本需求。
1 游戏设计
1.1 游戏主题
本案例是以向学习者科普基本化学仪器的使用为主题,借鉴卡牌配对游戏的精髓,在设计过程中加入化学仪器,使用Unity3D引擎制作的一款科普游戏,游戏共分为两大板块,即游戏板块和学习板块。学习者通过鼠标点击翻开卡牌,找到相互配对的卡牌,以此在与游戏的交互过程中,寓教于乐,获得新知。
1.2 游戏机制
本游戏共设置了3×4共12张卡牌,学习者可仅通过点击鼠标来完成游戏。在游戏板块,学习者在每点击两张卡牌后,游戏会检测这两张卡牌是否配对,配对成功则获得时间奖励,否则将自动翻过这两张卡牌,并重复上述操作;在学习板块,主要向学习者介绍一些基本的化学仪器,能在游戏过程中为学习者及时补充知识。作为一款科普类教育游戏,设定该游戏为单人版,难度适中,具有一定的可玩性和科普性。
1.3 游戏项目制作流程
该游戏的制作共分为两部分:一为前期的图片和音乐等资源的收集与整理;二为后期的游戏UI设计、场景设计及程序实现等。在该游戏的设计开发工作全部完成之后,要先经过游戏测试,方能发布到相关平台以投入使用。项目的具体制作流程如图1所示。
1.4 主要界面展示
基于以上游戲项目制作流程,展示游戏当中的一些主要界面图,游戏界面和学习界面分别如图2和图3所示。
1.5 游戏UI之间的逻辑关系
在游戏首页共为玩家提供了两种选择,玩家若点击“先学习”,则进入学习界面,学习完毕后会进入游戏界面,根据游戏结果进入相应的界面(游戏成功或游戏失败界面),并在相应界面点击要执行的相应的操作按钮进行跳转;玩家若在游戏首页点击“先游戏”,则进入游戏界面,根据游戏结果进入相应的界面(游戏成功或游戏失败界面),并在相应界面点击要执行的相应的操作按钮进行跳转。游戏逻辑图如图4所示。
2 游戏的算法设计及实现思路
2.1 如何生成牌面随机分布的卡牌矩阵
本游戏提供了六种互为配对,但牌面各不相同的共计12张卡牌。在游戏开始时,会初始化生成3×4的卡牌矩阵,并依据每张卡牌之间的间距,将每张卡牌放置到其相应的位置上,随后通过Random()函数实现卡牌的随机分布。具体实现思路为:首先,创建一个一维数组images[]来存放12张牌面;其次,创建一个一维数组numbers[],并初始化为{0,11,1,10,2,9,3,8,4,7,5,6},num-bers[]数组中每个元素的值代表了images[]数组中每张牌面所对应的索引值,其中每相邻的两个元素所代表的卡牌互为配对(即卡牌索引值相加为11的两张卡牌互为配对);再次,使用双重循环语句来存储卡牌的顺序,并定义一个临时变量tempObj来保存生成的卡牌;最后,使用Random()函数来实现卡牌分布的随机化。
2.2 如何通过鼠标点击实现卡牌翻面
每张卡牌均有三种状态,分别为“未翻面”“已翻面”和“配对成功”,可以创建一个枚举类型来保存这三种状态,定义两个变量first Revealed Card和second Revealed Card分别用来保存第一次和第二次翻开的卡牌,并且要实时刷新这两个变量的值。如果卡牌处于未被翻开状态或是未配对成功状态,则可通过鼠标点击来实现卡牌的翻面,同时修改卡牌的状态为“已翻面”状态。
2.3 如何检测卡牌是否配对
每当玩家连续翻开两张卡牌后,程序都要检测这两张卡牌是否配对成功。如若配对成功,则要使这两张卡牌牌面朝上,并修改其状态为“配对成功”状态。具体实现思路为:首先,要判断这两张卡牌的索引值相加是否等于11,若是,则修改两张卡牌的状态为“配对成功”状态,若否,则修改两张卡牌的状态为“未翻面”状态;其次,要实时刷新存储这两张卡牌的临时变量(即变量first Revealed Card和second Revealed Card),在判断结束后,要将这两个变量的值设为空。
2.4 其他功能
倒计时和时间奖励功能:规定该游戏要在30s的时间内完成,进入游戏时开始倒计时,若卡牌配对成功,会给予一定的时间奖励。具体实现思路为:定义一个浮点型变量time,并初始化为30.0f,定义一个布尔类型的变量canCountdown,初始化为false;当进入游戏时,修改canCountdown的值为true,变量time开始自减;当配对成功时,变量time自增1;当变量canCountdown的值再次变为false时,表明时间耗尽,游戏失败,并跳转到游戏失败界面。
游戏成功或失败的判定:在规定时间内,将所有卡牌均配对成功,则表明游戏胜利。具体实现思路为:定义一个整型变量score,并将其初始化为0,每当卡牌配对成功时,score自增1,在游戏的规定时间30 s内,若score的值达到卡牌总数量的一半,即表明游戏成功,并跳转到游戏成功界面。当时间耗尽,表明游戏失败。
游戏步数的判定:规定每连续翻开两张卡牌,步数加1。具体实现思路为:定义一个整型变量step来保存步数,并将其初始化为0;当翻开第二张卡牌时,step自增1。
背景音乐音效的触发:本游戏共有四段音乐:背景音乐、卡牌配对错误提示音、游戏成功音效以及游戏失败音效。当进入游戏时,触发背景音乐;当连续翻开两张卡牌,但未配对成功时,触发卡牌配对错误提示音效;当游戏成功或失败时分别触发游戏成功和游戏失败音效。
3 游戏关键功能的算法实现
通过上述对游戏算法的设计和实现思路,在Unity3D游戏引擎中来进行游戏的制作,以下给出了游戏当中一些关键功能的算法实现。
3.1 资源的导入和预制体的制作
在Unity3D引擎中的Project窗口创建“Prefabs”“Audio”和“Sprites”三个文件夹分别用来保存项目制作过程中所用到的预制体、音频资源和图片资源,分别如图5、图6和图7所示。该游戏中的预制体为卡牌的背面图片,音频资源主要包括游戏背景音和游戏中的各种触发音效,图片资源主要是游戏背景图、卡牌的牌面和各种UI背景等。
3.2 卡牌的初始化和随机分布
游戏初始界面生成3×4的卡牌矩阵。通过一个双重循环语句来保存生成的卡牌,借助Random()函数来实现卡牌的随机化分布。该功能的关键代码如下:
private int gridRows = 3, gridCols = 4;
//卡牌矩阵的行数和列数
private float offsetX = 2.5f, offsetY = 2.7f;
//卡牌之间的间距
private float originalX = -5f, originalY = -3f;
//卡牌的原始位置
//初始化生成卡牌
void ArrangeCards()
{
for (int i = 0; i < gridRows; i++)
{
for(int j = 0; j < gridCols; j++
{
//初始化生成卡牌
MemaryCard tempObj = Instantiate(Card) as MemaryCard;
tempObj.GetComponent
bers[i * gridCols + j]]);
//设置每张卡牌的状态为未翻开状态
tempObj.GetComponent
//计算每张卡牌的位置
float posX = (offsetX * j) + originalX;
float posY = (offsetY * i) + originalY;
//将每张卡牌放置到相对应的位置上
tempObj.transform.position = new Vector3(posX, posY, 0);
}
}
}
//卡牌的随机化分布
int[] ShuffleCards(int[] numbers)
{//定义一个数组来保存每张卡牌的索引值
int[] tempNums = numbers.Clone() as int[];
for (int i = 0; i < tempNums.Length; i++)
{
//定义一个变量来保存随机生成的索引值
int r = Random.Range(i, tempNums.Length);
//定义一个临时变量来存放每张卡牌,并将其与随机生成的索引值所代表的卡牌互换位置,从而实现卡牌的随机化分布
int temp = tempNums[i];
tempNums[i] = tempNums[r];
tempNums[r] = temp;
}
//返回卡牌的索引值
return tempNums;
}
3.3 鼠标点击卡牌翻面
当鼠标点击卡牌时,需完成的任务包括保存每次点击的卡牌以及需改卡牌的状态。需要判断是第一次还是第二次点击卡牌,当卡牌第一次被点击时,需保存到变量firstRevealedCard中,当卡牌第二次被点击时,需保存到变量secondRevealedCard中。该功能的关键代码如下:
public void CardReveal(MemaryCard card)
{
//首先判斷是否为第一次点击,翻开牌面
if(firstRevealedCard ==null)
{
//如果是,则将这张卡牌存储在变量firstRevealedCard中
firstRevealedCard = card;
}
else
{
//如果不是,则将这张卡牌存储在变量secondRevealedCard中
secondRevealedCrad = card;
//更新步数
step++;
stepText.text = “步数:” + step;
//调用CheckMatch()函数,判断是否配对成功
Invoke(“CheckMatch”, 1f);
}
}
//鼠标点击操作
public void OnMouseDown()
{
//可翻开卡牌的条件:卡牌处于未翻开状态、未配对成功状态以及第二张卡牌为空
if (cardstate == cardState.Unreveal && cardstate != cardState.Matched && sceneManager.canReveal())
{
//调用Reveal()函数,修改卡牌的状态为“已翻面”状态
Reveal();
sceneManager.CardReveal(this);
}
}
3.4 卡牌的配对
两张卡牌成功配对的条件为索引值相加等于11,若满足此条件说明卡牌成功配对,此后需要修改这两张卡牌的状态。该功能的关键代码如下:
private void CheckMatch()
{
//如果两张卡牌的索引值相加等于11,则说明这两张卡牌配对成功
if (firstRevealedCard.getID() + secondRevealedCrad.getID()==11)
{
//修改两张卡牌的状态为“配对成功”状态
firstRevealedCard.Matched();
secondRevealedCrad.Matched();
timer.time++;
//变量score用来保存已配对成功的卡牌数量
score++;
//每次成功配对后,都要判断游戏是否成功
Victory();
}
else
{
//触发警告音效
source.PlayOneShot(warningSound, 1F);
//修改两张卡牌的状态为“未翻面”状态
firstRevealedCard.Unreveal();
secondRevealedCrad.Unreveal();
}
//将临时存放两张卡牌的变量设为空
firstRevealedCard = null;
secondRevealedCrad = null;
}
4 结束语
本文借助Unity3D游戏引擎开发了一款关于基本化学仪器使用的卡牌配对类的科普教育游戏,后续可发布到PC端、Android手机等多种平台,具有较好的跨平台特征。本游戏能够将化学知识与Unity3D引擎有效融合,在游戏设计和开发的过程中,既提供了一定的娱乐功能,又保证了在游戏中融入一定的科普知识,使玩家通过简单的鼠标点击操作,在游戏的过程中学到知识,具有较好的互动性和沉浸效果,能够在一定程度上弥补传统的科普方式的缺陷,具有一定的辅助教学的功能。虽然在游戏的前期准备阶段和后续的开发阶段遇到了一些问题,但经过深入研究之后,都能够找到相应的解决方案。由于本游戏现在的结构功能还不完整,因此,笔者在后期会尝试将其他一些化学知识加入本游戏当中,从而形成一个更完整、更有体系的有关化学知识的科普类教育游戏。
5 参考文献
[1] 肖云,谷美慧.科普教育游戏化的研究与思考[M]//2018年(第五屆)科学与艺术研讨会论文集,2018:98-107.
[2] 刘玉花,费广正,姜珂.科普网游及其产业发展研究[J].科普研究,2011,6(6):34-38.
[3] 托波.游戏改变教育:数字游戏如何让我们的孩子变聪明[M].何威,褚萌萌,译.上海:华东师范大学出版社,2017.