Merge remote-tracking branch 'refs/remotes/origin/master' into 2.0-1.3-merge
# Conflicts: # drawMapGUI.html # libs/core.js # libs/data.js # libs/enemys.js # libs/maps.js # main.js
This commit is contained in:
commit
f6f4745b5d
@ -21,6 +21,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
|||||||
│ └─ *.png # 对应的某个具体的图片素材
|
│ └─ *.png # 对应的某个具体的图片素材
|
||||||
├── /libs/ # JS源代码目录
|
├── /libs/ # JS源代码目录
|
||||||
│ ├─ /floors/ # 剧本文件,记录了每个地图的数据和事件
|
│ ├─ /floors/ # 剧本文件,记录了每个地图的数据和事件
|
||||||
|
│ ├─ /thirdparty/ # 游戏所用到的第三方库文件
|
||||||
│ ├─ core.js # 系统核心文件
|
│ ├─ core.js # 系统核心文件
|
||||||
│ ├─ data.js # 记录了勇士的初始化信息、各个全局变量和全局Flag值
|
│ ├─ data.js # 记录了勇士的初始化信息、各个全局变量和全局Flag值
|
||||||
│ ├─ enemys.js # 记录了怪物的信息,包括怪物的数据和特殊属性、伤害计算公式、临界值计算等。
|
│ ├─ enemys.js # 记录了怪物的信息,包括怪物的数据和特殊属性、伤害计算公式、临界值计算等。
|
||||||
@ -44,9 +45,10 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
|||||||
|
|
||||||
## 更新说明
|
## 更新说明
|
||||||
|
|
||||||
### 2017.12.31 V1.3
|
### 2018.1.1 V1.3
|
||||||
|
|
||||||
* [x] 支持全键盘操作。
|
* [x] 支持全键盘操作。
|
||||||
|
* [x] 支持将某个图片作为某层的背景素材。
|
||||||
* [x] 便捷PS工具支持更改图片色相。
|
* [x] 便捷PS工具支持更改图片色相。
|
||||||
* [x] 支持经验升级(进阶/境界塔)。
|
* [x] 支持经验升级(进阶/境界塔)。
|
||||||
* [x] 打败怪物可以进行加点(加点塔)。
|
* [x] 打败怪物可以进行加点(加点塔)。
|
||||||
|
|||||||
297
_server/css/editor.css
Normal file
297
_server/css/editor.css
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
|
||||||
|
html,body,div,img{margin:0;padding:0;}
|
||||||
|
body{
|
||||||
|
font-family: Roboto,"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;;
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
}
|
||||||
|
/* ::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
} */
|
||||||
|
.main {
|
||||||
|
max-width: 100%;
|
||||||
|
min-height: 500px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
#left, #mid, #right{
|
||||||
|
border-radius: 2px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||||
|
}
|
||||||
|
#left{
|
||||||
|
position: absolute;
|
||||||
|
left: 5px;
|
||||||
|
top: 10px;
|
||||||
|
width: 435px;
|
||||||
|
height: 630px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#editArea{
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 70%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
/* padding: 10px 5px; */
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
#pout{
|
||||||
|
display: block;
|
||||||
|
width: 410px;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-left: 22px;
|
||||||
|
margin-top: 23px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 12.3px;
|
||||||
|
font-family: 'Lucida Console', Monaco, monospace;
|
||||||
|
white-space: pre;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
#editTip{
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
bottom:10px;
|
||||||
|
left: 10px;
|
||||||
|
}
|
||||||
|
#editArea p{
|
||||||
|
margin: 10px;
|
||||||
|
display: block;
|
||||||
|
width: 70%;
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
#editTip .btn{
|
||||||
|
float: right;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mid{
|
||||||
|
position: absolute;
|
||||||
|
left: 448px;
|
||||||
|
top: 10px;
|
||||||
|
width: 440px;
|
||||||
|
height: 630px;
|
||||||
|
}
|
||||||
|
.map {
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
top: 21px;
|
||||||
|
width: 416px;
|
||||||
|
height: 416px;
|
||||||
|
}
|
||||||
|
#mid .tools{
|
||||||
|
position: absolute;
|
||||||
|
width: 425px;
|
||||||
|
height: 180px;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
padding: 10px 5px;
|
||||||
|
margin-left: 8px;;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
#tip{
|
||||||
|
float: right;
|
||||||
|
width: 50%;
|
||||||
|
height: 95%;
|
||||||
|
padding: 5px 10px 10px 10px;
|
||||||
|
margin-right: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 14px;
|
||||||
|
}
|
||||||
|
.files {
|
||||||
|
width: 50%;
|
||||||
|
height: 120px;
|
||||||
|
/* padding: 10px; */
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
.input{
|
||||||
|
display: block;
|
||||||
|
max-width: 150px;
|
||||||
|
height: 20px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 10px;
|
||||||
|
color: #555;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
|
||||||
|
}
|
||||||
|
#bgSelect{
|
||||||
|
width: 50%;
|
||||||
|
height: 100px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
#bgSelect span{
|
||||||
|
/* display: block; */
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
#printOut{
|
||||||
|
margin-top: 10px;
|
||||||
|
height: 20px;
|
||||||
|
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
width: 80px;
|
||||||
|
border-radius: 2px;
|
||||||
|
line-height: 30px;
|
||||||
|
margin: 0;
|
||||||
|
min-width: 50px;
|
||||||
|
padding: 0 5px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
/* text-transform: uppercase; */
|
||||||
|
letter-spacing: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
border: 0;
|
||||||
|
background: rgba(158,158,158,.2);
|
||||||
|
box-shadow: 0 1px 1px 0 rgba(0,0,0,.14), 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 3px 0 rgba(0,0,0,.12);
|
||||||
|
color: #fff;
|
||||||
|
background-color: #26A69A;
|
||||||
|
}
|
||||||
|
.btn:hover {
|
||||||
|
background-color: #009688;
|
||||||
|
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||||
|
}
|
||||||
|
#right{
|
||||||
|
position: absolute;
|
||||||
|
left: 900px;
|
||||||
|
top: 10px;
|
||||||
|
width: 440px;
|
||||||
|
height: 630px;
|
||||||
|
/* border: 1px solid rgb(238, 13, 13); */
|
||||||
|
}
|
||||||
|
#iconLib{
|
||||||
|
position: absolute;
|
||||||
|
width: 435px;
|
||||||
|
height: 620px;
|
||||||
|
left: 5px;
|
||||||
|
top: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.gameCanvas {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
#dataSelection{
|
||||||
|
position: absolute;
|
||||||
|
/* top:0;
|
||||||
|
left:320px; */
|
||||||
|
z-index:75;
|
||||||
|
width:26px;
|
||||||
|
height:26px;
|
||||||
|
margin: 3px 0 0 3px;
|
||||||
|
padding:0;
|
||||||
|
/* display: none; */
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color:rgba(255, 255, 255, 0.0);
|
||||||
|
border: 1px solid #000;
|
||||||
|
box-shadow: 0 0 0 2px #fff,
|
||||||
|
0 0 0 3px #000;
|
||||||
|
}
|
||||||
|
.warnText{
|
||||||
|
color: #D50000;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.infoText{
|
||||||
|
color: #2196F3;
|
||||||
|
}
|
||||||
|
.successText{
|
||||||
|
color: #00897B
|
||||||
|
}
|
||||||
|
|
||||||
|
table, td {
|
||||||
|
border: 1px solid #fff;
|
||||||
|
color: #fff;
|
||||||
|
cursor:crosshair;
|
||||||
|
}
|
||||||
|
table.col{
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
table.col td{
|
||||||
|
background-color: #4DB6AC;
|
||||||
|
}
|
||||||
|
#arrColMark td{
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
#arrColMark {
|
||||||
|
top: 2px;
|
||||||
|
left: 36px;
|
||||||
|
width: 385px;
|
||||||
|
height: 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
#mapColMark {
|
||||||
|
top: 2px;
|
||||||
|
left: 19px;
|
||||||
|
width: 418px;
|
||||||
|
height: 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
#mapColMark td{
|
||||||
|
width: 29px;
|
||||||
|
}
|
||||||
|
#mapColMark td:hover .colBlock{
|
||||||
|
position: absolute;
|
||||||
|
top: 19px;
|
||||||
|
height: 416px;
|
||||||
|
width: 32px;
|
||||||
|
z-index: 100;
|
||||||
|
background-color: rgba(38,166,154,.5);
|
||||||
|
}
|
||||||
|
table.row{
|
||||||
|
position: relative;
|
||||||
|
text-align: right;
|
||||||
|
vertical-align:middle;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
table.row td{
|
||||||
|
background-color: #4C221B;
|
||||||
|
}
|
||||||
|
#arrRowMark{
|
||||||
|
top: 5px;
|
||||||
|
left: 2px;
|
||||||
|
width: 16px;
|
||||||
|
height: 262px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
#mapRowMark{
|
||||||
|
top: 1px;
|
||||||
|
left: 2px;
|
||||||
|
width: 16px;
|
||||||
|
height: 416px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
#mapRowMark td{
|
||||||
|
height: 29px;
|
||||||
|
}
|
||||||
|
#mapRowMark td:hover .rowBlock{
|
||||||
|
position: absolute;
|
||||||
|
left: 18px;
|
||||||
|
height: 32px;
|
||||||
|
width: 416px;
|
||||||
|
z-index: 100;
|
||||||
|
background-color: rgba(76,34,27,.5);
|
||||||
|
}
|
||||||
|
/* for vue dom */
|
||||||
|
[v-cloak] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
@ -187,7 +187,7 @@ var tip = new Vue({
|
|||||||
isClearBlock: false,
|
isClearBlock: false,
|
||||||
geneMapSuccess: false,
|
geneMapSuccess: false,
|
||||||
timer: null,
|
timer: null,
|
||||||
msgs: [ //分别编号1,2,3,4,5,6,7,8;奇数警告,偶数成功
|
msgs: [ //分别编号1,2,3,4,5,6,7,8,9,10;奇数警告,偶数成功
|
||||||
"当前未选择任何图块,请先在右边选择要画的图块!",
|
"当前未选择任何图块,请先在右边选择要画的图块!",
|
||||||
"生成地图成功!可点击复制按钮复制地图数组到剪切板",
|
"生成地图成功!可点击复制按钮复制地图数组到剪切板",
|
||||||
"生成失败! 地图中有未定义的图块,建议先用其他有效图块覆盖或点击清除地图!",
|
"生成失败! 地图中有未定义的图块,建议先用其他有效图块覆盖或点击清除地图!",
|
||||||
@ -195,7 +195,9 @@ var tip = new Vue({
|
|||||||
"复制失败!",
|
"复制失败!",
|
||||||
"复制成功!可直接粘贴到楼层文件的地图数组中。",
|
"复制成功!可直接粘贴到楼层文件的地图数组中。",
|
||||||
"复制失败!当前还没有数据",
|
"复制失败!当前还没有数据",
|
||||||
"修改成功!可点击复制按钮复制地图数组到剪切板"
|
"修改成功!可点击复制按钮复制地图数组到剪切板",
|
||||||
|
"选择背景图片失败!文件名格式错误或图片不存在!",
|
||||||
|
"更新背景图片成功!",
|
||||||
],
|
],
|
||||||
mapMsg: '',
|
mapMsg: '',
|
||||||
whichShow: 0,
|
whichShow: 0,
|
||||||
@ -255,12 +257,31 @@ var bgSelect = new Vue({
|
|||||||
el: '#bgSelect',
|
el: '#bgSelect',
|
||||||
data: {
|
data: {
|
||||||
bgs: {},
|
bgs: {},
|
||||||
selectedBg: 'ground'
|
selectedBg: 'ground',
|
||||||
|
imgname: ''
|
||||||
},
|
},
|
||||||
watch:{
|
watch:{
|
||||||
selectedBg: function(){
|
selectedBg: function(){
|
||||||
editor.bgY = this.bgs.indexOf(this.selectedBg);
|
editor.bgY = this.bgs.indexOf(this.selectedBg);
|
||||||
editor.drawMapBg();
|
editor.drawMapBg();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updatebg: function(){
|
||||||
|
tip.whichShow = 0;
|
||||||
|
var regx = /\S+\.(png|bmp|jpg|jpeg|gif)$/i;
|
||||||
|
if(regx.test(this.imgname)){
|
||||||
|
var url = 'images/'+this.imgname;
|
||||||
|
editor.loadImg(url).then(function(img){
|
||||||
|
editor.drawMapBg(img);
|
||||||
|
tip.whichShow = 10;
|
||||||
|
}).catch(function(err){
|
||||||
|
console.log(err);
|
||||||
|
tip.whichShow = 9;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
tip.whichShow = 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
37
docs/api.md
37
docs/api.md
@ -1,13 +1,44 @@
|
|||||||
# 附录:API列表
|
# 附录:API列表
|
||||||
|
|
||||||
|
?> 上次更新时间:* {docsify-updated} * 如不是最新版,请Ctrl+F5强制刷新缓存。
|
||||||
|
|
||||||
所有系统支持的API都列在了这里。所有可能被用到的API都在前面用\*标记。
|
所有系统支持的API都列在了这里。所有可能被用到的API都在前面用\*标记。
|
||||||
|
|
||||||
可以在chrome浏览器的控制台中(`ctrl+shift+I`,找到Console)中直接进行调用,以查看效果。
|
可以在chrome浏览器的控制台中(`ctrl+shift+I`,找到Console)中直接进行调用,以查看效果。
|
||||||
|
|
||||||
!> **`main.js`:游戏入口。所有其他JS文件都是被此文件加载。**
|
!> **`main.js`:游戏入口,所有其他JS文件都是被此文件加载。**
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
|
main.init // 初始化
|
||||||
|
main.loaderJs // 动态加载所有核心JS文件
|
||||||
|
main,loaderFloors // 动态加载所有楼层(剧本)
|
||||||
|
main.loadMod // 加载某一个JS文件
|
||||||
|
main.loadFloor // 加载某一个楼层
|
||||||
|
main.setMainTipsText // 加载过程提示
|
||||||
|
window.onresize // 窗口大小变化时
|
||||||
|
main.dom.body.onkeydown // 在界面上按下某按键时
|
||||||
|
main.dom.body.onkeydown // 在界面上放开某按键时
|
||||||
|
main.dom.body.onselectstart // 开始选择时
|
||||||
|
main.dom.data.onmousedown // 鼠标按下时
|
||||||
|
main.dom.data.onmousemove // 鼠标移动时
|
||||||
|
main.dom.data.onmouseup // 鼠标放开时
|
||||||
|
main.dom.data.onmousewheel // 鼠标滑轮滚动时
|
||||||
|
main.dom.data.ontouchstart // 手指在触摸屏开始触摸时
|
||||||
|
main.dom.data.ontouchmove // 手指在触摸屏上移动时
|
||||||
|
main.dom.data.ontouchend // 手指离开触摸屏时
|
||||||
|
main.statusBar.image.book.onclick // 点击状态栏中的怪物手册时
|
||||||
|
main.statusBar.image.fly.onclick // 点击状态栏中的楼层传送器时
|
||||||
|
main.statusBar.image.toolbox.onclick // 点击状态栏中的工具箱时
|
||||||
|
main.statusBar.image.shop.onclick // 点击状态栏中的快捷商店时
|
||||||
|
main.statusBar.image.save.onclick // 点击状态栏中的存档按钮时
|
||||||
|
main.statusBar.image.load.onclick // 点击状态栏中的读档按钮时
|
||||||
|
main.statusBar.image.settings.onclick // 点击状态栏中的系统菜单时
|
||||||
|
main.dom.playGame.onclick // 点击“开始游戏”时
|
||||||
|
main.dom.loadGame.onclick // 点击“载入游戏”时
|
||||||
|
main.dom.aboutGame.onclick // 点击“关于本塔”时
|
||||||
|
main.dom.easyLevel.onclick // 点击“简单难度”时
|
||||||
|
main.dom.normalLevel.onclick // 点击“普通难度”时
|
||||||
|
main.dom.hardLevel.onclick // 点击“困难难度”时
|
||||||
```
|
```
|
||||||
|
|
||||||
!> **`core.js`:系统核心文件。所有核心逻辑处理都在此文件完成。**
|
!> **`core.js`:系统核心文件。所有核心逻辑处理都在此文件完成。**
|
||||||
@ -97,7 +128,6 @@ core.setOpacity // 设置某个canvas的透明度
|
|||||||
core.setFillStyle // 设置某个canvas的绘制属性(如颜色等)
|
core.setFillStyle // 设置某个canvas的绘制属性(如颜色等)
|
||||||
* core.drawMap(mapId, callback) // 绘制某张地图。mapId为地图Id,绘制完毕将执行callback回调函数。
|
* core.drawMap(mapId, callback) // 绘制某张地图。mapId为地图Id,绘制完毕将执行callback回调函数。
|
||||||
core.drawAutotile // 绘制Autotile
|
core.drawAutotile // 绘制Autotile
|
||||||
core.drawAutotileBlock // 绘制Autotile的某一块
|
|
||||||
* core.noPassExists(x,y) // 某个点是否不可通行
|
* core.noPassExists(x,y) // 某个点是否不可通行
|
||||||
core.noPass // 某个点是否在区域内且不可通行
|
core.noPass // 某个点是否在区域内且不可通行
|
||||||
* core.npcExists(x,y) // 某个点是否存在NPC
|
* core.npcExists(x,y) // 某个点是否存在NPC
|
||||||
@ -291,6 +321,7 @@ core.maps.addChangeFloor // 向该楼层添加剧本的楼层转换事件
|
|||||||
core.maps.initMaps // 初始化所有地图
|
core.maps.initMaps // 初始化所有地图
|
||||||
core.maps.save // 将当前地图重新变成数字,以便于存档
|
core.maps.save // 将当前地图重新变成数字,以便于存档
|
||||||
core.maps.load // 将存档中的地图信息重新读取出来
|
core.maps.load // 将存档中的地图信息重新读取出来
|
||||||
|
core.maps.getMapArray // 将当前地图重新变成二维数组形式
|
||||||
```
|
```
|
||||||
|
|
||||||
!> `ui.js` 定义了各种界面的绘制。
|
!> `ui.js` 定义了各种界面的绘制。
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
# 元件说明
|
# 元件说明
|
||||||
|
|
||||||
|
?> 上次更新时间:* {docsify-updated} *
|
||||||
|
|
||||||
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
|
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
|
||||||
|
|
||||||
请打开样板0层 `sample0.js` 进行参照对比。
|
请打开样板0层 `sample0.js` 进行参照对比。
|
||||||
@ -70,6 +72,7 @@ enemys.prototype.getSpecialText = function (enemyId) {
|
|||||||
多属性可采用数组的写法,比如`'special': [1,3]`视为同时拥有先攻和坚固属性;`'special': [5,10,14,18]`视为拥有3连击、魔防、诅咒、阻击四个属性。
|
多属性可采用数组的写法,比如`'special': [1,3]`视为同时拥有先攻和坚固属性;`'special': [5,10,14,18]`视为拥有3连击、魔防、诅咒、阻击四个属性。
|
||||||
|
|
||||||
本塔支持战斗动画,在`data.js`中存在三个全局选项:`canOpenBattleAnimate`, `showBattleAnimateConfirm`, `battleAnimate`。
|
本塔支持战斗动画,在`data.js`中存在三个全局选项:`canOpenBattleAnimate`, `showBattleAnimateConfirm`, `battleAnimate`。
|
||||||
|
|
||||||
- `canOpenBattleAnimate`代表是否允许用户开启战斗动画。如果你添加了一些自定义属性,且不想修改战斗界面的UI,则可以将其关闭。
|
- `canOpenBattleAnimate`代表是否允许用户开启战斗动画。如果你添加了一些自定义属性,且不想修改战斗界面的UI,则可以将其关闭。
|
||||||
- `showBattleAnimateConfirm`代表是否在游戏开始时给用户提供开启动画的选项。对于一些偏向于萌新的塔,可以开启此项。
|
- `showBattleAnimateConfirm`代表是否在游戏开始时给用户提供开启动画的选项。对于一些偏向于萌新的塔,可以开启此项。
|
||||||
- `battleAnimate`代表是否默认开启战斗动画。此项会被用户存储的设置给覆盖。
|
- `battleAnimate`代表是否默认开启战斗动画。此项会被用户存储的设置给覆盖。
|
||||||
@ -117,7 +120,7 @@ N连击怪物的special是6,且我们可以为它定义n代表实际连击数
|
|||||||
|
|
||||||
如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。
|
如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。
|
||||||
|
|
||||||
### 路障,楼梯,传送门
|
## 路障,楼梯,传送门
|
||||||
|
|
||||||
血网的伤害数值、中毒后每步伤害数值、衰弱时暂时攻防下降的数值,都在 `data.js` 的values内定义。
|
血网的伤害数值、中毒后每步伤害数值、衰弱时暂时攻防下降的数值,都在 `data.js` 的values内定义。
|
||||||
|
|
||||||
@ -143,7 +146,7 @@ floorId指定的是目标楼层的唯一标识符(ID)。
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 背景音乐
|
## 背景音乐
|
||||||
|
|
||||||
本塔支持BGM和SE的播放。
|
本塔支持BGM和SE的播放。
|
||||||
|
|
||||||
@ -169,17 +172,19 @@ this.sounds = [ // 在此存放所有的SE,和文件名一致
|
|||||||
定义完毕后,我们可以调用`playBgm`/`playSound`事件来播放对应的音乐/音效,有关事件的详细介绍请参见[事件](event)。
|
定义完毕后,我们可以调用`playBgm`/`playSound`事件来播放对应的音乐/音效,有关事件的详细介绍请参见[事件](event)。
|
||||||
|
|
||||||
**另外,考虑到用户的流量问题,将遵循如下规则:**
|
**另外,考虑到用户的流量问题,将遵循如下规则:**
|
||||||
|
|
||||||
- **如果用户当前使用的电脑,则默认开启音乐效果,并播放默认BGM**
|
- **如果用户当前使用的电脑,则默认开启音乐效果,并播放默认BGM**
|
||||||
- **如果用户当前使用的手机,且处于Wifi状态,则默认开启音乐效果,并播放默认BGM**
|
- **如果用户当前使用的手机,且处于Wifi状态,则默认开启音乐效果,并播放默认BGM**
|
||||||
- **其他情况,将默认关闭音乐效果,只有在用户在菜单栏中点击“音乐开关”后才会播放音乐**
|
- **其他情况,将默认关闭音乐效果,只有在用户在菜单栏中点击“音乐开关”后才会播放音乐**
|
||||||
|
|
||||||
!> iOS平台以及部分浏览器不支持获得当前网络状态,此时即使在使用Wifi也必须要用户点击“音乐开关”才能播放音乐。
|
!> iOS平台以及部分浏览器不支持获得当前网络状态,此时即使在使用Wifi也必须要用户点击“音乐开关”才能播放音乐。
|
||||||
|
|
||||||
### 操作说明
|
## 操作说明
|
||||||
|
|
||||||
本塔主要支持鼠标(触摸屏)操作和键盘操作。
|
本塔主要支持鼠标(触摸屏)操作和键盘操作。
|
||||||
|
|
||||||
鼠标(触摸屏)操作说明如下:
|
鼠标(触摸屏)操作说明如下:
|
||||||
|
|
||||||
- **点状态栏中图标:** 进行对应的操作
|
- **点状态栏中图标:** 进行对应的操作
|
||||||
- **点任意块:** 寻路并移动
|
- **点任意块:** 寻路并移动
|
||||||
- **点任意块并拖动:** 指定寻路路线
|
- **点任意块并拖动:** 指定寻路路线
|
||||||
@ -187,6 +192,7 @@ this.sounds = [ // 在此存放所有的SE,和文件名一致
|
|||||||
- **双击勇士:** 轻按(仅在轻按开关打开时有效)
|
- **双击勇士:** 轻按(仅在轻按开关打开时有效)
|
||||||
|
|
||||||
键盘操作快捷键如下:
|
键盘操作快捷键如下:
|
||||||
|
|
||||||
- **[CTRL]** 跳过对话
|
- **[CTRL]** 跳过对话
|
||||||
- **[X]** 打开/关闭怪物手册
|
- **[X]** 打开/关闭怪物手册
|
||||||
- **[G]** 打开/关闭楼层传送器
|
- **[G]** 打开/关闭楼层传送器
|
||||||
@ -213,4 +219,3 @@ this.sounds = [ // 在此存放所有的SE,和文件名一致
|
|||||||
==========================================================================================
|
==========================================================================================
|
||||||
|
|
||||||
[继续阅读下一章:事件](event)
|
[继续阅读下一章:事件](event)
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
# 事件
|
# 事件
|
||||||
|
|
||||||
|
?> 上次更新时间:* {docsify-updated} *
|
||||||
|
|
||||||
本章内将对样板所支持的事件进行介绍。
|
本章内将对样板所支持的事件进行介绍。
|
||||||
|
|
||||||
## 事件的机制
|
## 事件的机制
|
||||||
@ -29,6 +31,7 @@
|
|||||||
"x,y": {
|
"x,y": {
|
||||||
"trigger": "action", // 触发的trigger, action代表自定义事件
|
"trigger": "action", // 触发的trigger, action代表自定义事件
|
||||||
"enable": true, // 该事件初始状态下是否处于启用状态
|
"enable": true, // 该事件初始状态下是否处于启用状态
|
||||||
|
"noPass": true, // 该点是否不可通行。true代表不可通行,false代表可通行。
|
||||||
"data": [ // 实际执行的事件列表
|
"data": [ // 实际执行的事件列表
|
||||||
// 事件1
|
// 事件1
|
||||||
// 事件2
|
// 事件2
|
||||||
@ -53,6 +56,7 @@
|
|||||||
"x,y": {
|
"x,y": {
|
||||||
// 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略
|
// 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略
|
||||||
"enable": true, // 该事件初始状态下是否处于启用状态
|
"enable": true, // 该事件初始状态下是否处于启用状态
|
||||||
|
"noPass": true, // 该点是否不可通行。true代表不可通行,false代表可通行。
|
||||||
"data": [ // 实际执行的事件列表
|
"data": [ // 实际执行的事件列表
|
||||||
// 事件1
|
// 事件1
|
||||||
// 事件2
|
// 事件2
|
||||||
@ -71,6 +75,28 @@
|
|||||||
"x,y": {
|
"x,y": {
|
||||||
// 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略
|
// 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略
|
||||||
// 该事件初始状态下是启用状态,则可以省略"enable": true;如果是禁用状态则必须加上"enable": false
|
// 该事件初始状态下是启用状态,则可以省略"enable": true;如果是禁用状态则必须加上"enable": false
|
||||||
|
"noPass": true, // 该点是否不可通行。true代表不可通行,false代表可通行。
|
||||||
|
"data": [ // 实际执行的事件列表
|
||||||
|
// 事件1
|
||||||
|
// 事件2
|
||||||
|
// ...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`"noPass"`为该点是否可通行的标记。`true`代表该点不可通行,`false`代表该点可通行。
|
||||||
|
|
||||||
|
对于目前所有的素材,都存在默认的是否可通行状态。如果你在该点指定`noPass`,则原本的可通行状态会被覆盖。
|
||||||
|
|
||||||
|
因此,除非你想覆盖默认的可通行选项(比如将一个空地设为不可通行),否则该项可以忽略。
|
||||||
|
|
||||||
|
``` js
|
||||||
|
"events": { // 该楼的所有可能事件列表
|
||||||
|
"x,y": {
|
||||||
|
// 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略
|
||||||
|
// 该事件初始状态下是启用状态,则可以省略"enable": true;如果是禁用状态则必须加上"enable": false
|
||||||
|
// 除非你想覆盖系统默认的可通行状态,否则"noPass"项可以忽略
|
||||||
"data": [ // 实际执行的事件列表
|
"data": [ // 实际执行的事件列表
|
||||||
// 事件1
|
// 事件1
|
||||||
// 事件2
|
// 事件2
|
||||||
@ -86,7 +112,7 @@
|
|||||||
|
|
||||||
``` js
|
``` js
|
||||||
"events": { // 该楼的所有可能事件列表
|
"events": { // 该楼的所有可能事件列表
|
||||||
// 如果大括号里只有"data"项(没有"action"或"enable"),则可以省略到只剩下中括号
|
// 如果大括号里只有"data"项(没有"action", "enable"或"noPass"),则可以省略到只剩下中括号
|
||||||
"x,y": [ // 实际执行的事件列表
|
"x,y": [ // 实际执行的事件列表
|
||||||
// 事件1
|
// 事件1
|
||||||
// 事件2
|
// 事件2
|
||||||
@ -97,7 +123,7 @@
|
|||||||
|
|
||||||
这种简写方式可以极大方便地造塔者进行造塔。
|
这种简写方式可以极大方便地造塔者进行造塔。
|
||||||
|
|
||||||
!> **请注意:如果该点初始的`enable`为`false`,或者该点本身有系统默认事件且需要覆盖(`trigger`),则必须采用上面那种大括号写的方式来定义。**
|
!> **请注意:如果该点初始的`enable`为`false`,或者该点本身有系统默认事件且需要覆盖(`trigger`),或者你想覆盖该点的默认通行状态,则必须采用上面那种大括号写的方式来定义。**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -941,6 +967,26 @@ events.prototype.addPoint = function (enemy) {
|
|||||||
|
|
||||||
当且仅当勇士第一次到达某层时,将会触发此事件。可以利用此事件来显示一些剧情,或再让它调用 `{"type": "trigger"}` 来继续调用其他的事件。
|
当且仅当勇士第一次到达某层时,将会触发此事件。可以利用此事件来显示一些剧情,或再让它调用 `{"type": "trigger"}` 来继续调用其他的事件。
|
||||||
|
|
||||||
|
## 战前剧情
|
||||||
|
|
||||||
|
有时候光战后事件`afterBattle`是不够的,我们可能还需要战前剧情,例如Boss战之前和Boss进行一段对话。
|
||||||
|
|
||||||
|
要使用战前剧情,首先你需要覆盖该店的系统默认事件,改成你自己的自定义事件,然后在战前剧情后调用`{"type": "battle"}`强制战斗。
|
||||||
|
|
||||||
|
值得注意的是,使用这种自定义事件来覆盖系统的默认战斗事件时,可以增加`displayDamage`代表该点是否需要显伤。此项可省略,默认为有显伤。
|
||||||
|
|
||||||
|
``` js
|
||||||
|
"x,y": { // (x,y)为该怪物坐标
|
||||||
|
"trigger": "action", // 覆盖该点本身默认事件,变成自定义事件
|
||||||
|
"displayDamage": true, // 覆盖后,该点是否有显伤;此项可忽略,默认为有。
|
||||||
|
"data": [ // 该点的自定义事件列表
|
||||||
|
// ... 战前剧情
|
||||||
|
{"type": "battle", "id": "xxx"}, // 强制战斗
|
||||||
|
// ... 战后剧情;请注意上面的强制战斗不会使怪物消失,如有需要请调动{"type": "hide"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 经验升级(进阶/境界塔)
|
## 经验升级(进阶/境界塔)
|
||||||
|
|
||||||
本塔也支持经验升级,即用户杀怪获得经验后,可以到达某些数值自动进阶,全面提升属性。
|
本塔也支持经验升级,即用户杀怪获得经验后,可以到达某些数值自动进阶,全面提升属性。
|
||||||
@ -1015,9 +1061,8 @@ events.prototype.setInitData = function (hard) {
|
|||||||
当获胜`{"type": "win"}`事件发生时,将调用`events.js`中的win事件。其显示一段恭喜文字,并重新开始游戏。
|
当获胜`{"type": "win"}`事件发生时,将调用`events.js`中的win事件。其显示一段恭喜文字,并重新开始游戏。
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
////// 游戏结束事件 //////
|
////// 游戏获胜事件 //////
|
||||||
events.prototype.win = function(reason) {
|
events.prototype.win = function(reason) {
|
||||||
// 获胜
|
|
||||||
core.waitHeroToStop(function() {
|
core.waitHeroToStop(function() {
|
||||||
core.removeGlobalAnimate(0,0,true);
|
core.removeGlobalAnimate(0,0,true);
|
||||||
core.clearMap('all'); // 清空全地图
|
core.clearMap('all'); // 清空全地图
|
||||||
@ -1035,8 +1080,8 @@ events.prototype.win = function(reason) {
|
|||||||
当失败(`{"type": "lose"}`,或者被怪强制战斗打死、被领域怪扣血死、中毒导致扣血死,路障导致扣血死等等)事件发生时,将调用`events.js`中的`lose`事件。其直接显示一段文字,并重新开始游戏。
|
当失败(`{"type": "lose"}`,或者被怪强制战斗打死、被领域怪扣血死、中毒导致扣血死,路障导致扣血死等等)事件发生时,将调用`events.js`中的`lose`事件。其直接显示一段文字,并重新开始游戏。
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
|
////// 游戏失败事件 //////
|
||||||
events.prototype.lose = function(reason) {
|
events.prototype.lose = function(reason) {
|
||||||
// 失败
|
|
||||||
core.waitHeroToStop(function() {
|
core.waitHeroToStop(function() {
|
||||||
core.drawText([
|
core.drawText([
|
||||||
"\t[结局1]你死了。\n如题。"
|
"\t[结局1]你死了。\n如题。"
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
<link rel="shortcut icon" type="image/png" href="./img/logo.png">
|
<link rel="shortcut icon" type="image/png" href="./img/logo.png">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
<meta name="description" content="Description">
|
<meta name="description" content="Description">
|
||||||
|
<meta http-equiv="cache-control" content="no-cache">
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
<link href="https://cdn.bootcss.com/docsify/4.5.5/themes/vue.css" rel="stylesheet">
|
<link href="https://cdn.bootcss.com/docsify/4.5.5/themes/vue.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
@ -37,8 +38,10 @@
|
|||||||
loadSidebar: '_sidebar.md',
|
loadSidebar: '_sidebar.md',
|
||||||
subMaxLevel: 2,
|
subMaxLevel: 2,
|
||||||
autoHeader: true,
|
autoHeader: true,
|
||||||
|
auto2top: true,
|
||||||
|
mergeNavbar: true,
|
||||||
|
formatUpdated: '{YYYY}-{MM}-{DD} {HH}:{mm}:{ss}',
|
||||||
}
|
}
|
||||||
//离线模式
|
|
||||||
if (typeof navigator.serviceWorker !== 'undefined') {
|
if (typeof navigator.serviceWorker !== 'undefined') {
|
||||||
navigator.serviceWorker.register('serviceWorker.js')
|
navigator.serviceWorker.register('serviceWorker.js')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
# HTML5 魔塔样板说明文档
|
# HTML5 魔塔样板说明文档
|
||||||
|
|
||||||
|
?> 上次更新时间:* {docsify-updated} *
|
||||||
|
|
||||||
众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。
|
众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。
|
||||||
|
|
||||||
但是,现在我们有了HTML5。 HTML5的画布(canvas)以及它被Android/iOS内置浏览器所支持的特性,可以让我们做出真正意义上的全平台覆盖的魔塔。
|
但是,现在我们有了HTML5。 HTML5的画布(canvas)以及它被Android/iOS内置浏览器所支持的特性,可以让我们做出真正意义上的全平台覆盖的魔塔。
|
||||||
@ -11,7 +13,7 @@
|
|||||||
|
|
||||||
继续查看文档的详细介绍,让你学会如何使用这一个样板来制作属于自己的HTML5魔塔。
|
继续查看文档的详细介绍,让你学会如何使用这一个样板来制作属于自己的HTML5魔塔。
|
||||||
|
|
||||||
视频教程地址:http://www.bilibili.com/video/av17608025/ ,配合本教程观看效果更佳~
|
视频教程地址:[http://www.bilibili.com/video/av17608025/](http://www.bilibili.com/video/av17608025/) ,配合本教程观看效果更佳~
|
||||||
|
|
||||||
==========================================================================================
|
==========================================================================================
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
# 个性化
|
# 个性化
|
||||||
|
|
||||||
|
?> 上次更新时间:* {docsify-updated} *
|
||||||
|
|
||||||
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
|
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
|
||||||
|
|
||||||
## 自定义素材
|
## 自定义素材
|
||||||
@ -21,6 +23,41 @@
|
|||||||
|
|
||||||
如果你需要某个素材已经存在,则可以直接将其覆盖images目录下的同名文件,就能看到效果。
|
如果你需要某个素材已经存在,则可以直接将其覆盖images目录下的同名文件,就能看到效果。
|
||||||
|
|
||||||
|
### 使用自己的图片作为某层楼的背景素材
|
||||||
|
|
||||||
|
由于HTML5功能(素材)有限,导致了对很多比较复杂的素材(比如房子内)等无法有着较好的绘图方式。
|
||||||
|
|
||||||
|
为了解决这个问题,我们允许用户自己放置一张图片作为某一层的背景素材。
|
||||||
|
|
||||||
|
要启用这个功能,我们首先需要在`main.js`中将可能的图片进行加载。
|
||||||
|
|
||||||
|
``` js
|
||||||
|
this.pngs = [ // 在此存放所有可能的背景图片;背景图片最好是416*416像素,其他分辨率会被强制缩放成416*416
|
||||||
|
// 建议对于较大的图片,在网上使用在线的“图片压缩工具”来进行压缩,以节省流量
|
||||||
|
"bg.png", // "yewai.png",
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
!> 背景素材只支持png格式,且会被强制缩放到416*416。
|
||||||
|
|
||||||
|
!> 请使用网上的一些[在线图片压缩工具](http://www.asqql.com/gifzip/)对png图片进行压缩,以节省流量。一张500KB的png图片可以被压缩到20-30KB,显示效果不会有太大差异。
|
||||||
|
|
||||||
|
之后,我们可以在每层剧本的`"png": "xxx"`里来定义该层的默认背景图片素材。
|
||||||
|
|
||||||
|
``` js
|
||||||
|
"png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。
|
||||||
|
```
|
||||||
|
|
||||||
|
你的图片背景素材将会覆盖原来本身的背景层。
|
||||||
|
|
||||||
|
**如果你需要让某些点不可通行(比如你建了个房子,墙壁和家具等位置不让通行),则需在`events`中指定`{"noPass": false}`,参见[自定义事件](event#自定义事件)的写法。
|
||||||
|
|
||||||
|
``` js
|
||||||
|
"events": {
|
||||||
|
"x,y": {"noPass": true} // (x,y)点不可通行
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### 使用便捷PS工具生成素材
|
### 使用便捷PS工具生成素材
|
||||||
|
|
||||||
如果我们有更多的素材要求,我们可以使用“便捷PS工具”进行处理。
|
如果我们有更多的素材要求,我们可以使用“便捷PS工具”进行处理。
|
||||||
@ -52,7 +89,6 @@
|
|||||||
|
|
||||||
如果需要添加一个素材到游戏,则必须为其分配一个唯一标识符,并同时修改`icons.js`和`maps.js`两个文件。
|
如果需要添加一个素材到游戏,则必须为其分配一个唯一标识符,并同时修改`icons.js`和`maps.js`两个文件。
|
||||||
|
|
||||||
|
|
||||||
#### 新添加自定义地形(路面、墙壁等)
|
#### 新添加自定义地形(路面、墙壁等)
|
||||||
|
|
||||||
如果你在terrains.png中新增了一行:
|
如果你在terrains.png中新增了一行:
|
||||||
|
|||||||
@ -3,7 +3,7 @@ const HOSTNAME_WHITELIST = [
|
|||||||
self.location.hostname,
|
self.location.hostname,
|
||||||
'fonts.gstatic.com',
|
'fonts.gstatic.com',
|
||||||
'fonts.googleapis.com',
|
'fonts.googleapis.com',
|
||||||
'unpkg.com'
|
'cdn.bootcss.com'
|
||||||
]
|
]
|
||||||
|
|
||||||
// The Util Function to hack URLs of intercepted requests
|
// The Util Function to hack URLs of intercepted requests
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
# 快速上手
|
# 快速上手
|
||||||
|
|
||||||
|
?> 上次更新时间:* {docsify-updated} *
|
||||||
|
|
||||||
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
|
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
|
||||||
|
|
||||||
## 前置需求
|
## 前置需求
|
||||||
@ -9,7 +11,7 @@
|
|||||||
- Windows 8以上操作系统;Windows 7需要安装.Net Framework 4.0。(能打开同目录下的“启动服务.exe”即可)
|
- Windows 8以上操作系统;Windows 7需要安装.Net Framework 4.0。(能打开同目录下的“启动服务.exe”即可)
|
||||||
- 任一款现代浏览器。强烈推荐Chrome。
|
- 任一款现代浏览器。强烈推荐Chrome。
|
||||||
- 一个很好的文本编辑器。推荐带有高亮染色、错误提示等效果。例如:WebStorm,VSCode,或者至少也要Sublime Text。
|
- 一个很好的文本编辑器。推荐带有高亮染色、错误提示等效果。例如:WebStorm,VSCode,或者至少也要Sublime Text。
|
||||||
([VSCode下载地址](https://code.visualstudio.com/),群里的群文件中也有,强烈推荐之。)
|
- ([VSCode下载地址](https://code.visualstudio.com/),群里的群文件中也有,强烈推荐之。)
|
||||||
|
|
||||||
只要满足了上述条件,你就可以开始做自己的塔啦!
|
只要满足了上述条件,你就可以开始做自己的塔啦!
|
||||||
|
|
||||||
|
|||||||
326
drawMapGUI.html
326
drawMapGUI.html
@ -2,304 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<style>
|
<link href="_server/css/editor.css" rel="stylesheet">
|
||||||
html,body,div,img{margin:0;padding:0;}
|
|
||||||
body{
|
|
||||||
font-family: Roboto,"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;;
|
|
||||||
background-color: #F5F5F5;
|
|
||||||
}
|
|
||||||
/* ::-webkit-scrollbar {
|
|
||||||
width: 5px;
|
|
||||||
} */
|
|
||||||
.main {
|
|
||||||
max-width: 100%;
|
|
||||||
min-height: 500px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
#left, #mid, #right{
|
|
||||||
border-radius: 2px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
|
|
||||||
}
|
|
||||||
#left{
|
|
||||||
position: absolute;
|
|
||||||
left: 5px;
|
|
||||||
top: 10px;
|
|
||||||
width: 435px;
|
|
||||||
height: 630px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editArea{
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 70%;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
/* padding: 10px 5px; */
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
#pout{
|
|
||||||
display: block;
|
|
||||||
width: 410px;
|
|
||||||
height: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin-left: 22px;
|
|
||||||
margin-top: 23px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: 12.3px;
|
|
||||||
font-family: 'Lucida Console', Monaco, monospace;
|
|
||||||
white-space: pre;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
#editTip{
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 80px;
|
|
||||||
bottom:10px;
|
|
||||||
left: 10px;
|
|
||||||
}
|
|
||||||
#editArea p{
|
|
||||||
margin: 10px;
|
|
||||||
display: block;
|
|
||||||
width: 70%;
|
|
||||||
line-height: 20px;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
#editTip .btn{
|
|
||||||
float: right;
|
|
||||||
margin-right: 20px;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mid{
|
|
||||||
position: absolute;
|
|
||||||
left: 448px;
|
|
||||||
top: 10px;
|
|
||||||
width: 440px;
|
|
||||||
height: 630px;
|
|
||||||
}
|
|
||||||
.map {
|
|
||||||
position: absolute;
|
|
||||||
left: 20px;
|
|
||||||
top: 21px;
|
|
||||||
width: 416px;
|
|
||||||
height: 416px;
|
|
||||||
}
|
|
||||||
#mid .tools{
|
|
||||||
position: absolute;
|
|
||||||
width: 425px;
|
|
||||||
height: 180px;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
border-top: 1px solid #ccc;
|
|
||||||
padding: 10px 5px;
|
|
||||||
margin-left: 8px;;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
#tip{
|
|
||||||
float: right;
|
|
||||||
width: 50%;
|
|
||||||
height: 95%;
|
|
||||||
padding: 5px 10px 10px 10px;
|
|
||||||
margin-right: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-radius: 2px;
|
|
||||||
font-size: 15px;
|
|
||||||
line-height: 14px;
|
|
||||||
}
|
|
||||||
.files {
|
|
||||||
width: 50%;
|
|
||||||
height: 120px;
|
|
||||||
/* padding: 10px; */
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
.files .input{
|
|
||||||
display: block;
|
|
||||||
max-width: 150px;
|
|
||||||
height: 20px;
|
|
||||||
padding: 6px 12px;
|
|
||||||
font-size: 14px;
|
|
||||||
margin-top: 10px;
|
|
||||||
color: #555;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-radius: 3px;
|
|
||||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
|
|
||||||
}
|
|
||||||
#bgSelect{
|
|
||||||
width: 50%;
|
|
||||||
height: 100px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
#bgSelect span{
|
|
||||||
display: block;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
|
||||||
#printOut{
|
|
||||||
margin-top: 10px;
|
|
||||||
height: 20px;
|
|
||||||
|
|
||||||
}
|
|
||||||
.btn {
|
|
||||||
width: 80px;
|
|
||||||
border-radius: 2px;
|
|
||||||
line-height: 30px;
|
|
||||||
margin: 0;
|
|
||||||
min-width: 50px;
|
|
||||||
padding: 0 5px;
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 400;
|
|
||||||
/* text-transform: uppercase; */
|
|
||||||
letter-spacing: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: none;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
border: 0;
|
|
||||||
background: rgba(158,158,158,.2);
|
|
||||||
box-shadow: 0 1px 1px 0 rgba(0,0,0,.14), 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 3px 0 rgba(0,0,0,.12);
|
|
||||||
color: #fff;
|
|
||||||
background-color: #26A69A;
|
|
||||||
}
|
|
||||||
.btn:hover {
|
|
||||||
background-color: #009688;
|
|
||||||
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
|
|
||||||
}
|
|
||||||
#right{
|
|
||||||
position: absolute;
|
|
||||||
left: 900px;
|
|
||||||
top: 10px;
|
|
||||||
width: 440px;
|
|
||||||
height: 630px;
|
|
||||||
/* border: 1px solid rgb(238, 13, 13); */
|
|
||||||
}
|
|
||||||
#iconLib{
|
|
||||||
position: absolute;
|
|
||||||
width: 435px;
|
|
||||||
height: 620px;
|
|
||||||
left: 5px;
|
|
||||||
top: 5px;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
.gameCanvas {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
#dataSelection{
|
|
||||||
position: absolute;
|
|
||||||
/* top:0;
|
|
||||||
left:320px; */
|
|
||||||
z-index:75;
|
|
||||||
width:26px;
|
|
||||||
height:26px;
|
|
||||||
margin: 3px 0 0 3px;
|
|
||||||
padding:0;
|
|
||||||
/* display: none; */
|
|
||||||
box-sizing: border-box;
|
|
||||||
background-color:rgba(255, 255, 255, 0.0);
|
|
||||||
border: 1px solid #000;
|
|
||||||
box-shadow: 0 0 0 2px #fff,
|
|
||||||
0 0 0 3px #000;
|
|
||||||
}
|
|
||||||
.warnText{
|
|
||||||
color: #D50000;
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.infoText{
|
|
||||||
color: #2196F3;
|
|
||||||
}
|
|
||||||
.successText{
|
|
||||||
color: #00897B
|
|
||||||
}
|
|
||||||
|
|
||||||
table, td {
|
|
||||||
border: 1px solid #fff;
|
|
||||||
color: #fff;
|
|
||||||
cursor:crosshair;
|
|
||||||
}
|
|
||||||
table.col{
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
text-align: center;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
table.col td{
|
|
||||||
background-color: #4DB6AC;
|
|
||||||
}
|
|
||||||
#arrColMark td{
|
|
||||||
width: 16px;
|
|
||||||
}
|
|
||||||
#arrColMark {
|
|
||||||
top: 2px;
|
|
||||||
left: 36px;
|
|
||||||
width: 385px;
|
|
||||||
height: 16px;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
#mapColMark {
|
|
||||||
top: 2px;
|
|
||||||
left: 19px;
|
|
||||||
width: 418px;
|
|
||||||
height: 16px;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
#mapColMark td{
|
|
||||||
width: 29px;
|
|
||||||
}
|
|
||||||
#mapColMark td:hover .colBlock{
|
|
||||||
position: absolute;
|
|
||||||
top: 19px;
|
|
||||||
height: 416px;
|
|
||||||
width: 32px;
|
|
||||||
z-index: 100;
|
|
||||||
background-color: rgba(38,166,154,.5);
|
|
||||||
}
|
|
||||||
table.row{
|
|
||||||
position: relative;
|
|
||||||
text-align: right;
|
|
||||||
vertical-align:middle;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
table.row td{
|
|
||||||
background-color: #4C221B;
|
|
||||||
}
|
|
||||||
#arrRowMark{
|
|
||||||
top: 5px;
|
|
||||||
left: 2px;
|
|
||||||
width: 16px;
|
|
||||||
height: 262px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
#mapRowMark{
|
|
||||||
top: 1px;
|
|
||||||
left: 2px;
|
|
||||||
width: 16px;
|
|
||||||
height: 416px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
#mapRowMark td{
|
|
||||||
height: 29px;
|
|
||||||
}
|
|
||||||
#mapRowMark td:hover .rowBlock{
|
|
||||||
position: absolute;
|
|
||||||
left: 18px;
|
|
||||||
height: 32px;
|
|
||||||
width: 416px;
|
|
||||||
z-index: 100;
|
|
||||||
background-color: rgba(76,34,27,.5);
|
|
||||||
}
|
|
||||||
/* for vue dom */
|
|
||||||
[v-cloak] {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
@ -349,14 +52,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<input class='btn' id='clear' type="button" value="清除地图" v-on:click="clearMap"/>
|
<input class='btn' id='clear' type="button" value="清除地图" v-on:click="clearMap"/>
|
||||||
<input class='btn' type="button" value="导出地图" id="exportM" v-on:click="exportMap"/>
|
<input class='btn' type="button" value="导出地图" id="exportM" v-on:click="exportMap"/>
|
||||||
|
|
||||||
<div id="bgSelect" v-cloak>
|
<div id="bgSelect" v-cloak>
|
||||||
|
<span>当前地板: </span>
|
||||||
<select v-model="selectedBg">
|
<select v-model="selectedBg">
|
||||||
<option disabled value="">请选择地板</option>
|
<option disabled value="">请选择地板</option>
|
||||||
<option v-for="bg in bgs" v-bind:value="bg">
|
<option v-for="bg in bgs" v-bind:value="bg">
|
||||||
{{ bg }}
|
{{ bg }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<span>当前地板: {{ selectedBg }}</span>
|
<div class="selectpng">
|
||||||
|
<input class='input' id='pin' v-model="imgname" placeholder="请输入自定义背景文件名"/>
|
||||||
|
<input class='btn' type="button" value="确定" v-on:click="updatebg"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -496,15 +204,10 @@
|
|||||||
<script src='_server/vm.js'></script>
|
<script src='_server/vm.js'></script>
|
||||||
<script id='mainScript' src='main.js'></script>
|
<script id='mainScript' src='main.js'></script>
|
||||||
<script>
|
<script>
|
||||||
printf = function(str,weak) {
|
|
||||||
var prefix='<span class="result">',postfix='</span>';
|
|
||||||
if (weak){prefix='<span class="weakresult">';}
|
|
||||||
if (typeof(str)==="undefined")str='';
|
|
||||||
printOut.innerHTML=prefix+String(str)+postfix;
|
|
||||||
}
|
|
||||||
//所有全局量
|
//所有全局量
|
||||||
__all__=['Vue','fs','printf','editor','main','core','fullX','fullY'];
|
__all__=['Vue','fs','printf','editor','main','core'];
|
||||||
__id__=['printOut','arrRowMark','mapRowMark','edata','bg','dataSelection'];
|
__id__=['printOut','arrRowMark','mapRowMark','data','bg','dataSelection'];
|
||||||
__Vue__=['exportM','editArea','editTip','clear','tip','selectBox'];
|
__Vue__=['exportM','editArea','editTip','clear','tip','selectBox'];
|
||||||
//var event = document.getElementById('event');
|
//var event = document.getElementById('event');
|
||||||
|
|
||||||
@ -533,7 +236,7 @@ editor.prototype.init = function(callback){
|
|||||||
}
|
}
|
||||||
|
|
||||||
editor.prototype.idsInit = function(maps, icons){
|
editor.prototype.idsInit = function(maps, icons){
|
||||||
editor.ids = [];
|
editor.ids = [0];
|
||||||
editor.indexs = [];
|
editor.indexs = [];
|
||||||
var MAX_NUM = 400;
|
var MAX_NUM = 400;
|
||||||
var getInfoById = function(id){
|
var getInfoById = function(id){
|
||||||
@ -632,7 +335,7 @@ editor.prototype.mapInit = function(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
editor.prototype.drawMapBg = function(){
|
editor.prototype.drawMapBg = function(img){
|
||||||
var bgc = bg.getContext('2d');
|
var bgc = bg.getContext('2d');
|
||||||
if (editor.bgY == 0){
|
if (editor.bgY == 0){
|
||||||
editor.main.editor.drawMapBg();
|
editor.main.editor.drawMapBg();
|
||||||
@ -644,10 +347,13 @@ editor.prototype.drawMapBg = function(){
|
|||||||
bgc.clearRect(ii*32, jj*32, 32, 32);
|
bgc.clearRect(ii*32, jj*32, 32, 32);
|
||||||
bgc.drawImage(editor.material.images['terrains'], 0, 32*(editor.bgY||0), 32, 32, ii*32, jj*32, 32, 32);
|
bgc.drawImage(editor.material.images['terrains'], 0, 32*(editor.bgY||0), 32, 32, ii*32, jj*32, 32, 32);
|
||||||
}
|
}
|
||||||
|
if(img){
|
||||||
|
bgc.drawImage(img, 0, 0, 416, 416);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.prototype.updateMap = function(){
|
editor.prototype.updateMap = function(){
|
||||||
var blocks = main.editor.mapIntoBlocks(editor.map.map(function(v){return v.map(function(v){return v.idnum||v||0})}),{'events':{},'changeFloor':{},'defaultGround':null});
|
var blocks = main.editor.mapIntoBlocks(editor.map.map(function(v){return v.map(function(v){return v.idnum||v||0})}),{'events':{},'changeFloor':{}});
|
||||||
core.status.thisMap.blocks = blocks;
|
core.status.thisMap.blocks = blocks;
|
||||||
main.editor.updateMap();
|
main.editor.updateMap();
|
||||||
|
|
||||||
|
|||||||
BIN
images/yewai.png
Normal file
BIN
images/yewai.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
273
libs/core.js
273
libs/core.js
@ -7,6 +7,7 @@ function core() {
|
|||||||
this.statusBar = {};
|
this.statusBar = {};
|
||||||
this.canvas = {};
|
this.canvas = {};
|
||||||
this.images = [];
|
this.images = [];
|
||||||
|
this.pngs = [];
|
||||||
this.bgms = [];
|
this.bgms = [];
|
||||||
this.sounds = [];
|
this.sounds = [];
|
||||||
this.floorIds = [];
|
this.floorIds = [];
|
||||||
@ -105,11 +106,12 @@ function core() {
|
|||||||
/////////// 系统事件相关 ///////////
|
/////////// 系统事件相关 ///////////
|
||||||
|
|
||||||
////// 初始化 //////
|
////// 初始化 //////
|
||||||
core.prototype.init = function (dom, statusBar, canvas, images, bgms, sounds, floorIds, floors, coreData) {
|
core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, sounds, floorIds, floors, coreData) {
|
||||||
core.dom = dom;
|
core.dom = dom;
|
||||||
core.statusBar = statusBar;
|
core.statusBar = statusBar;
|
||||||
core.canvas = canvas;
|
core.canvas = canvas;
|
||||||
core.images = images;
|
core.images = images;
|
||||||
|
core.pngs = pngs;
|
||||||
core.bgms = bgms;
|
core.bgms = bgms;
|
||||||
core.sounds = sounds;
|
core.sounds = sounds;
|
||||||
core.floorIds = floorIds;
|
core.floorIds = floorIds;
|
||||||
@ -138,8 +140,6 @@ core.prototype.init = function (dom, statusBar, canvas, images, bgms, sounds, fl
|
|||||||
core.material.icons = core.icons.getIcons();
|
core.material.icons = core.icons.getIcons();
|
||||||
core.material.events = core.events.getEvents();
|
core.material.events = core.events.getEvents();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (location.protocol.indexOf("http")==0) {
|
if (location.protocol.indexOf("http")==0) {
|
||||||
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
|
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
|
||||||
try {
|
try {
|
||||||
@ -202,6 +202,8 @@ core.prototype.showStartAnimate = function (callback) {
|
|||||||
core.dom.startButtonGroup.style.display = 'none';
|
core.dom.startButtonGroup.style.display = 'none';
|
||||||
core.dom.startButtons.style.display = 'block';
|
core.dom.startButtons.style.display = 'block';
|
||||||
core.dom.levelChooseButtons.style.display = 'none';
|
core.dom.levelChooseButtons.style.display = 'none';
|
||||||
|
core.dom.curtain.style.background = "#000000";
|
||||||
|
core.dom.curtain.style.opacity = 0;
|
||||||
core.status.played = false;
|
core.status.played = false;
|
||||||
core.clearStatus();
|
core.clearStatus();
|
||||||
core.clearMap('all');
|
core.clearMap('all');
|
||||||
@ -260,6 +262,13 @@ core.prototype.loader = function (callback) {
|
|||||||
core.setStartProgressVal(loadedImageNum * (100 / allImageNum));
|
core.setStartProgressVal(loadedImageNum * (100 / allImageNum));
|
||||||
if (loadedImageNum == allImageNum) {
|
if (loadedImageNum == allImageNum) {
|
||||||
|
|
||||||
|
// 加载pngs
|
||||||
|
core.material.images.pngs = {};
|
||||||
|
for (var x=0;x<core.pngs.length;x++) {
|
||||||
|
core.loadImage(core.pngs[x], function (pngId, image) {
|
||||||
|
core.material.images.pngs[pngId] = image;
|
||||||
|
if (Object.keys(core.material.images.pngs).length==core.pngs.length) {
|
||||||
|
|
||||||
// 加载Autotile
|
// 加载Autotile
|
||||||
core.material.images.autotile={};
|
core.material.images.autotile={};
|
||||||
var autotileIds = Object.keys(core.material.icons.autotile);
|
var autotileIds = Object.keys(core.material.icons.autotile);
|
||||||
@ -267,7 +276,8 @@ core.prototype.loader = function (callback) {
|
|||||||
core.loadImage(autotileIds[x], function (autotileId, image) {
|
core.loadImage(autotileIds[x], function (autotileId, image) {
|
||||||
core.material.images.autotile[autotileId]=image;
|
core.material.images.autotile[autotileId]=image;
|
||||||
if (Object.keys(core.material.images.autotile).length==autotileIds.length) {
|
if (Object.keys(core.material.images.autotile).length==autotileIds.length) {
|
||||||
// 音频
|
|
||||||
|
// 最后加载音频
|
||||||
core.loadMusic(callback);
|
core.loadMusic(callback);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -276,13 +286,19 @@ core.prototype.loader = function (callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////// 加载图片 //////
|
////// 加载图片 //////
|
||||||
core.prototype.loadImage = function (imgName, callback) {
|
core.prototype.loadImage = function (imgName, callback) {
|
||||||
try {
|
try {
|
||||||
core.setStartLoadTipText('加载图片 ' + imgName + ' 中...');
|
core.setStartLoadTipText('加载图片 ' + imgName + ' 中...');
|
||||||
|
var name=imgName;
|
||||||
|
if (name.indexOf(".png")<0) // 不包含"png"
|
||||||
|
name=name+".png";
|
||||||
var image = new Image();
|
var image = new Image();
|
||||||
image.src = 'images/' + imgName + '.png';
|
image.src = 'images/' + name + "?v=" + main.version;
|
||||||
if (image.complete) {
|
if (image.complete) {
|
||||||
callback(imgName, image);
|
callback(imgName, image);
|
||||||
return;
|
return;
|
||||||
@ -1996,6 +2012,13 @@ core.prototype.drawMap = function (mapName, callback) {
|
|||||||
core.canvas.bg.drawImage(blockImage, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32);
|
core.canvas.bg.drawImage(blockImage, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 如果存在png
|
||||||
|
if (core.isset(core.floors[mapName].png)) {
|
||||||
|
var png = core.floors[mapName].png;
|
||||||
|
if (core.isset(core.material.images.pngs[png])) {
|
||||||
|
core.canvas.bg.drawImage(core.material.images.pngs[png], 0, 0, 416, 416);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (main.mode=='editor'){
|
if (main.mode=='editor'){
|
||||||
main.editor.drawMapBg = function(){
|
main.editor.drawMapBg = function(){
|
||||||
@ -2012,17 +2035,16 @@ core.prototype.drawMap = function (mapName, callback) {
|
|||||||
var mapData = core.status.maps[core.status.floorId];
|
var mapData = core.status.maps[core.status.floorId];
|
||||||
var mapBlocks = mapData.blocks;
|
var mapBlocks = mapData.blocks;
|
||||||
|
|
||||||
var autotileMaps = [];
|
var mapArray = core.maps.getMapArray(core.status.maps, core.status.floorId);
|
||||||
for (var b = 0; b < mapBlocks.length; b++) {
|
for (var b = 0; b < mapBlocks.length; b++) {
|
||||||
// 事件启用
|
// 事件启用
|
||||||
var block = mapBlocks[b];
|
var block = mapBlocks[b];
|
||||||
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable)) {
|
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable)) {
|
||||||
if (block.event.cls == 'autotile') {
|
if (block.event.cls == 'autotile') {
|
||||||
// core.drawAutotile();
|
core.drawAutotile(core.canvas.event, mapArray, block, 32, 0, 0);
|
||||||
autotileMaps[13*block.x + block.y] = block.event.id;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (block.event.id!='none') {
|
||||||
var blockIcon = core.material.icons[block.event.cls][block.event.id];
|
var blockIcon = core.material.icons[block.event.cls][block.event.id];
|
||||||
var blockImage = core.material.images[block.event.cls];
|
var blockImage = core.material.images[block.event.cls];
|
||||||
core.canvas.event.drawImage(core.material.images[block.event.cls], 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32);
|
core.canvas.event.drawImage(core.material.images[block.event.cls], 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32);
|
||||||
@ -2030,7 +2052,7 @@ core.prototype.drawMap = function (mapName, callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
core.drawAutotile(mapName, 'event', autotileMaps, 0, 0, 32);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (main.mode=='editor'){
|
if (main.mode=='editor'){
|
||||||
@ -2044,138 +2066,89 @@ core.prototype.drawMap = function (mapName, callback) {
|
|||||||
drawEvent();
|
drawEvent();
|
||||||
}
|
}
|
||||||
core.setGlobalAnimate(core.values.animateSpeed);
|
core.setGlobalAnimate(core.values.animateSpeed);
|
||||||
|
|
||||||
if (core.isset(callback))
|
if (core.isset(callback))
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 绘制Autotile //////
|
////// 绘制Autotile //////
|
||||||
core.prototype.drawAutotile = function (floorId, canvas, autotileMaps, left, top, size, autotileId) {
|
core.prototype.drawAutotile = function(ctx, mapArr, block, size, left, top){
|
||||||
|
var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块
|
||||||
|
// +----+----+----+----+----+----+
|
||||||
|
[10, 9, 4, 3 ], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||||
|
[10, 9, 4, 13], //1 bin:0001 +----+----+----+----+----+----+
|
||||||
|
[10, 9, 18, 3 ], //2 bin:0010 | 7 | 8 | 9 | 10 | 11 | 12 |
|
||||||
|
[10, 9, 16, 15], //3 bin:0011 +----+----+----+----+----+----+
|
||||||
|
[10, 43, 4, 3 ], //4 bin:0100 | 13 | 14 | 15 | 16 | 17 | 18 |
|
||||||
|
[10, 31, 4, 25], //5 bin:0101 +----+----+----+----+----+----+
|
||||||
|
[10, 7, 2, 3 ], //6 bin:0110 | 19 | 20 | 21 | 22 | 23 | 24 |
|
||||||
|
[10, 31, 16, 5 ], //7 bin:0111 +----+----+----+----+----+----+
|
||||||
|
[48, 9, 4, 3 ], //8 bin:1000 | 25 | 26 | 27 | 28 | 29 | 30 |
|
||||||
|
[ 8, 9, 4, 1 ], //9 bin:1001 +----+----+----+----+----+----+
|
||||||
|
[36, 9, 30, 3 ], //10 bin:1010 | 31 | 32 | 33 | 34 | 35 | 36 |
|
||||||
|
[36, 9, 6, 15], //11 bin:1011 +----+----+----+----+----+----+
|
||||||
|
[46, 45, 4, 3 ], //12 bin:1100 | 37 | 38 | 39 | 40 | 41 | 42 |
|
||||||
|
[46, 11, 4, 25], //13 bin:1101 +----+----+----+----+----+----+
|
||||||
|
[12, 45, 30, 3 ], //14 bin:1110 | 43 | 44 | 45 | 46 | 47 | 48 |
|
||||||
|
[34, 33, 28, 27] //15 bin:1111 +----+----+----+----+----+----+
|
||||||
|
];
|
||||||
|
|
||||||
if (!core.isset(autotileId)) {
|
var drawBlockByIndex = function(ctx, dx, dy, autotileImg, index, size){ //index为autotile的图块索引1-48
|
||||||
var autotileIds = {};
|
var sx = 16*((index-1)%6), sy = 16*(~~((index-1)/6));
|
||||||
autotileMaps.forEach(function (t) {
|
ctx.drawImage(autotileImg, sx, sy, 16, 16, dx, dy, size/2, size/2);
|
||||||
if (core.isset(t)) autotileIds[t]=true;
|
|
||||||
});
|
|
||||||
Object.keys(autotileIds).forEach(function (t) {
|
|
||||||
core.drawAutotile(floorId, canvas, autotileMaps, left, top, size, t);
|
|
||||||
})
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
var getAutotileAroundId = function(currId, x, y){
|
||||||
|
if(x<0 || y<0 || x>12 || y>12) return 1;
|
||||||
|
else return mapArr[y][x]==currId ? 1:0;
|
||||||
|
}
|
||||||
|
var checkAround = function(x, y){ // 得到周围四个32*32块(周围每块都包含当前块的1/4,不清楚的话画下图你就明白)的数组索引
|
||||||
|
var currId = mapArr[y][x];
|
||||||
|
var pointBlock = [];
|
||||||
|
for(var i=0; i<4; i++){
|
||||||
|
var bsum = 0;
|
||||||
|
var offsetx = i%2, offsety = ~~(i/2);
|
||||||
|
for(var j=0; j<4; j++){
|
||||||
|
var mx = j%2, my = ~~(j/2);
|
||||||
|
var b = getAutotileAroundId(currId, x+offsetx+mx-1, y+offsety+my-1);
|
||||||
|
bsum += b*(Math.pow(2, 3-j));
|
||||||
|
}
|
||||||
|
pointBlock.push(bsum);
|
||||||
|
}
|
||||||
|
return pointBlock;
|
||||||
|
}
|
||||||
|
var getAutotileIndexs = function(x, y){
|
||||||
|
var indexArr = [];
|
||||||
|
var pointBlocks = checkAround(x, y);
|
||||||
|
for(var i=0; i<4; i++){
|
||||||
|
var arr = indexArrs[pointBlocks[i]]
|
||||||
|
indexArr.push(arr[3-i]);
|
||||||
|
}
|
||||||
|
return indexArr;
|
||||||
|
}
|
||||||
|
// 开始绘制autotile
|
||||||
|
var x = block.x, y = block.y;
|
||||||
|
var pieceIndexs = getAutotileIndexs(x, y);
|
||||||
|
|
||||||
var isAutotile = function(x, y) {
|
//修正四个边角的固定搭配
|
||||||
if (x<0 || x>12 || y<0 || y>12) return 1;
|
if(pieceIndexs[0] == 13){
|
||||||
return autotileMaps[13*x+y]==autotileId?1:0;
|
if(pieceIndexs[1] == 16) pieceIndexs[1] = 14;
|
||||||
|
if(pieceIndexs[2] == 31) pieceIndexs[2] = 19;
|
||||||
}
|
}
|
||||||
for (var xx=0;xx<13;xx++) {
|
if(pieceIndexs[1] == 18){
|
||||||
for (var yy=0;yy<13;yy++) {
|
if(pieceIndexs[0] == 15) pieceIndexs[0] = 17;
|
||||||
if (isAutotile(xx, yy)) {
|
if(pieceIndexs[3] == 36) pieceIndexs[3] = 24;
|
||||||
// 绘制autotile
|
|
||||||
var id=isAutotile(xx, yy - 1) + 2 * isAutotile(xx - 1, yy) + 4 * isAutotile(xx, yy + 1) + 8 * isAutotile(xx + 1, yy);
|
|
||||||
core.drawAutotileBlock(floorId, canvas, left + xx * size, top + yy * size, size, core.material.images.autotile[autotileId], id);
|
|
||||||
}
|
}
|
||||||
|
if(pieceIndexs[2] == 43){
|
||||||
|
if(pieceIndexs[0] == 25) pieceIndexs[0] = 37;
|
||||||
|
if(pieceIndexs[3] == 46) pieceIndexs[3] = 44;
|
||||||
}
|
}
|
||||||
|
if(pieceIndexs[3] == 48){
|
||||||
|
if(pieceIndexs[1] == 30) pieceIndexs[1] = 42;
|
||||||
|
if(pieceIndexs[2] == 45) pieceIndexs[2] = 47;
|
||||||
}
|
}
|
||||||
for (var xx=0;xx<13;xx++) {
|
for(var i=0; i<4; i++){
|
||||||
for (var yy=0;yy<13;yy++) {
|
var index = pieceIndexs[i];
|
||||||
if (isAutotile(xx, yy) + isAutotile(xx + 1, yy) + isAutotile(xx + 1, yy + 1) + isAutotile(xx, yy + 1) != 3) continue;
|
var dx = x*size + size/2*(i%2), dy = y*size + size/2*(~~(i/2));
|
||||||
if (!isAutotile(xx, yy)) {
|
drawBlockByIndex(ctx, dx+left, dy+top, core.material.images['autotile'][block.event.id], index, size);
|
||||||
core.drawAutotileBlock(floorId, canvas, left + xx * size + size, top + yy * size + size, size, core.material.images.autotile[autotileId], 16);
|
|
||||||
}
|
|
||||||
if (!isAutotile(xx + 1, yy)) {
|
|
||||||
core.drawAutotileBlock(floorId, canvas, left + xx * size + size / 2, top + yy * size + size, size, core.material.images.autotile[autotileId], 17);
|
|
||||||
}
|
|
||||||
if (!isAutotile(xx + 1, yy + 1)) {
|
|
||||||
core.drawAutotileBlock(floorId, canvas, left + xx * size + size / 2, top + yy * size + size / 2, size, core.material.images.autotile[autotileId], 18);
|
|
||||||
}
|
|
||||||
if (!isAutotile(xx, yy + 1)) {
|
|
||||||
core.drawAutotileBlock(floorId, canvas, left + xx * size + size, top + yy * size + size / 2, size, core.material.images.autotile[autotileId], 19);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////// 绘制Autotile的某一块 //////
|
|
||||||
core.prototype.drawAutotileBlock = function (floorId, map, x, y, size, autotile, index) {
|
|
||||||
var canvas = core.canvas[map];
|
|
||||||
var groundId = core.floors[floorId].defaultGround || "ground";
|
|
||||||
var blockIcon = core.material.icons.terrains[groundId];
|
|
||||||
var blockImage = core.material.images.terrains;
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
canvas.drawImage(autotile, 0, 0, 32, 32, x, y, size, size);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
canvas.drawImage(autotile, 0, 3 * 32, 16, 32, x, y, size / 2, size);
|
|
||||||
canvas.drawImage(autotile, 2 * 32 + 16, 3 * 32, 16, 32, x + size / 2, y, size / 2, size);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
canvas.drawImage(autotile, 2 * 32, 32, 32, 16, x, y, size, size / 2);
|
|
||||||
canvas.drawImage(autotile, 2 * 32, 3 * 32 + 16, 32, 16, x, y + size / 2, size, size / 2);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
canvas.drawImage(autotile, 2 * 32, 3 * 32, 32, 32, x, y, size, size);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
canvas.drawImage(autotile, 0, 1 * 32, 16, 32, x, y, size / 2, size);
|
|
||||||
canvas.drawImage(autotile, 2 * 32 + 16, 1 * 32, 16, 32, x + size / 2, y, size / 2, size);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
canvas.drawImage(autotile, 0, 2 * 32, 16, 32, x, y, size / 2, size);
|
|
||||||
canvas.drawImage(autotile, 2 * 32 + 16, 2 * 32, 16, 32, x + size / 2, y, size / 2, size);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
canvas.drawImage(autotile, 2 * 32, 1 * 32, 32, 32, x, y, size, size);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
canvas.drawImage(autotile, 2 * 32, 2 * 32, 32, 32, x, y, size, size);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
canvas.drawImage(autotile, 0, 32, 32, 16, x, y, size, size / 2);
|
|
||||||
canvas.drawImage(autotile, 0, 3 * 32 + 16, 32, 16, x, y + size / 2, size, size / 2);
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
canvas.drawImage(autotile, 0, 3 * 32, 32, 32, x, y, size, size);
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
canvas.drawImage(autotile, 32, 32, 32, 16, x, y, size, size / 2);
|
|
||||||
canvas.drawImage(autotile, 32, 3 * 32 + 16, 32, 16, x, y + size / 2, size, size / 2);
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
canvas.drawImage(autotile, 32, 3 * 32, 32, 32, x, y, size, size);
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
canvas.drawImage(autotile, 0, 32, 32, 32, x, y, size, size);
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
canvas.drawImage(autotile, 0, 2 * 32, 32, 32, x, y, size, size);
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
canvas.drawImage(autotile, 32, 32, 32, 32, x, y, size, size);
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
canvas.drawImage(autotile, 32, 2 * 32, 32, 32, x, y, size, size);
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
canvas.clearRect(x, y, size / 2, size / 2);
|
|
||||||
canvas.drawImage(blockImage, 0, blockIcon * 32, 16, 16, x, y, size / 2, size / 2);
|
|
||||||
canvas.drawImage(autotile, 2 * 32, 0, 16, 16, x, y, size / 2, size / 2);
|
|
||||||
break;
|
|
||||||
case 17:
|
|
||||||
canvas.clearRect(x, y, size / 2, size / 2);
|
|
||||||
canvas.drawImage(blockImage, 0, blockIcon * 32, 16, 16, x, y, size / 2, size / 2);
|
|
||||||
canvas.drawImage(autotile, 2 * 32 + 16, 0, 16, 16, x, y, size / 2, size / 2);
|
|
||||||
break;
|
|
||||||
case 18:
|
|
||||||
canvas.clearRect(x, y, size / 2, size / 2);
|
|
||||||
canvas.drawImage(blockImage, 0, blockIcon * 32, 16, 16, x, y, size / 2, size / 2);
|
|
||||||
canvas.drawImage(autotile, 2 * 32 + 16, 16, 16, 16, x, y, size / 2, size / 2);
|
|
||||||
break;
|
|
||||||
case 19:
|
|
||||||
canvas.clearRect(x, y, size / 2, size / 2);
|
|
||||||
canvas.drawImage(blockImage, 0, blockIcon * 32, 16, 16, x, y, size / 2, size / 2);
|
|
||||||
canvas.drawImage(autotile, 2 * 32, 16, 16, 16, x, y, size / 2, size / 2);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2882,8 +2855,19 @@ core.prototype.updateFg = function () {
|
|||||||
core.canvas.fg.textAlign = 'left';
|
core.canvas.fg.textAlign = 'left';
|
||||||
for (var b = 0; b < mapBlocks.length; b++) {
|
for (var b = 0; b < mapBlocks.length; b++) {
|
||||||
var x = mapBlocks[b].x, y = mapBlocks[b].y;
|
var x = mapBlocks[b].x, y = mapBlocks[b].y;
|
||||||
if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls == 'enemys' && mapBlocks[b].event.trigger == 'battle'
|
if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls == 'enemys'
|
||||||
&& !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)) {
|
&& !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)) {
|
||||||
|
|
||||||
|
// 非系统默认的战斗事件(被覆盖)
|
||||||
|
if (mapBlocks[b].event.trigger != 'battle') {
|
||||||
|
// 判断显伤
|
||||||
|
var event = core.floors[core.status.floorId].events[x+","+y];
|
||||||
|
if (core.isset(event) && !(event instanceof Array)) {
|
||||||
|
if (core.isset(event.displayDamage) && !event.displayDamage)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var id = mapBlocks[b].event.id;
|
var id = mapBlocks[b].event.id;
|
||||||
|
|
||||||
var damage = core.enemys.getDamage(id);
|
var damage = core.enemys.getDamage(id);
|
||||||
@ -3067,7 +3051,7 @@ core.prototype.drawTip = function (text, itemIcon) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!core.timeout.getItemTipTimeout) {
|
if (!core.isset(core.timeout.getItemTipTimeout)) {
|
||||||
core.timeout.getItemTipTimeout = window.setTimeout(function () {
|
core.timeout.getItemTipTimeout = window.setTimeout(function () {
|
||||||
hide = true;
|
hide = true;
|
||||||
core.timeout.getItemTipTimeout = null;
|
core.timeout.getItemTipTimeout = null;
|
||||||
@ -3427,30 +3411,29 @@ core.prototype.syncSave = function(type) {
|
|||||||
|
|
||||||
// send
|
// send
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.open("POST", "../sync.php");
|
xhr.open("POST", "/games/sync.php");
|
||||||
xhr.timeout = 1000;
|
|
||||||
xhr.onload = function(e) {
|
xhr.onload = function(e) {
|
||||||
if (xhr.status==200) {
|
if (xhr.status==200) {
|
||||||
// console.log("同步成功。");
|
// console.log("同步成功。");
|
||||||
var response = JSON.parse(xhr.response);
|
var response = JSON.parse(xhr.response);
|
||||||
if (response.code<0) {
|
if (response.code<0) {
|
||||||
core.drawText("出错啦!\n无法同步存档到服务器。");
|
core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+response.msg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.drawText("同步成功!\n\n您的存档编号: "+response.code+"\n您的存档密码: "+response.msg+"\n\n请牢记以上两个信息(如截图等),在从服务器\n同步存档时使用。")
|
core.drawText("同步成功!\n\n您的存档编号: "+response.code+"\n您的存档密码: "+response.msg+"\n\n请牢记以上两个信息(如截图等),在从服务器\n同步存档时使用。")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.drawText("出错啦!\n无法同步存档到服务器。");
|
core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:HTTP "+xhr.status);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhr.ontimeout = function(e) {
|
xhr.ontimeout = function(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
core.drawText("出错啦!\n无法同步存档到服务器。");
|
core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+e);
|
||||||
}
|
}
|
||||||
xhr.onerror = function(e) {
|
xhr.onerror = function(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
core.drawText("出错啦!\n无法同步存档到服务器。");
|
core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+e);
|
||||||
}
|
}
|
||||||
xhr.send(formData);
|
xhr.send(formData);
|
||||||
}, function() {
|
}, function() {
|
||||||
@ -3479,8 +3462,7 @@ core.prototype.syncSave = function(type) {
|
|||||||
|
|
||||||
// send
|
// send
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.open("POST", "../sync.php");
|
xhr.open("POST", "/games/sync.php");
|
||||||
xhr.timeout = 1000;
|
|
||||||
xhr.onload = function(e) {
|
xhr.onload = function(e) {
|
||||||
if (xhr.status==200) {
|
if (xhr.status==200) {
|
||||||
// console.log("同步成功。");
|
// console.log("同步成功。");
|
||||||
@ -3507,22 +3489,19 @@ core.prototype.syncSave = function(type) {
|
|||||||
core.drawText("出错啦!\n存档密码错误!");
|
core.drawText("出错啦!\n存档密码错误!");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
core.drawText("出错啦!\n无法从服务器同步存档。");
|
core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:"+response.msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.drawText("出错啦!\n无法从服务器同步存档。");
|
core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:HTTP "+xhr.status);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhr.ontimeout = function(e) {
|
xhr.ontimeout = function(e) {
|
||||||
console.log(e);
|
core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:"+e);
|
||||||
core.drawText("出错啦!\n无法从服务器同步存档。");
|
|
||||||
}
|
}
|
||||||
xhr.onerror = function(e) {
|
xhr.onerror = function(e) {
|
||||||
console.log(e);
|
core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:"+e);
|
||||||
core.drawText("出错啦!\n无法从服务器同步存档。");
|
|
||||||
}
|
}
|
||||||
xhr.send(formData);
|
xhr.send(formData);
|
||||||
}, function() {
|
}, function() {
|
||||||
|
|||||||
38
libs/maps.js
38
libs/maps.js
@ -18,7 +18,7 @@ maps.prototype.loadFloor = function (floorId, map) {
|
|||||||
for (var i = 0; i < 13; i++) {
|
for (var i = 0; i < 13; i++) {
|
||||||
for (var j = 0; j < 13; j++) {
|
for (var j = 0; j < 13; j++) {
|
||||||
var block = maps.getBlock(j, i, map[i][j]);
|
var block = maps.getBlock(j, i, map[i][j]);
|
||||||
if (block.event != undefined) {
|
if (core.isset(block.event)) {
|
||||||
if (block.event.cls == 'enemys' && block.event.trigger==undefined) {
|
if (block.event.cls == 'enemys' && block.event.trigger==undefined) {
|
||||||
block.event.trigger = 'battle';
|
block.event.trigger = 'battle';
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@ maps.prototype.loadFloor = function (floorId, map) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maps.addEvent(block,j,i,floor.events[j+","+i],floor.defaultGround || "ground")
|
maps.addEvent(block,j,i,floor.events[j+","+i]);
|
||||||
maps.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]);
|
maps.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]);
|
||||||
if (core.isset(block.event)) blocks.push(block);
|
if (core.isset(block.event)) blocks.push(block);
|
||||||
}
|
}
|
||||||
@ -80,10 +80,10 @@ maps.prototype.getBlock = function (x, y, id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////// 向该楼层添加剧本的自定义事件 //////
|
////// 向该楼层添加剧本的自定义事件 //////
|
||||||
maps.prototype.addEvent = function (block, x, y, event, ground) {
|
maps.prototype.addEvent = function (block, x, y, event) {
|
||||||
if (!core.isset(event)) return;
|
if (!core.isset(event)) return;
|
||||||
if (!core.isset(block.event)) { // 本身是空地?
|
if (!core.isset(block.event)) { // 本身是空地?
|
||||||
block.event = {'cls': 'terrains', 'id': ground, 'noPass': false};
|
block.event = {'cls': 'terrains', 'id': 'none', 'noPass': false};
|
||||||
}
|
}
|
||||||
// event是字符串或数组?
|
// event是字符串或数组?
|
||||||
if (typeof event == "string") {
|
if (typeof event == "string") {
|
||||||
@ -95,6 +95,10 @@ maps.prototype.addEvent = function (block, x, y, event, ground) {
|
|||||||
if (!core.isset(event.data))
|
if (!core.isset(event.data))
|
||||||
event.data = [];
|
event.data = [];
|
||||||
|
|
||||||
|
// 覆盖noPass
|
||||||
|
if (core.isset(event.noPass))
|
||||||
|
block.event.noPass = event.noPass;
|
||||||
|
|
||||||
// 覆盖enable
|
// 覆盖enable
|
||||||
if (!core.isset(block.enable) && core.isset(event.enable)) {
|
if (!core.isset(block.enable) && core.isset(event.enable)) {
|
||||||
block.enable=event.enable;
|
block.enable=event.enable;
|
||||||
@ -173,4 +177,30 @@ maps.prototype.load = function (data, floorId) {
|
|||||||
return this.loadFloor(floorId, data[floorId]);
|
return this.loadFloor(floorId, data[floorId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 将当前地图重新变成二维数组形式 //////
|
||||||
|
maps.prototype.getMapArray = function (maps, floorId){
|
||||||
|
if (!core.isset(floorId)) {
|
||||||
|
var map = {};
|
||||||
|
for (var id in maps) {
|
||||||
|
map[id] = this.getMapArray(maps, id);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
var thisFloor = maps[floorId];
|
||||||
|
|
||||||
|
var blocks = [];
|
||||||
|
for (var x=0;x<13;x++) {
|
||||||
|
blocks[x]=[];
|
||||||
|
for (var y=0;y<13;y++) {
|
||||||
|
blocks[x].push(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thisFloor.blocks.forEach(function (block) {
|
||||||
|
if (!(core.isset(block.enable) && !block.enable))
|
||||||
|
blocks[block.y][block.x] = block.id;
|
||||||
|
});
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
main.instance.maps = new maps();
|
main.instance.maps = new maps();
|
||||||
@ -8,7 +8,20 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
|||||||
|
|
||||||
"floorIds" : [ // 在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器的顺序和上楼器/下楼器的顺序
|
"floorIds" : [ // 在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器的顺序和上楼器/下楼器的顺序
|
||||||
"sample0", "sample1", "sample2"
|
"sample0", "sample1", "sample2"
|
||||||
]
|
],
|
||||||
|
"pngs" : [ // 在此存放所有可能的背景图片;背景图片最好是416*416像素,其他分辨率会被强制缩放成416*416
|
||||||
|
// 建议对于较大的图片,在网上使用在线的“图片压缩工具”来进行压缩,以节省流量
|
||||||
|
// 有关使用自定义背景图,请参见文档的“自定义素材”说明
|
||||||
|
"bg.png", "yewai.png", // 依次向后添加
|
||||||
|
],
|
||||||
|
"bgms" : [ // 在此存放所有的bgm,和文件名一致。第一项为默认播放项
|
||||||
|
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||||
|
'058-Slow01.mid', 'bgm.mp3', 'qianjin.mid', 'star.mid',
|
||||||
|
],
|
||||||
|
"sounds" : [ // 在此存放所有的SE,和文件名一致
|
||||||
|
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||||
|
'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
"firstData" : {
|
"firstData" : {
|
||||||
"title": "魔塔样板", // 游戏名,将显示在标题页面以及切换楼层的界面中
|
"title": "魔塔样板", // 游戏名,将显示在标题页面以及切换楼层的界面中
|
||||||
@ -148,11 +161,11 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
|||||||
"flags" : {
|
"flags" : {
|
||||||
/****** 状态栏相关 ******/
|
/****** 状态栏相关 ******/
|
||||||
"enableFloor": true, // 是否在状态栏显示当前楼层
|
"enableFloor": true, // 是否在状态栏显示当前楼层
|
||||||
"enableLv": false, // 是否在状态栏显示当前等级
|
"enableLv": true, // 是否在状态栏显示当前等级
|
||||||
"enableMDef": true, // 是否在状态栏及战斗界面显示魔防(护盾)
|
"enableMDef": true, // 是否在状态栏及战斗界面显示魔防(护盾)
|
||||||
"enableMoney": true, // 是否在状态栏、怪物手册及战斗界面显示金币
|
"enableMoney": true, // 是否在状态栏、怪物手册及战斗界面显示金币
|
||||||
"enableExperience": true, // 是否在状态栏、怪物手册及战斗界面显示经验
|
"enableExperience": true, // 是否在状态栏、怪物手册及战斗界面显示经验
|
||||||
"enableLevelUp": false, // 是否允许等级提升(进阶);如果上面enableExperience为false,则此项恒视为false
|
"enableLevelUp": true, // 是否允许等级提升(进阶);如果上面enableExperience为false,则此项恒视为false
|
||||||
"enableDebuff": true, // 是否涉及毒衰咒;如果此项为false则不会在状态栏中显示毒衰咒的debuff
|
"enableDebuff": true, // 是否涉及毒衰咒;如果此项为false则不会在状态栏中显示毒衰咒的debuff
|
||||||
////// 上述的几个开关将直接影响状态栏的显示效果 //////
|
////// 上述的几个开关将直接影响状态栏的显示效果 //////
|
||||||
/****** 道具相关 ******/
|
/****** 道具相关 ******/
|
||||||
|
|||||||
@ -16,7 +16,7 @@ enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 = //1:先攻,2:魔攻,3:坚固,4:2
|
|||||||
'zombieKnight': {'name': '兽人武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'zombieKnight': {'name': '兽人武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'rock': {'name': '石头人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 4, 'experience': 0, 'special': 3},
|
'rock': {'name': '石头人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 4, 'experience': 0, 'special': 3},
|
||||||
'slimeMan': {'name': '影子战士', 'hp': 100, 'atk': 0, 'def': 0, 'money': 11, 'experience': 0, 'special': 10}, // 模仿怪的攻防设为0就好
|
'slimeMan': {'name': '影子战士', 'hp': 100, 'atk': 0, 'def': 0, 'money': 11, 'experience': 0, 'special': 10}, // 模仿怪的攻防设为0就好
|
||||||
'bluePriest': {'name': '初级法师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 3, 'experience': 0, 'special': 2},
|
'bluePriest': {'name': '初级法师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 3, 'experience': 0, 'special': 2, 'point': 1}, // 'point'可以在打败怪物后进行加点,详见文档说明。
|
||||||
'redPriest': {'name': '高级法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'redPriest': {'name': '高级法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'brownWizard': {'name': '初级巫师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 16, 'experience': 0, 'special': 15, 'value': 100, 'zoneSquare': true}, // 领域怪需要加value表示领域伤害的数值;zoneSquare代表是否九宫格伤害
|
'brownWizard': {'name': '初级巫师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 16, 'experience': 0, 'special': 15, 'value': 100, 'zoneSquare': true}, // 领域怪需要加value表示领域伤害的数值;zoneSquare代表是否九宫格伤害
|
||||||
'redWizard': {'name': '高级巫师', 'hp': 1000, 'atk': 1200, 'def': 0, 'money': 160, 'experience': 0, 'special': 15, 'value': 200, 'range': 2}, // range可选,代表领域伤害的范围;不加默认为1
|
'redWizard': {'name': '高级巫师', 'hp': 1000, 'atk': 1200, 'def': 0, 'money': 160, 'experience': 0, 'special': 15, 'value': 200, 'range': 2}, // range可选,代表领域伤害的范围;不加默认为1
|
||||||
|
|||||||
@ -8,6 +8,7 @@ main.floors.MT0 = {
|
|||||||
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||||
"defaultGround": "ground", // 默认地面的图块ID(terrains中)
|
"defaultGround": "ground", // 默认地面的图块ID(terrains中)
|
||||||
|
// "png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。
|
||||||
// "color": [0,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
// "color": [0,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
||||||
// "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
|
// "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
|
||||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||||
|
|||||||
@ -8,6 +8,7 @@ main.floors.sample0 = {
|
|||||||
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||||
"defaultGround": "ground", // 默认地面的图块ID(terrains中)
|
"defaultGround": "ground", // 默认地面的图块ID(terrains中)
|
||||||
|
// "png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。
|
||||||
// "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
// "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
||||||
"bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
|
"bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
|
||||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||||
@ -20,7 +21,7 @@ main.floors.sample0 = {
|
|||||||
[224, 254, 212, 232, 204, 5, 0, 1, 31, 32, 34, 33, 36],
|
[224, 254, 212, 232, 204, 5, 0, 1, 31, 32, 34, 33, 36],
|
||||||
[201, 205, 217, 215, 207, 5, 0, 1, 27, 28, 29, 30, 35],
|
[201, 205, 217, 215, 207, 5, 0, 1, 27, 28, 29, 30, 35],
|
||||||
[5, 5, 125, 5, 5, 5, 0, 1, 21, 22, 23, 24, 25],
|
[5, 5, 125, 5, 5, 5, 0, 1, 21, 22, 23, 24, 25],
|
||||||
[0, 0, 0, 0, 0, 0, 45, 1, 1, 1, 121, 1, 1],
|
[0, 0, 237, 0, 0, 0, 45, 1, 1, 1, 121, 1, 1],
|
||||||
[4, 4, 126, 4, 4, 4, 0, 0, 0, 0, 0, 85, 124],
|
[4, 4, 126, 4, 4, 4, 0, 0, 0, 0, 0, 85, 124],
|
||||||
[87, 11, 12, 13, 14, 4, 4, 2, 2, 2, 122, 2, 2],
|
[87, 11, 12, 13, 14, 4, 4, 2, 2, 2, 122, 2, 2],
|
||||||
[88, 89, 90, 91, 92, 93, 94, 2, 81, 82, 83, 84, 86],
|
[88, 89, 90, 91, 92, 93, 94, 2, 81, 82, 83, 84, 86],
|
||||||
@ -53,7 +54,7 @@ main.floors.sample0 = {
|
|||||||
{"type": "hide", "time": 500}
|
{"type": "hide", "time": 500}
|
||||||
],
|
],
|
||||||
"2,8": [ // 守着第一批怪物的老人
|
"2,8": [ // 守着第一批怪物的老人
|
||||||
"\t[老人,magician]这些都是各种各样的怪物,所有怪物的数据都在enemys.js中设置。\n\n每个怪物最多只能有一个特殊属性。",
|
"\t[老人,magician]这些都是各种各样的怪物,所有怪物的数据都在enemys.js中设置。",
|
||||||
"\t[老人,magician]这批怪物分别为:普通、先攻、魔攻、坚固、2连击、3连击、4连击、破甲、反击、净化。",
|
"\t[老人,magician]这批怪物分别为:普通、先攻、魔攻、坚固、2连击、3连击、4连击、破甲、反击、净化。",
|
||||||
"\t[老人,magician]打败怪物后可触发 afterBattle 事件。\n\n有关事件的各种信息在下一层会有更为详细的说明。",
|
"\t[老人,magician]打败怪物后可触发 afterBattle 事件。\n\n有关事件的各种信息在下一层会有更为详细的说明。",
|
||||||
{"type": "hide", "time": 500}
|
{"type": "hide", "time": 500}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ main.floors.sample1 = {
|
|||||||
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||||
"defaultGround": "grass", // 默认地面的图块ID(terrains中)
|
"defaultGround": "grass", // 默认地面的图块ID(terrains中)
|
||||||
|
"png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。
|
||||||
// "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
// "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
||||||
// "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
|
// "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
|
||||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||||
|
|||||||
@ -8,6 +8,7 @@ main.floors.sample2 = {
|
|||||||
"canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
"canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||||
"defaultGround": "snowGround", // 默认地面的图块ID(terrains中)
|
"defaultGround": "snowGround", // 默认地面的图块ID(terrains中)
|
||||||
|
// "png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。
|
||||||
"color": [255,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
"color": [255,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
||||||
"bgm": "qianjin.mid", // 到达该层后默认播放的BGM。本项可忽略。
|
"bgm": "qianjin.mid", // 到达该层后默认播放的BGM。本项可忽略。
|
||||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||||
@ -201,10 +202,26 @@ main.floors.sample2 = {
|
|||||||
{"type": "trigger", "loc": [6,6]} // 立刻触发妖精事件
|
{"type": "trigger", "loc": [6,6]} // 立刻触发妖精事件
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"4,3": {"trigger":"action","enable":false}, // 四个角的大法师,添加trigger:action可避免该点出现显伤
|
"4,3": { // 四个角的大法师,
|
||||||
"8,3": {"trigger":"action","enable":false}, // 四个角的大法师
|
"trigger": "action",
|
||||||
"4,6": {"trigger":"action","enable":false}, // 四个角的大法师
|
"displayDamage": false,
|
||||||
"8,6": {"trigger":"action","enable":false}, // 四个角的大法师
|
"enable":false
|
||||||
|
},
|
||||||
|
"8,3": { // 四个角的大法师,
|
||||||
|
"trigger": "action",
|
||||||
|
"displayDamage": false,
|
||||||
|
"enable":false
|
||||||
|
},
|
||||||
|
"4,6": { // 四个角的大法师,
|
||||||
|
"trigger": "action",
|
||||||
|
"displayDamage": false,
|
||||||
|
"enable":false
|
||||||
|
},
|
||||||
|
"8,6": { // 四个角的大法师,
|
||||||
|
"trigger": "action",
|
||||||
|
"displayDamage": false,
|
||||||
|
"enable":false
|
||||||
|
},
|
||||||
|
|
||||||
"6,6": { // 妖精
|
"6,6": { // 妖精
|
||||||
"enable":false, // 初始时禁用状态
|
"enable":false, // 初始时禁用状态
|
||||||
|
|||||||
17
libs/ui.js
17
libs/ui.js
@ -1083,23 +1083,30 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL
|
|||||||
core.canvas[canvas].drawImage(blockImage, 0, blockIcon * 32, 32, 32, x + i * persize, y + j * persize, persize, persize);
|
core.canvas[canvas].drawImage(blockImage, 0, blockIcon * 32, 32, 32, x + i * persize, y + j * persize, persize, persize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var autotileMaps = [];
|
|
||||||
|
if (core.isset(core.floors[floorId].png)) {
|
||||||
|
var png = core.floors[floorId].png;
|
||||||
|
if (core.isset(core.material.images.pngs[png])) {
|
||||||
|
core.canvas.ui.drawImage(core.material.images.pngs[png], x, y, size, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var mapArray = core.maps.getMapArray(core.status.maps, floorId);
|
||||||
for (var b in blocks) {
|
for (var b in blocks) {
|
||||||
var block = blocks[b];
|
var block = blocks[b];
|
||||||
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable)) {
|
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable)) {
|
||||||
if (block.event.cls == 'autotile') {
|
if (block.event.cls == 'autotile') {
|
||||||
// core.drawAutotile();
|
core.drawAutotile(core.canvas.ui, mapArray, block, persize, x, y);
|
||||||
autotileMaps[13*block.x + block.y] = block.event.id;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (block.event.id!='none') {
|
||||||
var blockIcon = core.material.icons[block.event.cls][block.event.id];
|
var blockIcon = core.material.icons[block.event.cls][block.event.id];
|
||||||
var blockImage = core.material.images[block.event.cls];
|
var blockImage = core.material.images[block.event.cls];
|
||||||
core.canvas[canvas].drawImage(blockImage, 0, blockIcon * 32, 32, 32, x + block.x * persize, y + block.y * persize, persize, persize);
|
core.canvas[canvas].drawImage(blockImage, 0, blockIcon * 32, 32, 32, x + block.x * persize, y + block.y * persize, persize, persize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
core.drawAutotile(floorId, 'ui', autotileMaps, x, y, persize);
|
}
|
||||||
|
|
||||||
if (core.isset(heroLoc)) {
|
if (core.isset(heroLoc)) {
|
||||||
var heroIcon = core.material.icons.hero[heroLoc.direction];
|
var heroIcon = core.material.icons.hero[heroLoc.direction];
|
||||||
|
|||||||
64
main.js
64
main.js
@ -1,4 +1,11 @@
|
|||||||
function main() {
|
function main() {
|
||||||
|
|
||||||
|
//------------------------ 用户修改内容 ------------------------//
|
||||||
|
|
||||||
|
this.version = "0.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。
|
||||||
|
|
||||||
|
//------------------------ 用户修改内容 END ------------------------//
|
||||||
|
|
||||||
this.dom = {
|
this.dom = {
|
||||||
'body': document.body,
|
'body': document.body,
|
||||||
'gameGroup': document.getElementById('gameGroup'),
|
'gameGroup': document.getElementById('gameGroup'),
|
||||||
@ -50,14 +57,7 @@ function main() {
|
|||||||
this.images = [
|
this.images = [
|
||||||
'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains'
|
'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains'
|
||||||
];
|
];
|
||||||
this.bgms = [ // 在此存放所有的bgm,和文件名一致。第一项为默认播放项
|
|
||||||
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
|
||||||
'058-Slow01.mid', 'bgm.mp3', 'qianjin.mid', 'star.mid'
|
|
||||||
];
|
|
||||||
this.sounds = [ // 在此存放所有的SE,和文件名一致
|
|
||||||
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
|
||||||
'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg'
|
|
||||||
]
|
|
||||||
this.statusBar = {
|
this.statusBar = {
|
||||||
'image': {
|
'image': {
|
||||||
'floor': document.getElementById('img-floor'),
|
'floor': document.getElementById('img-floor'),
|
||||||
@ -94,11 +94,6 @@ function main() {
|
|||||||
'curse': document.getElementById('curse'),
|
'curse': document.getElementById('curse'),
|
||||||
'hard': document.getElementById("hard")
|
'hard': document.getElementById("hard")
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------ 用户修改内容 ------------------------//
|
|
||||||
this.version = "0.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。
|
|
||||||
//------------------------ 用户修改内容 END ------------------------//
|
|
||||||
|
|
||||||
this.floors = {}
|
this.floors = {}
|
||||||
this.instance = {};
|
this.instance = {};
|
||||||
this.canvas = {};
|
this.canvas = {};
|
||||||
@ -113,8 +108,8 @@ main.prototype.init = function (mode) {
|
|||||||
if (mode === 'editor')main.editor = {'disableGlobalAnimate':true};
|
if (mode === 'editor')main.editor = {'disableGlobalAnimate':true};
|
||||||
}
|
}
|
||||||
main.loadPureData(function(){
|
main.loadPureData(function(){
|
||||||
main.useCompress=data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.useCompress;
|
var mainData = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main;
|
||||||
main.floorIds=data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds;
|
for(var ii in mainData)main[ii]=mainData[ii];
|
||||||
main.loaderJs(function () {
|
main.loaderJs(function () {
|
||||||
var coreData = {};
|
var coreData = {};
|
||||||
for (i = 0; i < main.loadList.length; i++) {
|
for (i = 0; i < main.loadList.length; i++) {
|
||||||
@ -124,13 +119,14 @@ main.prototype.init = function (mode) {
|
|||||||
coreData[name] = main[name];
|
coreData[name] = main[name];
|
||||||
}
|
}
|
||||||
main.loaderFloors(function() {
|
main.loaderFloors(function() {
|
||||||
main.core.init(main.dom, main.statusBar, main.canvas, main.images, main.bgms, main.sounds, main.floorIds, main.floors, coreData);
|
main.core.init(main.dom, main.statusBar, main.canvas, main.images, main.pngs, main.bgms, main.sounds, main.floorIds, main.floors, coreData);
|
||||||
main.core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight);
|
main.core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 动态加载所有核心JS文件 //////
|
||||||
main.prototype.loaderJs = function (callback) {
|
main.prototype.loaderJs = function (callback) {
|
||||||
var instanceNum = 0;
|
var instanceNum = 0;
|
||||||
// 加载js
|
// 加载js
|
||||||
@ -151,13 +147,14 @@ main.prototype.loaderJs = function (callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 动态加载所有楼层(剧本) //////
|
||||||
main.prototype.loaderFloors = function (callback) {
|
main.prototype.loaderFloors = function (callback) {
|
||||||
|
|
||||||
// 加载js
|
// 加载js
|
||||||
main.setMainTipsText('正在加载楼层文件...')
|
main.setMainTipsText('正在加载楼层文件...')
|
||||||
if (this.useCompress) { // 读取压缩文件
|
if (this.useCompress) { // 读取压缩文件
|
||||||
var script = document.createElement('script');
|
var script = document.createElement('script');
|
||||||
script.src = 'libs/project/floors.min.js?' + this.version;
|
script.src = 'libs/project/floors.min.js?v=' + this.version;
|
||||||
main.dom.body.appendChild(script);
|
main.dom.body.appendChild(script);
|
||||||
script.onload = function () {
|
script.onload = function () {
|
||||||
main.dom.mainTips.style.display = 'none';
|
main.dom.mainTips.style.display = 'none';
|
||||||
@ -177,10 +174,11 @@ main.prototype.loaderFloors = function (callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 加载某一个JS文件 //////
|
||||||
main.prototype.loadMod = function (modName, callback) {
|
main.prototype.loadMod = function (modName, callback) {
|
||||||
var script = document.createElement('script');
|
var script = document.createElement('script');
|
||||||
var name = modName;
|
var name = modName;
|
||||||
script.src = 'libs/' + modName + (this.useCompress?".min":"") + '.js?' + this.version;
|
script.src = 'libs/' + modName + (this.useCompress?".min":"") + '.js?v=' + this.version;
|
||||||
main.dom.body.appendChild(script);
|
main.dom.body.appendChild(script);
|
||||||
script.onload = function () {
|
script.onload = function () {
|
||||||
main[name] = main.instance[name];
|
main[name] = main.instance[name];
|
||||||
@ -188,9 +186,10 @@ main.prototype.loadMod = function (modName, callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 加载某一个楼层 //////
|
||||||
main.prototype.loadFloor = function(floorId, callback) {
|
main.prototype.loadFloor = function(floorId, callback) {
|
||||||
var script = document.createElement('script');
|
var script = document.createElement('script');
|
||||||
script.src = 'libs/project/floors/' + floorId +'.js?' + this.version;
|
script.src = 'libs/project/floors/' + floorId +'.js?v=' + this.version;
|
||||||
main.dom.body.appendChild(script);
|
main.dom.body.appendChild(script);
|
||||||
script.onload = function () {
|
script.onload = function () {
|
||||||
callback(floorId);
|
callback(floorId);
|
||||||
@ -201,7 +200,7 @@ main.prototype.loadPureData = function(callback) {
|
|||||||
var loadedNum = 0;
|
var loadedNum = 0;
|
||||||
main.pureData.forEach(function(name){
|
main.pureData.forEach(function(name){
|
||||||
var script = document.createElement('script');
|
var script = document.createElement('script');
|
||||||
script.src = 'libs/project/' + name +'.js?' + this.version;
|
script.src = 'libs/project/' + name +'.js?v=' + this.version;
|
||||||
main.dom.body.appendChild(script);
|
main.dom.body.appendChild(script);
|
||||||
script.onload = function () {
|
script.onload = function () {
|
||||||
loadedNum++;
|
loadedNum++;
|
||||||
@ -211,6 +210,7 @@ main.prototype.loadPureData = function(callback) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 加载过程提示 //////
|
||||||
main.prototype.setMainTipsText = function (text) {
|
main.prototype.setMainTipsText = function (text) {
|
||||||
main.dom.mainTips.innerHTML = text;
|
main.dom.mainTips.innerHTML = text;
|
||||||
}
|
}
|
||||||
@ -219,12 +219,14 @@ main.prototype.setMainTipsText = function (text) {
|
|||||||
|
|
||||||
main.prototype.listen = function () {
|
main.prototype.listen = function () {
|
||||||
|
|
||||||
|
////// 窗口大小变化时 //////
|
||||||
window.onresize = function () {
|
window.onresize = function () {
|
||||||
try {
|
try {
|
||||||
main.core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight);
|
main.core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight);
|
||||||
}catch (e) {}
|
}catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 在界面上按下某按键时 //////
|
||||||
main.dom.body.onkeydown = function(e) {
|
main.dom.body.onkeydown = function(e) {
|
||||||
try {
|
try {
|
||||||
if (main.core.isPlaying() || main.core.status.lockControl)
|
if (main.core.isPlaying() || main.core.status.lockControl)
|
||||||
@ -232,6 +234,7 @@ main.dom.body.onkeydown = function(e) {
|
|||||||
} catch (ee) {}
|
} catch (ee) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 在界面上放开某按键时 //////
|
||||||
main.dom.body.onkeyup = function(e) {
|
main.dom.body.onkeyup = function(e) {
|
||||||
try {
|
try {
|
||||||
if (main.core.isPlaying() || main.core.status.lockControl)
|
if (main.core.isPlaying() || main.core.status.lockControl)
|
||||||
@ -239,10 +242,12 @@ main.dom.body.onkeyup = function(e) {
|
|||||||
} catch (ee) {}
|
} catch (ee) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 开始选择时 //////
|
||||||
main.dom.body.onselectstart = function () {
|
main.dom.body.onselectstart = function () {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 鼠标按下时 //////
|
||||||
main.dom.data.onmousedown = function (e) {
|
main.dom.data.onmousedown = function (e) {
|
||||||
try {
|
try {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -257,6 +262,7 @@ main.dom.data.onmousedown = function (e) {
|
|||||||
} catch (ee) {}
|
} catch (ee) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 鼠标移动时 //////
|
||||||
main.dom.data.onmousemove = function (e) {
|
main.dom.data.onmousemove = function (e) {
|
||||||
try {
|
try {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -267,12 +273,14 @@ main.dom.data.onmousemove = function (e) {
|
|||||||
}catch (ee) {}
|
}catch (ee) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 鼠标放开时 //////
|
||||||
main.dom.data.onmouseup = function () {
|
main.dom.data.onmouseup = function () {
|
||||||
try {
|
try {
|
||||||
main.core.onup();
|
main.core.onup();
|
||||||
}catch (e) {}
|
}catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 鼠标滑轮滚动时 //////
|
||||||
main.dom.data.onmousewheel = function(e) {
|
main.dom.data.onmousewheel = function(e) {
|
||||||
try {
|
try {
|
||||||
if (e.wheelDelta)
|
if (e.wheelDelta)
|
||||||
@ -282,6 +290,7 @@ main.dom.data.onmousewheel = function(e) {
|
|||||||
} catch (ee) {}
|
} catch (ee) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 手指在触摸屏开始触摸时 //////
|
||||||
main.dom.data.ontouchstart = function (e) {
|
main.dom.data.ontouchstart = function (e) {
|
||||||
try {
|
try {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -293,6 +302,7 @@ main.dom.data.ontouchstart = function (e) {
|
|||||||
}catch (ee) {}
|
}catch (ee) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 手指在触摸屏上移动时 //////
|
||||||
main.dom.data.ontouchmove = function (e) {
|
main.dom.data.ontouchmove = function (e) {
|
||||||
try {
|
try {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -303,6 +313,7 @@ main.dom.data.ontouchmove = function (e) {
|
|||||||
}catch (ee) {}
|
}catch (ee) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 手指离开触摸屏时 //////
|
||||||
main.dom.data.ontouchend = function () {
|
main.dom.data.ontouchend = function () {
|
||||||
try {
|
try {
|
||||||
main.core.onup();
|
main.core.onup();
|
||||||
@ -310,41 +321,49 @@ main.dom.data.ontouchend = function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击状态栏中的怪物手册时 //////
|
||||||
main.statusBar.image.book.onclick = function () {
|
main.statusBar.image.book.onclick = function () {
|
||||||
if (main.core.isPlaying())
|
if (main.core.isPlaying())
|
||||||
main.core.openBook(true);
|
main.core.openBook(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击状态栏中的楼层传送器时 //////
|
||||||
main.statusBar.image.fly.onclick = function () {
|
main.statusBar.image.fly.onclick = function () {
|
||||||
if (main.core.isPlaying())
|
if (main.core.isPlaying())
|
||||||
main.core.useFly(true);
|
main.core.useFly(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击状态栏中的工具箱时 //////
|
||||||
main.statusBar.image.toolbox.onclick = function () {
|
main.statusBar.image.toolbox.onclick = function () {
|
||||||
if (main.core.isPlaying())
|
if (main.core.isPlaying())
|
||||||
main.core.openToolbox(true);
|
main.core.openToolbox(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击状态栏中的快捷商店时 //////
|
||||||
main.statusBar.image.shop.onclick = function () {
|
main.statusBar.image.shop.onclick = function () {
|
||||||
if (main.core.isPlaying())
|
if (main.core.isPlaying())
|
||||||
main.core.ui.drawQuickShop(true);
|
main.core.ui.drawQuickShop(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击状态栏中的存档按钮时 //////
|
||||||
main.statusBar.image.save.onclick = function () {
|
main.statusBar.image.save.onclick = function () {
|
||||||
if (main.core.isPlaying())
|
if (main.core.isPlaying())
|
||||||
main.core.save(true);
|
main.core.save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击状态栏中的读档按钮时 //////
|
||||||
main.statusBar.image.load.onclick = function () {
|
main.statusBar.image.load.onclick = function () {
|
||||||
if (main.core.isPlaying())
|
if (main.core.isPlaying())
|
||||||
main.core.load(true);
|
main.core.load(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击状态栏中的系统菜单时 //////
|
||||||
main.statusBar.image.settings.onclick = function () {
|
main.statusBar.image.settings.onclick = function () {
|
||||||
if (main.core.isPlaying())
|
if (main.core.isPlaying())
|
||||||
main.core.ui.drawSettings(true);
|
main.core.ui.drawSettings(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击“开始游戏”时 //////
|
||||||
main.dom.playGame.onclick = function () {
|
main.dom.playGame.onclick = function () {
|
||||||
main.dom.startButtons.style.display='none';
|
main.dom.startButtons.style.display='none';
|
||||||
|
|
||||||
@ -356,22 +375,27 @@ main.dom.playGame.onclick = function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击“载入游戏”时 //////
|
||||||
main.dom.loadGame.onclick = function() {
|
main.dom.loadGame.onclick = function() {
|
||||||
main.core.load();
|
main.core.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击“关于本塔”时 //////
|
||||||
main.dom.aboutGame.onclick = function () {
|
main.dom.aboutGame.onclick = function () {
|
||||||
main.core.ui.drawAbout();
|
main.core.ui.drawAbout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击“简单难度”时 //////
|
||||||
main.dom.easyLevel.onclick = function() {
|
main.dom.easyLevel.onclick = function() {
|
||||||
core.events.startGame('Easy');
|
core.events.startGame('Easy');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击“普通难度”时 //////
|
||||||
main.dom.normalLevel.onclick = function () {
|
main.dom.normalLevel.onclick = function () {
|
||||||
core.events.startGame('Normal');
|
core.events.startGame('Normal');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 点击“困难难度”时 //////
|
||||||
main.dom.hardLevel.onclick = function () {
|
main.dom.hardLevel.onclick = function () {
|
||||||
core.events.startGame('Hard');
|
core.events.startGame('Hard');
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user