学号 | 姓名 | 作业博客链接 | 具体分工 |
---|---|---|---|
032002621 | 林灿彬 | 待填写 | JavaScript编程、AI设计 |
032002623 | 林达锴 | 待填写 | 原型制作、html页面 |
一、结对探索
1.1 队伍基本信息
结对编号:3 队伍名称:现在是幻想时间
1.2 描述结对的过程
- 达:彬组队吗?
- 彬:好!
1.3 非摆拍的两人在讨论设计或结对编程过程的照片
二、原型设计
2.1 原型工具的选择
本次使用的原型设计工具是“墨刀”。
原因是这款原型设计软件功能比较强大(能模拟PC端网页、手机、iPad等设备的实机预览界面),生态配套也和国内的开发环境更接近。
自带一些经典的素材库,很方便就可以模拟出微信小程序的样式。
更重要的是墨刀的入门门槛更低,原生中文的环境使它更容易理解,而且可以在网页端直接操作,不需要下载程序。作为开发软件,它
足够“轻量”。同时也具有相对完善的基本功能,可以在确保原型质量的同时,给后续的开发腾出足够的时间。相较于Axure等经典原型开发工
具,墨刀对于更适合作为入门软件。
但如果后续还需要做更大项目的原型设计的话,Axure可能是更好的选择,墨刀的共享开发功能需要付费,同时也不支持将原型保存到本
地。对于小项目的开发游刃有余;但面对较大项目时,墨刀这种轻量的原型设计软件就比较捉襟见肘了。
2.2 遇到的困难与解决办法
- 困难描述:在原型设计软件中比较难以模拟游戏内的互动效果,游戏逻辑可能难以在原型界面中直接反馈;
- 解决过程:参考了历届学长学姐的优秀原型设计,发现他们的交互性原型都是仅展示固定的操作,在原型这一步体现游戏的反馈效果即可,各种游戏逻辑是后续开发环节考虑的内容;
- 有何收获:对原型设计有了较为准确的认识。学会了较为合理地规划开发的各个环节——需求分析、原型设计、构建初步模型、模型迭代、完成产品。学会了运用原型设计大概模拟产品的功能,确定基本的美工设计基调。
2.3 原型作品链接
2.4 原型界面图片展示
游戏的新手引导界面,老玩家可以选择跳过教程
新手教程的大致内容,采取图片搭配简练文本的方式,教程结束时通过按钮跳转到模式选择界面
游戏的模式选择界面,选择一种进入游戏
游戏对局界面,上方的比分条可以实时直观地显示双方的比分,
左下角是规则引导栏,右下角是回合提示栏
游戏结束时的弹窗提示,会显示出胜利玩家,可以在弹窗中选择再来一局或回到主菜单
三、编程实现
3.1 网络接口的使用
null
3.2 代码组织与内部实现设计(类图)
function randomNum():用来产生随机数并限制玩家在自己的回合多次摇骰子
function setNum(x,y,z):已经在下文说明
function attack(x,z):用于消除敌方棋盘同行同点数的数字
function get_id(x,y,z):该函数利用(x,y,z)生成对应的button id
function update_score():计分模块,在每次放置之后进行双方分数的更新,同时通过分数版展示
function game_over():判断游戏是否结束
玩家A点击play按钮,触发 randomNum()函数,产生随机数,选择棋盘位置后点击触发setNum函数,在setNum()函数中嵌套了剩余的其他函数,完成消除,计分,切换回合等功能,这样就完成了一个回合,接着再从玩家B开始,直到游戏结束。
3.3 说明算法的关键与关键实现部分流程图
3.4 贴出重要的/有价值的代码片段并解释
setNum()函数,是本次作业的核心函数,考虑了填充数字和掷骰子的多种情况,对玩家可能的误操作做了逻辑上的保护,同时能通过页面的提示框引导玩家进行符合游戏规则的操作,增加玩家的游戏体验。详情请看代码和注释
/* 函数中调用的全局变量说明:
rNum用于储存骰子的数字
round用于切换玩家回合。0代表A的回合,1代表B的回合(A先手),2代表游戏结束
rDone用于限制骰子的投掷,1代表可以投掷骰子,0代表骰子已投掷,防止投掷骰子的函数在同一回合被重复调用
*/
function setNum(x,y,z){
var Tid;
if(rNum==0){
document.getElementById("window").innerHTML = '请先投掷骰子';
return
}
if(z!=round&&round!=2){
// 下错棋盘
if(round==0){
document.getElementById("window").innerHTML = '现在是玩家A的回合,请在A的位置放置';
}else if(round==1){
document.getElementById("window").innerHTML = '现在是玩家B的回合,请在B的位置放置';
}else{
document.getElementById("window").innerHTML = '游戏结束';
}
}else{
// 棋盘正确,接下来考虑是否可下
if(round==0){
// A的回合
if(A[x][y]==0){
Tid = get_id(x,y,z)
document.getElementById(Tid).innerHTML = rNum;
A[x][y] = rNum;
round = 1;
attack(x,z);
rDone = 1; //确保放置成功后,再解锁对骰子的限制
rNum = 0; //在放置成功后,将rNum重置为0,此时在调用setNum会触发未投掷的保护机制
document.getElementById("window").innerHTML = '现在是玩家B的回合';
computer(A,B);//AI放在setnum()的A的回合里面
round=0;
}else{
document.getElementById("window").innerHTML = '该位置已有骰子';
}
}else{
if(B[x][y]==0){
//computer(A,B);
Tid = get_id(x,y,z)
document.getElementById(Tid).innerHTML = rNum;
B[x][y] = rNum;
round = 0;
attack(x,z);
rDone = 1; //确保放置成功后,再解锁对骰子的限制
rNum = 0; //在放置成功后,将rNum重置为0,此时在调用setNum会触发未投掷的保护机制
document.getElementById("window").innerHTML = '现在是玩家A的回合';
}else{
document.getElementById("window").innerHTML = '该位置已有骰子';
}
}
//完成骰子放置之后更新回合数(根据全局变量round)
if(round==0){
document.getElementById("playerName").innerHTML = 'A';
}else if(round==1){
document.getElementById("playerName").innerHTML = 'B';
}else{
document.getElementById("playerName").innerHTML = '';
}
// 已完成骰子放置,重新解锁投掷骰子(重新解锁环节可能存在问题,需要确保已放置之后再解锁)
// todo:rDone的重置需要在放置完成后再进行
// rDone = 1;
}
3.5 性能分析与改进
3.6 单元测试
3.7 贴出GitHub的代码签入记录,合理记录commit信息
四、总结反思
4.1 本次任务的PSP表格
PSP2.1 | PSPS | 预估耗时/min | 实际耗时/min |
---|---|---|---|
Planning | 计划 | 60 | 80 |
Estimate | 估计这个任务需要多少时间 | 40 | 50 |
Development | 开发 | 960 | 1050 |
Analysis | 需求分析 (包括学习新技术) | 600 | 360 |
Design Spec | 生成设计文档 | 120 | 40 |
Design Review | 设计复审 | 60 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 60 | 20 |
Design | 具体设计 | 120 | 120 |
Coding | 具体编码 | 780 | 420 |
Code Review | 代码复审 | 60 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 360 | 240 |
Reporting | 报告 | 180 | 240 |
Test Report | 测试报告 | 120 | 200 |
Size Measurement | 计算工作量 | 40 | 30 |
Postmortem & ProcessImprovement Plan | 事后总结, 并提出过程改进计划 | 120 | 60 |
total | 合计 | 3680 | 3000 |
4.2 学习进度条(每周追加)
林灿彬:
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 重要成长 |
---|---|---|---|---|
1 | 50 | 50 | 10 | 了解前端三件套,设计伪函数和主要框架 |
2 | 100+ | 100+ | 14 | 前端三件套入门,边写边学,着手于主框架的实现和页面设计 |
3 | 200+ | 300+ | 14 | 基本完成主框架的实现和页面设计 |
林达锴:
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 重要成长 |
---|---|---|---|---|
1 | 50 | 50 | 10 | 初步掌握墨刀,实现了原型设计 |
2 | 100+ | 100+ | 14 | 学习了html和CSS,选择了grid布局方式进一步学习,用gird完成了页面主要元素的定位 |
3 | 200+ | 300+ | 14 | 在CSS-Inspiration等前端素材网站上学习了更丰富的美化和展示特效,对网页进行了美化 |
4.3 最初想象中的产品形态、原型设计作品、软件开发成果三者的差距如何?
基本能够实现预期的效果,有些缺憾是界面还没能优化得更美观一点,比如设想中直接将摇得的骰子填入棋盘,或者在消除对手骰子的时候加入一些动效,体验感会更好一点,联机对战的功能还尚未实现。但在做的过程中也有比较有亮点的一些特点,比如加入了血条机制。理想很丰满和现实比较匀称,相对还是比较满意的。
因素:技术力和时间的双重限制,归根结底还是太菜了和缺乏经验。
4.4 评价你的队友
林灿彬:我的队友兢兢业业,创造力和想象力十分丰富,我提出构思,他能够想方设法去实现,本次项目的主要逻辑框架是由他一个个代码敲出来的,表示respect,他对新技术的热情和完美主义的追求令我自愧不如。
林达锴:队友的攻坚速度和开发效率强而有力(๑•̀ㅂ•́)و✧。他在开发时的节奏很稳,总是会先确保实现基础的功能,然后在此基础上魔改迭代。他开发的对战AI让舍友们印象深刻,从刚开始的只能进行基本的随机落子完成对局,一直进化到能随着比赛实况变换策略,和宿舍的同学对战得有来有回,在半天内就完成了青春版AI到完全体AI的迭代开发。他用前端三件套让网页里出现可以互动的立体骰子时,我大受震撼。队友总能做出令人眼前一亮的技术突破,他的学习能力和创造力令人惊喜。
4.5 结对编程作业心得体会
林灿彬:
相比于个人编程的枯燥和毫无头绪,结对编程就显得有趣了很多,一方面是本次作业是做小游戏,一方面是做网页的时候修改代码的效果立竿见影,更重要的是在本次作业中我真正体会到合作共赢的重要性,有些bug我修了半天也找不出错误,有些bug队友修半天也找不出错误,而此时如果求助一下对方,问题居然能奇迹般迎刃而解。自己一个人的想法比较具有局限性,两个人的思维火花碰撞后往往能产生意想不到的结果。
林达锴:
结对编程是崭新的体验,在开发过程中和队友的沟通是很重要的一个环节,每次沟通之后都能找到新的突破口,确定下一个目标。在结对编程中也养成了写备注的好习惯,在和队友对接代码时流畅了不少。开发时的分工极大提高了效率,和队友的交流也让开发的思路清晰了不少。