Merge pull request #286 from ckcz123/v2.0

V2.0
This commit is contained in:
Zhang Chen 2018-12-22 02:15:48 +08:00 committed by GitHub
commit 91077ebf15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 300 additions and 144 deletions

View File

@ -62,7 +62,7 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
* [x] \r[red]可以动态调整剧情文本的颜色
* [x] 升级事件改用事件编辑器完成
* [x] 每层楼都增添该层的并行事件处理
* [x] 新增快捷键N返回标题P查看评论O打开工程
* [x] 新增快捷键N返回标题P游戏主页O打开工程
* [x] 新增事件:设置全局属性或全局数值
* [x] 新增事件:隐藏/显示状态栏
* [x] 道具可以设置是否在回放时绘制道具栏或直接使用

View File

@ -270,6 +270,7 @@ action
| showGif_1_s
| setFg_0_s
| setFg_1_s
| screenFlash_s
| setWeather_s
| move_s
| moveHero_s
@ -1155,6 +1156,29 @@ var code = '{"type": "setFg"'+Int_0 +async+'},\n';
return code;
*/;
screenFlash_s
: '画面闪烁' Number ',' Number ',' Number '强度' Number '单次时间' Int '执行次数' Int? '不等待执行完毕' Bool Newline
/* screenFlash_s
tooltip : screenFlash: 画面闪烁,动画时间可不填
helpUrl : https://h5mota.com/games/template/docs/#/event?id=screenFlash%EF%BC%9A%E7%94%BB%E9%9D%A2%E9%97%AA%E7%83%81
default : [255,255,255,1,500,1,false]
colour : this.soundColor
var limit = function(v,min,max) {
if(v>max) return max;
if(v<min) return min;
return v;
}
Number_0 = limit(Number_0,0,255);
Number_1 = limit(Number_1,0,255);
Number_2 = limit(Number_2,0,255);
Number_3 = limit(Number_3,0,1);
Int_1 = Int_1!=='' ?(', "times": '+Int_1):'';
var async = Bool_0?', "async": true':'';
var code = '{"type": "screenFlash", "color": ['+Number_0+','+Number_1+','+Number_2+','+Number_3+'], "time": '+Int_0 +Int_1+async+'},\n';
return code;
*/;
setWeather_s
: '更改天气' Weather_List '强度' Int Newline
@ -2140,6 +2164,10 @@ ActionParser.prototype.parseAction = function() {
data.time||0,data.async||false,this.next]);
}
break;
case "screenFlash": // 画面闪烁
this.next = MotaActionBlocks['screenFlash_s'].xmlText([
data.color[0],data.color[1],data.color[2],data.color[3]||1,data.time||500,data.times||1,data.async||false,this.next]);
break;
case "setWeather": // 更改天气
this.next = MotaActionBlocks['setWeather_s'].xmlText([
data.name||'无',data.level||1,this.next]);

View File

@ -838,6 +838,11 @@ editor.prototype.listen = function () {
var reDo = null;
var shortcut = core.getLocalStorage('shortcut',{48: 0, 49: 0, 50: 0, 51: 0, 52: 0, 53: 0, 54: 0, 55: 0, 56: 0, 57: 0});
document.body.onkeydown = function (e) {
// 如果是开启事件/脚本编辑器状态,则忽略
if (editor_multi.id!="" || editor_blockly.id!="")
return;
// 禁止快捷键的默认行为
if (e.ctrlKey && [89, 90, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1)
e.preventDefault();
@ -898,15 +903,18 @@ editor.prototype.listen = function () {
printf('已保存该快捷图块, ctrl + '+(e.keyCode-48)+' 使用.')
core.setLocalStorage('shortcut',shortcut);
}
// wasd平移大地图
if (e.keyCode==87)
editor.moveViewport(0,-1)
else if (e.keyCode==65)
editor.moveViewport(-1,0)
else if (e.keyCode==83)
editor.moveViewport(0,1);
else if (e.keyCode==68)
editor.moveViewport(1,0);
var focusElement = document.activeElement;
if (!focusElement || focusElement.tagName.toLowerCase()=='body') {
// wasd平移大地图
if (e.keyCode==87)
editor.moveViewport(0,-1)
else if (e.keyCode==65)
editor.moveViewport(-1,0)
else if (e.keyCode==83)
editor.moveViewport(0,1);
else if (e.keyCode==68)
editor.moveViewport(1,0);
}
}
var dataSelection = document.getElementById('dataSelection');

View File

@ -140,6 +140,7 @@ editor_blockly = function () {
MotaActionBlocks['hideStatusBar_s'].xmlText(),
MotaActionBlocks['setFg_0_s'].xmlText(),
MotaActionBlocks['setFg_1_s'].xmlText(),
MotaActionBlocks['screenFlash_s'].xmlText(),
MotaActionBlocks['setWeather_s'].xmlText(),
MotaActionBlocks['playBgm_s'].xmlText(),
MotaActionBlocks['pauseBgm_s'].xmlText(),

View File

@ -467,25 +467,24 @@ core.maps.removeBlockByIds(floorId, ids)
ui.js主要用来进行UI窗口的绘制比如对话框、怪物手册、楼传器、存读档界面等等。
core.ui.getContextByName(name)
core.ui.getContextByName(canvas)
根据画布名找到一个画布的context支持系统画布和自定义画布。如果不存在画布返回null。
也可以传画布的context自身则返回自己。
core.clearMap(name)
清空某个画布图层。
name为画布名可以是系统画布之一也可以是任意自定义动态创建的画布名。
name为画布名可以是系统画布之一也可以是任意自定义动态创建的画布名还可以直接传画布的context本身(下同)
如果name也可以是'all'若为all则为清空所有系统画布。
core.ui.fillText(name, text, x, y, style, font)
在某个画布上绘制一段文字。
name为画布名可以是系统画布之一也可以是任意自定义动态创建的画布名。下同
text为要绘制的文本x,y为要绘制的坐标style可选为绘制的样式font可选为绘制的字体。
text为要绘制的文本x,y为要绘制的坐标style可选为绘制的样式font可选为绘制的字体。下同
core.ui.fillBoldText(canvas, text, style, x, y, font)
core.ui.fillBoldText(name, text, style, x, y, font)
在某个画布上绘制一个描黑边的文字。
canvas为要绘制的画布的contexttext为文本style为颜色样式x,y坐标font可选为要绘制的字体。
core.ui.fillRect(name, x, y, width, height, style)
@ -531,7 +530,7 @@ font可选如果存在则会先设置该画布上的字体。
core.ui.drawImage(name, image, x, y, w, h, x1, y1, w1, h1)
在一个画布上绘制图片。
name为画布名可以是系统画布之一也可以是任意自定义动态创建的画布名。
name为画布名可以是系统画布之一也可以是任意自定义动态创建的画布名还可以直接传画布的context本身
image为要绘制的图片可以是一个全塔属性中定义的图片名会从images中去获取图片本身或者一个画布。
后面的8个坐标参数与canvas的drawImage的八个参数完全相同。
请查看 http://www.w3school.com.cn/html5/canvas_drawimage.asp 了解更多。

View File

@ -473,7 +473,7 @@ HTML5魔塔一大亮点就是存在录像系统可以很方便进行录像回
- **[G]** 打开/关闭楼层传送器
- **[A]** 读取自动存档
- **[S/D]** 打开/关闭存/读档页面
- **[K/V]** 打开/关闭快捷商店选择列表
- **[V]** 打开/关闭快捷商店选择列表
- **[T]** 打开/关闭工具栏
- **[Q]** 打开/关闭装备栏
- **[ESC]** 打开/关闭系统菜单

View File

@ -1061,6 +1061,27 @@ time为可选的如果指定则会作为更改画面色调的时间。
async可选如果为true则会异步执行即不等待当前事件执行完毕立刻执行下一个事件
### screenFlash画面闪烁
我们可以使用 `{"type": "screenFlash"}` 来进行画面闪烁。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "screenFlash", "color": [255,255,255,0.6], "time": 500, "times": 1}, // 闪光为白色不透明度0.6动画时间1000毫秒
{"type": "screenFlash", "color": [255,0,0,1], "time": 100, "times": 2, "async": true}, // 闪光为红色强度最大动画时间100毫秒闪烁两次且异步执行
]
```
color为闪光的颜色。它是一个数组分别指定目标颜色的R,G,B,A值。
- 常见RGB颜色 纯黑[0,0,0],纯白[255,255,255],纯红[255,0,0],等等。
A即闪光的不透明度为一个0到1之间的数值越高闪烁效果越强。默认为1
time为闪烁时间默认值为500
times为闪烁次数两次闪烁会连续进行默认值为1
async可选如果为true则会异步执行即不等待当前事件执行完毕立刻执行下一个事件
### setWeather更改天气
我们可以使用 `{"type": "setWeather"}` 来更改天气。

View File

@ -196,10 +196,14 @@ actions.prototype.keyUp = function(keyCode, altKey, fromReplay) {
if (!fromReplay && core.isset(core.status.replay)&&core.status.replay.replaying
&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0&&core.status.event.id!='viewMaps') return;
var ok = function (keycode) {
return keycode==27 || keycode==88 || keycode==13 || keycode==32 || keycode==67;
}
if (core.status.lockControl) {
core.status.holdingKeys = [];
// 全键盘操作部分
if (core.status.event.id == 'text' && (keyCode==13 || keyCode==32 || keyCode==67)) {
if (core.status.event.id == 'text' && ok(keyCode)) {
core.drawText();
return;
}
@ -211,15 +215,19 @@ actions.prototype.keyUp = function(keyCode, altKey, fromReplay) {
this.keyUpAction(keyCode);
return;
}
if (core.status.event.id=='about' && (keyCode==13 || keyCode==32 || keyCode==67)) {
if (core.status.event.id=='about' && ok(keyCode)) {
this.clickAbout();
return;
}
if (core.status.event.id=='help' && ok(keyCode)) {
core.ui.closePanel();
return;
}
if (core.status.event.id=='book') {
this.keyUpBook(keyCode);
return;
}
if (core.status.event.id=='book-detail' && (keyCode==13 || keyCode==32 || keyCode==67)) {
if (core.status.event.id=='book-detail' && ok(keyCode)) {
this.clickBookDetail();
return;
}
@ -251,6 +259,10 @@ actions.prototype.keyUp = function(keyCode, altKey, fromReplay) {
this.keyUpSL(keyCode);
return;
}
if (core.status.event.id == 'keyBoard' && ok(keyCode)) {
core.ui.closePanel();
return;
}
if (core.status.event.id=='switchs') {
this.keyUpSwitchs(keyCode);
return;
@ -551,6 +563,11 @@ actions.prototype.onclick = function (x, y, stepPostfix) {
this.clickAbout(x,y);
return;
}
if (core.status.event.id == 'help') {
this.clickHelp(x,y);
return;
}
if (core.status.event.id == 'action') {
this.clickAction(x,y);
@ -2604,6 +2621,10 @@ actions.prototype.clickAbout = function () {
core.restart(true);
}
////// “帮助”界面时的点击操作 //////
actions.prototype.clickHelp = function () {
core.ui.closePanel();
}
////// 绘图相关 //////

View File

@ -76,15 +76,13 @@ control.prototype.setRequestAnimationFrame = function () {
}
if ((core.status.autotileAnimateObjs.blocks||[]).length>0) {
var groundId = (core.status.maps||core.floors)[core.status.floorId].defaultGround || "ground";
var blockIcon = core.material.icons.terrains[groundId];
core.status.autotileAnimateObjs.status++;
core.status.autotileAnimateObjs.blocks.forEach(function (block) {
var cv = core.isset(block.name)?core.canvas[block.name]:core.canvas.event;
cv.clearRect(block.x * 32, block.y * 32, 32, 32);
if (core.isset(block.name)) {
if (block.name == 'bg') {
core.drawImage('bg', core.material.images.terrains, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32);
core.drawImage('bg', core.material.groundCanvas.canvas, block.x * 32, block.y * 32);
}
core.drawAutotile(cv, core.status.autotileAnimateObjs[block.name+"map"], block, 32, 0, 0, core.status.autotileAnimateObjs.status);
}
@ -1335,7 +1333,7 @@ control.prototype.setFg = function(color, time, callback) {
core.status.curtainColor = [0,0,0,0];
}
var fromColor = core.status.curtainColor;
var nowColor = core.status.curtainColor;
if (!core.isset(color))
color = [0,0,0,0];
@ -1351,19 +1349,20 @@ control.prototype.setFg = function(color, time, callback) {
return;
}
var per_time = 10, step=0, steps = parseInt(time / per_time);
var per_time = 10, step = parseInt(time / per_time);
var changeAnimate = setInterval(function() {
step++;
var nowA = fromColor[3]+(color[3]-fromColor[3])*step/steps;
var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/steps);
var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/steps);
var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/steps);
nowColor = [
parseInt(nowColor[0]*(step-1)+color[0])/step,
parseInt(nowColor[1]*(step-1)+color[1])/step,
parseInt(nowColor[2]*(step-1)+color[2])/step,
(nowColor[3]*(step-1)+color[3])/step,
];
core.clearMap('curtain');
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGBA([nowR,nowG,nowB,nowA]));
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGBA(nowColor));
step--;
if (step>=steps) {
if (step <= 0) {
delete core.animateFrame.asyncId[changeAnimate];
clearInterval(changeAnimate);
core.status.curtainColor = color;
@ -1375,6 +1374,22 @@ control.prototype.setFg = function(color, time, callback) {
core.animateFrame.asyncId[changeAnimate] = true;
}
////// 画面闪烁 //////
control.prototype.screenFlash = function (color, time, times, callback) {
times = times || 1;
time = time/3;
var nowColor = core.clone(core.status.curtainColor);
core.setFg(color, time, function() {
core.setFg(nowColor, time * 2, function() {
if (times > 1)
core.screenFlash(color, time * 3, times - 1, callback);
else {
if (core.isset(callback)) callback();
}
});
});
}
////// 更新全地图显伤 //////
control.prototype.updateDamage = function (floorId, canvas) {
floorId = floorId || core.status.floorId;
@ -2077,10 +2092,10 @@ control.prototype.doSL = function (id, type) {
}, function(err) {
console.info(err);
if (core.platform.useLocalForage) {
alert("存档失败,请将控制台的报错信息反馈给管理员。");
alert("存档失败,错误信息:\n"+err);
}
else {
alert("存档空间不足,请先使用垃圾存档清理工具进行清理!");
alert("存档失败,错误信息:\n"+err+"\n建议使用垃圾存档清理工具进行清理!");
}
})
return;
@ -2094,7 +2109,9 @@ control.prototype.doSL = function (id, type) {
return;
}
if (core.isset(data.hashCode) && data.hashCode != core.utils.hashCode(data.hero)) {
alert("存档校验失败,请勿修改存档文件!");
if (confirm("存档校验失败,请勿修改存档文件!\n你想回放此存档的录像吗")) {
core.startGame(data.hard, data.hero.flags.__seed__, core.decodeRoute(data.route));
}
return;
}
if (data.version != core.firstData.version) {

View File

@ -333,11 +333,9 @@ core.prototype.init = function (coreData, callback) {
core.flags.displayCritical = core.getLocalStorage('critical', core.flags.displayCritical);
core.flags.displayExtraDamage = core.getLocalStorage('extraDamage', core.flags.displayExtraDamage);
core.material.ground = new Image();
core.material.ground.onload = function () {
core.material.groundPattern = core.canvas.ui.createPattern(core.material.ground, "repeat");
}
core.material.ground.src = "project/images/ground.png";
core.material.groundCanvas = document.createElement('canvas').getContext('2d');
core.material.groundCanvas.canvas.width = core.material.groundCanvas.canvas.height = 32;
core.material.groundPattern = core.material.groundCanvas.createPattern(core.material.groundCanvas.canvas, 'repeat');
core.animateFrame.weather.fog = new Image();
core.animateFrame.weather.fog.onerror = function () {
@ -345,6 +343,12 @@ core.prototype.init = function (coreData, callback) {
}
core.animateFrame.weather.fog.src = "project/images/fog.png";
core.material.images.keyboard = new Image();
core.material.images.keyboard.onerror = function () {
core.material.images.keyboard = null;
}
core.material.images.keyboard.src = "project/images/keyboard.png";
core.bigmap.tempCanvas = document.createElement('canvas').getContext('2d');
core.loader.load(function () {
@ -632,8 +636,8 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback,
}
////// 从名字获得画布 //////
core.prototype.getContextByName = function (name) {
return core.ui.getContextByName(name);
core.prototype.getContextByName = function (canvas) {
return core.ui.getContextByName(canvas);
}
////// 清除地图 //////
@ -647,8 +651,8 @@ core.prototype.fillText = function (name, text, x, y, style, font) {
}
////// 在某个canvas上绘制一段描边文字 //////
core.prototype.fillBoldText = function (canvas, text, style, x, y, font) {
core.ui.fillBoldText(canvas, text, style , x, y, font);
core.prototype.fillBoldText = function (name, text, style, x, y, font) {
core.ui.fillBoldText(name, text, style , x, y, font);
}
////// 在某个canvas上绘制一个矩形 //////
@ -923,6 +927,11 @@ core.prototype.setFg = function(color, time, callback) {
core.control.setFg(color, time, callback);
}
////// 画面闪烁 //////
core.prototype.screenFlash = function (color, time, times, callback) {
core.control.screenFlash(color, time, times, callback);
}
////// 更新全地图显伤 //////
core.prototype.updateDamage = function () {
core.control.updateDamage();

View File

@ -822,6 +822,17 @@ events.prototype.doAction = function() {
});
}
break;
case "screenFlash": // 画面闪烁
if (data.async) {
core.screenFlash(data.color, data.time, data.times);
this.doAction();
}
else {
core.screenFlash(data.color, data.time, data.times, function() {
core.events.doAction();
});
}
break;
case "setWeather": // 更改天气
core.setWeather(data.name, data.level);
if (core.isset(data.name))

View File

@ -377,9 +377,7 @@ maps.prototype.drawBlock = function (block, animate, dx, dy) {
if (core.isset(block.name)) {
core.canvas[block.name].clearRect(block.x * 32, block.y * 32, 32, 32);
if (block.name == 'bg') {
var groundId = (core.status.maps||core.floors)[core.status.floorId].defaultGround || "ground";
var blockIcon = core.material.icons.terrains[groundId];
core.drawImage('bg', core.material.images.terrains, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32);
core.drawImage('bg', core.material.groundCanvas.canvas, block.x * 32, block.y * 32);
}
core.canvas[block.name].drawImage(image, x * 32, y * 32, 32, 32, block.x * 32, block.y * 32, 32, 32);
return;
@ -477,18 +475,22 @@ maps.prototype.drawMap = function (floorId, callback) {
}
core.clearMap('all');
var groundId = (core.status.maps||core.floors)[floorId].defaultGround || "ground";
core.material.groundCanvas.clearRect(0, 0, 32, 32);
core.material.groundCanvas.drawImage(core.material.images.terrains, 0, 32*core.material.icons.terrains[groundId], 32, 32, 0, 0, 32, 32);
core.material.groundPattern = core.material.groundCanvas.createPattern(core.material.groundCanvas.canvas, 'repeat');
var drawBg = function(){
var width = core.floors[floorId].width || 13;
var height = core.floors[floorId].height || 13;
var groundId = (core.status.maps||core.floors)[floorId].defaultGround || "ground";
var blockIcon = core.material.icons.terrains[groundId];
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
core.drawImage('bg', core.material.images.terrains, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32);
core.drawImage('bg', core.material.groundCanvas.canvas, 32*x, 32*y);
}
}
// 获得image
var images = [];
if (core.isset(core.status.maps[floorId].images)) {
images = core.status.maps[floorId].images;

View File

@ -17,11 +17,16 @@ ui.prototype.init = function () {
////////////////// 地图设置
ui.prototype.getContextByName = function (name) {
if (core.isset(core.canvas[name]))
return core.canvas[name];
if (core.isset(core.dymCanvas[name]))
return core.dymCanvas[name];
ui.prototype.getContextByName = function (canvas) {
if (typeof canvas == 'string') {
if (core.isset(core.canvas[canvas]))
canvas = core.canvas[canvas];
else if (core.isset(core.dymCanvas[canvas]))
canvas = core.dymCanvas[canvas];
}
if (core.isset(canvas) && core.isset(canvas.canvas)) {
return canvas;
}
return null;
}
@ -53,15 +58,17 @@ ui.prototype.fillText = function (name, text, x, y, style, font) {
}
////// 在某个canvas上绘制粗体 //////
ui.prototype.fillBoldText = function (canvas, text, style, x, y, font) {
if (core.isset(font)) canvas.font = font;
canvas.fillStyle = '#000000';
canvas.fillText(text, x-1, y-1);
canvas.fillText(text, x-1, y+1);
canvas.fillText(text, x+1, y-1);
canvas.fillText(text, x+1, y+1);
canvas.fillStyle = style;
canvas.fillText(text, x, y);
ui.prototype.fillBoldText = function (name, text, style, x, y, font) {
var ctx = this.getContextByName(name);
if (!ctx) return;
if (core.isset(font)) ctx.font = font;
ctx.fillStyle = '#000000';
ctx.fillText(text, x-1, y-1);
ctx.fillText(text, x-1, y+1);
ctx.fillText(text, x+1, y-1);
ctx.fillText(text, x+1, y+1);
ctx.fillStyle = style;
ctx.fillText(text, x, y);
}
////// 在某个canvas上绘制一个矩形 //////
@ -94,12 +101,11 @@ ui.prototype.drawLine = function (name, x1, y1, x2, y2, style, lineWidth) {
core.setLineWidth(name, lineWidth);
}
var ctx = this.getContextByName(name);
if (ctx) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
if (!ctx) return;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
////// 在某个canvas上绘制一个箭头 //////
@ -112,18 +118,17 @@ ui.prototype.drawArrow = function (name, x1, y1, x2, y2, style, lineWidth) {
core.setLineWidth(name, lineWidth);
}
var ctx = this.getContextByName(name);
if (ctx) {
var head = 10;
var dx = x2-x1, dy=y2-y1;
var angle = Math.atan2(dy,dx);
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x2-head*Math.cos(angle-Math.PI/6),y2-head*Math.sin(angle-Math.PI/6));
ctx.moveTo(x2, y2);
ctx.lineTo(x2-head*Math.cos(angle+Math.PI/6),y2-head*Math.sin(angle+Math.PI/6));
ctx.stroke();
}
if (!ctx) return;
var head = 10;
var dx = x2-x1, dy=y2-y1;
var angle = Math.atan2(dy,dx);
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x2-head*Math.cos(angle-Math.PI/6),y2-head*Math.sin(angle-Math.PI/6));
ctx.moveTo(x2, y2);
ctx.lineTo(x2-head*Math.cos(angle+Math.PI/6),y2-head*Math.sin(angle+Math.PI/6));
ctx.stroke();
}
////// 设置某个canvas的文字字体 //////
@ -200,14 +205,17 @@ ui.prototype.drawImage = function (name, image, x, y, w, h, x1, y1, w1, h1) {
}
// 只能接受2, 4, 8个参数
if (core.isset(x) && core.isset(y) && core.isset(w) && core.isset(h) && core.isset(x1) && core.isset(y1) && core.isset(w1) && core.isset(h1)) {
ctx.drawImage(image, x, y, w, h, x1, y1, w1, h1);
}
else if (core.isset(x) && core.isset(y) && core.isset(w) && core.isset(h)) {
ctx.drawImage(image, x, y, w, h);
}
else if (core.isset(x) && core.isset(y)) {
if (core.isset(x) && core.isset(y)) {
if (core.isset(w) && core.isset(h)) {
if (core.isset(x1) && core.isset(y1) && core.isset(w1) && core.isset(h1)) {
ctx.drawImage(image, x, y, w, h, x1, y1, w1, h1);
return;
}
ctx.drawImage(image, x, y, w, h);
return;
}
ctx.drawImage(image, x, y);
return;
}
}
@ -424,13 +432,12 @@ ui.prototype.drawWindowSkin = function(background,canvas,x,y,w,h,direction,px,py
// 仿RM窗口皮肤 ↓
var dstImage = core.getContextByName(canvas);
if (!dstImage) return;
var dx = 0, dy = 0;
// 绘制背景
dstImage.drawImage(background, 0, 0, 128, 128, x+2, y+2, w-4, h-4);
// 绘制边框
// 上方
dstImage.drawImage(background, 128, 0, 16, 16, x, y, 16, 16);
for (dx = 0; dx < w - 64; dx += 32) {
for (var dx = 0; dx < w - 64; dx += 32) {
dstImage.drawImage(background, 144, 0, 32, 16,x+dx+16, y, 32, 16);
dstImage.drawImage(background, 144,48, 32, 16,x+dx+16, y+h-16, 32, 16);
}
@ -438,7 +445,7 @@ ui.prototype.drawWindowSkin = function(background,canvas,x,y,w,h,direction,px,py
dstImage.drawImage(background, 144,48,w-dx-32, 16,x+dx+16, y+h-16,w-dx-32, 16);
dstImage.drawImage(background, 176, 0, 16, 16, x+w-16, y, 16, 16);
// 左右
for (dy = 0; dy < h - 64; dy += 32) {
for (var dy = 0; dy < h - 64; dy += 32) {
dstImage.drawImage(background, 128,16, 16, 32, x,y+dy+16, 16, 32);
dstImage.drawImage(background, 176,16, 16, 32, x+w-16,y+dy+16, 16, 32);
}
@ -1478,7 +1485,7 @@ ui.prototype.drawReplay = function () {
ui.prototype.drawGameInfo = function () {
core.status.event.id = 'gameInfo';
this.drawChoices(null, [
"数据统计", "查看工程", "查看评论", "操作帮助", "关于本塔","下载离线版本", "返回主菜单"
"数据统计", "查看工程", "游戏主页", "操作帮助", "关于本塔","下载离线版本", "返回主菜单"
]);
}
@ -2499,16 +2506,37 @@ ui.prototype.drawKeyBoard = function () {
core.clearLastEvent();
var left = 16, top = 48, right = 416 - 2 * left, bottom = 416 - 2 * top;
core.fillRect('ui', left, top, right, bottom, core.material.groundPattern);
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
var left = 16, top = 48, width = 416 - 2 * left, height = 416 - 2 * top;
var background = core.status.textAttribute.background;
var isWindowSkin = false;
if (typeof background == 'string') {
background = core.material.images.images[background];
if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true;
else background = core.initStatus.textAttribute.background;
}
if (!isWindowSkin) background = core.arrayToRGBA(background);
var borderColor = core.status.globalAttribute.borderColor;
var titleColor = core.arrayToRGBA(core.status.textAttribute.title);
var textColor = core.arrayToRGBA(core.status.textAttribute.text);
core.clearMap('ui');
if (isWindowSkin) {
core.setAlpha('ui', 0.85);
this.drawWindowSkin(background,'ui',left,top,width,height);
}
else {
core.fillRect('ui', left, top, width, height, background);
core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, borderColor, 2);
}
core.setAlpha('ui', 1);
core.setTextAlign('ui', 'center');
var globalFont = core.status.globalAttribute.font;
core.fillText('ui', "虚拟键盘", 208, top+35, "#FFD700", "bold 22px "+globalFont);
core.fillText('ui', "虚拟键盘", 208, top+35, titleColor, "bold 22px "+globalFont);
core.setFont('ui', '17px '+globalFont);
core.setFillStyle('ui', '#FFFFFF');
core.setFillStyle('ui', textColor);
var offset = 128-9;
var lines = [
@ -2519,7 +2547,7 @@ ui.prototype.drawKeyBoard = function () {
["Z","X","C","V","B","N","M"],
["-","=","[","]","\\",";","'",",",".","/","`"],
["ES","TA","CA","SH","CT","AL","SP","BS","EN","DE"]
]
];
lines.forEach(function (line) {
for (var i=0;i<line.length;i++) {
@ -2528,9 +2556,12 @@ ui.prototype.drawKeyBoard = function () {
offset+=32;
});
core.setTextAlign('ui', 'center');
core.fillText("ui", "返回游戏", 416-80, offset-3, '#FFFFFF', 'bold 15px '+globalFont);
if (isWindowSkin)
this.drawWindowSelector(background, 300, offset - 22, 72, 27);
else
core.strokeRect('ui', 300, offset - 22, 72, 27, "#FFD700", 2);
}
////// 绘制状态栏 /////
@ -2580,7 +2611,7 @@ ui.prototype.drawStatistics = function () {
var current = core.clone(total);
core.floorIds.forEach(function (floorId) {
var floor=core.status.maps[floorId];
var floor=core.status.maps[floorId]||core.floors[floorId];
var blocks=core.status.maps[floorId].blocks;
// 隐藏层不给看
if (floor.cannotViewMap && floorId!=core.status.floorId) return;
@ -2605,14 +2636,12 @@ ui.prototype.drawStatistics = function () {
else {
var id = event.id;
var temp = core.clone(core.status.hero);
core.setFlag("__statistics__", true);
if (core.isset(total.count[id])) {
var hp=0, atk=0, def=0, mdef=0;
if (cls[id]=='items' && id!='superPotion') {
var temp = core.clone(core.status.hero);
core.setFlag("__statistics__", true);
var ratio = floor.item_ratio||1;
if (core.isset(core.items.itemEffect[id])) {
try {
@ -2625,6 +2654,7 @@ ui.prototype.drawStatistics = function () {
atk = core.status.hero.atk - temp.atk;
def = core.status.hero.def - temp.def;
mdef = core.status.hero.mdef - temp.mdef;
core.status.hero = temp;
}
else {
// 装备
@ -2644,7 +2674,6 @@ ui.prototype.drawStatistics = function () {
if (t!="") ext[id]=t;
}
core.status.hero = core.clone(temp);
total.count[id]++;
total.add.hp+=hp;
total.add.atk+=atk;
@ -2776,30 +2805,39 @@ ui.prototype.drawPaint = function () {
////// 绘制帮助页面 //////
ui.prototype.drawHelp = function () {
core.drawText([
"\t[键盘快捷键列表]"+
"[CTRL] 跳过对话 [Z] 转向\n" +
"[X] 怪物手册 [G] 楼层传送\n" +
"[A] 读取自动存档 [S/D] 存读档页面\n" +
"[K/V] 快捷商店 [ESC] 系统菜单\n" +
"[T] 道具页面 [Q] 装备页面\n" +
"[B] 数据统计 [H] 帮助页面\n" +
"[R] 回放录像 [E] 显示光标\n" +
"[SPACE] 轻按 [M] 绘图模式\n" +
"[N] 返回标题页面 [P] 查看评论区\n" +
"[O] 查看工程 [F7] 打开debug穿墙模式\n" +
"[PgUp/PgDn] 浏览地图\n"+
"[1~4] 快捷使用破炸飞和其他道具\n"+
"[Alt+0~9] 快捷换装",
"\t[鼠标操作]"+
"点状态栏中图标: 进行对应的操作\n"+
"点任意块: 寻路并移动\n"+
"点任意块并拖动: 指定寻路路线\n"+
"双击空地: 瞬间移动\n"+
"单击勇士: 转向\n"+
"双击勇士: 轻按(仅在轻按开关打开时有效)\n"+
"长按任意位置:跳过剧情对话或打开虚拟键盘"
]);
core.clearLastEvent();
if (core.material.images.keyboard) {
core.status.event.id = 'help';
core.lockControl();
core.setAlpha('ui', 1);
core.drawImage('ui', core.material.images.keyboard, 0, 0);
}
else {
core.drawText([
"\t[键盘快捷键列表]"+
"[CTRL] 跳过对话 [Z] 转向\n" +
"[X] 怪物手册 [G] 楼层传送\n" +
"[A] 读取自动存档 [S/D] 存读档页面\n" +
"[V] 快捷商店 [ESC] 系统菜单\n" +
"[T] 道具页面 [Q] 装备页面\n" +
"[B] 数据统计 [H] 帮助页面\n" +
"[R] 回放录像 [E] 显示光标\n" +
"[SPACE] 轻按 [M] 绘图模式\n" +
"[N] 返回标题页面 [P] 游戏主页\n" +
"[O] 查看工程 [F7] 打开debug穿墙模式\n" +
"[PgUp/PgDn] 浏览地图\n"+
"[1~4] 快捷使用破炸飞和其他道具\n"+
"[Alt+0~9] 快捷换装",
"\t[鼠标操作]"+
"点状态栏中图标: 进行对应的操作\n"+
"点任意块: 寻路并移动\n"+
"点任意块并拖动: 指定寻路路线\n"+
"双击空地: 瞬间移动\n"+
"单击勇士: 转向\n"+
"双击勇士: 轻按(仅在轻按开关打开时有效)\n"+
"长按任意位置:跳过剧情对话或打开虚拟键盘"
]);
}
}
////// 动态canvas //////

View File

@ -436,18 +436,17 @@ utils.prototype.decodeRoute = function (route) {
index++;
return str;
}
var mp = {
"U": "up",
"D": "down",
"L": "left",
"R": "right"
}
while (index<route.length) {
var c=route.charAt(index++);
var nxt=(c=='I'|| c=='e' ||c=='F'||c=='S'||c=='Q'||c=='t')?getString():getNumber();
var mp = {
"U": "up",
"D": "down",
"L": "left",
"R": "right"
}
switch (c) {
case "U": case "D": case "L": case "R": for (var i=0;i<nxt;i++) ans.push(mp[c]); break;
case "I": ans.push("item:"+nxt); break;
@ -639,6 +638,7 @@ utils.prototype.readFileContent = function (content) {
}
catch (e) {
console.log(e);
alert(e);
}
alert("不是有效的JSON文件");

View File

@ -27,7 +27,8 @@ main.floors.sample0=
"firstArrive": [
{
"type": "setText",
"background": "winskin.png"
"background": "winskin.png",
"time": 0
},
"\t[样板提示]首次到达某层可以触发 firstArrive 事件该事件可类似于RMXP中的“自动执行脚本”。\n\n本事件支持一切的事件类型常常用来触发对话例如",
"\t[hero]\b[up,hero]我是谁?我从哪来?我又要到哪去?",

View File

@ -703,7 +703,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
case 90: // Z转向
core.turnHero();
break;
case 75: case 86: // K/V打开快捷商店列表
case 86: // V打开快捷商店列表
core.openQuickShop(true);
break;
case 32: // SPACE轻按
@ -741,7 +741,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
case 79: // O查看工程
window.open(core.platform.isPC?"editor.html":"editor-mobile.html", "_blank");
break;
case 80: // P查看评论
case 80: // P游戏主页
window.open("/score.php?name="+core.firstData.name+"&num=10", "_blank");
break;
case 49: // 快捷键1: 破

BIN
project/images/keyboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -7,7 +7,7 @@
\r[red]可以动态调整剧情文本的颜色
升级事件改用事件编辑器完成
每层楼都增添该层的并行事件处理
新增快捷键N返回标题P查看评论O打开工程
新增快捷键N返回标题P游戏主页O打开工程
新增事件:设置全局属性或全局数值
新增事件:隐藏/显示状态栏
道具可以设置是否在回放时绘制道具栏或直接使用