13
.idea/codeStyleSettings.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectCodeStyleSettingsManager">
|
||||
<option name="PER_PROJECT_SETTINGS">
|
||||
<value>
|
||||
<MarkdownNavigatorCodeStyleSettings>
|
||||
<option name="RIGHT_MARGIN" value="72" />
|
||||
</MarkdownNavigatorCodeStyleSettings>
|
||||
</value>
|
||||
</option>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</component>
|
||||
</project>
|
||||
72
.idea/markdown-navigator.xml
Normal file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MarkdownProjectSettings">
|
||||
<PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="false" showSelectionInPreview="true" openRemoteLinks="true">
|
||||
<PanelProvider>
|
||||
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" />
|
||||
</PanelProvider>
|
||||
</PreviewSettings>
|
||||
<ParserSettings gitHubSyntaxChange="false">
|
||||
<PegdownExtensions>
|
||||
<option name="ABBREVIATIONS" value="false" />
|
||||
<option name="ANCHORLINKS" value="true" />
|
||||
<option name="ASIDE" value="false" />
|
||||
<option name="ATXHEADERSPACE" value="true" />
|
||||
<option name="AUTOLINKS" value="true" />
|
||||
<option name="DEFINITIONS" value="false" />
|
||||
<option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" />
|
||||
<option name="FENCED_CODE_BLOCKS" value="true" />
|
||||
<option name="FOOTNOTES" value="false" />
|
||||
<option name="HARDWRAPS" value="false" />
|
||||
<option name="HTML_DEEP_PARSER" value="false" />
|
||||
<option name="INSERTED" value="false" />
|
||||
<option name="QUOTES" value="false" />
|
||||
<option name="RELAXEDHRULES" value="true" />
|
||||
<option name="SMARTS" value="false" />
|
||||
<option name="STRIKETHROUGH" value="true" />
|
||||
<option name="SUBSCRIPT" value="false" />
|
||||
<option name="SUPERSCRIPT" value="false" />
|
||||
<option name="SUPPRESS_HTML_BLOCKS" value="false" />
|
||||
<option name="SUPPRESS_INLINE_HTML" value="false" />
|
||||
<option name="TABLES" value="true" />
|
||||
<option name="TASKLISTITEMS" value="true" />
|
||||
<option name="TOC" value="false" />
|
||||
<option name="WIKILINKS" value="true" />
|
||||
</PegdownExtensions>
|
||||
<ParserOptions>
|
||||
<option name="COMMONMARK_LISTS" value="true" />
|
||||
<option name="DUMMY" value="false" />
|
||||
<option name="EMOJI_SHORTCUTS" value="true" />
|
||||
<option name="FLEXMARK_FRONT_MATTER" value="false" />
|
||||
<option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="false" />
|
||||
<option name="GFM_TABLE_RENDERING" value="true" />
|
||||
<option name="GITBOOK_URL_ENCODING" value="false" />
|
||||
<option name="GITHUB_EMOJI_URL" value="false" />
|
||||
<option name="GITHUB_LISTS" value="false" />
|
||||
<option name="GITHUB_WIKI_LINKS" value="true" />
|
||||
<option name="JEKYLL_FRONT_MATTER" value="false" />
|
||||
<option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
|
||||
</ParserOptions>
|
||||
</ParserSettings>
|
||||
<HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true" embedImages="false" embedHttpImages="false">
|
||||
<GeneratorProvider>
|
||||
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" />
|
||||
</GeneratorProvider>
|
||||
<headerTop />
|
||||
<headerBottom />
|
||||
<bodyTop />
|
||||
<bodyBottom />
|
||||
</HtmlSettings>
|
||||
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssTextEnabled="false" isDynamicPageWidth="true">
|
||||
<StylesheetProvider>
|
||||
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" />
|
||||
</StylesheetProvider>
|
||||
<ScriptProviders />
|
||||
<cssText />
|
||||
</CssSettings>
|
||||
<HtmlExportSettings updateOnSave="false" parentDir="$ProjectFileDir$" targetDir="$ProjectFileDir$" cssDir="" scriptDir="" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetExt="" useTargetExt="false" noCssNoScripts="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" linkFormatType="HTTP_ABSOLUTE" />
|
||||
<LinkMapSettings>
|
||||
<textMaps />
|
||||
</LinkMapSettings>
|
||||
</component>
|
||||
</project>
|
||||
3
.idea/markdown-navigator/profiles_settings.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<component name="MarkdownNavigator.ProfileManager">
|
||||
<settings default="" pdf-export="" />
|
||||
</component>
|
||||
5
HTML5魔塔样板使用指南.url
Normal file
@ -0,0 +1,5 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,2
|
||||
[InternetShortcut]
|
||||
IDList=
|
||||
URL=http://ckcz123.github.io/mota-js/
|
||||
33
README.md
@ -2,21 +2,36 @@
|
||||
|
||||
## 简介
|
||||
|
||||
HTML5 canvas制作的魔塔样板,支持全平台;即使不会编程的用户,按照模板和说明文档也能很快做出一个魔塔游戏;对于有编程基础的用户,那就更好了,根据文档能做出更个性化的魔塔。
|
||||
HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
|
||||
## 文档
|
||||
**即使完全不会编程的用户,按照模板和说明文档也能很快做出一个魔塔游戏!**
|
||||
|
||||
* [Demo](http://ckcz123.com/games/template/)
|
||||
* [Docs](http://ckcz123.github.io/mota-js)
|
||||
* [Demo / 样板效果](http://ckcz123.com/games/template/)
|
||||
* [Docs / 使用文档说明](http://ckcz123.github.io/mota-js)
|
||||
|
||||

|
||||
|
||||
## 更新说明
|
||||
|
||||
- [x] 新增:战斗过程显示!可在全局Flag中开关,也可针对某一怪物单独设置
|
||||
#### 2017.12.16
|
||||
|
||||
- [x] 新增:战斗过程显示,可以在设置中关闭
|
||||
- [x] 新增:勇士支持48*32(大图)的行走图
|
||||
- [x] 新增:更改画面色调
|
||||
- [x] 新增:文字显示支持自动换行
|
||||
- [x] 部分修改状态栏UI
|
||||
- [ ] 移除doc和pdf文档,现在请参考Web端,有很好的索引。
|
||||
- [x] 移除不再支持的全局变量中的bombTrigger选项
|
||||
- [x] 修复键盘开门导致openDoor重复触发的Bug
|
||||
- [x] 更新快捷商店(文字显示&禁用)
|
||||
- [x] 增添Web的Markdown文档,移除原本的doc和pdf文档。
|
||||
- [x] 修复若干Bug。
|
||||
|
||||
#### 2017.12.9
|
||||
|
||||
- 发布初版HTML5魔塔样板
|
||||
|
||||
|
||||
## 联系我们
|
||||
|
||||
本塔由 `ckcz123` (百度ID `艾之葵`)编写,非常感谢 `iEcho` 在包括状态栏等方面的帮助。
|
||||
|
||||
HTML5魔塔交流群群号: `539113091`
|
||||
|
||||
如有其它意见或建议,也可以通过发issues、或邮件至<a href="mailto:ckcz123.com">ckcz123.com</a>联系我。
|
||||
|
||||
BIN
doc/H5样板使用指南.pdf
419
docs/api.md
@ -1,244 +1,247 @@
|
||||
# 附录:API列表
|
||||
|
||||
所有系统支持的API都列在了这里。可能被做塔时自定义JS脚本中涉及到的以红色字体标出,并有着详细的解释。
|
||||
所有系统支持的API都列在了这里。所有可能被用到的API都在前面用\*标记。
|
||||
|
||||
可以在chrome浏览器的控制台中(`ctrl+shift+I`,找到Console)中直接进行调用,以查看效果。
|
||||
|
||||
!> `core.js`:系统核心文件。所有核心逻辑处理都在此文件完成。
|
||||
!> **`core.js`:系统核心文件。所有核心逻辑处理都在此文件完成。**
|
||||
|
||||
``` js
|
||||
core.status.floorId //获得当前层floorId
|
||||
core.status.thisMap //获得当前层的地图信息
|
||||
* core.status.floorId // 获得当前层floorId
|
||||
* core.status.thisMap // 获得当前层的地图信息
|
||||
|
||||
//------ 初始化部分 ------
|
||||
core.init //初始化
|
||||
core.showStartAnimate //显示开始界面
|
||||
core.hideStartAnimate //隐藏开始界面
|
||||
core.setStartProgressVal //设置加载进度条进度
|
||||
core.setStartLoadTipText //设置加载进度条提示文字
|
||||
core.loader //加载图片和音频
|
||||
core.loadImage //加载图片
|
||||
core.loadSound //加载音频
|
||||
core.loadSoundItem //加载某一个音频
|
||||
core.isPlaying //游戏是否已经开始
|
||||
core.clearStatus //清除游戏状态和数据
|
||||
core.resetStatus //重置游戏状态和初始数据
|
||||
core.startGame //具体开始游戏
|
||||
core.restart //重新开始游戏;此函数将回到标题页面
|
||||
// ------ 初始化部分 ------
|
||||
core.init // 初始化
|
||||
core.showStartAnimate // 显示开始界面
|
||||
core.hideStartAnimate // 隐藏开始界面
|
||||
core.setStartProgressVal // 设置加载进度条进度
|
||||
core.setStartLoadTipText // 设置加载进度条提示文字
|
||||
core.loader // 加载图片和音频
|
||||
core.loadImage // 加载图片
|
||||
core.loadSound // 加载音频
|
||||
core.loadSoundItem // 加载某一个音频
|
||||
core.isPlaying // 游戏是否已经开始
|
||||
core.clearStatus // 清除游戏状态和数据
|
||||
core.resetStatus // 重置游戏状态和初始数据
|
||||
core.startGame // 具体开始游戏
|
||||
* core.restart // 重新开始游戏;此函数将回到标题页面
|
||||
|
||||
//------ 键盘、鼠标事件 ------
|
||||
core.onKeyDown //按下某个键时
|
||||
core.onKeyUp //放开某个键时
|
||||
core.pressKey //按住某个键不动时
|
||||
core.keyDown //根据按下键的code来执行一系列操作
|
||||
core.keyUp //根据放开键的code来执行一系列操作
|
||||
core.ondown //点击(触摸)事件按下时
|
||||
core.onmove //当在触摸屏上滑动时
|
||||
core.onup //当点击(触摸)事件放开时
|
||||
core.getClickLoc //获得点击事件相对左上角的坐标(0到12之间)
|
||||
core.onclick //具体点击屏幕上(x,y)点时,执行的操作
|
||||
core.onmousewheel //滑动鼠标滚轮时的操作(楼层传送时可用滚轮切换楼层)
|
||||
// ------ 键盘、鼠标事件 ------
|
||||
core.onKeyDown // 按下某个键时
|
||||
core.onKeyUp // 放开某个键时
|
||||
core.pressKey // 按住某个键不动时
|
||||
core.keyDown // 根据按下键的code来执行一系列操作
|
||||
core.keyUp // 根据放开键的code来执行一系列操作
|
||||
core.ondown // 点击(触摸)事件按下时
|
||||
core.onmove // 当在触摸屏上滑动时
|
||||
core.onup // 当点击(触摸)事件放开时
|
||||
core.getClickLoc // 获得点击事件相对左上角的坐标(0到12之间)
|
||||
core.onclick // 具体点击屏幕上(x,y)点时,执行的操作
|
||||
core.onmousewheel // 滑动鼠标滚轮时的操作(楼层传送时可用滚轮切换楼层)
|
||||
|
||||
//------ 自动寻路代码相关 ------
|
||||
core.clearAutomaticRouteNode //清除自动寻路路线
|
||||
core.stopAutomaticRoute //停止自动寻路操作
|
||||
core.continueAutomaticRoute //继续剩下的自动寻路操作
|
||||
core.clearContinueAutomaticRoute //清除剩下的自动寻路列表
|
||||
core.setAutomaticRoute //设置一个自动寻路
|
||||
core.automaticRoute //自动寻路算法,找寻最优路径
|
||||
core.fillPosWithPoint //显示离散的寻路点
|
||||
core.clearStepPostfix //清除已经寻路过的部分
|
||||
// ------ 自动寻路代码相关 ------
|
||||
core.clearAutomaticRouteNode // 清除自动寻路路线
|
||||
core.stopAutomaticRoute // 停止自动寻路操作
|
||||
core.continueAutomaticRoute // 继续剩下的自动寻路操作
|
||||
core.clearContinueAutomaticRoute // 清除剩下的自动寻路列表
|
||||
core.setAutomaticRoute // 设置一个自动寻路
|
||||
core.automaticRoute // 自动寻路算法,找寻最优路径
|
||||
core.fillPosWithPoint // 显示离散的寻路点
|
||||
core.clearStepPostfix // 清除已经寻路过的部分
|
||||
|
||||
//------ 自动行走,行走控制 ------
|
||||
core.stopAutoHeroMove //停止勇士的自动行走
|
||||
core.setAutoHeroMove //设置勇士的自动行走路线
|
||||
core.autoHeroMove //让勇士开始自动行走
|
||||
core.setHeroMoveInterval //设置行走的效果动画
|
||||
core.setHeroMoveTriggerInterval //设置勇士行走过程中对途经事件的触发检测
|
||||
core.turnHero(direction) //设置勇士的方向(转向);如果指定了direction则会面向该方向,否则执行一个转向操作。
|
||||
core.moveHero //让勇士开始移动
|
||||
core.moveOneStep //每移动一格后执行的事件。中毒时在这里进行扣血判断。
|
||||
core.waitHeroToStop(callback) //停止勇士的一切行动,等待勇士行动结束后,再执行callback回调函数。
|
||||
core.stopHero //停止勇士的移动状态。
|
||||
core.drawHero //在hero层绘制勇士。
|
||||
core.setHeroLoc(name, value) //设置勇士的位置。name为”direction”,”x”,”y”
|
||||
core.getHeroLoc(name) //获得勇士的位置。
|
||||
core.nextX //获得勇士面对位置的x坐标
|
||||
core.nextY //获得勇士面对位置的y坐标
|
||||
// ------ 自动行走,行走控制 ------
|
||||
core.stopAutoHeroMove // 停止勇士的自动行走
|
||||
core.setAutoHeroMove // 设置勇士的自动行走路线
|
||||
core.autoHeroMove // 让勇士开始自动行走
|
||||
core.setHeroMoveInterval // 设置行走的效果动画
|
||||
core.setHeroMoveTriggerInterval // 设置勇士行走过程中对途经事件的触发检测
|
||||
* core.turnHero(direction) // 设置勇士的方向(转向);如果指定了direction则会面向该方向,否则执行一个转向操作。
|
||||
core.moveHero // 让勇士开始移动
|
||||
core.moveOneStep // 每移动一格后执行的事件。中毒时在这里进行扣血判断。
|
||||
core.waitHeroToStop(callback) // 停止勇士的一切行动,等待勇士行动结束后,再执行callback回调函数。
|
||||
core.stopHero // 停止勇士的移动状态。
|
||||
core.drawHero // 在hero层绘制勇士。
|
||||
* core.setHeroLoc(name, value) // 设置勇士的位置。name为”direction”,”x”,”y”
|
||||
* core.getHeroLoc(name) // 获得勇士的位置。
|
||||
* core.nextX // 获得勇士面对位置的x坐标
|
||||
* core.nextY // 获得勇士面对位置的y坐标
|
||||
|
||||
//------ 地图和事件处理 ------
|
||||
core.openDoor(id, x, y, needKey, callback) //打开一扇位于 (x,y) 的门
|
||||
core.battle(id, x, y, force, callback) //进行战斗;force表示是否强制战斗
|
||||
core.trigger(x,y) //触发x,y点的事件
|
||||
core.changeFloor(floorId, stair, heroLoc, time, callback) //楼层切换floorId为目标楼层Id,stair可指定为上/下楼梯,time动画时间
|
||||
core.mapChangeAnimate //实际切换的动画效果
|
||||
core.clearMap //清除地图显示
|
||||
core.fillText //在某个canvas上绘制一段文字
|
||||
core.fillRect //在某个canvas上绘制一个矩形
|
||||
core.strokeRect //在某个canvas上绘制一个矩形的边框
|
||||
core.setFont //设置某个canvas的文字字体
|
||||
core.setLineWidth //设置某个canvas的线宽度
|
||||
core.saveCanvas //保存某个canvas状态
|
||||
core.loadCanvas //读取某个canvas状态
|
||||
core.setStrokeStyle //设置某个canvas边框属性
|
||||
core.setAlpha //设置某个canvas的alpha值
|
||||
core.setOpacity //设置某个canvas的透明度
|
||||
core.setFillStyle //设置某个canvas的绘制属性(如颜色等)
|
||||
core.drawMap(mapId, callback) //绘制某张地图。mapId为地图Id,绘制完毕将执行callback回调函数。
|
||||
core.noPassExists(x,y) //某个点是否不可通行
|
||||
core.noPass //某个点是否在区域内且不可通行
|
||||
core.npcExists(x,y) //某个点是否存在NPC
|
||||
core.terrainExists(x,y) //某个点是否存在指定的地形
|
||||
core.stairExists(x,y) //某个点是否存在楼梯
|
||||
core.nearStair //当前位置是否在楼梯边
|
||||
core.enemyExists(x,y) //某个点是否存在怪物
|
||||
core.getBlock(x, y, floorId, needEnable) // 获得某个点的block。floorId指定目标楼层,needEnable如果为false则即使该点的事件处于禁用状态也将被返回(否则只有事件启用的点才被返回)
|
||||
core.moveBlock //显示移动某块的动画,达到{“type”:”move”}的效果
|
||||
core.animateBlock //显示/隐藏某个块时的动画效果
|
||||
core.addBlock //将某个块从禁用变成启用状态
|
||||
core.removeBlock //将某个块从启用变成禁用状态
|
||||
core.removeBlockById //根据block的索引删除该块
|
||||
core.removeBlockByIds //一次性删除多个block
|
||||
core.addGlobalAnimate //添加一个全局动画
|
||||
core.removeGlobalAnimate //删除一个或所有全局动画
|
||||
core.setGlobalAnimate //设置全局动画的显示效果
|
||||
core.setBoxAnimate //显示UI层某个box的动画(如怪物手册中怪物的动画)
|
||||
// ------ 地图和事件处理 ------
|
||||
* core.openDoor(id, x, y, needKey, callback) // 打开一扇位于 (x,y) 的门
|
||||
* core.battle(id, x, y, force, callback) // 进行战斗;force表示是否强制战斗
|
||||
core.afterBattle // 战斗完毕
|
||||
core.trigger(x,y) // 触发x,y点的事件
|
||||
* core.changeFloor(floorId, stair, heroLoc, time, callback) // 楼层切换floorId为目标楼层Id,stair可指定为上/下楼梯,time动画时间
|
||||
core.mapChangeAnimate // 实际切换的动画效果
|
||||
core.clearMap // 清除地图显示
|
||||
core.fillText // 在某个canvas上绘制一段文字
|
||||
core.fillRect // 在某个canvas上绘制一个矩形
|
||||
core.strokeRect // 在某个canvas上绘制一个矩形的边框
|
||||
core.setFont // 设置某个canvas的文字字体
|
||||
core.setLineWidth // 设置某个canvas的线宽度
|
||||
core.saveCanvas // 保存某个canvas状态
|
||||
core.loadCanvas // 读取某个canvas状态
|
||||
core.setStrokeStyle // 设置某个canvas边框属性
|
||||
core.setAlpha // 设置某个canvas的alpha值
|
||||
core.setOpacity // 设置某个canvas的透明度
|
||||
core.setFillStyle // 设置某个canvas的绘制属性(如颜色等)
|
||||
* core.drawMap(mapId, callback) // 绘制某张地图。mapId为地图Id,绘制完毕将执行callback回调函数。
|
||||
* core.noPassExists(x,y) // 某个点是否不可通行
|
||||
core.noPass // 某个点是否在区域内且不可通行
|
||||
* core.npcExists(x,y) // 某个点是否存在NPC
|
||||
* core.terrainExists(x,y) // 某个点是否存在指定的地形
|
||||
* core.stairExists(x,y) // 某个点是否存在楼梯
|
||||
* core.nearStair // 当前位置是否在楼梯边
|
||||
* core.enemyExists(x,y) // 某个点是否存在怪物
|
||||
* core.getBlock(x, y, floorId, needEnable) // 获得某个点的block。floorId指定目标楼层,needEnable如果为false则即使该点的事件处于禁用状态也将被返回(否则只有事件启用的点才被返回)
|
||||
core.moveBlock // 显示移动某块的动画,达到{“type”:”move”}的效果
|
||||
core.animateBlock // 显示/隐藏某个块时的动画效果
|
||||
core.addBlock // 将某个块从禁用变成启用状态
|
||||
core.removeBlock // 将某个块从启用变成禁用状态
|
||||
core.removeBlockById // 根据block的索引删除该块
|
||||
core.removeBlockByIds // 一次性删除多个block
|
||||
core.addGlobalAnimate // 添加一个全局动画
|
||||
core.removeGlobalAnimate // 删除一个或所有全局动画
|
||||
core.setGlobalAnimate // 设置全局动画的显示效果
|
||||
core.setBoxAnimate // 显示UI层某个box的动画(如怪物手册中怪物的动画)
|
||||
core.drawBoxAnimate // 绘制UI层的box动画
|
||||
core.updateFg() //更新全地图的显伤
|
||||
core.itemCount //获得某个物品的个数
|
||||
core.hasItem //是否存在某个物品
|
||||
core.setItem //设置某个物品的个数
|
||||
core.removeItem //删除某个物品
|
||||
core.useItem // 使用某个物品;直接调用items.js中的useItem函数。
|
||||
core.canUseItem //能否使用某个物品。直接调用items.js中的canUseItem函数。
|
||||
core.addItem //增加某个物品的个数
|
||||
core.getItem //获得某个物品时的事件
|
||||
core.drawTip //左上角绘制一段提示
|
||||
core.drawText //地图中间绘制一段文字
|
||||
core.setFg // 色调渐变
|
||||
* core.updateFg // 更新全地图的显伤
|
||||
* core.itemCount // 获得某个物品的个数
|
||||
* core.hasItem // 是否存在某个物品
|
||||
* core.setItem // 设置某个物品的个数
|
||||
* core.removeItem // 删除某个物品
|
||||
* core.useItem // 使用某个物品;直接调用items.js中的useItem函数。
|
||||
* core.canUseItem // 能否使用某个物品。直接调用items.js中的canUseItem函数。
|
||||
* core.addItem // 增加某个物品的个数
|
||||
* core.getItem // 获得某个物品时的事件
|
||||
* core.drawTip // 左上角绘制一段提示
|
||||
* core.drawText // 地图中间绘制一段文字
|
||||
|
||||
//------ 系统机制 ------
|
||||
core.replaceText //将文字中的${和}(表达式)进行替换
|
||||
core.calValue //计算表达式的值
|
||||
core.unshift //向某个数组前插入另一个数组或元素
|
||||
core.setLocalStorage //设置本地存储
|
||||
core.getLocalStorage //获得本地存储
|
||||
core.removeLocalStorage //移除本地存储
|
||||
core.clone //复制一个对象
|
||||
core.formatDate //格式化时间为字符串
|
||||
core.setTwoDigits //两位数显示
|
||||
core.win //获胜;将直接调用events.js中的win函数
|
||||
core.lose //失败;将直接调用events.js中的lose函数
|
||||
core.debug //进入Debug模式,攻防血和钥匙都调成很高的数值
|
||||
core.checkStatus //判断当前能否进入某个事件
|
||||
core.openBook //点击怪物手册时的打开操作
|
||||
core.useFly //点击楼层传送器时的打开操作
|
||||
core.openToolbox //点击工具栏时的打开操作
|
||||
core.save //点击保存按钮时的打开操作
|
||||
core.load //点击读取按钮时的打开操作
|
||||
core.doSL //实际进行存读档事件
|
||||
core.syncSave //存档同步操作
|
||||
core.saveData //存档到本地
|
||||
core.loadData //从本地读档
|
||||
core.setStatus //设置勇士属性
|
||||
core.getStatus //获得勇士属性
|
||||
core.setFlag //设置某个自定义变量或flag
|
||||
core.getFlag //获得某个自定义变量或flag
|
||||
core.hasFlag //是否存在某个自定义变量或flag,且值为true
|
||||
core.insertAction //往当前事件列表之前插入一系列事件
|
||||
core.lockControl //锁定状态栏,常常用于事件处理
|
||||
core.unlockControl //解锁状态栏
|
||||
core.isset //判断某对象是否不为undefined也不会null
|
||||
core.playSound //播放音频
|
||||
core.playBgm //播放背景音乐
|
||||
core.changeSoundStatus //切换声音状态
|
||||
core.enableSound //启用音效
|
||||
core.disableSound //禁用音效
|
||||
core.show //动画显示某对象
|
||||
core.hide //动画使某对象消失
|
||||
core.clearStatusBar //清空状态栏
|
||||
core.updateStatusBar //更新状态栏
|
||||
core.resize //屏幕分辨率改变后重新自适应
|
||||
core.resetSize //屏幕分辨率改变后重新自适应
|
||||
// ------ 系统机制 ------
|
||||
core.replaceText // 将文字中的${和}(表达式)进行替换
|
||||
core.calValue // 计算表达式的值
|
||||
core.splitText // 字符串自动换行的分割
|
||||
core.unshift // 向某个数组前插入另一个数组或元素
|
||||
core.setLocalStorage // 设置本地存储
|
||||
core.getLocalStorage // 获得本地存储
|
||||
core.removeLocalStorage // 移除本地存储
|
||||
core.clone // 复制一个对象
|
||||
core.formatDate // 格式化时间为字符串
|
||||
core.setTwoDigits // 两位数显示
|
||||
core.win // 获胜;将直接调用events.js中的win函数
|
||||
core.lose // 失败;将直接调用events.js中的lose函数
|
||||
core.debug // 进入Debug模式,攻防血和钥匙都调成很高的数值
|
||||
core.checkStatus // 判断当前能否进入某个事件
|
||||
core.openBook // 点击怪物手册时的打开操作
|
||||
core.useFly // 点击楼层传送器时的打开操作
|
||||
core.openToolbox // 点击工具栏时的打开操作
|
||||
core.save // 点击保存按钮时的打开操作
|
||||
core.load // 点击读取按钮时的打开操作
|
||||
core.doSL // 实际进行存读档事件
|
||||
core.syncSave // 存档同步操作
|
||||
core.saveData // 存档到本地
|
||||
core.loadData // 从本地读档
|
||||
* core.setStatus // 设置勇士属性
|
||||
* core.getStatus // 获得勇士属性
|
||||
* core.setFlag // 设置某个自定义变量或flag
|
||||
* core.getFlag // 获得某个自定义变量或flag
|
||||
* core.hasFlag // 是否存在某个自定义变量或flag,且值为true
|
||||
core.insertAction // 往当前事件列表之前插入一系列事件
|
||||
* core.lockControl // 锁定状态栏,常常用于事件处理
|
||||
* core.unlockControl // 解锁状态栏
|
||||
* core.isset // 判断某对象是否不为undefined也不会null
|
||||
* core.playSound // 播放音频
|
||||
* core.playBgm // 播放背景音乐
|
||||
core.changeSoundStatus // 切换声音状态
|
||||
core.enableSound // 启用音效
|
||||
core.disableSound // 禁用音效
|
||||
core.show // 动画显示某对象
|
||||
core.hide // 动画使某对象消失
|
||||
core.clearStatusBar // 清空状态栏
|
||||
core.updateStatusBar // 更新状态栏
|
||||
core.resize // 屏幕分辨率改变后重新自适应
|
||||
core.resetSize // 屏幕分辨率改变后重新自适应
|
||||
|
||||
//------ core.js 结束 ------
|
||||
// ------ core.js 结束 ------
|
||||
```
|
||||
|
||||
!> `data.js` 定义了一些初始化的数据信息。
|
||||
!> **`data.js` 定义了一些初始化的数据信息。**
|
||||
|
||||
!> `enemys.js` 定义了怪物信息。
|
||||
!> **`enemys.js` 定义了怪物信息。**
|
||||
|
||||
``` js
|
||||
core.enemys.getSpecialText //获得特殊属性的文字
|
||||
core.enemys.getDamage //获得某个怪物的伤害
|
||||
core.enemys.getCritical //计算某个怪物的临界值
|
||||
core.enemys.getCriticalDamage //计算某个怪物的临界减伤
|
||||
core.enemys.getDefDamage //计算某个怪物的1防减伤
|
||||
core.enemys.calDamage //实际的伤害计算公式
|
||||
core.enemys.getCurrentEnemys //获得当前层剩下的的怪物列表
|
||||
|
||||
* core.enemys.getSpecialText // 获得特殊属性的文字
|
||||
* core.enemys.getDamage // 获得某个怪物的伤害
|
||||
* core.enemys.getExtraDamage // 获得某个怪物的额外伤害(吸血)
|
||||
* core.enemys.getCritical // 计算某个怪物的临界值
|
||||
* core.enemys.getCriticalDamage // 计算某个怪物的临界减伤
|
||||
* core.enemys.getDefDamage // 计算某个怪物的1防减伤
|
||||
* core.enemys.calDamage // 实际的伤害计算公式
|
||||
core.enemys.getCurrentEnemys // 获得当前层剩下的的怪物列表
|
||||
```
|
||||
|
||||
!> `events.js` 定义了各个事件的处理流程。
|
||||
!> **`events.js` 定义了各个事件的处理流程。**
|
||||
|
||||
``` js
|
||||
core.events.startGame //开始游戏
|
||||
core.events.win //获胜
|
||||
core.events.lose //失败
|
||||
core.events.checkBlock //检查领域、夹击事件
|
||||
core.events.afterChangeFloor //楼层切换结束时的事件
|
||||
core.events.doEvents //开始执行一系列自定义事件
|
||||
core.events.doAction //执行当前自定义事件列表中的下一个事件
|
||||
core.events.insertAction //往当前自定义事件列表前插入若干个事件
|
||||
core.events.openShop //打开一个全局商店
|
||||
core.events.disableQuickShop //禁用一个快捷商店
|
||||
core.events.canUseQuickShop //当前能否使用快捷商店
|
||||
core.events.useItem //尝试使用道具
|
||||
core.events.afterBattle //战斗结束后触发的事件
|
||||
core.events.afterOpenDoor //开一个门后触发的事件
|
||||
core.events.passNet //经过一个路障
|
||||
core.events.beforeSaveData //即将存档前可以执行的操作
|
||||
core.events.afterLoadData //读档后,载入事件前可以执行的操作
|
||||
|
||||
//------ 界面上的点击事件 ------
|
||||
core.events.clickAction //自定义事件处理时,对用户点击的处理
|
||||
core.events.clickBook //怪物手册打开时,对用户点击的处理
|
||||
core.events.clickFly //楼层传送器打开时,对用户点击的处理
|
||||
core.events.clickShop //全局商店打开时,对用户点击的处理
|
||||
core.events.clickQuickShop //快捷商店选项打开时
|
||||
core.events.clickToolbox //工具栏打开时
|
||||
core.events.clickSL //存/读档界面打开时
|
||||
core.events.clickSettings //设置页面打开时
|
||||
* core.events.startGame // 开始游戏
|
||||
* core.events.win // 获胜
|
||||
* core.events.lose // 失败
|
||||
core.events.checkBlock // 检查领域、夹击事件
|
||||
core.events.afterChangeFloor // 楼层切换结束时的事件
|
||||
core.events.doEvents // 开始执行一系列自定义事件
|
||||
core.events.doAction // 执行当前自定义事件列表中的下一个事件
|
||||
core.events.insertAction // 往当前自定义事件列表前插入若干个事件
|
||||
core.events.openShop // 打开一个全局商店
|
||||
core.events.disableQuickShop // 禁用一个快捷商店
|
||||
* core.events.canUseQuickShop // 当前能否使用快捷商店
|
||||
* core.events.useItem // 尝试使用道具
|
||||
core.events.afterBattle // 战斗结束后触发的事件
|
||||
core.events.afterOpenDoor // 开一个门后触发的事件
|
||||
core.events.passNet // 经过一个路障
|
||||
core.events.beforeSaveData // 即将存档前可以执行的操作
|
||||
core.events.afterLoadData // 读档后,载入事件前可以执行的操作
|
||||
|
||||
// ------ 界面上的点击事件 ------
|
||||
core.events.clickAction // 自定义事件处理时,对用户点击的处理
|
||||
core.events.clickBook // 怪物手册打开时,对用户点击的处理
|
||||
core.events.clickFly // 楼层传送器打开时,对用户点击的处理
|
||||
core.events.clickShop // 全局商店打开时,对用户点击的处理
|
||||
core.events.clickQuickShop // 快捷商店选项打开时
|
||||
core.events.clickToolbox // 工具栏打开时
|
||||
core.events.clickSL // 存/读档界面打开时
|
||||
core.events.clickSettings // 设置页面打开时
|
||||
```
|
||||
|
||||
!> `maps.js` 定义了地图,以及每个数字所代表的意义。
|
||||
|
||||
``` js
|
||||
core.maps.loadFloor //加载某个楼层(从剧本或存档中)
|
||||
core.maps.getBlock //将数字替换成实际的内容
|
||||
core.maps.addEvent //向该楼层添加剧本的自定义事件
|
||||
core.maps.addChangeFloor //向该楼层添加剧本的楼层转换事件
|
||||
core.maps.initMaps //初始化所有地图
|
||||
core.maps.save //将当前地图重新变成数字,以便于存档
|
||||
core.maps.load //将存档中的地图信息重新读取出来
|
||||
core.maps.loadFloor // 加载某个楼层(从剧本或存档中)
|
||||
core.maps.getBlock // 将数字替换成实际的内容
|
||||
core.maps.addEvent // 向该楼层添加剧本的自定义事件
|
||||
core.maps.addChangeFloor // 向该楼层添加剧本的楼层转换事件
|
||||
core.maps.initMaps // 初始化所有地图
|
||||
core.maps.save // 将当前地图重新变成数字,以便于存档
|
||||
core.maps.load // 将存档中的地图信息重新读取出来
|
||||
```
|
||||
|
||||
!> `ui.js` 定义了各种界面的绘制。
|
||||
|
||||
``` js
|
||||
core.ui.closePanel //结束一切事件和绘制,关闭UI窗口,返回游戏进程
|
||||
core.ui.drawTextBox //绘制一个对话框
|
||||
core.ui.drawChoices //绘制一个选项界面
|
||||
core.ui.drawConfirmBox //绘制一个确认/取消的警告页面
|
||||
core.ui.drawSettings //绘制系统菜单栏
|
||||
core.ui.drawQuickShop //绘制快捷商店选择栏
|
||||
core.ui.drawWaiting //绘制一个“请稍后”页面
|
||||
core.ui.drawSyncSave //绘制存档同步选项
|
||||
core.ui.drawPagination //绘制分页
|
||||
core.ui.drawEnemyBook //绘制怪物手册
|
||||
core.ui.drawFly //绘制楼层传送器
|
||||
core.ui.drawToolbox //绘制道具栏
|
||||
core.ui.drawSLPanel //绘制存档/读档界面
|
||||
core.ui.drawThumbnail //绘制一个缩略图
|
||||
core.ui.drawAbout //绘制“关于”界面
|
||||
core.ui.closePanel // 结束一切事件和绘制,关闭UI窗口,返回游戏进程
|
||||
core.ui.drawTextBox // 绘制一个对话框
|
||||
core.ui.drawChoices // 绘制一个选项界面
|
||||
core.ui.drawConfirmBox // 绘制一个确认/取消的警告页面
|
||||
core.ui.drawSettings // 绘制系统菜单栏
|
||||
core.ui.drawQuickShop // 绘制快捷商店选择栏
|
||||
core.ui.drawBattleAnimate // 绘制战斗过程
|
||||
core.ui.drawWaiting // 绘制一个“请稍后”页面
|
||||
core.ui.drawSyncSave // 绘制存档同步选项
|
||||
core.ui.drawPagination // 绘制分页
|
||||
core.ui.drawEnemyBook // 绘制怪物手册
|
||||
core.ui.drawFly // 绘制楼层传送器
|
||||
core.ui.drawToolbox // 绘制道具栏
|
||||
core.ui.drawSLPanel // 绘制存档/读档界面
|
||||
core.ui.drawThumbnail // 绘制一个缩略图
|
||||
core.ui.drawAbout // 绘制“关于”界面
|
||||
```
|
||||
|
||||
2
docs/docsify.min.js
vendored
Normal file
@ -3,19 +3,20 @@
|
||||
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
|
||||
|
||||
请打开样板0层 `sample0.js` 进行参照对比。
|
||||
|
||||

|
||||
|
||||
## 道具
|
||||
|
||||
本塔目前支持的所有道具列表在样板0层中已全部给出。当你在样板0层中拿到某个宝物时会有提示,这里不再赘述,详见拿到该道具的说明。
|
||||
|
||||
大多数宝物都有默认的效果,十字架和屠龙匕首暂未定义,如有自己的需求可参见[自定义道具效果](./personalization#自定义道具效果)。
|
||||
大多数宝物都有默认的效果,十字架和屠龙匕首暂未定义,如有自己的需求可参见[自定义道具效果](personalization#自定义道具效果)。
|
||||
|
||||
!> 请注意,本塔没有"装备"的说法,所有剑盾拿到后将立刻作为攻防数值直接加到勇士的属性上。
|
||||
|
||||
拿到道具后将触发`afterGetItem`事件,有关事件的详细介绍请参见[事件](./event)。
|
||||
拿到道具后将触发`afterGetItem`事件,有关事件的详细介绍请参见[事件](event)。
|
||||
|
||||
如需修改某个道具的效果,在不同区域宝石数据发生变化等问题,请参见[自定义道具效果](./personalization#自定义道具效果)的说明。
|
||||
如需修改某个道具的效果,在不同区域宝石数据发生变化等问题,请参见[自定义道具效果](personalization#自定义道具效果)的说明。
|
||||
|
||||
## 门
|
||||
|
||||
@ -27,11 +28,12 @@
|
||||
|
||||
## 怪物
|
||||
|
||||
本塔支持的怪物列表参见`enemys.js`。其与images目录下的`enemys.png`素材按顺序一一对应。如不知道怪物素材长啥样的请打开`enemys.png`对比查看。
|
||||
如有自己的怪物素材需求请参见[自定义素材](./personalization#自定义素材)的内容。
|
||||
本塔支持的怪物列表参见`enemys.js`。其与images目录下的`enemys.png`素材按顺序一一对应。如不知道怪物素材长啥样的请打开`enemys.png`对比查看。
|
||||
如有自己的怪物素材需求请参见[自定义素材](personalization#自定义素材)的内容。
|
||||
|
||||
怪物可以由特殊属性,每个怪物最多只能有一个特殊属性。怪物的特殊属性所对应的数字(special)在下面的`getSpecialText`中定义,请勿对已有的属性进行修改。
|
||||

|
||||
|
||||

|
||||
|
||||
怪物的伤害计算在下面的`calDamage`函数中,如有自己需求的伤害计算公式请修改该函数的代码。
|
||||
|
||||
@ -40,26 +42,31 @@
|
||||
拿到幸运金币后,打怪获得的金币将翻倍。
|
||||
|
||||
吸血怪需要在怪物后添加value,代表吸血的比例。
|
||||
|
||||

|
||||
|
||||
中毒怪让勇士中毒后,每步扣减的生命值由`data.js`中的values定义。
|
||||
衰弱怪让勇士衰弱后,攻防会暂时下降一定的数值(直到衰弱状态解除恢复);这个下降的数值同在`data.js`中的values定义。
|
||||
|
||||

|
||||
|
||||
诅咒怪将让勇士陷入诅咒状态,诅咒状态下杀怪不获得金币和经验值。
|
||||
|
||||
领域怪需要在怪物后添加value,代表领域伤害的数值。如果勇士生命值扣减到0,则直接死亡触发lose事件。
|
||||

|
||||
|
||||

|
||||
|
||||
出于游戏性能的考虑,我们不可能每走一步都对领域和夹击进行检查。因此我们需要在本楼层的 checkBlock 中指明哪些点可能会触发领域和夹击事件,在这些点才会对领域和夹击进行检查和处理。
|
||||
|
||||
!> 请注意这里的`"x,y"`代表该点的横坐标为x,纵坐标为y;即从左到右第x列,从上到下的第y行(从0开始计算)。
|
||||

|
||||
|
||||
!> **请注意这里的`"x,y"`代表该点的横坐标为x,纵坐标为y;即从左到右第x列,从上到下的第y行(从0开始计算)。**
|
||||
|
||||
本塔不支持阻击、激光、仇恨、自爆、退化等属性。
|
||||
|
||||
(这些属性基本都太恶心了,恶心到都不想加上去)
|
||||
|
||||
如有额外需求,可参见[自定义自定义怪物属性](./personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。
|
||||
如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。
|
||||
|
||||
### 路障、楼梯、传送门
|
||||
|
||||
@ -68,9 +75,10 @@
|
||||
路障同样会尽量被自动寻路绕过。
|
||||
|
||||
有关楼梯和传送门,必须在该层样板的changeFloor里指定传送点的目标。
|
||||

|
||||
|
||||
!> 请注意这里的`"x,y"`代表该点的横坐标为x,纵坐标为y;即从左到右第x列,从上到下的第y行(从0开始计算)。如(6,0)代表最上面一行的正中间一列。
|
||||

|
||||
|
||||
!> **请注意这里的`"x,y"`代表该点的横坐标为x,纵坐标为y;即从左到右第x列,从上到下的第y行(从0开始计算)。如(6,0)代表最上面一行的正中间一列。**
|
||||
|
||||
floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
|
||||
@ -83,8 +91,18 @@ floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
可以指定time,指定后切换动画时长为指定的数值。
|
||||
|
||||
楼梯和传送门默认可`"穿透"`。所谓穿透,就是当寻路穿过一个楼梯/传送门后,不会触发楼层传送事件,而是继续前进。通过系统Flag可以指定是否穿透,你也可以对每个传送点单独设置该项。
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
上面就是整个样板中的各个元件说明。通过这种方式,你就已经可以做出一部没有任何事件的塔了。
|
||||
|
||||
尝试着做一个两到三层的塔吧!
|
||||
|
||||
==========================================================================================
|
||||
|
||||
[继续阅读下一章:事件](event)
|
||||
|
||||
|
||||
688
docs/event.md
BIN
docs/img/checkblock.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/img/chrome.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 124 KiB |
BIN
docs/img/flag.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
BIN
docs/img/imginfo.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
docs/img/init.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
@ -7,7 +7,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="description" content="Description">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
||||
<link rel="stylesheet" href="vue.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
@ -43,6 +43,6 @@
|
||||
navigator.serviceWorker.register('serviceWorker.js')
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
<script src="docsify.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -10,3 +10,7 @@
|
||||
> 这个魔塔样板,可以让你在完全不懂任何编程的情况下,做出自己的H5魔塔。不会代码?没关系!只要你想做,就能做出来!
|
||||
|
||||
继续查看文档的详细介绍,让你学会如何使用这一个样板来制作属于自己的HTML5魔塔。
|
||||
|
||||
==========================================================================================
|
||||
|
||||
[继续阅读下一章:现在就做出自己的第一部H5魔塔!](start)
|
||||
|
||||
@ -5,18 +5,12 @@
|
||||
## 自定义素材
|
||||
|
||||
所有素材的图片都在`images`目录下。
|
||||
|
||||
`animates.png` 为所有动画效果。主要是星空熔岩,开门,毒网,传送门之类的效果。为四帧。
|
||||
|
||||
`enemys.png` 为所有怪物的图片。地图生成器中对应的数字,从上至下依次是会从201开始计算(即,绿色史莱姆为201,小蝙蝠为205,依次类推)。请注意,动画效果为两帧,一般是原始四帧中的1和3。(四帧中12相同,34相同,因此只取1和3即可)
|
||||
|
||||
`heros.png`为勇士行走图。这里是`4*3`的,你也可以用`4*4`的,不过需要一些修改,之后会提到。
|
||||
|
||||
`items.png` 为所有道具的图标。
|
||||
|
||||
`npcs.png` 为所有NPC的图标,也是两帧。
|
||||
|
||||
`terrains.png` 为所有地形的图标。
|
||||
- `animates.png` 为所有动画效果。主要是星空熔岩,开门,毒网,传送门之类的效果。为四帧。
|
||||
- `enemys.png` 为所有怪物的图片。地图生成器中对应的数字,从上至下依次是会从201开始计算(即,绿色史莱姆为201,小蝙蝠为205,依次类推)。请注意,动画效果为两帧,一般是原始四帧中的1和3。(四帧中12相同,34相同,因此只取1和3即可)
|
||||
- `heros.png`为勇士行走图。
|
||||
- `items.png` 为所有道具的图标。
|
||||
- `npcs.png` 为所有NPC的图标,也是两帧。
|
||||
- `terrains.png` 为所有地形的图标。
|
||||
|
||||
系统会读取`icon.js`文件,并获取每个ID对应的图标所在的位置。
|
||||
|
||||
@ -27,6 +21,7 @@
|
||||
在使用自定义素材后,我们可以使用地图生成器来识别新的素材。打开同目录下的`meaning.txt`,按照已有的方式来增加或编辑内容即可。
|
||||
|
||||
第一列是地图生成器中的数字,第二列是它所在的文件名,第三列是坐标。
|
||||
|
||||

|
||||
|
||||
### 使用自定义地形(路面、墙壁等)
|
||||
@ -46,22 +41,20 @@
|
||||
如果`items.png`中不存在你需要的图标,则可以自己P一张图,将你需要的图标覆盖到某个用不到的图标上。或者也可以接着后面向下拉伸。
|
||||
|
||||
所有道具必须是`32x32`像素。
|
||||
|
||||
P图完毕后,可以在地图生成器中加入对应的数字和图标的对应关系。
|
||||
|
||||
要在系统中启用你的图标,你需要自己指定一个道具的ID(不能和任何已有的重名),然后进行如下操作:
|
||||
|
||||
- 在`items.js`中道具的定义列表中编辑,修改你的自定义道具的名称,类型,说明文字等。
|
||||
1. 在`items.js`中道具的定义列表中编辑,修改你的自定义道具的名称,类型,说明文字等。
|
||||
- 即捡即用类道具的cls为items,消耗类道具的cls为tools,永久类道具的cls为constants。
|
||||
- 在`icon.js`中,找到items一栏,往里面添加你的图标位置。
|
||||
- 在`maps.js`中,找到对应位置,往里面添加自己的数字和道具的一一对应关系。(该数字可任意指定,不能和已有的冲突),类似下面这样
|
||||
2. 在`icon.js`中,找到items一栏,往里面添加你的图标位置。
|
||||
3. 在`maps.js`中,找到对应位置,往里面添加自己的数字和道具的一一对应关系。(该数字可任意指定,不能和已有的冲突),类似下面这样
|
||||
|
||||
``` js
|
||||
if (id == 60) tmp.event = {'cls': 'items', 'id': 'curseWine'} // 解咒药水
|
||||
if (id == 61) tmp.event = {'cls': 'items', 'id': 'superWine'} // 万能药水
|
||||
if (id == 62) tmp.event = {'cls': 'items', 'id': 'knife'} // 屠龙匕首
|
||||
if (id == 63) tmp.event = {'cls': 'items', 'id': 'moneyPocket'} // 金钱袋
|
||||
if (id == 64) tmp.event = {'cls': 'items', 'id': 'shoes'} // 绿鞋
|
||||
if (id == 65) tmp.event = {'cls': 'items', 'id': 'hammer'} // 圣锤
|
||||
// 可以在这里添加自己的数字-道具对应关系
|
||||
```
|
||||
|
||||
有关如何自行实现一个道具的效果,参见[自定义道具效果](#自定义道具效果)。
|
||||
@ -93,46 +86,19 @@ P图完毕后,可以在地图生成器中加入对应的数字和图标的对
|
||||
1. 在`icon.js`中,找到npcs一栏,往里面添加你的图标位置。
|
||||
2. 在`maps.js`中,找到对应位置,往里面添加自己的数字和NPC的一一对应关系。
|
||||
|
||||
``` js
|
||||
// 121-150 NPC
|
||||
if (id == 121) tmp.event = {'cls': 'npcs', 'id': 'man'};
|
||||
if (id == 122) tmp.event = {'cls': 'npcs', 'id': 'woman'};
|
||||
if (id == 123) tmp.event = {'cls': 'npcs', 'id': 'thief'};
|
||||
if (id == 124) tmp.event = {'cls': 'npcs', 'id': 'fairy'};
|
||||
if (id == 125) tmp.event = {'cls': 'npcs', 'id': 'magician'};
|
||||
if (id == 126) tmp.event = {'cls': 'npcs', 'id': 'womanMagician'};
|
||||
```
|
||||
|
||||
### 使用自定义勇士图标
|
||||
|
||||
我们同样可以使用自定义的勇士图标,比如小可绒之类。
|
||||
|
||||
拿一个勇士的行走图覆盖`hero.png`即可。
|
||||
直接拿一个勇士的行走图覆盖`hero.png`即可。
|
||||
|
||||
请注意:勇士必须是`32x32`像素,不能使用超过`32x32`的图片。
|
||||
**支持任何行走大图,如`32x32`, `48x32`, `64x32`等等。**
|
||||
|
||||
覆盖了`hero.png`后,我们需要在`icons.js`中编辑图标的位置信息。
|
||||
|
||||
``` js
|
||||
'heros': {
|
||||
'hero1': {
|
||||
'down': {'loc': 0, 'stop': 0, 'leftFoot': 1, 'rightFoot': 2},
|
||||
'left': {'loc': 1, 'stop': 0, 'leftFoot': 1, 'rightFoot': 2},
|
||||
'right': {'loc': 2, 'stop': 0, 'leftFoot': 1, 'rightFoot': 2},
|
||||
'up': {'loc': 3, 'stop': 0, 'leftFoot': 1, 'rightFoot': 2}
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
hero1为勇士ID,和`data.js`中的ID对应,一般不修改。
|
||||
|
||||
接着`down/left/right/up`是勇士四个朝向,每个朝向中的loc表示是在`hero.png`中的第几行;后面的stop,leftFoor,rightFoot分别是停止图,左脚行走图和右脚行走图在该行的第几列就行。
|
||||
|
||||
我们只需要覆盖图片后编辑这里即可。即使是`4x4`的行走图,也是没问题的(需要指定左脚和右脚所在的第几列)。
|
||||
|
||||
|
||||
通过上述这几种方式,我们可以修改素材图片(使用自定义素材),指定数字并放入地图生成器中,然后在系统中进行启用。
|
||||
|
||||
!> 请注意:强制要求所有素材都必须是`32x32`的,不然可能会造成不可预料的后果。
|
||||
!> **请注意:除了勇士行走图外,其他所有素材强制要求必须是`32x32`的,不然可能会造成不可预料的后果。**
|
||||
|
||||
## 自定义道具效果
|
||||
|
||||
@ -148,56 +114,33 @@ hero1为勇士ID,和`data.js`中的ID对应,一般不修改。
|
||||
|
||||
1. 找到`getItemEffect`函数;所有即捡即用类道具的效果都在这里实现。
|
||||
2. 算道具效果系数,或应该增加的值。
|
||||
3. 修改同样修改下面的`getItemEffectTip`函数,使提示文字相应变动。
|
||||
|
||||
``` js
|
||||
items.prototype.getItemEffect = function(itemId, itemNum) {
|
||||
var itemCls = core.material.items[itemId].cls;
|
||||
// 消耗品
|
||||
if (itemCls === 'items') {
|
||||
if (itemId === 'redJewel') core.status.hero.atk += core.values.redJewel;
|
||||
if (itemId === 'blueJewel') core.status.hero.def += core.values.blueJewel;
|
||||
if (itemId === 'greenJewel') core.status.hero.mdef += core.values.greenJewel;
|
||||
var floor = parseInt(core.status.thisMap.name); // 获得当前楼层。此name和剧本中的name完全一致。
|
||||
var ratio = 1; // 道具效果系数
|
||||
if (floor>=11 && floor<=20 ) ratio = 2; // 11-20F(二区),道具效果翻倍
|
||||
if (floor>=21 && floor<=30 ) ratio = 3; // 21-30F(二区),道具效果三倍
|
||||
// ... 根据自己的需要来写
|
||||
|
||||
if (itemId === 'redJewel') core.status.hero.atk += core.values.redJewel * ratio; // 将初始效果乘以倍数
|
||||
if (itemId === 'blueJewel') core.status.hero.def += core.values.blueJewel * ratio; // 将初始效果乘以倍数
|
||||
if (itemId === 'greenJewel') core.status.hero.mdef += core.values.greenJewel * ratio; // 将初始效果乘以倍数
|
||||
if (itemId == 'yellowJewel') { // 黄宝石属性:需自己定义
|
||||
core.status.hero.hp+=1000;
|
||||
core.status.hero.atk+=6;
|
||||
core.status.hero.def+=6;
|
||||
core.status.hero.mdef+=10;
|
||||
}
|
||||
if (itemId === 'redPotion') core.status.hero.hp += core.values.redPotion;
|
||||
if (itemId === 'bluePotion') core.status.hero.hp += core.values.bluePotion;
|
||||
if (itemId === 'yellowPotion') core.status.hero.hp += core.values.yellowPotion;
|
||||
if (itemId === 'greenPotion') core.status.hero.hp += core.values.greenPotion;
|
||||
if (itemId === 'sword1') core.status.hero.atk += core.values.sword1;
|
||||
if (itemId === 'sword2') core.status.hero.atk += core.values.sword2;
|
||||
if (itemId == 'sword3') core.status.hero.atk += core.values.sword3;
|
||||
if (itemId == 'sword4') core.status.hero.atk += core.values.sword4;
|
||||
if (itemId === 'sword5') core.status.hero.atk += core.values.sword5;
|
||||
if (itemId === 'shield1') core.status.hero.def += core.values.shield1;
|
||||
if (itemId === 'shield2') core.status.hero.def += core.values.shield2;
|
||||
if (itemId === 'shield3') core.status.hero.def += core.values.shield3;
|
||||
if (itemId === 'shield4') core.status.hero.def += core.values.shield4;
|
||||
if (itemId === 'shield5') core.status.hero.def += core.values.shield5;
|
||||
if (itemId === 'bigKey') { // 只有是钥匙盒才会执行这一步
|
||||
core.status.hero.items.keys.yellowKey++;
|
||||
core.status.hero.items.keys.blueKey++;
|
||||
core.status.hero.items.keys.redKey++;
|
||||
}
|
||||
if (itemId == 'superPotion') core.status.hero.hp *= 2;
|
||||
if (itemId == 'moneyPocket') core.status.hero.money += core.values.moneyPocket;
|
||||
}
|
||||
else {
|
||||
core.addItem(itemId, itemNum);
|
||||
}
|
||||
}
|
||||
// ... 下略
|
||||
```
|
||||
3. 修改同样修改下面的`getItemEffectTip`函数,使提示文字相应变动。
|
||||
|
||||
!> 请注意这里`core.status.thisMap.name`获取的是当前层中,你在剧本文件里写的name那一项(即状态栏中的层数显示)。然后可以通过几个简单的if来判断应该增加的值。
|
||||
!> **请注意这里`core.status.thisMap.name`获取的是当前层中,你在剧本文件里写的name那一项(即状态栏中的层数显示)。然后可以通过几个简单的if来判断应该增加的值。**
|
||||
|
||||
### 消耗类道具(cls: tools);永久类道具(cls: constants)
|
||||
|
||||
如果要自己实现消耗类道具或永久类道具的使用效果,则需修改`items.js`中的canUseItem和useItem两个函数。
|
||||
具体过程比较复杂,需要一定的JS能力,在这里就不多说了,有需求可以找艾之葵进行了解。
|
||||
|
||||
具体过程比较复杂,需要一定的JS能力,在这里就不多说了,有需求可以找`艾之葵`进行了解。
|
||||
|
||||
但值得一提的是,我们可以使用`core.hasItem(name)` 来判断是否某个道具是否存在。例如下面是passNet(通过路障处理)的一部分:
|
||||
|
||||
``` js
|
||||
@ -206,31 +149,7 @@ events.prototype.passNet = function (data) {
|
||||
// 有鞋子
|
||||
if (core.hasItem('shoes')) return;
|
||||
if (data.event.id=='lavaNet') { // 血网
|
||||
core.status.hero.hp -= core.values.lavaDamage;
|
||||
if (core.status.hero.hp<=0) {
|
||||
core.status.hero.hp=0;
|
||||
core.updateStatusBar();
|
||||
core.events.lose('lava');
|
||||
return;
|
||||
}
|
||||
core.drawTip('经过血网,生命-'+core.values.lavaDamage);
|
||||
}
|
||||
if (data.event.id=='poisonNet') { // 毒网
|
||||
if (core.hasFlag('poison')) return;
|
||||
core.setFlag('poison', true);
|
||||
}
|
||||
if (data.event.id=='weakNet') { // 衰网
|
||||
if (core.hasFlag('weak')) return;
|
||||
core.setFlag('weak', true);
|
||||
core.status.hero.atk-=core.values.weakValue;
|
||||
core.status.hero.def-=core.values.weakValue;
|
||||
}
|
||||
if (data.event.id=='curseNet') { // 咒网
|
||||
if (core.hasFlag('curse')) return;
|
||||
core.setFlag('curse', true);
|
||||
}
|
||||
core.updateStatusBar();
|
||||
}
|
||||
// ... 下略
|
||||
```
|
||||
|
||||
我们进行了一个简单的判断,如果拥有绿鞋,则不进行任何路障的处理。
|
||||
@ -238,8 +157,36 @@ events.prototype.passNet = function (data) {
|
||||
### 实战!拿到神圣盾后免疫吸血、领域、夹击效果
|
||||
|
||||
1. 在getItemEffect中修改拿到神圣盾时的效果,标记一个自定义Flag。
|
||||
2. 免疫吸血效果:在`enemys.js`的getDamage函数中,找到extra_damage,并编辑成如果存在神圣盾标记,额外伤害为0。
|
||||
``` js
|
||||
if (itemId === 'shield5') {
|
||||
core.status.hero.def += core.values.shield5;
|
||||
core.setFlag("shield5", true); // 增加一个自定义Flag:已经拿到神圣盾
|
||||
}
|
||||
```
|
||||
2. 免疫吸血效果:在`enemys.js`的getExtraDamage函数中,编辑成如果存在神圣盾标记,额外伤害为0。
|
||||
``` js
|
||||
enemys.prototype.getExtraDamage = function (monster) {
|
||||
var extra_damage = 0;
|
||||
if (monster.special == 11) { // 吸血
|
||||
// 吸血的比例
|
||||
extra_damage = core.status.hero.hp * monster.value;
|
||||
if (core.hasFlag("shield5")) extra_damage = 0; // 如果存在神圣盾,则免疫吸血
|
||||
extra_damage = parseInt(extra_damage);
|
||||
}
|
||||
return extra_damage;
|
||||
}
|
||||
```
|
||||
3. 免疫领域、夹击效果:在`events.js`中,找到checkBlock函数,并编辑成如果有神圣盾标记,则直接返回。
|
||||
``` js
|
||||
////// 检查领域、夹击事件 //////
|
||||
events.prototype.checkBlock = function (x,y) {
|
||||
if (core.hasFlag("shield5")) return; // 如果拥有神圣盾立刻返回,免疫领域和夹击
|
||||
var damage = 0;
|
||||
// 获得四个方向的怪物
|
||||
var directions = [[0,-1],[-1,0],[0,1],[1,0]]; // 上,左,下,右
|
||||
var enemys = [null,null,null,null];
|
||||
// ... 下略
|
||||
```
|
||||
4. 如果有更高的需求,例如想让吸血效果变成一半(如异空间),则还是在上面这些地方进行对应的修改即可。
|
||||
|
||||
## 自定义怪物属性
|
||||
@ -253,10 +200,18 @@ events.prototype.passNet = function (data) {
|
||||
因此无敌属性可以这样设置:
|
||||
|
||||
``` js
|
||||
if (hero_atk <= mon_def) return 999999999; // 不可战斗时请直接返回999999999
|
||||
// 我们需要对无敌属性指定一个数字,比如18
|
||||
|
||||
enemys.prototype.calDamage = function (hero_atk, hero_def, hero_mdef, mon_hp, mon_atk, mon_def, mon_special) {
|
||||
if (mon_special==18 && !core.hasItem("cross")) // 如果是无敌属性,且勇士未持有十字架
|
||||
return 999999999; // 返回无限大
|
||||
|
||||
// 魔攻
|
||||
if (mon_special == 2) hero_def = 0;
|
||||
// ... 下略
|
||||
```
|
||||
|
||||
对于吸血怪的额外伤害计算在getDamage中的`extra_damage`中。
|
||||
对于吸血怪的额外伤害计算在getExtraDamage中。
|
||||
|
||||
对于毒衰弱怪物的战斗后结算在`events.js`中的afterBattle函数中。
|
||||
|
||||
@ -264,7 +219,7 @@ if (hero_atk <= mon_def) return 999999999; // 不可战斗时请直接返回9999
|
||||
|
||||
`getCritical`, `getCriticalDamage`和`getDefDamage`三个函数依次计算的是该怪物的临界值、临界减伤和1防减伤。也可以适当进行修改。
|
||||
|
||||
## 自定义地图
|
||||
## 根据难度分歧来自定义地图
|
||||
|
||||
遗憾的是,所有地图数据必须在剧本的map中指定,换句话说,我们无法在游戏进行中动态修改地图,比如为简单难度增加一个血瓶。
|
||||
|
||||
@ -272,22 +227,22 @@ if (hero_atk <= mon_def) return 999999999; // 不可战斗时请直接返回9999
|
||||
|
||||
``` js
|
||||
"firstArrive": [ // 第一次到该楼层触发的事件
|
||||
{"type": "if", "condition": "flag:hard!=3", // 判断是否困难难度
|
||||
"true": [ // 不为困难,则为普通或简单难度
|
||||
{"type": "show", "loc": [3, 6]} // 显示血瓶
|
||||
{"type": "if", "condition": "flag:hard==1", // 判断是否是简单难度
|
||||
"true": [
|
||||
{"type": "show", "loc": [3, 7]} // 简单难度则显示宝石
|
||||
{"type": "if", "condition": "flag:hard!=3", // 判断是否困难难度
|
||||
"true": [ // 不为困难,则为普通或简单难度
|
||||
{"type": "show", "loc": [3,6]} // 显示血瓶
|
||||
{"type": "if", "condition": "flag:hard==1", // 判断是否是简单难度
|
||||
"true": [
|
||||
{"type": "show", "loc": [3,7]} // 简单难度则显示宝石
|
||||
],
|
||||
"false": [] // 普通难度则只显示血瓶
|
||||
},
|
||||
],
|
||||
"false": [] // 普通难度则只显示血瓶
|
||||
},
|
||||
],
|
||||
"false": [] // 困难难度,不进行任何操作
|
||||
"false": [] // 困难难度,不进行任何操作
|
||||
},
|
||||
],
|
||||
"events": {
|
||||
"3, 6": {"enable": false} // 比如[3, 6]点是一个血瓶,初始不可见
|
||||
"3, 7": {"enable": false} // 比如[3, 7]点是一个宝石,初始不可见
|
||||
"3,6": {"enable": false} // 比如[3,6]点是一个血瓶,初始不可见
|
||||
"3,7": {"enable": false} // 比如[3,7]点是一个宝石,初始不可见
|
||||
}
|
||||
```
|
||||
|
||||
@ -296,3 +251,7 @@ if (hero_atk <= mon_def) return 999999999; // 不可战斗时请直接返回9999
|
||||
当第一次到达该楼层时,进行一次判断;如果不为困难难度,则将血瓶显示出来;再判断是否为简单难度,如果是则再把宝石显示出来。
|
||||
|
||||
通过对`flag:hard`进行判断的方式,我们也可以达成“对于不同的难度有着不同的地图效果”。
|
||||
|
||||
==========================================================================================
|
||||
|
||||
[继续阅读附录:所有API列表](api)
|
||||
|
||||
@ -8,7 +8,8 @@
|
||||
|
||||
- Windows 8以上操作系统;Windows 7需要安装.Net Framework 4.0。(能打开同目录下的“地图生成器.exe”即可)
|
||||
- 任一款现代浏览器。强烈推荐Chrome。
|
||||
- 一个很好的文本编辑器。推荐带有高亮染色、错误提示等效果。例如:WebStorm,VSCode,或者至少也要Sublime Text。[Sublime Text下载地址](https://www.sublimetext.com/ ),如提示注册的话百度随便搜索一个注册码输入即可。
|
||||
- 一个很好的文本编辑器。推荐带有高亮染色、错误提示等效果。例如:WebStorm,VSCode,或者至少也要Sublime Text。
|
||||
([VSCode下载地址](https://code.visualstudio.com/),群里的群文件中也有,强烈推荐之。)
|
||||
- RPG Maker XP,任一个魔塔样板(推荐魔塔样板7630)
|
||||
|
||||
只要满足了上述条件,你就可以开始做自己的塔啦!
|
||||
@ -17,14 +18,14 @@
|
||||
|
||||
类似于RMXP,本塔每层楼都是一个“剧本”,剧本内主要定义了本层的地图和各种事件。主函数将读取每个剧本,并生成实际的地图供游戏使用。
|
||||
|
||||
我们打开 `libs/floors/` 目录,这个目录是所有剧本的目录。我们需要指定一个楼层名,例如MT1;然后,我们可以将`MT0.js`(模板)复制重命名为为`MT1.js`,并使用文本编辑器打开。(参见下面的图)。
|
||||
我们打开 `libs/floors/` 目录,这个目录是所有剧本的目录。我们需要指定一个楼层名,例如MT1;然后,我们可以将`MT0.js`(模板)复制重命名为为`MT1.js`,并使用文本编辑器打开。
|
||||
|
||||

|
||||
|
||||
然后将楼层名改为MT1,floorId改名为MT1;title可以改成任意内容,将在切换楼层时进行显示(比如可以改成“1层小塔”)。
|
||||
|
||||
具体样板文件的每个要素都有详细的注释。我们最终的任务其实是,将每个楼层的剧本(地图&事件)给写完即可。
|
||||
|
||||

|
||||
|
||||
换句话说,只需要简单的复制操作,我们就可以新建一个剧本了。
|
||||
|
||||
## 绘制地图
|
||||
@ -32,11 +33,13 @@
|
||||
遗憾的是,我们的样板是没有像RMXP那样有着很好的UI界面,供大家直接进行绘图可视化操作的。然而,我们仍然可以利用已有的RMXP和魔塔样板,绘制好地图,然后利用目录中的“地图生成器”来转成样板所识别的格式。
|
||||
|
||||
首先,我们打开RMXP和魔塔样板,来到绘制地图页面。
|
||||
|
||||

|
||||
|
||||
然后,任意绘制一张地图。
|
||||
|
||||
在这里我们就以1层小塔的地图为例。你也可以任意绘制自己的地图
|
||||
在这里我们就以1层小塔的地图为例。你也可以任意绘制自己的地图。
|
||||
|
||||

|
||||
|
||||
(我把原塔素材改成了经典样式,但是本质上是一样的。)
|
||||
@ -47,17 +50,22 @@
|
||||
|
||||

|
||||
|
||||
截图时请注意:只截取有效游戏空间内数据,并且有效空间内的范围必须是13\*13。(如果地图小于13\*13,请用星空或墙壁填充到13\*13)。
|
||||
截图时请注意:**只截取有效游戏空间内数据,并且有效空间内的范围必须是13x13。(如果地图小于13*13,请用星空或墙壁填充到13x13)。**
|
||||
|
||||
确认地图的图片文件已经复制到剪切板后,我们打开工具中的“地图生成器”,并点“加载图片”。大约1-2秒后,可以得到地图的数据。
|
||||
|
||||
确认地图的图片文件已经复制到剪切板后,我们打开“地图生成器”,并点“加载图片”。大约1-2秒后,可以得到地图的数据。
|
||||

|
||||
|
||||
如果有识别不一致的存在,即生成的地图和实际的地图不符,则需要在左边的输入框内实际手动修改,然后再点“图片生成”即可。有关每个数字对应的图块名称,请参见images目录下的`meaning.txt`
|
||||
|
||||
!> 注:地图生成器默认只支持经典素材。如果有自定义素材需求(例如原版的1层小塔那种素材),请参见[自定义素材](./personalization#自定义素材)。
|
||||
!> **地图生成器默认只支持经典素材。如果有自定义素材需求(例如原版的1层小塔那种素材),请参见[自定义素材](personalization#自定义素材)。**
|
||||
|
||||
!> **请确保截图范围刚好为13x13,并且保证每个位置的像素都是32x32。**
|
||||
|
||||
经过确认,生成的地图和原始地图保持一致后,点击“复制地图”,然后粘贴到刚刚剧本文件里的maps中。
|
||||

|
||||
|
||||

|
||||
|
||||
通过这种在RMXP中画图,截图复制,再用地图生成器识别的方式,我们成功将我们需要的地图变成了样板可识别的格式。
|
||||
|
||||
## 录入数据
|
||||
@ -71,29 +79,41 @@
|
||||
下面依次进行说明。
|
||||
|
||||
我们打开`data.js`文件,这里面定义了各种全局属性和勇士初始值。
|
||||
我们可以将本塔标题改名为“1层小塔”,游戏的唯一标识符叫onefloor,然后可以直接修改勇士的各项初始数据.
|
||||

|
||||
|
||||
!> 请注意,勇士的初始位置一栏,x为横坐标,y为纵坐标;即,x为从左到右第几列,y为从上到下第几行,均从0开始计算。
|
||||
我们可以将本塔标题改名为“1层小塔”,
|
||||
|
||||
游戏的唯一标识符叫onefloor,然后可以直接修改勇士的各项初始数据.
|
||||
|
||||
!> **注:name作为游戏的唯一标识符必须进行修改,否则可能会导致存档等出现问题。**
|
||||
|
||||

|
||||
|
||||
!> **请注意,勇士的初始位置一栏,x为横坐标,y为纵坐标;即,x为从左到右第几列,y为从上到下第几行,均从0开始计算。**
|
||||
|
||||
修改完初始化信息后,接下来我们需要修改道具的信息(比如宝石加攻防的数值,血瓶加生命的数值等)。还是在这个`data.js`文件,往下拉,找到values一项,并进行相应的设置
|
||||

|
||||
|
||||
然后,再设置一些系统Flag,以进行游戏。继续将`data.js`往下拉,我们注意到本塔是存在魔防的,不存在经验,因此我们可以简单地将enableMDef改为true,enableExperience改成false。
|
||||

|
||||

|
||||
|
||||
然后,再设置一些系统Flag,以进行游戏。继续将`data.js`往下拉,我们注意到本塔是存在魔防的,不存在经验,因此我们可以简单地将enableMDef改为true,enableExperience改成false,enableDebuff改成false。
|
||||
|
||||
同理,本塔的破墙镐只能破面前的墙壁,因此`pickaxeFourDirections`需要改成`false`。
|
||||

|
||||
|
||||

|
||||
|
||||
其他的几项暂时不会被涉及到,因此不用考虑。
|
||||
|
||||
全局变量修改完毕后,我们需要告诉主函数加载该楼层。打开`main.js`(该文件和index.html同级),找到`this.floorIds`项,将其值改为楼层ID即MT1。
|
||||
|
||||

|
||||
|
||||
最后一步就是录入怪物数据。打开`enemys.js`文件,依次输入你在本塔内使用到的所有怪物的攻防血的数据。其中怪物的特殊属性(special项)与该文件下面的getSpecialText对应。
|
||||
|
||||

|
||||
|
||||
只需要修改自己用到的怪物属性即可,其他没有用到的怪物完全无所谓。
|
||||
|
||||
做完后保存所有文件,然后右键,选择使用chrome浏览器打开`index.html`,就能立刻看到自己的塔并开始游戏啦!是不是很简单呢!
|
||||
|
||||

|
||||
|
||||
## 压缩与发布
|
||||
@ -105,8 +125,8 @@
|
||||
- 手机端的部分浏览器如chrome也支持本地网页,可以下载到手机然后直接打开进行游戏。
|
||||
- 在线版本:将游戏放到某个服务器上,大家在线联网游戏。
|
||||
|
||||
离线版本的好处是:先全部下载后再游戏,无需考虑流量的问题,也可以支持高清音乐的播放。坏处是:没办法在多平台之间迁移(平台同步的锅),而浏览器打开本地文件有丢失存档的风险。
|
||||
在线版本的好处是:随时随地可以玩,可以多平台接档,还可以在后台看到一些统计信息,了解大概有多少人进行了游戏(如果需要);坏处是需要一个服务器,且还要考虑到用户流量的问题。
|
||||
**离线版本的好处是:先全部下载后再游戏,无需考虑流量的问题,也可以支持高清音乐的播放。坏处是:没办法在多平台之间迁移,无法及时获得游戏更新(需要重新下载),而浏览器打开本地文件有丢失存档的风险。
|
||||
在线版本的好处是:随时随地可以玩,可以多平台接档,还可以在后台看到一些统计信息,可以随时对游戏进行更新;坏处是需要一个服务器,且还要考虑到用户流量的问题。**
|
||||
|
||||
在此我们只讨论在线版本。当你决定发布游戏时,强烈建议先将JS代码进行压缩以节省可能的IO请求以及网络流量。直接打开同目录下的“JS代码压缩工具”进行压缩即可。
|
||||
|
||||
@ -116,4 +136,32 @@
|
||||
|
||||
然后就是发布帖子、链接二维码,能让任何人在任何时候任何平台上都能进行游戏啦!是不是很简单呢!
|
||||
|
||||
在下面的几章里,将对样板的各个元件、事件等依次进行介绍。
|
||||
## 注意事项和常见FAQ
|
||||
|
||||
1. 截图请务必刚好截取13x13的图片,并需要保证每个位置必须为32x32像素。一般无放缩的RMXP符合条件。
|
||||
2. 游戏的唯一标识符name请务必修改。如果不修改可能会导致存档出现异常。
|
||||
3. 别忘了main.js中要修改floorIds指明所用到的所有楼层哦~
|
||||
|
||||
下面是几个常见的FAQ:
|
||||
|
||||
**Q: 为什么截图识别不出来?**
|
||||
|
||||
**A:** 请保证刚好为13x13,且每个位置必须32x32像素。如果不确定,可以保存你的截图,右键属性查看详细信息,看像素的宽高是不是在416左右。多少几十像素都是没关系的。
|
||||
|
||||

|
||||
|
||||
**Q: 打开游戏时卡死在了xxx.js加载完毕!无法进入游戏。**
|
||||
|
||||
**A:** 最大的可能是因为少了逗号,或者反括号等等。一般而言VSCode都会有错误提示,你哪里少了东西。
|
||||
|
||||
如果没有,可以采用如下方式debug:
|
||||
|
||||
Ctrl+Shift+I 打开Chrome的控制台,找到Console。
|
||||
|
||||
如果出现了语法错误,会有红色提示 **Unexpected xxx** ,找到后面文件名和行号,打开,使用VSCode检查该处是否存在问题,即可。
|
||||
|
||||

|
||||
|
||||
==========================================================================================
|
||||
|
||||
[继续阅读下一章:元件说明](element)
|
||||
1
docs/vue.css
Normal file
BIN
fonts/number.ttf
31
libs/core.js
@ -1262,8 +1262,21 @@ core.prototype.battle = function (id, x, y, force, callback) {
|
||||
core.clearContinueAutomaticRoute();
|
||||
return;
|
||||
}
|
||||
core.playSound('attack', 'ogg');
|
||||
core.status.hero.hp -= damage;
|
||||
if (core.flags.battleAnimate) {
|
||||
core.waitHeroToStop(function() {
|
||||
core.ui.drawBattleAnimate(id, function() {
|
||||
core.afterBattle(id, x, y, callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
core.playSound('attack', 'ogg');
|
||||
core.afterBattle(id, x, y, callback);
|
||||
}
|
||||
}
|
||||
|
||||
core.prototype.afterBattle = function(id, x, y, callback) {
|
||||
core.status.hero.hp -= core.enemys.getDamage(id);
|
||||
if (core.status.hero.hp<=0) {
|
||||
core.status.hero.hp=0;
|
||||
core.updateStatusBar();
|
||||
@ -1290,6 +1303,7 @@ core.prototype.battle = function (id, x, y, force, callback) {
|
||||
|
||||
// 打完怪物,触发事件
|
||||
core.events.afterBattle(id,x,y,callback);
|
||||
|
||||
}
|
||||
|
||||
core.prototype.trigger = function (x, y) {
|
||||
@ -1422,6 +1436,19 @@ core.prototype.strokeRect = function (map, x, y, width, height, style, lineWidth
|
||||
core.canvas[map].strokeRect(x, y, width, height);
|
||||
}
|
||||
|
||||
core.prototype.drawLine = function (map, x1, y1, x2, y2, style, lineWidth) {
|
||||
if (core.isset(style)) {
|
||||
core.setStrokeStyle(map, style);
|
||||
}
|
||||
if (core.isset(lineWidth)) {
|
||||
core.setLineWidth(map, lineWidth);
|
||||
}
|
||||
core.canvas[map].beginPath();
|
||||
core.canvas[map].moveTo(x1, y1);
|
||||
core.canvas[map].lineTo(x2, y2);
|
||||
core.canvas[map].stroke();
|
||||
}
|
||||
|
||||
core.prototype.setFont = function (map, font) {
|
||||
core.canvas[map].font = font;
|
||||
}
|
||||
|
||||
@ -109,7 +109,6 @@ data.prototype.init = function() {
|
||||
"moneyPocket": 500, // 金钱袋加金币的数值
|
||||
|
||||
/****** 系统相关 ******/
|
||||
"cannotUseQuickShop": ["MT0"], // 不能使用快捷商店的楼层列表
|
||||
'animateSpeed': 500,
|
||||
}
|
||||
// 系统FLAG,在游戏运行中中请不要修改它。
|
||||
@ -125,7 +124,7 @@ data.prototype.init = function() {
|
||||
"bigKeyIsBox": false, // 如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙
|
||||
|
||||
/****** 系统相关 ******/
|
||||
"startDirectly": true, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面
|
||||
"startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面
|
||||
"battleAnimate": true, // 是否默认显示战斗动画;用户可以手动在菜单栏中关闭
|
||||
"portalWithoutTrigger": true, // 经过楼梯、传送门时是否能“穿透”。穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件
|
||||
"potionWhileRouting": false, // 寻路算法是否经过血瓶;如果该项为false,则寻路算法会自动尽量绕过血瓶
|
||||
|
||||
@ -103,14 +103,17 @@ enemys.prototype.getDamage = function (monsterId) {
|
||||
var mon_hp = monster.hp, mon_atk = monster.atk, mon_def = monster.def, mon_special = monster.special;
|
||||
var damage = this.calDamage(hero_atk, hero_def, hero_mdef, mon_hp, mon_atk, mon_def, mon_special);
|
||||
if (damage == 999999999) return damage;
|
||||
return damage + this.getExtraDamage(monster);
|
||||
}
|
||||
|
||||
enemys.prototype.getExtraDamage = function (monster) {
|
||||
var extra_damage = 0;
|
||||
if (monster.special == 11) { // 吸血
|
||||
// 吸血的比例
|
||||
extra_damage = core.status.hero.hp * monster.value;
|
||||
extra_damage = parseInt(extra_damage);
|
||||
}
|
||||
return damage + extra_damage;
|
||||
return extra_damage;
|
||||
}
|
||||
|
||||
// 临界值计算
|
||||
|
||||
@ -461,8 +461,9 @@ events.prototype.decreaseHard = function() {
|
||||
|
||||
////// 能否使用快捷商店 //////
|
||||
events.prototype.canUseQuickShop = function(shopIndex) {
|
||||
if (core.isset(core.values.cannotUseQuickShop) && core.values.cannotUseQuickShop.indexOf(core.status.floorId)>=0)
|
||||
if (core.isset(core.floors[core.status.floorId].canUseQuickShop) && !core.isset(core.floors[core.status.floorId].canUseQuickShop))
|
||||
return '当前不能使用快捷商店。';
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ main.floors.MT0 = {
|
||||
"title": "主塔 0 层", // 楼层中文名
|
||||
"name": 0, // 显示在状态栏中的层数
|
||||
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||
|
||||
],
|
||||
|
||||
@ -6,6 +6,7 @@ main.floors.sample0 = {
|
||||
"title": "样板 0 层", // 楼层中文名
|
||||
"name": 0, // 显示在状态栏中的层数
|
||||
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||
[0, 0, 220, 0, 0, 6, 87, 3, 65, 64, 44, 43, 42],
|
||||
[0, 246, 0, 246, 0, 6, 0, 3, 58, 59, 60, 61, 41],
|
||||
@ -98,8 +99,7 @@ main.floors.sample0 = {
|
||||
],
|
||||
"10,5": ["破墙镐是破面前的墙壁还是四个方向的墙壁,由data.js中的系统Flag所决定。"],
|
||||
"8,4": [
|
||||
"炸弹可以炸四个方向的怪物。\n如只需要炸前方怪物请使用上面的圣锤。",
|
||||
"不能被炸的怪物在enemys中可以定义,可参见样板里黑衣魔王的写法。\n\n炸死怪物是否触发事件由 data.js 中的系统Flag所决定。"
|
||||
"炸弹可以炸四个方向的怪物。\n如只需要炸前方怪物请使用上面的圣锤。\n不能被炸的怪物在enemys中可以定义,可参见样板里黑衣魔王和黑暗大法师的写法。",
|
||||
],
|
||||
"10,4": ["“上楼”和“下楼”的目标层由 main.js 的 floorIds顺序所决定。"],
|
||||
"10,3": ["十字架目前未被定义,可能需要自行实现功能。\n有关如何实现一个道具功能参见doc文档。"],
|
||||
|
||||
@ -6,6 +6,7 @@ main.floors.sample1 = {
|
||||
"title": "样板 1 层", // 楼层中文名
|
||||
"name": 1, // 显示在状态栏中的层数
|
||||
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||
[7, 131, 8, 2, 9, 130, 10, 2, 0, 0, 132, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0],
|
||||
|
||||
@ -6,6 +6,7 @@ main.floors.sample2 = {
|
||||
"title": "主塔 40 层", // 楼层中文名
|
||||
"name": 40, // 显示在状态栏中的层数
|
||||
"canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||
[5, 5, 5, 5, 5, 5, 87, 5, 5, 5, 5, 5, 5],
|
||||
[5, 4, 4, 4, 4, 1, 0, 1, 4, 4, 4, 4, 5],
|
||||
|
||||
245
libs/ui.js
@ -362,12 +362,255 @@ ui.prototype.drawQuickShop = function (need) {
|
||||
|
||||
}
|
||||
|
||||
ui.prototype.drawBattleAnimate = function() {
|
||||
ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
||||
|
||||
// UI层
|
||||
core.lockControl();
|
||||
if (!core.isset(core.status.event.id)) {
|
||||
core.status.event = {'id': 'battle'};
|
||||
}
|
||||
|
||||
var hero_hp = core.getStatus('hp'), hero_atk = core.getStatus('atk'), hero_def = core.getStatus('def'),
|
||||
hero_mdef = core.getStatus('mdef');
|
||||
var monster = core.material.enemys[monsterId];
|
||||
var mon_hp = monster.hp, mon_atk = monster.atk, mon_def = monster.def, mon_money=monster.money, mon_exp = monster.experience, mon_special=monster.special;
|
||||
|
||||
hero_hp -= core.enemys.getExtraDamage(monster);
|
||||
|
||||
if (mon_special==2) hero_def=0; // 魔攻
|
||||
if (mon_special==3 && mon_def<hero_atk) mon_def=hero_atk-1; // 坚固
|
||||
if (mon_special==10) { // 模仿
|
||||
mon_atk=hero_atk;
|
||||
mon_def=hero_def;
|
||||
}
|
||||
var turns = 2;
|
||||
if (mon_special==4) turns=3;
|
||||
if (mon_special==5) turns=4;
|
||||
if (mon_special==6) turns=5;
|
||||
|
||||
// 初始伤害(破甲、净化)
|
||||
var initDamage = 0;
|
||||
if (mon_special==7) initDamage=parseInt(0.9 * hero_def);
|
||||
if (mon_special==9) initDamage=parseInt(3*hero_mdef);
|
||||
hero_mdef-=initDamage;
|
||||
if (hero_mdef<0) {
|
||||
hero_hp+=hero_mdef;
|
||||
hero_mdef=0;
|
||||
}
|
||||
|
||||
|
||||
var specialText = core.enemys.getSpecialText(monsterId);
|
||||
|
||||
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||
|
||||
core.clearMap('ui', 0, 0, 416, 416);
|
||||
var left=10, right=416-2*left;
|
||||
|
||||
|
||||
var lines = core.flags.enableExperience?5:4;
|
||||
|
||||
var lineHeight = 60;
|
||||
var height = lineHeight * lines + 50;
|
||||
|
||||
var top = (416-height)/2, bottom = height;
|
||||
|
||||
// var left = 97, top = 64, right = 416 - 2 * left, bottom = 416 - 2 * top;
|
||||
core.setAlpha('ui', 0.85);
|
||||
core.fillRect('ui', left, top, right, bottom, '#000000');
|
||||
core.setAlpha('ui', 1);
|
||||
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
|
||||
core.status.boxAnimateObjs = [];
|
||||
core.setBoxAnimate();
|
||||
|
||||
var margin = 35;
|
||||
var boxWidth = 40;
|
||||
|
||||
// 方块
|
||||
var heroHeight = core.material.icons.hero.height;
|
||||
core.strokeRect('ui', left + margin - 1, top + margin - 1, boxWidth+2, heroHeight+boxWidth-32+2, '#FFD700', 2);
|
||||
core.strokeRect('ui', left + right - margin - boxWidth - 1 , top+margin-1, boxWidth+2, boxWidth+2);
|
||||
|
||||
// 名称
|
||||
core.canvas.ui.textAlign='center';
|
||||
core.fillText('ui', core.status.hero.name, left+margin+boxWidth/2, top+margin+heroHeight+40, '#FFD700', 'bold 22px Verdana');
|
||||
core.fillText('ui', "怪物", left+right-margin-boxWidth/2, top+margin+32+40);
|
||||
core.fillText('ui', specialText, left+right-margin-boxWidth/2, top+margin+32+40+24, '#FF6A6A', '15px Verdana');
|
||||
|
||||
// 图标
|
||||
core.clearMap('ui', left + margin, top + margin, boxWidth, heroHeight+boxWidth-32);
|
||||
core.fillRect('ui', left + margin, top + margin, boxWidth, heroHeight+boxWidth-32, background);
|
||||
var heroIcon = core.material.icons.hero['down'];
|
||||
core.canvas.ui.drawImage(core.material.images.hero, heroIcon.stop * 32, heroIcon.loc *heroHeight, 32, heroHeight, left+margin+(boxWidth-32)/2, top+margin+(boxWidth-32)/2, 32, heroHeight);
|
||||
// 怪物的
|
||||
core.status.boxAnimateObjs = [];
|
||||
core.status.boxAnimateObjs.push({
|
||||
'bgx': left + right - margin - 40, 'bgy': top+margin, 'bgsize': boxWidth,
|
||||
'image': core.material.images.enemys, 'x': left + right - margin - 40 + (boxWidth-32)/2, 'y': top + margin + (boxWidth-32)/2, 'icon': core.material.icons.enemys[monsterId]
|
||||
});
|
||||
core.setBoxAnimate();
|
||||
|
||||
var lineWidth = 80;
|
||||
|
||||
var left_start = left + margin + boxWidth + 10;
|
||||
var left_end = left_start+lineWidth;
|
||||
|
||||
var right_end = left+right-margin-boxWidth-10;
|
||||
var right_start = right_end-lineWidth;
|
||||
|
||||
// 勇士的线
|
||||
core.canvas.ui.textAlign='left';
|
||||
var textTop = top+margin+10;
|
||||
core.fillText('ui', "生命值", left_start, textTop, '#DDDDDD', '16px Verdana');
|
||||
core.drawLine('ui', left_start, textTop+8, left_end, textTop+8, '#FFFFFF', 2);
|
||||
core.canvas.data.textAlign='right';
|
||||
core.fillText('data', hero_hp, left_end, textTop+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
|
||||
textTop+=lineHeight;
|
||||
core.canvas.ui.textAlign='left';
|
||||
core.fillText('ui', "攻击", left_start, textTop, '#DDDDDD', '16px Verdana');
|
||||
core.drawLine('ui', left_start, textTop+8, left_end, textTop+8, '#FFFFFF', 2);
|
||||
core.canvas.ui.textAlign='right';
|
||||
core.fillText('ui', hero_atk, left_end, textTop+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
|
||||
textTop+=lineHeight;
|
||||
core.canvas.ui.textAlign='left';
|
||||
core.fillText('ui', "防御", left_start, textTop, '#DDDDDD', '16px Verdana');
|
||||
core.drawLine('ui', left_start, textTop+8, left_end, textTop+8, '#FFFFFF', 2);
|
||||
core.canvas.ui.textAlign='right';
|
||||
core.fillText('ui', hero_def, left_end, textTop+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
|
||||
if (core.flags.enableMDef) {
|
||||
textTop += lineHeight;
|
||||
core.canvas.ui.textAlign='left';
|
||||
core.fillText('ui', "魔防", left_start, textTop, '#DDDDDD', '16px Verdana');
|
||||
core.drawLine('ui', left_start, textTop + 8, left_end, textTop + 8, '#FFFFFF', 2);
|
||||
core.canvas.data.textAlign='right';
|
||||
core.fillText('data', hero_mdef, left_end, textTop+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
}
|
||||
|
||||
// 怪物的线
|
||||
core.canvas.ui.textAlign='right';
|
||||
var textTop = top+margin+10;
|
||||
core.fillText('ui', "生命值", right_end, textTop, '#DDDDDD', '16px Verdana');
|
||||
core.drawLine('ui', right_start, textTop+8, right_end, textTop+8, '#FFFFFF', 2);
|
||||
core.canvas.data.textAlign='left';
|
||||
core.fillText('data', mon_hp, right_start, textTop+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
|
||||
textTop+=lineHeight;
|
||||
core.canvas.ui.textAlign='right';
|
||||
core.fillText('ui', "攻击", right_end, textTop, '#DDDDDD', '16px Verdana');
|
||||
core.drawLine('ui', right_start, textTop+8, right_end, textTop+8, '#FFFFFF', 2);
|
||||
core.canvas.ui.textAlign='left';
|
||||
core.fillText('ui', mon_atk, right_start, textTop+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
|
||||
textTop+=lineHeight;
|
||||
core.canvas.ui.textAlign='right';
|
||||
core.fillText('ui', "防御", right_end, textTop, '#DDDDDD', '16px Verdana');
|
||||
core.drawLine('ui', right_start, textTop+8, right_end, textTop+8, '#FFFFFF', 2);
|
||||
core.canvas.ui.textAlign='left';
|
||||
core.fillText('ui', mon_def, right_start, textTop+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
|
||||
textTop += lineHeight;
|
||||
core.canvas.ui.textAlign='right';
|
||||
core.fillText('ui', "金币", right_end, textTop, '#DDDDDD', '16px Verdana');
|
||||
core.drawLine('ui', right_start, textTop + 8, right_end, textTop + 8, '#FFFFFF', 2);
|
||||
core.canvas.ui.textAlign='left';
|
||||
core.fillText('ui', mon_money, right_start, textTop+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
|
||||
if (core.flags.enableExperience) {
|
||||
textTop += lineHeight;
|
||||
core.canvas.ui.textAlign='right';
|
||||
core.fillText('ui', "经验", right_end, textTop, '#DDDDDD', '16px Verdana');
|
||||
core.drawLine('ui', right_start, textTop + 8, right_end, textTop + 8, '#FFFFFF', 2);
|
||||
core.canvas.ui.textAlign='left';
|
||||
core.fillText('ui', mon_exp, right_start, textTop+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
}
|
||||
|
||||
core.canvas.ui.textAlign='left';
|
||||
core.fillText("ui", "V", left_end+8, 208-15, "#FFFFFF", "italic bold 40px Verdana");
|
||||
|
||||
core.canvas.ui.textAlign='right';
|
||||
core.fillText("ui", "S", right_start-8, 208+15, "#FFFFFF", "italic bold 40px Verdana");
|
||||
/*
|
||||
core.drawLine('data', left + right - margin - boxWidth + 6, top+margin+boxWidth-6,
|
||||
left+right-margin-6, top+margin+6, '#FF0000', 4);
|
||||
core.drawLine('data', left + margin + 6, top+margin+heroHeight+(boxWidth-32)-6,
|
||||
left+margin+boxWidth-6, top+margin+6, '#FF0000', 4);
|
||||
*/
|
||||
|
||||
// 实际操作
|
||||
var turn = 0; // 0为勇士攻击
|
||||
if (mon_special==1) turn=1;
|
||||
var battleInterval = setInterval(function() {
|
||||
core.playSound("attack", "ogg");
|
||||
|
||||
if (turn==0) {
|
||||
// 勇士攻击
|
||||
core.drawLine('data', left + right - margin - boxWidth + 6, top+margin+boxWidth-6,
|
||||
left+right-margin-6, top+margin+6, '#FF0000', 4);
|
||||
setTimeout(function() {
|
||||
core.clearMap('data', left + right - margin - boxWidth, top+margin,
|
||||
boxWidth, boxWidth);
|
||||
}, 250);
|
||||
|
||||
if (hero_atk-mon_def>0)
|
||||
mon_hp-=hero_atk-mon_def;
|
||||
if (mon_hp<0) mon_hp=0;
|
||||
|
||||
// 更新怪物伤害
|
||||
core.clearMap('data', right_start, top+margin+10, lineWidth, 40);
|
||||
core.canvas.data.textAlign='left';
|
||||
core.fillText('data', mon_hp, right_start, top+margin+10+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
|
||||
}
|
||||
else {
|
||||
// 怪物攻击
|
||||
core.drawLine('data', left + margin + 6, top+margin+heroHeight+(boxWidth-32)-6,
|
||||
left+margin+boxWidth-6, top+margin+6, '#FF0000', 4);
|
||||
setTimeout(function() {
|
||||
core.clearMap('data', left + margin, top+margin, boxWidth, heroHeight+boxWidth-32);
|
||||
}, 250);
|
||||
|
||||
var per_damage = mon_atk-hero_def;
|
||||
if (mon_special == 8) per_damage += parseInt(0.1 * hero_atk); // 反击
|
||||
|
||||
hero_mdef-=per_damage;
|
||||
if (hero_mdef<0) {
|
||||
hero_hp+=hero_mdef;
|
||||
hero_mdef=0;
|
||||
}
|
||||
// 更新勇士数据
|
||||
core.clearMap('data', left_start, top+margin+10, lineWidth, 40);
|
||||
core.canvas.data.textAlign='right';
|
||||
core.fillText('data', hero_hp, left_end, top+margin+10+26, '#DDDDDD', 'bold 16px Verdana');
|
||||
|
||||
if (core.flags.enableMDef) {
|
||||
core.clearMap('data', left_start, top+margin+10+3*lineHeight, lineWidth, 40);
|
||||
core.fillText('data', hero_mdef, left_end, top+margin+10+26+3*lineHeight);
|
||||
}
|
||||
|
||||
}
|
||||
turn++;
|
||||
if (turn>=turns) turn=0;
|
||||
|
||||
if (hero_hp<=0 || mon_hp<=0) {
|
||||
// 战斗结束
|
||||
clearInterval(battleInterval);
|
||||
core.status.boxAnimateObjs = [];
|
||||
core.setBoxAnimate();
|
||||
core.clearMap('ui', 0, 0, 416, 416);
|
||||
core.setAlpha('ui', 1.0);
|
||||
core.clearMap('data', 0, 0, 416, 416);
|
||||
if (core.status.event.id=='battle') {
|
||||
core.unLockControl();
|
||||
core.status.event.id=null;
|
||||
}
|
||||
if (core.isset(callback))
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
}, 500);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
html, body {
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
@ -6,12 +6,7 @@ html, body {
|
||||
background-color: #000;
|
||||
overflow: hidden;
|
||||
}
|
||||
/*
|
||||
@font-face {
|
||||
font-family: number;
|
||||
src: url("fonts/number.ttf");
|
||||
}
|
||||
*/
|
||||
|
||||
#gameGroup {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
|
||||