猜拳游戏——石头剪刀布。里面使用了LBitmapData、LBitmap、LSprite、LTextField等几个类和lufylegend库件里的鼠标事件。
一、游戏分析
游戏需要的要素:
- 图片描画:将石头剪刀布三张图片会知道画面上
- 图形绘制:背景、边框
- 文字绘制:统计次数的文字
- 鼠标点击:通过点击三个不同按钮选择出拳
- 电脑AI:电脑随机出拳
- 条件分支与判断:胜负判定结果
二、必要的Javascript知识
2.1 随机数
Math.random()函数,可以随机生成0到1之间的一个小数。如果需要随机生成5-10之间的整数,则用:
Math.floor(5 + 5*Math.random());
2.2 条件分支
if..else if..else:
if(条件1){
条件1成立执行代码;
}else if(条件2){
条件2成立执行代码;
}else{
条件1、2都不成立时执行代码;
}switch:
switch(变量){
case 值1:
执行代码块1
break;
case 值2:
执行代码块2
break;
default;
当变量既不是值1也不是值2时执行的代码块
}三、分层实现
层次划分:
- 整个游戏界面一层
- 选择出拳部分一层
- 结果显示部分一层
3层分别显示到画面上:
init(50,"mylegend",800,400,main);
/*新建3个变量层,分别代表3个显示层*/
var backLayer,
resultLayer,
clickLayer;
function main(){
gameInit();
}
function gameInit(){
/*初始化层backLayer,将其作为背景层显示出来*/
backLayer = new LSprite();
addChild(backLayer);
//添加游戏界面背景
backLayer.graphics.drawRect(10,'#008800',[0,0,LGlobal.width,LGlobal.height],true,'#000000');
//结果显示层初始化
initResultLayer();
//操作层初始化
initClickLayer();
}
/*初始化resultLayer层,将其作为结果表示层,并在层上绘制一个白色矩形,当作结果表示层的背景色*/
function initResultLayer(){
resultLayer = new LSprite();
resultLayer.graphics.drawRect(4,'#ff8800',[0,0,150,110],true,'#ffffff');
resultLayer.x = 10;
resultLayer.y = 100;
backLayer.addChild(resultLayer);
}
/*初始化clickLayer层,并将其作为控制点击层,同时再层上绘制一个白色矩形,当作控制点击层的背景色*/
function initClickLayer(){
clickLayer = new LSprite();
clickLayer.graphics.drawRect(4,'#ff8800',[0,0,300,110],true,'#ffffff');
clickLayer.x = 250;
clickLayer.y = 275;
backLayer.addChild(clickLayer);
}四、各个层的基本功能
4.1 基本画面显示
将图片读取到电脑,然后按照需求显示到画面。




图片的读取,再这篇博客已经介绍过,我们这次使用lufylegend库件中另一种比较方便的图片读取方式,即静态类LLoadManage中的load函数来一次性读取多张图片:
LLoadManage.load ($list,$onupdata,$oncomplete);
$list:尧都区的图片数组
$onupdata:没读取数组中一张图片后调用的函数,可以为空
$oncomplet:读取玩数组中所有图片后调用的函数
init(50,"mylegend",800,400,main);
var loadingLayer,
backLayer,
resultLayer,
clickLayer,
/*变量imglist用来保存读取后的图片数据的数组,保存方式以key=>value的形式,key就是imgData对于的name值*/
var imglist = {};
var imgData = new Array(
{name:"title",path:"../images/title.png"},
{name:"shitou",path:"../images/shitou.png"},
{name:"jiandao",path:"../images/jiandao.png"},
{name:"bu",path:"../images/bu.png"}
);
function main(){
backLayer = new LSprite();
addChild(backLayer);
/*加载进度条,有三种样式,这里使用样式3*/
loadingLayer = new LoadingSample3();
backLayer.addChild(loadingLayer);
/*利用静态类LLoadManage的load函数来读取数组中的图片*/
LLoadManage.load(
imgData,
function(progress){
loadingLayer.setProgress(progress);
},
function(result){
imglist = result;
backLayer.removeChild(loadingLayer);
loadingLayer = null;
gameInit();
}
);
}LLoadManage的load函数:
- 第一个参数imgData:要读取的图片数组
- 第二个参数function:function类型,每读取一张图片后调用的函数,其中progress指的是读完的图片数占总图片数的比例,将这个比例值通过setProgress传给LoadingSample3对象,就实现了同台的进度条
- 第三个参数:function类型,是将读取完图片后的结果赋值给变量imglist,然后移除画面上的进度条对象,最后调用gameInit,进行游戏下一步的操作。
修改gameInit函数,添加相应变量:
init(50,"mylegend",800,400,main);
/*添加selfBitmap、enemyBitmap变量,用于显示己方的电脑的出拳结果*/
var loadingLayer,
backLayer,
resultLayer,
clickLayer,
selfBitmap,
enemyBitmap;
var imglist = {};
var imgData = new Array(
{name:"title",path:"../images/title.png"},
{name:"shitou",path:"../images/shitou.png"},
{name:"jiandao",path:"../images/jiandao.png"},
{name:"bu",path:"../images/bu.png"}
);
var showList = new Array();
function main(){
backLayer = new LSprite();
addChild(backLayer);
loadingLayer = new LoadingSample3();
backLayer.addChild(loadingLayer);
LLoadManage.load(
imgData,
function(progress){
loadingLayer.setProgress(progress);
},
function(result){
imglist = result;
backLayer.removeChild(loadingLayer);
loadingLayer = null;
gameInit();
}
);
}
function gameInit(){
/*为了避免反复新建LBitmapData对象,所以将新建的LBitmapData对象添加到数组showList中。imglist是利用LLoadManage读取图片后返回的结果集。*/
showList.push(new LBitmapData(imglist["shitou"]));
showList.push(new LBitmapData(imglist["jiandao"]));
showList.push(new LBitmapData(imglist["bu"]));
//添加游戏界面背景
backLayer.graphics.drawRect(10,'#008800',[0,0,LGlobal.width,LGlobal.height],true,'#000000');
//显示游戏标题
var titleBitmap = new LBitmap(new LBitmapData(imglist["title"]));
titleBitmap.x = (LGlobal.width - titleBitmap.width)/2;
titleBitmap.y = 10;
backLayer.addChild(titleBitmap);
//玩家方出拳图片
selfBitmap = new LBitmap(showList[0]);
selfBitmap.x = 400 - selfBitmap.width - 50;
selfBitmap.y = 130;
backLayer.addChild(selfBitmap);
//电脑方出拳图片
enemyBitmap = new LBitmap(showList[0]);
enemyBitmap.x = 400 + 50;
enemyBitmap.y = 130;
backLayer.addChild(enemyBitmap);
//玩家电脑名称设定
var nameText;
nameText = new LTextField();
nameText.text = "玩家";
nameText.weight = "bolder";
nameText.color = "#ffffff";
nameText.size = 24;
nameText.x = selfBitmap.x + (selfBitmap.width - nameText.getWidth())/2;
nameText.y = 95;
backLayer.addChild(nameText);
nameText = new LTextField();
nameText.text = "电脑";
nameText.weight = "bolder";
nameText.color = "#ffffff";
nameText.size = 24;
nameText.x = enemyBitmap.x + (enemyBitmap.width - nameText.getWidth())/2;
nameText.y = 95;
backLayer.addChild(nameText);
//结果显示层初始化
initResultLayer();
//操作层初始化
initClickLayer();
}
function initResultLayer(){
resultLayer = new LSprite();
resultLayer.graphics.drawRect(4,'#ff8800',[0,0,150,110],true,'#ffffff');
resultLayer.x = 10;
resultLayer.y = 100;
backLayer.addChild(resultLayer);
}
function initClickLayer(){
clickLayer = new LSprite();
clickLayer.graphics.drawRect(4,'#ff8800',[0,0,300,110],true,'#ffffff');
clickLayer.x = 250;
clickLayer.y = 275;
backLayer.addChild(clickLayer);
}4.2 结果层的显示
在结果层中记录审理、失败和平局等各种结果的次数
定义相应变量:
var loadingLayer,
backLayer,
resultLayer,
clickLayer,
selfBitmap,
enemyBitmap,
/*LTextField对象,用于显示各种结果值*/
selfTextAll,
selfTextWin,
selfTextLoss,
selfTextDraw,
/*次数*/
win = 0,
loss = 0,
draw = 0;初始化几个对象,并显示到结果层:
function initResultLayer(){
resultLayer = new LSprite();
resultLayer.graphics.drawRect(4,'#ff8800',[0,0,150,110],true,'#ffffff');
resultLayer.x = 10;
resultLayer.y = 100;
backLayer.addChild(resultLayer);
selfTextAll = new LTextField();
selfTextAll.text = "猜拳次数 : 0";
selfTextAll.weight = "bolder";
selfTextAll.x = 10;
selfTextAll.y = 20;
resultLayer.addChild(selfTextAll);
selfTextWin = new LTextField();
selfTextWin.text = "胜利次数 : 0";
selfTextWin.weight = "bolder";
selfTextWin.x = 10;
selfTextWin.y = 40;
resultLayer.addChild(selfTextWin);
selfTextLoss = new LTextField();
selfTextLoss.text = "失败次数 : 0";
selfTextLoss.weight = "bolder";
selfTextLoss.x = 10;
selfTextLoss.y = 60;
resultLayer.addChild(selfTextLoss);
selfTextDraw = new LTextField();
selfTextDraw.text = "平局次数 : 0";
selfTextDraw.weight = "bolder";
selfTextDraw.x = 10;
selfTextDraw.y = 80;
resultLayer.addChild(selfTextDraw);
}4.3 控制层的显示
添加石头、剪刀、布三个按钮:
function initClickLayer(){
clickLayer = new LSprite();
clickLayer.graphics.drawRect(4,'#ff8800',[0,0,300,110],true,'#ffffff');
var msgText = new LTextField();
msgText.text = "请出拳:";
msgText.weight = "bolder";
msgText.x = 10;
msgText.y = 10;
/*调用getButton函数,通过传入相应参数来建立按钮*/
clickLayer.addChild(msgText);
var btnShitou = getButton("shitou");
btnShitou.x = 30;
btnShitou.y = 35;
clickLayer.addChild(btnShitou);
var btnJiandao = getButton("jiandao");
btnJiandao.x = 115;
btnJiandao.y = 35;
clickLayer.addChild(btnJiandao);
var btnBu = getButton("bu");
btnBu.x = 200;
btnBu.y = 35;
clickLayer.addChild(btnBu);
clickLayer.x = 250;
clickLayer.y = 275;
backLayer.addChild(clickLayer);
}五、出拳
给按钮添加鼠标点击事件:
function initClickLayer(){
clickLayer = new LSprite();
clickLayer.graphics.drawRect(4,'#ff8800',[0,0,300,110],true,'#ffffff');
var msgText = new LTextField();
msgText.text = "请出拳:";
msgText.weight = "bolder";
msgText.x = 10;
msgText.y = 10;
clickLayer.addChild(msgText);
/*建立3个按钮之后,分别给按钮加上MOUSE_UP事件,当鼠标单击按钮并弹起时候,调用onclick函数*/
var btnShitou = getButton("shitou");
btnShitou.x = 30;
btnShitou.y = 35;
clickLayer.addChild(btnShitou);
btnShitou.addEventListener(LMouseEvent.MOUSE_UP,onclick);
var btnJiandao = getButton("jiandao");
btnJiandao.x = 115;
btnJiandao.y = 35;
clickLayer.addChild(btnJiandao);
btnJiandao.addEventListener(LMouseEvent.MOUSE_UP,onclick);
var btnBu = getButton("bu");
btnBu.x = 200;
btnBu.y = 35;
clickLayer.addChild(btnBu);
btnBu.addEventListener(LMouseEvent.MOUSE_UP,onclick);
clickLayer.x = 250;
clickLayer.y = 275;
backLayer.addChild(clickLayer);
}
function onclick(event,display){
var selfValue,enemyValue;
if(display.name == "shitou"){
selfValue = 0;
}else if(display.name == "jiandao"){
selfValue = 1;
}else if(display.name == "bu"){
selfValue = 2;
}
enemyValue = Math.floor(Math.random()*3);
selfBitmap.bitmapData = showList[selfValue];
enemyBitmap.bitmapData = showList[enemyValue];
}六、结果判定
为方便判断结果,我们准备一个结果判定数组:

function onclick(event,display){
var selfValue,enemyValue;
if(display.name == "shitou"){
selfValue = 0;
}else if(display.name == "jiandao"){
selfValue = 1;
}else if(display.name == "bu"){
selfValue = 2;
}
enemyValue = Math.floor(Math.random()*3);
selfBitmap.bitmapData = showList[selfValue];
enemyBitmap.bitmapData = showList[enemyValue];
var result = checkList[selfValue][enemyValue];
if(result == -1){
loss += 1;
}else if(result == 1){
win += 1;
}else{
draw += 1;
}
selfTextWin.text = "胜利次数 : " + win;
selfTextLoss.text = "失败次数 : " + loss;
selfTextDraw.text = "平局次数 : " + draw;
selfTextAll.text = "猜拳次数 : " + (win + loss + draw);
}运行效果:
七、完整代码
init(50,"mylegend",800,400,main);
var loadingLayer,
backLayer,
resultLayer,
clickLayer,
selfBitmap,
enemyBitmap,
selfTextAll,
selfTextWin,
selfTextLoss,
selfTextDraw,
win = 0,
loss = 0,
draw = 0;
var imglist = {};
var imgData = new Array(
{name:"title",path:"../images/title.png"},
{name:"shitou",path:"../images/shitou.png"},
{name:"jiandao",path:"../images/jiandao.png"},
{name:"bu",path:"../images/bu.png"}
);
var checkList = [
[0,1,-1],
[-1,0,1],
[1,-1,0]
];
var showList = new Array();
function main(){
LGlobal.setDebug(true);
backLayer = new LSprite();
addChild(backLayer);
loadingLayer = new LoadingSample3();
backLayer.addChild(loadingLayer);
LLoadManage.load(
imgData,
function(progress){
loadingLayer.setProgress(progress);
},
function(result){
imglist = result;
backLayer.removeChild(loadingLayer);
loadingLayer = null;
gameInit();
}
);
}
function gameInit(){
showList.push(new LBitmapData(imglist["shitou"]));
showList.push(new LBitmapData(imglist["jiandao"]));
showList.push(new LBitmapData(imglist["bu"]));
//添加游戏界面背景
backLayer.graphics.drawRect(10,'#008800',[0,0,LGlobal.width,LGlobal.height],true,'#000000');
//显示游戏标题
var titleBitmap = new LBitmap(new LBitmapData(imglist["title"]));
titleBitmap.x = (LGlobal.width - titleBitmap.width)/2;
titleBitmap.y = 10;
backLayer.addChild(titleBitmap);
//玩家方出拳图片
selfBitmap = new LBitmap(showList[0]);
selfBitmap.x = 400 - selfBitmap.width - 50;
selfBitmap.y = 130;
backLayer.addChild(selfBitmap);
//电脑方出拳图片
enemyBitmap = new LBitmap(showList[0]);
enemyBitmap.x = 400 + 50;
enemyBitmap.y = 130;
backLayer.addChild(enemyBitmap);
//玩家电脑名称设定
var nameText;
nameText = new LTextField();
nameText.text = "玩家";
nameText.weight = "bolder";
nameText.color = "#ffffff";
nameText.size = 24;
nameText.x = selfBitmap.x + (selfBitmap.width - nameText.getWidth())/2;
nameText.y = 95;
backLayer.addChild(nameText);
nameText = new LTextField();
nameText.text = "电脑";
nameText.weight = "bolder";
nameText.color = "#ffffff";
nameText.size = 24;
nameText.x = enemyBitmap.x + (enemyBitmap.width - nameText.getWidth())/2;
nameText.y = 95;
backLayer.addChild(nameText);
//结果显示层初始化
initResultLayer();
//操作层初始化
initClickLayer();
}
function initResultLayer(){
resultLayer = new LSprite();
resultLayer.graphics.drawRect(4,'#ff8800',[0,0,150,110],true,'#ffffff');
resultLayer.x = 10;
resultLayer.y = 100;
backLayer.addChild(resultLayer);
selfTextAll = new LTextField();
selfTextAll.text = "猜拳次数 : 0";
selfTextAll.weight = "bolder";
selfTextAll.x = 10;
selfTextAll.y = 20;
resultLayer.addChild(selfTextAll);
selfTextWin = new LTextField();
selfTextWin.text = "胜利次数 : 0";
selfTextWin.weight = "bolder";
selfTextWin.x = 10;
selfTextWin.y = 40;
resultLayer.addChild(selfTextWin);
selfTextLoss = new LTextField();
selfTextLoss.text = "失败次数 : 0";
selfTextLoss.weight = "bolder";
selfTextLoss.x = 10;
selfTextLoss.y = 60;
resultLayer.addChild(selfTextLoss);
selfTextDraw = new LTextField();
selfTextDraw.text = "平局次数 : 0";
selfTextDraw.weight = "bolder";
selfTextDraw.x = 10;
selfTextDraw.y = 80;
resultLayer.addChild(selfTextDraw);
}
function initClickLayer(){
clickLayer = new LSprite();
clickLayer.graphics.drawRect(4,'#ff8800',[0,0,300,110],true,'#ffffff');
var msgText = new LTextField();
msgText.text = "请出拳:";
msgText.weight = "bolder";
msgText.x = 10;
msgText.y = 10;
clickLayer.addChild(msgText);
var btnShitou = getButton("shitou");
btnShitou.x = 30;
btnShitou.y = 35;
clickLayer.addChild(btnShitou);
btnShitou.addEventListener(LMouseEvent.MOUSE_UP,onclick);
var btnJiandao = getButton("jiandao");
btnJiandao.x = 115;
btnJiandao.y = 35;
clickLayer.addChild(btnJiandao);
btnJiandao.addEventListener(LMouseEvent.MOUSE_UP,onclick);
var btnBu = getButton("bu");
btnBu.x = 200;
btnBu.y = 35;
clickLayer.addChild(btnBu);
btnBu.addEventListener(LMouseEvent.MOUSE_UP,onclick);
clickLayer.x = 250;
clickLayer.y = 275;
backLayer.addChild(clickLayer);
}
function onclick(event,display){
var selfValue,enemyValue;
if(display.name == "shitou"){
selfValue = 0;
}else if(display.name == "jiandao"){
selfValue = 1;
}else if(display.name == "bu"){
selfValue = 2;
}
enemyValue = Math.floor(Math.random()*3);
selfBitmap.bitmapData = showList[selfValue];
enemyBitmap.bitmapData = showList[enemyValue];
var result = checkList[selfValue][enemyValue];
if(result == -1){
loss += 1;
}else if(result == 1){
win += 1;
}else{
draw += 1;
}
selfTextWin.text = "胜利次数 : " + win;
selfTextLoss.text = "失败次数 : " + loss;
selfTextDraw.text = "平局次数 : " + draw;
selfTextAll.text = "猜拳次数 : " + (win + loss + draw);
}
function getButton(value){
var btnUp = new LBitmap(new LBitmapData(imglist[value]));
btnUp.scaleX = 0.5;
btnUp.scaleY = 0.5;
var btnOver = new LBitmap(new LBitmapData(imglist[value]));
btnOver.scaleX = 0.5;
btnOver.scaleY = 0.5;
btnOver.x = 2;
btnOver.y = 2;
var btn = new LButton(btnUp,btnOver);
btn.name = value;
return btn;
}