This commit is contained in:
ckcz123 2018-07-21 14:59:45 +08:00
parent 1470487fed
commit e987725523
14 changed files with 173 additions and 59 deletions

View File

@ -59,7 +59,19 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
## 更新说明
### 2018.7.9 V2.3.3
### 2018.7.21 V2.3.3
HTML5魔塔样板V2.3.3
* [x] 将怪物特殊属性定义和伤害计算函数移动到脚本编辑中
* [x] 事件:画面震动
* [x] 事件:更新怪物数据
* [x] 移动事件和跳跃事件增加“不消失”选项
* [x] 修改默认bgm
* [x] 修复读档开启战斗动画等Bug
* [x] 大量细节优化
### 2018.7.9 V2.3.2
* [x] 适配手机端的造塔页面
* [x] 启动服务的多开版本

View File

@ -206,6 +206,7 @@ action
| follow_s
| unfollow_s
| animate_s
| viberate_s
| showImage_0_s
| showImage_1_s
| animateImage_0_s
@ -652,6 +653,20 @@ var code = '{"type": "unfollow"' + EvalString_0 + '},\n';
return code;
*/;
viberate_s
: '画面震动' '时间' Int Newline
/* viberate_s
tooltip : viberate: 画面震动
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=viberate%ef%bc%9a%e7%94%bb%e9%9d%a2%e9%9c%87%e5%8a%a8
default : [2000]
colour : this.soundColor
Int_0 = Int_0 ?(', "time": '+Int_0):'';
var code = '{"type": "viberate"' + Int_0 + '},\n';
return code;
*/;
animate_s
: '显示动画' IdString '位置' EvalString? Newline
@ -819,20 +834,20 @@ return code;
*/;
move_s
: '移动事件' 'x' PosString? ',' 'y' PosString? '动画时间' Int? '消失时无动画时间' Bool BGNL? StepString Newline
: '移动事件' 'x' PosString? ',' 'y' PosString? '动画时间' Int? '消失' Bool BGNL? StepString Newline
/* move_s
tooltip : move: 让某个NPC/怪物移动,位置可不填代表当前事件
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=move%EF%BC%9A%E8%AE%A9%E6%9F%90%E4%B8%AAnpc%E6%80%AA%E7%89%A9%E7%A7%BB%E5%8A%A8
default : ["","",500,null,"上右3下2左上左2"]
default : ["","",500,false,"上右3下2左上左2"]
colour : this.eventColor
var floorstr = '';
if (PosString_0 && PosString_1) {
floorstr = ', "loc": ['+PosString_0+','+PosString_1+']';
}
Int_0 = Int_0 ?(', "time": '+Int_0):'';
var code = '{"type": "move"'+floorstr+''+Int_0+', "steps": '+JSON.stringify(StepString_0)+', "immediateHide": '+Bool_0+'},\n';
var code = '{"type": "move"'+floorstr+''+Int_0+', "steps": '+JSON.stringify(StepString_0)+', "keep": '+Bool_0+'},\n';
return code;
*/;
@ -851,13 +866,13 @@ return code;
*/;
jump_s
: '跳跃事件' '起始 x' PosString? ',' 'y' PosString? '终止 x' PosString? ',' 'y' PosString? BGNL? '动画时间' Int? '消失时无动画时间' Bool Newline
: '跳跃事件' '起始 x' PosString? ',' 'y' PosString? '终止 x' PosString? ',' 'y' PosString? '动画时间' Int? '消失' Bool Newline
/* jump_s
tooltip : jump: 让某个NPC/怪物跳跃
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=jump%EF%BC%9A%E8%AE%A9%E6%9F%90%E4%B8%AANPC%2F%E6%80%AA%E7%89%A9%E8%B7%B3%E8%B7%83
default : ["","","","",500,null]
default : ["","","","",500,true]
colour : this.eventColor
var floorstr = '';
if (PosString_0 && PosString_1) {
@ -867,7 +882,7 @@ if (PosString_2 && PosString_3) {
floorstr += ', "to": ['+PosString_2+','+PosString_3+']';
}
Int_0 = Int_0 ?(', "time": '+Int_0):'';
var code = '{"type": "jump"'+floorstr+''+Int_0+', "immediateHide": '+Bool_0+'},\n';
var code = '{"type": "jump"'+floorstr+''+Int_0+', "keep": '+Bool_0+'},\n';
return code;
*/;
@ -1235,7 +1250,7 @@ Floor_List
/*Floor_List ['floorId',':before',':next']*/;
Stair_List
: '坐标'|'上楼'|'下楼'
: '坐标'|'上楼'|'下楼'
/*Stair_List ['loc','upFloor','downFloor']*/;
SetTextPosition_List
@ -1526,7 +1541,7 @@ ActionParser.prototype.parseAction = function() {
case "move": // 移动事件
data.loc=data.loc||['',''];
this.next = MotaActionBlocks['move_s'].xmlText([
data.loc[0],data.loc[1],data.time||0,data.immediateHide,this.StepString(data.steps),this.next]);
data.loc[0],data.loc[1],data.time||0,data.keep,this.StepString(data.steps),this.next]);
break;
case "moveHero":
this.next = MotaActionBlocks['moveHero_s'].xmlText([
@ -1536,7 +1551,7 @@ ActionParser.prototype.parseAction = function() {
data.from=data.from||['',''];
data.to=data.to||['',''];
this.next = MotaActionBlocks['jump_s'].xmlText([
data.from[0],data.from[1],data.to[0],data.to[1],data.time||0,data.immediateHide,this.next]);
data.from[0],data.from[1],data.to[0],data.to[1],data.time||0,data.keep,this.next]);
break;
case "jumpHero": // 跳跃勇士
data.loc=data.loc||['','']
@ -1569,6 +1584,9 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['animate_s'].xmlText([
data.name,animate_loc,this.next]);
break;
case "viberate": // 画面震动
this.next = MotaActionBlocks['viberate_s'].xmlText([data.time||0, this.next]);
break;
case "showImage": // 显示图片
if(this.isset(data.name)){
this.next = MotaActionBlocks['showImage_0_s'].xmlText([

View File

@ -116,6 +116,7 @@ editor_blockly = function () {
'<label text="特效/声音"></label>',
MotaActionBlocks['sleep_s'].xmlText(),
MotaActionBlocks['wait_s'].xmlText(),
MotaActionBlocks['viberate_s'].xmlText(),
MotaActionBlocks['animate_s'].xmlText(),
MotaActionBlocks['setFg_0_s'].xmlText(),
MotaActionBlocks['setFg_1_s'].xmlText(),

View File

@ -87,19 +87,7 @@ functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
}
}
},
"ui": {
"_leaf": false,
"_type": "object",
"_data": {
"drawAbout": {
"_leaf": true,
"_type": "textarea",
"_lint": true,
"_data": "绘制“关于”界面"
}
}
},
"enemy": {
"enemys": {
"_leaf": false,
"_type": "object",
"_data": {
@ -123,6 +111,18 @@ functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
}
}
},
"ui": {
"_leaf": false,
"_type": "object",
"_data": {
"drawAbout": {
"_leaf": true,
"_type": "textarea",
"_lint": true,
"_data": "绘制“关于”界面"
}
}
},
"plugins": {
"_leaf": false,
"_type": "object",

View File

@ -655,6 +655,10 @@ name为可选的是要取消跟随的行走图文件名。
如果name省略则会取消所有的跟随效果。
### viberate画面震动
使用 `{"type": "viberate", "time": 2000}` 可以造成画面震动效果后面time可以指定震动时间。
### animate显示动画
我们可以使用 `{"type": "animate"}` 来显示一段动画。
@ -812,7 +816,7 @@ level为天气的强度等级在1-10之间。1级为最弱10级为最强
{"type": "move", "time": 750, "loc": [x,y], "steps": [// 动画效果time为移动速度(比如这里每750ms一步)loc为位置可选steps为移动数组
{"direction": "right", "value": 2},// 这里steps 的效果为向右移动2步在向下移动一步并消失
"down" // 如果该方向上只移动一步则可以这样简写效果等价于上面value为1
], "immediateHide": true }, //immediateHide可选制定为true则立刻消失,否则渐变消失
], "keep": true }, // keep可选如果为true则不消失,否则渐变消失
]
```
@ -824,13 +828,13 @@ steps为一个数组其每一项为一个 `{"direction" : xxx, "value": n}`
如果只移动一步可以直接简单的写方向字符串(`up/left/down/right`)。
immediateHide为一个可选项,代表该事件移动完毕后是否立刻消失。如果该项指定了并为true则移动完毕后直接消失,否则以动画效果消失。
keep为一个可选项代表该事件移动完毕后是否消失。如果该项指定了并为true则移动完毕后将不消失,否则以动画效果消失。
值得注意的是当调用move事件时实际上是使事件脱离了原始地点。为了避免冲突规定move事件会自动调用该点的hide事件。
换句话说当move事件被调用后该点本身的事件将被禁用。
move完毕后移动的NPC/怪物一定会消失只不过可以通过immediateHide决定是否立刻消失还是以time作为时间来动画效果消失
如果指定了`"keep": true`,则相当于会在目标地点触发一个`setBlock`事件;如需能继续对话交互请在目标地点再写事件
如果想让move后的NPC/怪物仍然可以被交互,需采用如下的写法:
@ -838,11 +842,9 @@ move完毕后移动的NPC/怪物一定会消失只不过可以通过immediate
"4,3": [ // [4,3]是一个NPC比如小偷
{"type": "move", "time": 750, "steps": [ // 向上移动两格每步750毫秒
{"direction": "up", "value": 2},
], "immediateHide": true}, // 移动完毕立刻消失
{"type": "show", "loc": [4,1]} // 指定[4,1]点的NPC立刻生效显示
{"type": "trigger", "loc": [4,1]} // 立刻触发[4,1]点的事件
], "keep": true}, // 移动完毕后不消失
],
"4,1": { // [4,1]也是这个NPC而且是向上移动两个的位置
"4,1": { // [4,1]为目标地点
"enable": false, // 初始时需要是禁用状态被show调用后将显示出来
"data": [
"\t[杰克,thief]这样看起来就好像移动过去后也可以被交互。"
@ -879,7 +881,7 @@ move完毕后移动的NPC/怪物一定会消失只不过可以通过immediate
``` js
"x,y": [ // 实际执行的事件列表
{"type": "jump", "from": [3,6], "to": [2,1], "time": 750, "immediateHide": true},
{"type": "jump", "from": [3,6], "to": [2,1], "time": 750, "keep": true},
]
```
@ -889,13 +891,9 @@ to为要跳跃到的坐标。可以省略如果省略则跳跃到当前坐标
time选项必须指定为全程跳跃所需要用到的时间。
immediateHide为一个可选项同上代表该跳跃完毕后是否立刻消失。如果该项指定了并为true则跳跃完毕后直接消失,否则以动画效果消失。
keep为一个可选项同上代表该跳跃完毕后是否不消失。如果该项指定了并为true则跳跃完毕后不会消失,否则以动画效果消失。
值得注意的是当调用jump事件时实际上是使事件脱离了原始地点。
为了避免冲突同move事件一样规定jump事件会自动调用该点的hide事件。
如果是本地跳跃,需要在跳跃完毕后再启用事件。
如果指定了`"keep": true`,则相当于会在目标地点触发一个`setBlock`事件;如需能继续对话交互请在目标地点再写事件。
### jumpHero跳跃勇士

View File

@ -1917,10 +1917,17 @@ control.prototype.replay = function () {
}
}
else if (action.indexOf('move:')==0) {
while (core.status.replay.toReplay.length>0 &&
core.status.replay.toReplay[0].indexOf('move:')==0) {
action = core.status.replay.toReplay.shift();
}
var pos=action.substring(5).split(":");
var x=parseInt(pos[0]), y=parseInt(pos[1]);
if (core.control.moveDirectly(x,y)) {
core.replay();
setTimeout(function () {
core.replay();
}, 750 / core.status.replay.speed);
return;
}
}

View File

@ -665,13 +665,13 @@ core.prototype.getBlockId = function (x, y, floorId, needEnable) {
}
////// 显示移动某块的动画,达到{“type”:”move”}的效果 //////
core.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) {
core.maps.moveBlock(x,y,steps,time,immediateHide,callback)
core.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
core.maps.moveBlock(x,y,steps,time,keep,callback)
}
////// 显示跳跃某块的动画,达到{"type":"jump"}的效果 //////
core.prototype.jumpBlock = function(sx,sy,ex,ey,time,immediateHide,callback) {
core.maps.jumpBlock(sx,sy,ex,ey,time,immediateHide,callback);
core.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) {
core.maps.jumpBlock(sx,sy,ex,ey,time,keep,callback);
}
////// 显示/隐藏某个块时的动画效果 //////

View File

@ -5,7 +5,7 @@ function enemys() {
////// 初始化 //////
enemys.prototype.init = function () {
this.enemys = enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80;
this.enemydata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.enemy;
this.enemydata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.enemys;
this.enemydata.hasSpecial = function (a, b) {return core.enemys.hasSpecial(a, b)};
}

View File

@ -461,7 +461,7 @@ events.prototype.doAction = function() {
x=core.calValue(data.loc[0]);
y=core.calValue(data.loc[1]);
}
core.moveBlock(x,y,data.steps,data.time,data.immediateHide,function() {
core.moveBlock(x,y,data.steps,data.time,data.keep,function() {
core.events.doAction();
})
break;
@ -481,7 +481,7 @@ events.prototype.doAction = function() {
ex=core.calValue(data.to[0]);
ey=core.calValue(data.to[1]);
}
core.jumpBlock(sx,sy,ex,ey,data.time,data.immediateHide,function() {
core.jumpBlock(sx,sy,ex,ey,data.time,data.keep,function() {
core.events.doAction();
});
break;
@ -807,6 +807,11 @@ events.prototype.doAction = function() {
core.updateStatusBar();
this.doAction();
break;
case "viberate":
core.events.vibrate(data.time, function () {
core.events.doAction();
})
break;
case "sleep": // 等待多少毫秒
if (core.status.replay.replaying)
core.events.doAction();
@ -1307,6 +1312,65 @@ events.prototype.setVolume = function (value, time, callback) {
}, time / 32);
}
////// 画面震动 //////
events.prototype.vibrate = function(time, callback) {
if (core.isset(core.status.replay)&&core.status.replay.replaying) {
if (core.isset(callback)) callback();
return;
}
core.status.replay.animate=true;
var setGameCanvasTranslate=function(x,y){
for(var ii=0,canvas;canvas=core.dom.gameCanvas[ii];ii++){
if(['data','ui'].indexOf(canvas.getAttribute('id'))!==-1)continue;
canvas.style.transform='translate('+x+'px,'+y+'px)';
canvas.style.webkitTransform='translate('+x+'px,'+y+'px)';
canvas.style.OTransform='translate('+x+'px,'+y+'px)';
canvas.style.MozTransform='translate('+x+'px,'+y+'px)';
}
}
if (!core.isset(time) || time<1000) time=1000;
var shake_duration = time*3/50;
var shake_speed = 5;
var shake_power = 5;
var shake_direction = 1;
var shake = 0;
var update = function() {
if(shake_duration >= 1 || shake != 0){
var delta = (shake_power * shake_speed * shake_direction) / 10.0;
if(shake_duration <= 1 && shake * (shake + delta) < 0){
shake = 0;
}else{
shake += delta;
}
if(shake > shake_power * 2){
shake_direction = -1;
}
if(shake < - shake_power * 2){
shake_direction = 1;
}
if(shake_duration >= 1){
shake_duration -= 1
}
}
}
var animate=setInterval(function(){
update();
setGameCanvasTranslate(shake,0);
if(shake_duration===0) {
clearInterval(animate);
core.status.replay.animate=false;
if (core.isset(callback)) callback();
}
}, 50/3);
}
////// 打开一个全局商店 //////
events.prototype.openShop = function(shopId, needVisited) {
var shop = core.status.shops[shopId];

View File

@ -557,9 +557,8 @@ maps.prototype.getBlockId = function (x, y, floorId, needEnable) {
}
////// 显示移动某块的动画,达到{“type”:”move”}的效果 //////
maps.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) {
maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
time = time || 500;
core.status.replay.animate=true;
core.clearMap('animate', 0, 0, 416, 416);
@ -568,6 +567,9 @@ maps.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) {
if (core.isset(callback)) callback();
return;
}
var id = block.block.id;
core.status.replay.animate=true;
// 需要删除该块
core.removeBlock(x,y);
@ -625,7 +627,7 @@ maps.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) {
// 已经移动完毕,消失
if (moveSteps.length==0) {
if (immediateHide) opacityVal=0;
if (keep) opacityVal=0;
else opacityVal -= 0.06;
core.setOpacity('animate', opacityVal);
core.clearMap('animate', nowX, nowY-height+32, 32, height);
@ -634,6 +636,11 @@ maps.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) {
clearInterval(animate);
core.clearMap('animate', 0, 0, 416, 416);
core.setOpacity('animate', 1);
// 不消失
if (keep) {
core.setBlock(id, nowX/32, nowY/32);
core.showBlock(nowX/32, nowY/32);
}
core.status.replay.animate=false;
if (core.isset(callback)) callback();
}
@ -656,15 +663,17 @@ maps.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) {
}
////// 显示跳跃某块的动画,达到{"type":"jump"}的效果 //////
maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,immediateHide,callback) {
maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) {
time = time || 500;
core.status.replay.animate=true;
core.clearMap('animate', 0, 0, 416, 416);
var block = core.getBlock(sx,sy);
if (block==null) {
if (core.isset(callback)) callback();
return;
}
var id = block.block.id;
core.status.replay.animate=true;
// 需要删除该块
core.removeBlock(sx,sy);
@ -724,7 +733,7 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,immediateHide,callback) {
core.canvas.animate.drawImage(blockImage, animateCurrent * 32, blockIcon * height, 32, height, drawX(), drawY()-height+32, 32, height);
}
else {
if (immediateHide) opacityVal=0;
if (keep) opacityVal=0;
else opacityVal -= 0.06;
core.setOpacity('animate', opacityVal);
core.clearMap('animate', drawX(), drawY()-height+32, 32, height);
@ -733,6 +742,10 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,immediateHide,callback) {
clearInterval(animate);
core.clearMap('animate', 0, 0, 416, 416);
core.setOpacity('animate', 1);
if (keep) {
core.setBlock(id, ex, ey);
core.showBlock(ex, ey);
}
core.status.replay.animate=false;
if (core.isset(callback)) callback();
}
@ -873,6 +886,7 @@ maps.prototype.removeBlockByIds = function (floorId, ids) {
maps.prototype.setBlock = function (number, x, y, floorId) {
floorId = floorId || core.status.floorId;
if (!core.isset(number) || !core.isset(x) || !core.isset(y)) return;
if (x<0 || x>12 || y<0 || y>12) return;
var originBlock=core.getBlock(x,y,floorId,false);
var block = core.maps.initBlock(x,y,number);

View File

@ -2,7 +2,7 @@ function main() {
//------------------------ 用户修改内容 ------------------------//
this.version = "2.3.2"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.version = "2.3.3"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.useCompress = false; // 是否使用压缩文件
// 当你即将发布你的塔时请使用“JS代码压缩工具”将所有js代码进行压缩然后将这里的useCompress改为true。

View File

@ -26,7 +26,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"firstData" : {
"title": "魔塔样板",
"name": "template",
"version": "Ver 2.3.2",
"version": "Ver 2.3.3",
"floorId": "sample0",
"hero": {
"name": "阳光",

View File

@ -306,7 +306,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
core.enemys.updateEnemys();
}
},
"enemy": {
"enemys": {
"getSpecials" : function() {
// 获得怪物的特殊属性,每一行定义一个特殊属性。
// 分为三项,第一项为该特殊属性的数字,第二项为特殊属性的名字,第三项为特殊属性的描述

View File

@ -1,12 +1,12 @@
HTML5魔塔样板V2.3.3
将怪物特殊属性定义和伤害计算函数移动到脚本编辑中
将怪物特殊属性定义和伤害计算函数移动到脚本编辑中
事件:画面震动
事件:更新怪物数据
事件:更新怪物数据
移动事件和跳跃事件增加“不消失”选项
修改默认bgm
修复读档开启战斗动画等Bug
大量细节优化
修改默认bgm
修复读档开启战斗动画等Bug
大量细节优化
-----------------------------------------------------------------------