资源描述
Widget应用程序设计与实现
———————————————————————————————— 作者:
———————————————————————————————— 日期:
2
个人收集整理 勿做商业用途
计算机科学与工程学院
课程设计报告
题目全称: Widget应用程序设计与实现
学生学号: 2606006021 姓名: 章晨
指导老师: 桑楠 职称: 教授
指导老师评语:
签字:
课程设计成绩:
设计过程表现
设计报告质量
总分
- 13 -
摘要
随着Widget编程的兴起,人们不断追寻个性化的桌面,以充分突出“个人电脑”这一概念.Widget在一面世出来后便被称作:“桌面的精灵”。它们一般都很小,在终端上嵌入非常方便,运行快速。本论文基于以YaHoo Widget Engine软件平台,利用软件工程思想,开发出一款实用有效的桌面软件,并完成软件的演示实例,以此为今后的进一步研究Widget应用开发提供了依据和资料。
关键字:widget编程,个性化,应用开发
目录
第1章 引言 - 1 —
1.1 Widget选题背景及概述 - 1 -
1。2 国内外发展现状 — 2 -
1.2.1 Widget的分类 — 2 -
1.2。2 国内外发展现状 — 2 -
1.2。3 Widget未来展望 - 2 —
1。3 课题研究内容 — 3 —
1。4 任务分工及工作计划 - 3 -
1。4.1 整体计划 — 3 -
1。4.2 个人工作计划 — 1 —
第2章 相关技术分析 - 2 -
2。1 相关技术分析 - 2 —
第3章 项目需求与分析 — 4 -
3.1 需求分析 - 4 -
3。1。1 模块划分 - 4 -
3。1.2 模块功能 - 4 -
3.1。3 模块流程图 — 5 —
第4章 系统实现与测试 - 7 -
4.1 系统功能演示 - 7 —
4。2 系统测试 — 9 -
4.2.1 环境测试 - 9 -
4。2.2 界面测试 - 9 -
第5章 开发心得体会 — 1 -
参考文献 — 1 —
附录 - 1 -
第1章 引言
1.1 Widget选题背景及概述
在牛津词典中,“Widget"一词的释义是“一个小器具或机械设备,特指那些名字未知或未被特别提及过的物件”。我们通常指的Widget是一种可供自己制作和下载的工具集合,可以在电脑桌面、网页、手机终端上单独执行,无需通过浏览器便可连接到网络。
Widget是互联网应用的产物,更加开放,更便于信息获取。Widget在互联网中的作用主要体现在以下两点:首先,实现了桌面应用和网络服务的结合,用户可以不用从浏览器登录网站就可以获得网络信息;其次,它提供了一个平台,用户可以自由地创建、发布、共享各类业务应用.
随着Widget应用的不断演进,国际上很多Widget产品已经开始在手机媒体上应用。Nokia推出了S60平台的Widget,苹果的Phone也搭载了Widget,然而由于规范的不统一,各个厂家的Widget应用还不能做到互通。随着标准的制定,未来W1dget会向着跨平台、跨系统、跨终端方向发展,这才能充分体现Web2.0所倡导的用户参与的实质。
1.2 国内外发展现状
1.2.1 Widget的分类
目前存在各种形式的Widget,在技术层面上可分为:桌面Widget、网页Widget、手机Widget;在业务应用层面上可分为:静态Widget和动态Widget。
桌面Widget是轻量级的Web应用程序,为使用者提供简便式的服务.它通常被设计为具有特定的功能,如提供天气、股票、拍卖等的信息。网页Widget的主要功能是帮助内容提供商将自身的各种多媒体信息聚合在一张网页上,其聚合的内容包括:广告信息、信息咨询、网络工具等。手机Widget是一种通过手机查找信息时使用的功能。一般通过手机来查找信息时,首先连接无线网络,然后再经过繁琐的操作过程之后才能浏览信息,但是如果在待机画面上设有可直接调入股市、天气等信息的Widget的话,不需要繁琐的操作过程。
1.2.2 国内外发展现状
各主要的互联网公司,如facebook,Google等均在大力发展Widget业务.国外的Widget应用已进入发展期,业务应用已逐渐走向成熟,市场竞争者众多,业务提供商之间的竞争已经从简单的业务应用争夺发展到更深层次的平台之间的竞争。与此同时,国内用户对于在手机上使用Widget来获取自己相关信息也越来越感兴趣,运营商也在积极努力开展,Widget将在几年内变得非常流行。
1.2.3 Widget未来展望
为了使Widget业务应用能跨平台、跨终端使用,需要对Widget引擎、Widget业务应用以及Widget运行的终端进行详细的定义。Widget平台开放接口中需要对传输的数据包格式、开放API、编写工具/脚本、数字签名进行规范统一。Widget业务应用中需要对开发环境、开发工具,以及Widget组件文件如:Info。1ist、[Name]。html、Icon。png等组件规范化。用户参照业务规范中研发出来的Widget业务才能在不同型号、不同平台的终端上使用。同时,不同的Widget业务对终端有着不同的要求,在硬件上需要统一规定,如:CPU、内存大小、屏幕分辨率、尺寸、摄像头像素及数据接口等;软件上需要定义网络协议、多媒体格式、操作系统、文件管理器、Widget应用数量。只有对上述内容进行规范化,才能充分发挥Widget的真正作用。
1.3 课题研究内容
本次项目的主要目的是分析引擎的各个功能模块的具体实现方式,以及各个模块之间的关系。在理解了实现原理的基础上,优化部分功能模块,在引擎上实现一个具体的Widget应用程序.
1.4 任务分工及工作计划
1.4.1 整体计划
任务包括:分析课题的可行性,国内外现状以及产生历史和使用情况。其次,对Widget引擎源码进行分析,提炼出各功能模块,理清各模块之间的关系。然后,对功能模块进行优化。最后,编写一个Widget应用程序进行演示与测试,并对项目进行汇总及总结.
1.4.2 个人工作计划
首先,分析课题的可行性,国内外现状以及产生历史和使用情况。
其次,进行可行性与需求分析,给出编程思想以及流程图。然后进行
代码编写与调试。最后,进行项目汇总及总结。
时间安排如下:
需求分析: 7月11日 至 7月20日
代码编写与调试: 7月21日 至 8月27日
项目汇总及总结: 8月28日 至 9月4日
第2章 相关技术分析
2.1 相关技术分析
本次选题设计使用的平台是Windows OS,Yahoo Widget engine;设计的编程语言是javascript,XML。
Widget应用程序主要构成:
.kon
包含 Widget工具 的主要程式代码。Widget Engine首先会寻找这个档案,并会在使用者按两Widget工具 配套时读取其中的指示。
.js
它通常包含大部分Widget工具 执行所需要的 JavaScript。Javascript是一种由NETSPACE的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言
.scpt
這是一個 AppleScript 文件,其中包含了 AppleScript 命令.
编写widget需要的工具
文本编辑器 NotePad 或者 或者其他任何支持 Unicode 的文字编辑器.
图形编辑器 任何一款具有图形编辑功能的软件。
图2-1系统面向的用户分类图
说明:Widget程序使用者:
普通的PC用户,能够通过GUI界面交互完成需要的任务,比如单击鼠标和键盘命令完成对网络资源的访问更新,单击关闭图标退出Widget等
Widget应用程序开发人员:
具有一定编程经验的程序设计开发人员。负责利用Engine提供的接口功能,结合用户需要,实现具有特定用途的Widget应用软件.
Widget Engine:
本次项目的核心内容。面向具有系统分析和设计的编程人员。为应用开发人员提供编程接口工具,实现从支持平台(此次为Windows操作系统)API函数构建功能模块,以及访问互联网实时数据资源。应用编程接口是提供给应用开发人员的接口工具,是应用程序开发的基础。考虑到系统以后的扩展,针对系统编程人员提供了扩展接口。实现这些模块调用了操作系统平台API函数,访问网络数据时需要用到网络数据库知识.
第3章 项目需求与分析
3.1 需求分析
3.1.1 模块划分
1) 清除小球系统模块
2) 游戏成功失败判断模块
3) 评分系统模块
3.1.2 模块功能
1。界面模块
界面操作简单,具有良好的动画效果,可以准确无误的在widget engine上运行。
2.清除小球系统模块
按钮设计人性化,界面简洁大方,具有下拉栏功能,具有上下月份翻页按钮,具有程序关闭按钮,下拉页面大小合适。判断5个或者大于5个小球在同一直线上(横竖斜3个方向)时消除小球。
3.游戏成功失败判断模块
判断游戏界面中只有一种颜色的小球时后续只显示1个小球且这个小球和界面中的小球在同一直线上的相邻位置,则游戏成功结束。反之,当界面所有空格都有小球时系统判断游戏失败。
4.系统评分模块
移动小球,当N个小球在同一直线上时,得分为2^(N-5)*5。反之,不得分。(N≥5)
3.1.3 模块流程图
清除小球模块如图3—1所示。
图3—1清除小球模块流程图
判断游戏结束模块如图3—2所示,首先获得小球位置,然后按照操作移动小球,获得小球的颜色,如果界面只有一种颜色小球,则游戏结束。
图3-2判断游戏结束流程图
评分模块如图3—3所示,首先获取小球,然后移动小球位置,获取移动后位置颜色,如果有不少于5个同色小球在一条直线上,则评分为2^(N-5)*5。
图3—3 评分模块流程图
第4章 系统实现与测试
4.1 系统功能演示
说明:使用Widget Yahoo平台,在Windows XP操作系统上运行。
1. 打开Yahoo Widget Engine添加该系统
2. 打开界面如图4-1所示
图4—1 主界面
3. 游戏设置界面如图4—2 4—3所示。
图4—2游戏难度小球个数选择界面
图4—3 游戏样式选择界面
4.2 系统测试
4.2.1 环境测试
配置测试环境是测试实施的一个重要阶段,测试环境适合与否会严重影响测试结果的真实性和正确性。
在比较普及的操作系统windows xp下进行测试,稳定可用
1) Cpu及内存占有率低
2) 与其他widget应用程序互不干扰
3) 测试环境中没有病毒。该程序与杀毒软件没有充突。
4.2.2 界面测试
界面是软件与用户交互的最直接的层,界面的好坏决定用户对软件的第一印象.而且设计良好的界面能够引导用户自己完成相应的操作,起到向导的作用。
1.易用性测试
系统的易用性包括以下内容:
1) 长宽接近黄金点比例
2) 布局较合理
3) 前景与背景色搭配合理协调,反差不大
4) 颜色柔和,具有亲和力与磁力
5) 界面风格要保持一致,字的大小、颜色、字体要相同,除非是需要艺术处理或有特殊要求的地方。
6) 窗体支持最小化和最大化,窗体上的控件也要随着窗体而缩放
综上所述,如图4-1所示,界面简洁美观,界面易懂易于操作,符合易用性。
2. 合理性:
1) 父窗体或主窗体的中心位置应该在对角线焦点附近。屏幕居中。 子窗体位置应该在主窗体的左上角或正中。
2) 重要的命令按钮与使用较频繁的按钮要放在界面上较注目的位置.
3) 当下拉框(ComboBox)允许用户不选择任何选项时,不应显示一个空的选项,应使用文字描述,如“请选择…"等.
4) 对于文本框(TextBox)一般需要根据其对应的数据库字段的类型以及长度来限制用户允许输入的字符和长度,测试时要注意输入框中的数值的最大数和最小数,以及默认值、空白值或空格时的情况。
综上所述,如图4-5所示,该系统界面简洁大方,文字明了。相关信息详细丰富,下拉栏设计合理,按钮设置合理,充分体现了易用性与合理性。
图4-4界面测试效果图
第5章 开发心得体会
在论文即将完成之际,本人在此向所有关心我的及帮助我的老师和同学们致以最真诚的感谢。
在本次课程设计中,我从指导老师——吴老师身上学到了很多东西。他认真负责的工作态度,严谨的治学精神和深厚的理论水平都使我受益匪浅。 在此感谢他耐心的辅导.在撰写论文阶段,吴老师审阅我的论文,提出了许多宝贵意见,没有他的指导,我就不能较好的完成课题设计的任务。
另外,我还要感谢在这几年来对我有所教导的老师,他们孜孜不倦的教诲不但让我学到了很多知识,而且让我掌握了学习的方法,更教会了我做人处事的道理,在此表示感谢。
参考文献
1(美)哈梅斯(美)迪亚斯 著。《JavaScript设计模式》人民邮电出版社
2 Yahoo! Widget Widget 4.0 參考手冊 2007320 4。0。0 2007 Yahoo!
3 widget_creation_tutorial_102參考手冊
4 诺基亚 Web Widget 开发入门版 1。0;2007年 11月9日
5 (美)雅可布斯 《XML基础教程(入门\DOM\Ajax与Flash) 》人民邮电出版社
6 朱福喜 傅建明 唐晓军 编著《Java项目设计与开发范例》电子工业出版社
附录
Line.js如下:
longwosion.namespace("widget。game”);
longwosion。widget。game.linesPanel = function(){
/**面板宽*/
this。width = 9;
/**面板高*/
this。height = 9;
/**小球颜色总数*/
this。maxColor = 7;
/**面板数组,存放小球颜色*/
this。panels = new Array();
/**面板中的小球数*/
this。ballCount = 0;
/**下面的三个球*/
this。nextThree = null;
/**几球相连为胜*/
this。linesBall = 5;
this.inGame =false;
/**
* 获取某位置小球颜色
*/
this。getBallColor = function(x,y){
if ( x〉= this.width || y〉= this。height) return -1;
if ( x〈0 || y<0 ) return -1;
return this。panels[x + y * this.width];
};
/**
* 设定某位置小球颜色
*/
this。setBallColor = function(x, y, color){
this.panels[x + y * this.width] = color;
this.ballCount ++;
this。inGame = !(this.width*this。height==this。ballCount);
};
/**
* 清除小球颜色
*/
this.clearBallColor = function(x, y){
this。panels[x + y * this。width] = —1;
this.ballCount --;
};
/**
* 移动小球
*/
this。moveBall = function(p1, p2) {
this.panels[p2[0] + p2[1] * this.width] = this.panels[p1[0] + p1[1] * this.width];
this.panels[p1[0] + p1[1] * this.width] = —1;
};
/**
* 重置面板为空
*/
this.restartPanels = function(){
for(var x=0; x< this.width; x++){
for(var y=0; y〈 this。height; y++){
this.panels[x + y * this。width] = -1;
}
}
this.ballCount = 0;
this。inGame = true;
};
/**
* 下一个球颜色
*/
this.getNext = function() { return Math.floor(Math.random()* this。maxColor); };
/**
* 下三个球颜色
*/
this.getNextThree = function() {
this。nextThree = new Array(this。getNext(),this。getNext(),this。getNext());
return this。nextThree;
};
/**
* 获取下一个小球放置位置
*/
this.getNextPostion = function() {
var p = Math。floor(Math.random() * (this.width*this。height—this。ballCount));
var count = —1;
for(var i=0; i〈 this。width*this。height; i++){
if(this.panels[i]==—1){
count ++;
}
if(p==count){
return new Array(i%this。width, Math。floor(i/this.width));
}
}
};
/**
* 判断游戏是否结束
*/
this.gameOver = function() {
return !this。inGame;
};
/**
* 检查两点的连通性,如果连通,返回值为连接路径
* @param {Array} p1 点1坐标,为一数组对象,[0]为x坐标,[1]为y坐标
* @param {Array} p2 点2坐标
* @return 如果连通,返回值为连接路径
*/
this。checkConnective = function(p1, p2) {
var tree = [];
var level = 0;
tree[level] = [p1];
var panelsFlag = new Array();
var self = this;
for(var x=0; x< this.width; x++){
for(var y=0; y< this。height; y++){
panelsFlag[x + y * this。width] = null;
}
};
var checkPoint = function(p, level, parent, self){
//print(" checkPoint — p: \t” + p);
//print(” checkPoint — level: \t" + level);
//print(” checkPoint — parent: \t” + parent);
if(p[0]>=self.width || p[1]>=self.height) return 0;
if(p[0]<=-1 || p[1]〈=—1) return 0;
var color = self.getBallColor(p[0],p[1]);
//print(" checkPoint — color: \t” + color);
if(color == —1 && panelsFlag[p[0] + p[1]*self.width]==null){
tree[level][tree[level]。length] = p;
panelsFlag[p[0] + p[1]*self。width] = parent;
return 1;
}
};
var checkFind = function(array, p){
//print(”check Find Function:");
for(o in array){
if(array[o][0] == p[0] && array[o][1] == p[1]) return true;
}
return false;
};
//print("—---—---———————--—---—-———”);
//print("check Connective");
//print(" p1 : \t” + p1);
//print(” p2 : \t” + p2);
//print(” level : \t” + level);
//print(” tree[”+level+”] : \t" + tree[level]);
while(!checkFind(tree[level], p2)&&tree[level].length>0){
tree[level+1] = [];
for(o in tree[level]) {
var p = tree[level][o];
//print(” checkPoint : \t” + p);
checkPoint([p[0]+1,p[1]], level+1, p, self);
checkPoint([p[0]-1,p[1]], level+1, p, self);
checkPoint([p[0],p[1]+1], level+1, p, self);
checkPoint([p[0],p[1]-1], level+1, p, self);
}
level ++;
//print(" while tree[”+level+"] : \t” + tree[level]);
};
if(tree[level].length==0){
return [];
} else {
var path = new Array();
var count = 0;
path[count] = p2;
while(panelsFlag[path[count][0] + path[count][1]*this。width]!=null){
path[count + 1] = panelsFlag[path[count][0] + path[count][1]*this。width];
count ++;
}
return path;
}
};
/**
* 检查小球是否有成行成列或斜线的
* @param {Array} ball 小球坐标数组
* @return 返回值为消除小球的坐标列表
*/
this。checkLines = function(ball) {
var lines = [];
var x = ball[0];
var y = ball[1];
var ballColor = this。getBallColor(x,y);
print(”checkLines");
print("ball :” + ball);
//水平
var startBall = ball;
for(var i=x; i>=0; i--){
if(this.getBallColor(i,y) != ballColor) break;
};
startBall = [i+1,y];
print("startBall :" + startBall);
var count = 0;
for(var i=startBall[0]; i〈this。width; i++){
if(this.getBallColor(i,y) != ballColor) break;
};
count = i - startBall[0];
if(count>=this。linesBall){
for(var i=startBall[0]; i<startBall[0]+count; i++){
if (i!=x) lines[lines。length] = [i,y];
}
};
print(”h count :" + count);
//垂直
var startBall = ball;
for(var i=y; i>=0; i—-){
if(this。getBallColor(x,i) != ballColor) break;
};
startBall = [x,i+1];
print(”startBall :" + startBall);
var count = 0;
for(var i = startBall[1]; i〈this.height; i++){
if(this。getBallColor(x,i) != ballColor) break;
};
count = i — startBall[1]
if(count>=this.linesBall){
for(var i=startBall[1]; i〈startBall[1]+count; i++){
if (i!=y) lines[lines。length] = [x,i];
}
};
print(”v count :" + count);
//对角1
var startBall = ball;
for(var i=y; i〉=0; i--){
if(this。getBallColor(x+(i—y),i) != ballColor) break;
};
startBall = [x+(i—y)+1,i+1];
print("startBall :" + startBall);
var count = 0;
for(var i = startBall[1]; i〈this.height; i++){
if(this。getBallColor(x+(i-y),i) != ballColor) break;
};
count = i - startBall[1]
if(count>=this。linesBall){
for(var i=startBall[1]; i<startBall[1]+count; i++){
if (i!=y) lines[lines.length] = [x+(i-y),i];
}
};
print(”c1 count :” + count);
//对角2
var startBall = ball;
for(var i=y; i〉=0; i-—){
if(this.getBallColor(x-(i—y),i) != ballColor) break;
};
startBall = [x—(i-y)—1,i+1];
print("startBall :" + startBall);
var count = 0;
for(var i = startBall[1]; i〈this。height; i++){
if(this.getBallColor(x-(i-y),i) != ballColor) break;
};
count = i — startBall[1]
if(count〉=this。linesBall){
for(var i=startBall[1]; i<startBall[1]+count; i++){
if (i!=y) lines[lines.length] = [x-(i-y),i];
}
};
print("c2 count :" + count);
if(lines。length〉0){ lines[lines。length] = [x,y] }
return lines;
}
};
longwosion。widget。game.lines = function(){
var LinePanel = new longwosion。widget。game。linesPanel();
var imagePath = ”Resources/Images/classical/”, ballTag = "Ball”;
var nullImage = ”Resources/Images/onePixel.gif”
var imageSize = 31;
var previewBallCount = 3, previewTag = ”Preview";
var chooseBallTag = "chooseBall";
var images = new Array();
var currentActiveBall = [—1,-1];
var nextThree = null;
var gameScore = 0;
return {
/**
* 初始化游戏
*/
initialize : function(){
LinePanel.linesBall = preferences.prefBallLinesNumber。value;
LinePanel.maxColor = preferences。prefBallColorMaxNumber.value;
imagePath = "Resources/Images/"+preferences.prefBallSkin.value+"/";
background.src = ”Resources/Images/background”+preferences.prefBackGroundSkin.value+”.png”;
txtHighscore。data = preferences。highScore.value;
//预览小球
for (var i=0; i<previewBallCount; i++) {
var j = (previewTag + i +””);
if(!images[j]){ images[j] = new Image(); };
images[j].hOffset = 365 + 32*i;
images[j]。vOffset = 97;
images[j]。src = nullImage;
images[j].window = MainWindows;
};
this.generateNextThree();
this。startGame();
var j = chooseBallTag;
if(!images[j]){ images[j] = new Image(); };
images[j].hOffset = 0;
images[j]。vOffset = 0;
images[j].opacity = 0;
images[j]。zOrder = 100;
images[j]。src = imagePath + "ballselect。png”;
frmPanel。addSubview(images[j]);
},
/**
* 保存设置修改
*/
applyPreferences : function(){
LinePanel。linesBall = preferences.prefBallLinesNumber.value;
LinePanel.maxColor = preferences。prefBallColorMaxNumber。value;
imagePath = "Resources/Images/"+preferences。prefBallSkin。value+”/";
background.src = "Resources/Images/background”+preferences。prefBackGroundSkin。value+".png”;
//restartGame
gameoverBox。visible = 0;
展开阅读全文