这个作业属于哪个课程 | 构建之法-2021秋-福州大学软件工程 |
---|---|
这个作业要求在哪里 | 2021秋软工实践第二次结对编程作业 |
个人学号 | 031902139 |
结对成员学号 | 031902144 |
结对小伙伴的作业博客链接 | 队友博客 |
GitHub 仓库地址 | GitHub仓库 |
视频演示链接 | 视频演示 |
文章目录
一、GitHub 仓库
我们先在各自的分支 master1、master2 上提交各自完成的编程代码,最后再将代码整合至 main 分支
二、软件运行视频
- ☞视频演示
三、重点或难点功能、编程思考
- 从原型到游戏
- 设计方面:我们先前对于原型的设计缺少游戏的动态感,仅仅是绘制了游戏的界面。而在对于游戏进行编码的时候,我们讨论出了一些可以用于改善游戏体验的设计细节,增加了文字滚动栏、按钮特效、组件动画、游戏音乐等。文字滚动栏在应当每一个界面上都有呈现,确保让每一个页面至少有一种动态元素
- 代码实现方面:首先我们讨论了游戏逻辑使用什么语言实现。本来想通过前后端分离的模式,但是发现不是特别容易实现,最终确定用纯前端的方式实现
- 网页打开方式方面:如果采用 localhost 的方法打开网页,会遇到的困难的地方是 JavaScript 文件向 Html 文件的引入问题。采用原来的方式,Html 文件中引入的 JavaScript 和 CSS 文件就会失效。这时只能通过引入绝对路径实现,查找如何通过绝对路径引入时我们花费了一定量的时间,而且修改整个代码的 img 标签的 src 是个大工程,在网站上点击 onclick 事件服务器会产生莫名报错。所以最终我们采用 live server 的方式打开页面来实现
- 联机模式
- 联机可以体现于很多形式,所以在联机上我们设想了一些方式:类似于欢乐斗地主一样的机制,如果玩家没有进入游戏,就让系统自动参与游戏;设置游戏计分板和游戏进行顺序等机制;通过输入 IP 地址和姓名登录等
- 但是通过在网上搜索资料,发现输入 IP 地址进入游戏页面的方式难以正确运行,容易产生无法登录的问题。与此同时,设置游戏进行顺序对于博饼游戏来说没有很大必要性,我们的游戏主要是娱乐作用而非竞技作用,所以不应该在游戏中设置过多商业化和竞技化的选项,而应着重处理相互通信的功能
- 于是打算采用通过增减网页来增减用户的方式,并且通过广播将玩家博饼结果传播到每一个用户端
- 联机模式的消息发送实现
var btn = document.querySelector("#pause");
var text = document.querySelector("#text");
var x = document.querySelector("#haha1");
var socket = new WebSocket('ws://localhost:5500')
//open:当websocket服务连接成功时触发
socket.addEventListener('open', function() {
alert("连接服务成功了")
})
//主动给websocket服务发送信息
btn.addEventListener('click', function() {
socket.send(outcome)
})
//接收websocket的服务信息
socket.addEventListener('message', function(e) {
var x1 = document.createElement('li');
x1.innerText = e.data;
x.insertBefore(x1, x.children[0]);
});
socket.addEventListener('close', function(e) {
console.log("haha断开连接")
});
- 博饼结果的判定
- 设计系统判定骰子结果的算法是一个难点。我们参考了真实的博饼现场样貌,决定通过点击开始按钮让骰子开始自动生成点数,点击结束系统自动生成博饼结果的方式实现
- 博饼结果判定代码
function fun2() {
var sijin = 0;
window.clearTimeout(flagtime);
if (num[3] >= 4) {
if (num[3] == 6)
result_player1.innerHTML = "<span>状元-红六勃</span>";
else if (num[3] == 5)
result_player1.innerHTML = "<span>状元-五红</span>";
else if (num[0] == 2)
result_player1.innerHTML = "<span>状元-插金花</span>";
else
result_player1.innerHTML = "<span>状元-四红</span>";
} else if (num[0] == 6)
result_player1.innerHTML = "<span>状元-遍地锦</span>";
else if (num[1] == 6 || num[2] == 6 || num[4] == 6 || num[5] == 6)
result_player1.innerHTML = "<span>状元-黒六勃</span>";
else if (num[0] == 5 || num[1] == 5 || num[2] == 5 || num[4] == 5 || num[5] == 5)
result_player1.innerHTML = "<span>状元-五子登科</span>";
else {
for (var i = 0; i < 6; i++) {
if (num[i] == 4)
sijin = 1;
}
if (sijin == 1)
result_player1.innerHTML = "<span>进士-四进</span>";
else if (num[0] == 1 && num[1] == 1 && num[2] == 1 && num[3] == 1 && num[4] == 1 && num[5] == 1)
result_player1.innerHTML = "<span>榜眼-对堂</span>";
else if (num[3] == 3)
result_player1.innerHTML = "<span>探花-三红</span>";
else if (num[3] == 2)
result_player1.innerHTML = "<span>举人-二举</span>";
else if (num[3] == 1)
result_player1.innerHTML = "<span>秀才-一秀</span>";
else
result_player1.innerHTML = "<span>哎呀,再博一次吧</span>";
}
}
- 积分机制
- 关于是否要设置积分机制,我们在编程的过程中也一直在反复思考。在设计原型的时候,我们是没有设置积分的。但在看其他人的原型时,我们就发现还挺多人设置了这个积分机制的。所以在编程过程中,我们一直在思考这个问题
- 我们觉得我们设计的游戏是希望不像其它游戏那样有严格的顺序限制的,不一定要按照玩家 1 -> 玩家 2 -> 玩家 3 这样的顺序依次执行。我们的游戏应该是可以比较自由的来进行的,这样有时游戏也可以应用在其它场合,比如像之前老师提到的:决定谁倒垃圾。所以,经过各个方面的思考之后,我们选择不增加积分机制
- 随之,也就没有奖品设置了
- 创新点
- 在助教给的评分标准中,创新度占到了 10 分。所以,在完成作业的过程中,我们也一直在思考哪些地方可以有一些创新
- 首先,我们最先想到的就是给按钮增加一些效果,比如:彩虹动图、发光等。接着,我们想到了在页面上方加一个滚动文字来介绍一些博饼的历史以及加点背景音乐,或者,来一个隐藏按钮。在编程末尾,我们又想到了给背景图加点忽明忽暗的效果
- 不过,想的容易,实现起来还是有难度的。我们花了挺长一段时间来学习相关知识。然后在实现的过程中,如何把某种按钮效果应用在全部页面,如何在跳转页面的时候保持背景音乐不中断,都是我们重点思考的
- 背景音乐、滚动文字、发光按钮的主要实现代码
<!--背景音乐-->
<audio src="bgsound/眉间醉.mp3" id="music" controls="controls" autoplay="autoplay" loop="loop" preload id="music"></audio>
<!--滚动文字-->
<div class="hty_word">
<h1>
<marquee hspace="20px">
中秋博饼,起源于福建厦门,由郑成功驻兵时发明,是闽南地区特有的由饼文化外延的一种传统民俗活动。博饼是中秋节时的一种大众娱乐活动,用六粒骰子投掷结果组合来决定参与者的奖品。传统的奖品为大小不同的月饼,共计一会,设状元1个,对堂2个,三红4个,四进8个,二举16个,一秀32个。相传这种游戏可以预测人未来一年内的运气。 在闽南地区,中秋赌饼也已成为一种商业活动和大众游戏。福建人民出版社1985年出版的《福建风物志》记载:在闽南一带,中秋节有“夺状元饼”的习俗。在台湾中部和东部地区的一些城乡以及台湾离岛金门县,还流行中秋博状元饼的习俗。在金门,金城镇吴厝社区发展协会每年庆祝中秋社区联欢晚会,都有博状元饼大赛。
</marquee>
</h1>
</div>
/*发光按钮*/
.btn789 {
cursor: pointer;
color: white;
background: red;
width: 70px;
height: 35px;
border-radius: 50px;
-webkit-transform: scale(1, 0.9);
border: 0px;
position: absolute;
left: 730px;
top: 397px;
}
.btn789:hover {
color: white;
border: 0;
}
四、在编码、争论、复审中花费时间较长,收获较大的事件
- 按钮特效
- 因为设置在鼠标点击按钮时产生流动的五彩色的效果会给整个游戏带来更好的页面效果,所以我们决定尝试。在实现过程中比较困难的地方是很多 CSS 属性先前没有接触过,所以要到网上学习;同时,如何将属性组合起来也是一个问题
- 隐藏按钮
- 在游戏页面中,我们设置了一个隐藏按钮,只有当玩家把鼠标移到按钮上的时候,这个按钮才会显现出来。这个是我们的一个创新点,刚想出来这个点的时候,我们还挺开心的,觉得这个点还挺妙,应该可以加分
- 不过,想的时候有多开心,实现的时候就有多痛苦。我们在网上查找如何实现隐藏按钮的资料的时候,基本都是看别人写的博客。但因为一开始忘了先把人家的代码先运行一遍,就直接模仿写到自己的代码上,这就导致我们跳进了不少坑中——里面很多人给的方法其实根本实现不了。因此,我们在实现这一功能的时候,耗费时间较长。但我们觉得,其实里面有些时间其实是浪费了,是不应该花的
- 通过这件事,我们觉得比较大的一个收获就是:不管时间再赶,在参考网上给的资料时,还是要先自己运行一遍,不要图省事。不然后面可能浪费更多时间
- 博饼结果
- 在编码过程中遇到的主要困难不在于算法而在于算法和 Html 元素的适配问题。innerHTML 在使用时如果调用出错,就没有办法正常传输数据,页面就会卡住不动,而不像 Java 一样编译器会报错,这时候就需要逐步排查函数在哪个地方被卡住了,很多时候代码不能像先前设想的一样动起来。我们在网上不断查找网页元素的运用特性,调整其在函数中的运用方式,最终让函数符合预期地执行
- 联机争论
- 到底要不要实现联机应该算是我们争论最大、最久的一件事。从原型设计开始持续到游戏编程时联机功能真的实现了
- 在原型设计的时候,我们一个人觉得要学的知识还有很多,时间上可能来不及去学联机的相关知识,所以干脆先放弃,后面有时间再说。另一个人在大致浏览了联机的相关知识后觉得这个应该不会太难,还是可以实现的。最后,如原型所示,我们把联机模式弄上去了
- 不过等到真正编码的过程中,争论又来了。在经历了两个晚上弄到一点左右还没有实现联机的时候。我有点想放弃了。但我的队友觉得都花了两个晚上的时间了,后面再坚持坚持应该可以的。就这样,争论又开始了。不过,最后,我还是再队友的鼓励下坚持了。当最后看到网页上出现的联机模式成功实现了,我觉得还是挺骄傲的,也感谢当时队友的不放弃
- 复审
我们先按照之前画好地原型进行实现,但是在实现过程中感受到了原型设计中不合理的地方,对此我们进行了代码调整和功能增减- 联机模式页面在原型中采用两个博饼碗的样式,后经联机模式的讨论,发现这有点多余,通过网页间通信完全可以将结果传送给其他玩家,没有必要挤在一个页面之中。所以调整之后,联机模式的页面只有一套开始-结束按钮,一个博饼碗
修改前:
修改后:
- 宿舍模式:游戏基本完成之后,我们认为应当增加游戏在现实场景中的使用,与校园日常结合起来,同时要增加游戏的趣味性和神秘性,所以进行了功能的增添。在游戏模式选择页面增加了轻易不可见的“神秘”按钮,如果用户仔细寻找才能找到,点击进入后进入宿舍的模拟博饼场景
- 组件动态性:游戏基本完成后,我们发现界面有点 “呆呆的”。于是增加了背景忽明忽暗的效果,配合背景效果,我们将游戏的开始和结束按钮设置成了发光按钮的样式。同时,我们让骰子和碗一直处于 “动起来” 的状态
- 联机模式页面在原型中采用两个博饼碗的样式,后经联机模式的讨论,发现这有点多余,通过网页间通信完全可以将结果传送给其他玩家,没有必要挤在一个页面之中。所以调整之后,联机模式的页面只有一套开始-结束按钮,一个博饼碗
五、单元测试
- ☞测试用例
- 测试结果
关于单元测试,我们主要是对 JavaScript 中的核心代码用 mocha 进行测试
由上图可以看出,几次进行的单元测试都是成功的
六、结对过程照片
七、结对编程体验总结
- 这次是第二次结对编程了,相较于上一次,我也有了不同的体验
- 首先在编码方面,每个人的习惯不同,所以在开始之前,就要花上一段时间去制定两个人都能适应的规范,就不像以前的个人编码那样可以随心所欲一点
- 以前一个人完成作业的时候,就经常会被一些作业以外的事情打断。但这次两个人坐在一起打代码,专注度明显就上去了,也不会去下意识的关注其它事情
- 同时,结对编程,总怕自己会拖后腿,所以这几天这份作业就被我排在了首位,每天两人都会约好今天几点开始做作业,总体上效率就提高了,不会拖拖拉拉
- 结对编程,当你遇到难题的时候,也有一个人可以讨论。有些时候我觉得某一功能实现太难,想要放弃的时候,就有队友鼓励你。两个人一起加油,再难都不是问题
- 这是我第一次把一个原型用代码给实现出来。经历种种困难,当最后看到我们实现的结果时,就会觉得特别的自豪,能做到这种程度,这是我们刚看到作业时所不能想象的
- 通过这次结对编程,我也对 Html、CSS、JavaScript 这三种语言有了一个更深刻的了解。以前有学过一点知识,但多是局限于纸面上,这也算是一次比较好的实践
- 在这次作业中完成了整个游戏的网页设计,并且加了一些特效,这是以前没有实现过的事情。与此同时,我的 Html 和 CSS 技术得到了精进,以前网页排版对于我来说是有点困难的事情,这次排版变得更加随心所欲了。再者,这次作业完成了一整套的网页+函数的实现逻辑,并且实现了 CSS 的一部分特效,知识得到了扩充。总体来说工作效率还挺高的,没有什么拖延的情况,大家都想把作业做好,团队氛围比较浓厚
八、PSP 和学习进度条
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 10 |
· Estimate | · 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 1760 | 1620 |
· Analysis | · 需求分析 (包括学习新技术) | 300 | 120 |
· Design Spec | · 生成设计文档 | 60 | 45 |
· Design Review | · 设计复审 (和同事审核设计文档) | 280 | 300 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 40 | 60 |
· Design | · 具体设计 | ||
· Coding | · 具体编码 | 900 | 930 |
· Code Review | · 代码复审 | 60 | 45 |
· Test | · 测试(自我测试,修改代码,提交修改) | 120 | 120 |
Reporting | 报告 | 130 | 130 |
· Test Report | · 测试报告 | ||
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 120 | 120 |
合计 | 1900 | 1760 |
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 1600 | 1600 | 22 | 22 | 学习如何使用 html 搭建游戏页面,如何用 websocket 进行联机 |
2 | 500 | 2100 | 6 | 28 | 关于游戏设计复审的研讨,如何增加游戏动态性 |