Merge remote-tracking branch 'refs/remotes/ckcz123/master'
This commit is contained in:
commit
04424fbe57
@ -113,5 +113,6 @@
|
|||||||
<canvas class='gameCanvas' id='data' width='416' height='416'>此浏览器不支持HTML5</canvas>
|
<canvas class='gameCanvas' id='data' width='416' height='416'>此浏览器不支持HTML5</canvas>
|
||||||
</div>
|
</div>
|
||||||
<script id='mainScript' src='main.js'></script>
|
<script id='mainScript' src='main.js'></script>
|
||||||
|
<script src='libs/thirdparty/mid.js'></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
703
libs/core.js
703
libs/core.js
@ -7,12 +7,14 @@ function core() {
|
|||||||
this.statusBar = {};
|
this.statusBar = {};
|
||||||
this.canvas = {};
|
this.canvas = {};
|
||||||
this.images = [];
|
this.images = [];
|
||||||
this.sounds = {};
|
this.bgms = [];
|
||||||
|
this.sounds = [];
|
||||||
this.floorIds = [];
|
this.floorIds = [];
|
||||||
this.floors = {};
|
this.floors = {};
|
||||||
this.firstData = {};
|
this.firstData = {};
|
||||||
this.material = {
|
this.material = {
|
||||||
'images': {},
|
'images': {},
|
||||||
|
'bgms': {},
|
||||||
'sounds': {},
|
'sounds': {},
|
||||||
'ground': null,
|
'ground': null,
|
||||||
'items': {},
|
'items': {},
|
||||||
@ -35,12 +37,12 @@ function core() {
|
|||||||
'openDoorAnimate': null
|
'openDoorAnimate': null
|
||||||
}
|
}
|
||||||
this.musicStatus = {
|
this.musicStatus = {
|
||||||
'isIOS': false,
|
'audioContext': null, // WebAudioContext
|
||||||
'loaded': false,
|
'startDirectly': false, // 是否直接播放(加载)音乐
|
||||||
'bgmStatus': false,
|
'bgmStatus': false, // 是否播放BGM
|
||||||
'soundStatus': true,
|
'soundStatus': true, // 是否播放SE
|
||||||
'playedSound': null,
|
'playingBgm': null, // 正在播放的BGM
|
||||||
'playedBgm': null,
|
'isPlaying': false,
|
||||||
}
|
}
|
||||||
// 样式
|
// 样式
|
||||||
this.domStyle = {
|
this.domStyle = {
|
||||||
@ -57,7 +59,7 @@ function core() {
|
|||||||
'floorId': null,
|
'floorId': null,
|
||||||
'thisMap': null,
|
'thisMap': null,
|
||||||
'maps': null,
|
'maps': null,
|
||||||
'checkBlock': [], // 显伤伤害
|
'checkBlock': {}, // 显伤伤害
|
||||||
|
|
||||||
// 勇士状态;自动寻路相关
|
// 勇士状态;自动寻路相关
|
||||||
'heroMoving': false,
|
'heroMoving': false,
|
||||||
@ -102,11 +104,12 @@ function core() {
|
|||||||
|
|
||||||
/////////// 系统事件相关 ///////////
|
/////////// 系统事件相关 ///////////
|
||||||
|
|
||||||
core.prototype.init = function (dom, statusBar, canvas, images, sounds, floorIds, floors, coreData) {
|
core.prototype.init = function (dom, statusBar, canvas, images, 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.bgms = bgms;
|
||||||
core.sounds = sounds;
|
core.sounds = sounds;
|
||||||
core.floorIds = floorIds;
|
core.floorIds = floorIds;
|
||||||
core.floors = floors;
|
core.floors = floors;
|
||||||
@ -134,15 +137,42 @@ core.prototype.init = function (dom, statusBar, canvas, images, sounds, floorIds
|
|||||||
core.material.icons = core.icons.getIcons();
|
core.material.icons = core.icons.getIcons();
|
||||||
core.material.events = core.events.getEvents();
|
core.material.events = core.events.getEvents();
|
||||||
|
|
||||||
// test if iOS
|
|
||||||
core.musicStatus.soundStatus = core.getLocalStorage('soundStatus', true);
|
|
||||||
var userAgent = navigator.userAgent;
|
|
||||||
|
|
||||||
if (userAgent.indexOf('iPhone') > -1 || userAgent.indexOf('iPad') > -1) {
|
|
||||||
console.log("你的设备为iphone,不自动播放音乐!");
|
if (location.protocol.indexOf("http")==0) {
|
||||||
core.musicStatus.isIOS = true;
|
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
|
||||||
core.musicStatus.soundStatus = false;
|
try {
|
||||||
|
core.musicStatus.audioContext = new window.AudioContext();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("该浏览器不支持AudioContext");
|
||||||
|
core.musicStatus.audioContext = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音效设置部分
|
||||||
|
var isPC = true;
|
||||||
|
["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"].forEach(function (t) {
|
||||||
|
if (navigator.userAgent.indexOf(t)>=0) isPC=false;
|
||||||
|
});
|
||||||
|
if (isPC) {
|
||||||
|
// 如果是PC端直接加载
|
||||||
|
core.musicStatus.startDirectly = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var connection = navigator.connection;
|
||||||
|
if (core.isset(connection) && connection.type=='wifi')
|
||||||
|
core.musicStatus.startDirectly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先从存储中读取BGM状态
|
||||||
|
core.musicStatus.bgmStatus = core.getLocalStorage('bgmStatus', true);
|
||||||
|
if (!core.musicStatus.startDirectly) // 如果当前网络环境不允许
|
||||||
|
core.musicStatus.bgmStatus = false;
|
||||||
|
core.setLocalStorage('bgmStatus', core.musicStatus.bgmStatus);
|
||||||
|
|
||||||
|
core.musicStatus.soundStatus = core.getLocalStorage('soundStatus', true);
|
||||||
|
core.setLocalStorage('soundStatus', core.musicStatus.soundStatus);
|
||||||
|
|
||||||
|
|
||||||
// switchs
|
// switchs
|
||||||
core.flags.battleAnimate = core.getLocalStorage('battleAnimate', core.flags.battleAnimate);
|
core.flags.battleAnimate = core.getLocalStorage('battleAnimate', core.flags.battleAnimate);
|
||||||
@ -232,7 +262,7 @@ core.prototype.loader = function (callback) {
|
|||||||
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.loadSounds(callback);
|
core.loadMusic(callback);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -259,65 +289,111 @@ core.prototype.loadImage = function (imgName, callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.loadSounds = function (callback) {
|
core.prototype.loadMusic = function (callback) {
|
||||||
for (var key in core.sounds) {
|
|
||||||
for (var i = 0; i < core.sounds[key].length; i++) {
|
core.bgms.forEach(function (t) {
|
||||||
var soundName=core.sounds[key][i];
|
|
||||||
soundName = soundName.split('-');
|
// 判断是不是mid
|
||||||
var sound = new Audio();
|
if (/^.*\.mid$/.test(t)) {
|
||||||
sound.preload = 'none';
|
|
||||||
sound.src = 'sounds/' + soundName[0] + '.' + key;
|
if (core.musicStatus.audioContext!=null) {
|
||||||
if (soundName[1] == 'loop') {
|
core.material.bgms[t] = 'loading';
|
||||||
sound.loop = 'loop';
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', 'sounds/'+t, true);
|
||||||
|
xhr.overrideMimeType("text/plain; charset=x-user-defined");
|
||||||
|
xhr.onload = function(e) { //下载完成
|
||||||
|
try {
|
||||||
|
var ff = [];
|
||||||
|
var mx = this.responseText.length;
|
||||||
|
for (var z = 0; z < mx; z++)
|
||||||
|
ff[z] = String.fromCharCode(this.responseText.charCodeAt(z) & 255);
|
||||||
|
var shouldStart = core.material.bgms[t] == 'starting';
|
||||||
|
core.material.bgms[t] = AudioPlayer(core.musicStatus.audioContext, Replayer(MidiFile(ff.join("")), Synth(44100)), true);
|
||||||
|
|
||||||
|
if (shouldStart)
|
||||||
|
core.playBgm(t);
|
||||||
|
}
|
||||||
|
catch (ee) {
|
||||||
|
console.log(ee);
|
||||||
|
core.material.bgms[t] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!core.isset(core.material.sounds[key]))
|
};
|
||||||
core.material.sounds[key] = {};
|
xhr.ontimeout = function(e) {
|
||||||
core.material.sounds[key][soundName[0]] = sound;
|
console.log(e);
|
||||||
|
core.material.bgms[t] = null;
|
||||||
|
}
|
||||||
|
xhr.onerror = function(e) {
|
||||||
|
console.log(e);
|
||||||
|
core.material.bgms[t] = null;
|
||||||
|
}
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.material.bgms[t] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
var music = new Audio();
|
||||||
|
music.preload = core.musicStatus.startDirectly?'auto':'none';
|
||||||
|
music.src = 'sounds/'+t;
|
||||||
|
music.loop = 'loop';
|
||||||
|
core.material.bgms[t] = music;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
core.sounds.forEach(function (t) {
|
||||||
|
|
||||||
|
if (core.musicStatus.audioContext != null) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', 'sounds/'+t, true);
|
||||||
|
xhr.responseType = 'arraybuffer';
|
||||||
|
xhr.onload = function(e) { //下载完成
|
||||||
|
try {
|
||||||
|
core.musicStatus.audioContext.decodeAudioData(this.response, function (buffer) {
|
||||||
|
core.material.sounds[t] = buffer;
|
||||||
|
}, function (e) {
|
||||||
|
console.log(e);
|
||||||
|
core.material.sounds[t] = null;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
catch (ee) {
|
||||||
|
console.log(ee);
|
||||||
|
core.material.sounds[t] = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.ontimeout = function(e) {
|
||||||
|
console.log(e);
|
||||||
|
core.material.sounds[t] = null;
|
||||||
|
}
|
||||||
|
xhr.onerror = function(e) {
|
||||||
|
console.log(e);
|
||||||
|
core.material.sounds[t] = null;
|
||||||
|
}
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var music = new Audio();
|
||||||
|
music.src = 'sounds/'+t;
|
||||||
|
core.material.sounds[t] = music;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 直接开始播放
|
||||||
|
if (core.musicStatus.startDirectly && core.bgms.length>0)
|
||||||
|
core.playBgm(core.bgms[0]);
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.loadSound = function() {
|
|
||||||
if (!core.isset(core.material.sounds.mp3)) return;
|
|
||||||
if (core.musicStatus.isIOS) return;
|
|
||||||
if (core.musicStatus.loaded) return;
|
|
||||||
core.musicStatus.loaded=true;
|
|
||||||
console.log("加载音乐");
|
|
||||||
|
|
||||||
var toLoadList = [];
|
|
||||||
|
|
||||||
for (var key in core.material.sounds) {
|
|
||||||
for (var name in core.material.sounds[key]) {
|
|
||||||
toLoadList.push(core.material.sounds[key][name]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
core.loadSoundItem(toLoadList);
|
|
||||||
}
|
|
||||||
|
|
||||||
core.prototype.loadSoundItem = function (toLoadList) {
|
|
||||||
if (toLoadList.length==0) {
|
|
||||||
if (core.musicStatus.bgmStatus>0) return;
|
|
||||||
core.musicStatus.bgmStatus=1;
|
|
||||||
if (core.musicStatus.soundStatus)
|
|
||||||
core.playBgm('bgm', 'mp3');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var item = toLoadList.shift();
|
|
||||||
item.oncanplay = function() {
|
|
||||||
core.loadSoundItem(toLoadList);
|
|
||||||
}
|
|
||||||
item.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
core.prototype.isPlaying = function() {
|
core.prototype.isPlaying = function() {
|
||||||
if (core.isset(core.status.played) && core.status.played)
|
if (core.isset(core.status.played) && core.status.played)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
core.prototype.clearStatus = function() {
|
core.prototype.clearStatus = function() {
|
||||||
// 停止各个Timeout和Interval
|
// 停止各个Timeout和Interval
|
||||||
for (var i in core.interval) {
|
for (var i in core.interval) {
|
||||||
@ -538,6 +614,10 @@ core.prototype.keyUp = function(keyCode) {
|
|||||||
core.events.keyUpBook(keyCode);
|
core.events.keyUpBook(keyCode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (core.status.event.id=='book-detail' && (keyCode==13 || keyCode==32 || keyCode==67)) {
|
||||||
|
core.events.clickBookDetail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (core.status.event.id=='fly') {
|
if (core.status.event.id=='fly') {
|
||||||
core.events.keyUpFly(keyCode);
|
core.events.keyUpFly(keyCode);
|
||||||
return;
|
return;
|
||||||
@ -780,6 +860,12 @@ core.prototype.onclick = function (x, y, stepPostfix) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 怪物详细信息
|
||||||
|
if (core.status.event.id == 'book-detail') {
|
||||||
|
core.events.clickBookDetail(x,y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 楼层飞行器
|
// 楼层飞行器
|
||||||
if (core.status.event.id == 'fly') {
|
if (core.status.event.id == 'fly') {
|
||||||
core.events.clickFly(x,y);
|
core.events.clickFly(x,y);
|
||||||
@ -886,6 +972,7 @@ core.prototype.onmousewheel = function (direct) {
|
|||||||
/////////// 寻路代码相关 ///////////
|
/////////// 寻路代码相关 ///////////
|
||||||
|
|
||||||
core.prototype.clearAutomaticRouteNode = function (x, y) {
|
core.prototype.clearAutomaticRouteNode = function (x, y) {
|
||||||
|
if (core.status.event.id==null)
|
||||||
core.canvas.ui.clearRect(x * 32 + 5, y * 32 + 5, 27, 27);
|
core.canvas.ui.clearRect(x * 32 + 5, y * 32 + 5, 27, 27);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1098,8 +1185,8 @@ core.prototype.automaticRoute = function (destX, destY) {
|
|||||||
// 绕过可能的夹击点
|
// 绕过可能的夹击点
|
||||||
// if (nextBlock.block.event.trigger == 'checkBlock') deepAdd=200;
|
// if (nextBlock.block.event.trigger == 'checkBlock') deepAdd=200;
|
||||||
}
|
}
|
||||||
if (core.status.checkBlock[nid]>0)
|
if (core.status.checkBlock.damage[nid]>0)
|
||||||
deepAdd = core.status.checkBlock[nid];
|
deepAdd = core.status.checkBlock.damage[nid];
|
||||||
|
|
||||||
if (nx == destX && ny == destY) {
|
if (nx == destX && ny == destY) {
|
||||||
route[nid] = direction;
|
route[nid] = direction;
|
||||||
@ -1270,9 +1357,9 @@ core.prototype.setHeroMoveTriggerInterval = function () {
|
|||||||
core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
|
core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
|
||||||
}
|
}
|
||||||
core.trigger(core.getHeroLoc('x'), core.getHeroLoc('y'));
|
core.trigger(core.getHeroLoc('x'), core.getHeroLoc('y'));
|
||||||
core.checkBlock();
|
|
||||||
clearInterval(core.interval.heroMoveInterval);
|
clearInterval(core.interval.heroMoveInterval);
|
||||||
core.status.heroMoving = false;
|
core.status.heroMoving = false;
|
||||||
|
core.checkBlock();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 50);
|
}, 50);
|
||||||
@ -1471,7 +1558,7 @@ core.prototype.openDoor = function (id, x, y, needKey, callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// open
|
// open
|
||||||
core.playSound("door", "ogg");
|
core.playSound("door.ogg");
|
||||||
var state = 0;
|
var state = 0;
|
||||||
var doorId = id;
|
var doorId = id;
|
||||||
if (!(doorId.substring(doorId.length-4)=="Door")) {
|
if (!(doorId.substring(doorId.length-4)=="Door")) {
|
||||||
@ -1517,7 +1604,7 @@ core.prototype.battle = function (id, x, y, force, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.playSound('attack', 'ogg');
|
core.playSound('attack.ogg');
|
||||||
core.afterBattle(id, x, y, callback);
|
core.afterBattle(id, x, y, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1549,7 +1636,6 @@ core.prototype.afterBattle = function(id, x, y, callback) {
|
|||||||
hint += ",经验+" + core.material.enemys[id].experience;
|
hint += ",经验+" + core.material.enemys[id].experience;
|
||||||
core.drawTip(hint);
|
core.drawTip(hint);
|
||||||
|
|
||||||
core.updateCheckBlockMap();
|
|
||||||
// 打完怪物,触发事件
|
// 打完怪物,触发事件
|
||||||
core.events.afterBattle(id,x,y,callback);
|
core.events.afterBattle(id,x,y,callback);
|
||||||
|
|
||||||
@ -1613,7 +1699,7 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback)
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.setTimeout(function () {
|
window.setTimeout(function () {
|
||||||
core.playSound('floor', 'mp3');
|
core.playSound('floor.mp3');
|
||||||
core.mapChangeAnimate('show', time/2, function () {
|
core.mapChangeAnimate('show', time/2, function () {
|
||||||
|
|
||||||
// 根据文字判断是否斜体
|
// 根据文字判断是否斜体
|
||||||
@ -1624,6 +1710,27 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback)
|
|||||||
core.statusBar.floor.style.fontStyle = 'italic';
|
core.statusBar.floor.style.fontStyle = 'italic';
|
||||||
else core.statusBar.floor.style.fontStyle = 'normal';
|
else core.statusBar.floor.style.fontStyle = 'normal';
|
||||||
|
|
||||||
|
// 不存在事件时,更改画面色调
|
||||||
|
if (core.status.event.id == null) {
|
||||||
|
// 默认画面色调
|
||||||
|
if (core.isset(core.floors[floorId].color)) {
|
||||||
|
var color = core.floors[floorId].color;
|
||||||
|
|
||||||
|
// 直接变色
|
||||||
|
var nowR = parseInt(color[0]), nowG = parseInt(color[1]), nowB = parseInt(color[2]);
|
||||||
|
var toRGB = "#"+((1<<24)+(nowR<<16)+(nowG<<8)+nowB).toString(16).slice(1);
|
||||||
|
core.dom.curtain.style.background = toRGB;
|
||||||
|
if (core.isset(color[3]))
|
||||||
|
core.dom.curtain.style.opacity = color[3];
|
||||||
|
else core.dom.curtain.style.opacity=1;
|
||||||
|
core.status.curtainColor = color;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.dom.curtain.style.background = "#000000";
|
||||||
|
core.dom.curtain.style.opacity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
core.drawMap(floorId, function () {
|
core.drawMap(floorId, function () {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
core.mapChangeAnimate('hide', time/4, function () {
|
core.mapChangeAnimate('hide', time/4, function () {
|
||||||
@ -1637,9 +1744,6 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback)
|
|||||||
core.setHeroLoc('y', heroLoc.y);
|
core.setHeroLoc('y', heroLoc.y);
|
||||||
core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
|
core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
|
||||||
core.updateStatusBar();
|
core.updateStatusBar();
|
||||||
// core.updateCheckBlockMap();
|
|
||||||
// core.updateCheckBlock();
|
|
||||||
// core.updateFg();
|
|
||||||
}, 15)
|
}, 15)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1831,7 +1935,7 @@ core.prototype.drawAutotile = function (floorId, canvas, autotileMaps, left, top
|
|||||||
}
|
}
|
||||||
|
|
||||||
var isAutotile = function(x, y) {
|
var isAutotile = function(x, y) {
|
||||||
if (x<0 || x>12 || y<0 || y>12) return 0;
|
if (x<0 || x>12 || y<0 || y>12) return 1;
|
||||||
return autotileMaps[13*x+y]==autotileId?1:0;
|
return autotileMaps[13*x+y]==autotileId?1:0;
|
||||||
}
|
}
|
||||||
for (var xx=0;xx<13;xx++) {
|
for (var xx=0;xx<13;xx++) {
|
||||||
@ -1987,7 +2091,7 @@ core.prototype.nearStair = function() {
|
|||||||
core.prototype.enemyExists = function (x, y, id,floorId) {
|
core.prototype.enemyExists = function (x, y, id,floorId) {
|
||||||
var block = core.getBlock(x,y,floorId);
|
var block = core.getBlock(x,y,floorId);
|
||||||
if (block==null) return false;
|
if (block==null) return false;
|
||||||
return block.block.event.cls=='enemys' && block.block.event.id==id;
|
return block.block.event.cls=='enemys' && (core.isset(id)?block.block.event.id==id:true);
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.getBlock = function (x, y, floorId, needEnable) {
|
core.prototype.getBlock = function (x, y, floorId, needEnable) {
|
||||||
@ -2153,7 +2257,6 @@ core.prototype.addBlock = function(x,y,floodId) {
|
|||||||
// 本身是禁用事件,启用之
|
// 本身是禁用事件,启用之
|
||||||
if (core.isset(block.enable) && !block.enable) {
|
if (core.isset(block.enable) && !block.enable) {
|
||||||
block.enable = true;
|
block.enable = true;
|
||||||
core.updateCheckBlockMap();
|
|
||||||
// 在本层,添加动画
|
// 在本层,添加动画
|
||||||
if (floodId == core.status.floorId && core.isset(block.event)) {
|
if (floodId == core.status.floorId && core.isset(block.event)) {
|
||||||
blockIcon = core.material.icons[block.event.cls][block.event.id];
|
blockIcon = core.material.icons[block.event.cls][block.event.id];
|
||||||
@ -2195,17 +2298,12 @@ core.prototype.removeBlockById = function (index, floorId) {
|
|||||||
if (!core.isset(event))
|
if (!core.isset(event))
|
||||||
event = core.floors[floorId].changeFloor[x+","+y];
|
event = core.floors[floorId].changeFloor[x+","+y];
|
||||||
|
|
||||||
var shouldUpdateBlockMap = blocks[index].event.cls == 'enemys';
|
|
||||||
// 不存在事件,直接删除
|
// 不存在事件,直接删除
|
||||||
if (!core.isset(event)) {
|
if (!core.isset(event)) {
|
||||||
blocks.splice(index,1);
|
blocks.splice(index,1);
|
||||||
if (shouldUpdateBlockMap)
|
|
||||||
core.updateCheckBlockMap();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
blocks[index].enable = false;
|
blocks[index].enable = false;
|
||||||
if (shouldUpdateBlockMap)
|
|
||||||
core.updateCheckBlockMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.removeBlockByIds = function (floorId, ids) {
|
core.prototype.removeBlockByIds = function (floorId, ids) {
|
||||||
@ -2282,6 +2380,15 @@ core.prototype.setGlobalAnimate = function (speed) {
|
|||||||
}, speed / 2);
|
}, speed / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core.prototype.syncGlobalAnimate = function () {
|
||||||
|
core.status.twoAnimateObjs.forEach(function (t) {
|
||||||
|
t.status=0;
|
||||||
|
})
|
||||||
|
core.status.fourAnimateObjs.forEach(function (t) {
|
||||||
|
t.status=0;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
core.prototype.setBoxAnimate = function () {
|
core.prototype.setBoxAnimate = function () {
|
||||||
clearInterval(core.interval.boxAnimate);
|
clearInterval(core.interval.boxAnimate);
|
||||||
if (core.status.boxAnimateObjs.length > 0) {
|
if (core.status.boxAnimateObjs.length > 0) {
|
||||||
@ -2304,84 +2411,136 @@ core.prototype.drawBoxAnimate = function (background) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.updateCheckBlockMap = function() {
|
// 更新领域、显伤
|
||||||
// 更新领域、夹击地图
|
core.prototype.updateCheckBlock = function() {
|
||||||
core.status.checkBlockMap = [];
|
core.status.checkBlock = {};
|
||||||
|
if (!core.isset(core.status.thisMap)) return;
|
||||||
var blocks = core.status.thisMap.blocks;
|
var blocks = core.status.thisMap.blocks;
|
||||||
|
|
||||||
|
// Step1: 更新怪物地图
|
||||||
|
core.status.checkBlock.map = []; // 记录怪物地图
|
||||||
for (var n=0;n<blocks.length;n++) {
|
for (var n=0;n<blocks.length;n++) {
|
||||||
var block = blocks[n];
|
var block = blocks[n];
|
||||||
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable)) {
|
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls=='enemys') {
|
||||||
if (block.event.cls=='enemys') {
|
var id = block.event.id, enemy = core.enemys.getEnemys(id);
|
||||||
var enemy = core.enemys.getEnemys(block.event.id);
|
|
||||||
if (core.isset(enemy)) {
|
if (core.isset(enemy)) {
|
||||||
var value=0;
|
core.status.checkBlock.map[13*block.x+block.y]=id;
|
||||||
if (core.enemys.hasSpecial(enemy.special, 15)) // 领域
|
|
||||||
value += enemy.value;
|
|
||||||
if (core.enemys.hasSpecial(enemy.special, 16)) // 夹击
|
|
||||||
value += 1000000 * block.id;
|
|
||||||
core.status.checkBlockMap[13*block.x+block.y] = value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新领域、显伤点
|
// Step2: 更新领域、阻击伤害
|
||||||
core.prototype.updateCheckBlock = function() {
|
core.status.checkBlock.damage = []; // 记录(x,y)点的伤害
|
||||||
if (!core.isset(core.status.thisMap)) return;
|
for (var x=0;x<13*13;x++) core.status.checkBlock.damage[x]=0;
|
||||||
if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap();
|
|
||||||
core.status.checkBlock = [];
|
|
||||||
for (var x=0;x<13;x++) {
|
for (var x=0;x<13;x++) {
|
||||||
for (var y=0;y<13;y++) {
|
for (var y=0;y<13;y++) {
|
||||||
// 计算(x,y)点伤害
|
var id = core.status.checkBlock.map[13*x+y];
|
||||||
var damage = 0;
|
if (core.isset(id)) {
|
||||||
if (!core.enemyExists(x,y)) { // 如果该点本身不存在怪物(打死怪物会调用更新)
|
var enemy = core.enemys.getEnemys(id);
|
||||||
|
// 存在领域
|
||||||
// 领域
|
if (core.enemys.hasSpecial(enemy.special, 15)) {
|
||||||
[[-1,0],[0,-1],[1,0],[0,1]].forEach(function (dir) {
|
var range = enemy.range || 1;
|
||||||
var nx = x+dir[0], ny = y+dir[1];
|
var zoneSquare = core.flags.zoneSquare;
|
||||||
if (nx<0 || nx>12 || ny<0 || ny>12) return;
|
if (core.isset(enemy.zoneSquare)) zoneSquare=enemy.zoneSquare;
|
||||||
if (core.status.checkBlockMap[13*nx+ny]%1000000>0) {
|
for (var dx=-range;dx<=range;dx++) {
|
||||||
damage += core.status.checkBlockMap[13*nx+ny] % 1000000;
|
for (var dy=-range;dy<=range;dy++) {
|
||||||
|
if (dx==0 && dy==0) continue;
|
||||||
|
var nx=x+dx, ny=y+dy;
|
||||||
|
if (nx<0 || nx>12 || ny<0 || ny>12) continue;
|
||||||
|
if (!zoneSquare && Math.abs(dx)+Math.abs(dy)>range) continue;
|
||||||
|
core.status.checkBlock.damage[13*nx+ny]+=enemy.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 存在阻击
|
||||||
|
if (core.enemys.hasSpecial(enemy.special, 18)) {
|
||||||
|
for (var dx=-1;dx<=1;dx++) {
|
||||||
|
for (var dy=-1;dy<=1;dy++) {
|
||||||
|
if (dx==0 && dy==0) continue;
|
||||||
|
var nx=x+dx, ny=y+dy;
|
||||||
|
if (nx<0 || nx>12 || ny<0 || ny>12 || Math.abs(dx)+Math.abs(dy)>1) continue;
|
||||||
|
core.status.checkBlock.damage[13*nx+ny]+=enemy.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
var leftValue = core.status.hero.hp - damage;
|
|
||||||
if (leftValue>1) {
|
// Step3: 更新夹击点坐标,并将夹击伤害加入到damage中
|
||||||
var has = false;
|
core.status.checkBlock.betweenAttack = []; // 记录(x,y)点是否有夹击
|
||||||
// 夹击
|
for (var x=0;x<13;x++) {
|
||||||
|
for (var y=0;y<13;y++) {
|
||||||
|
var has=false;
|
||||||
if (x>0 && x<12) {
|
if (x>0 && x<12) {
|
||||||
var id1=parseInt(core.status.checkBlockMap[13*(x-1)+y]/1000000),
|
var id1=core.status.checkBlock.map[13*(x-1)+y],
|
||||||
id2=parseInt(core.status.checkBlockMap[13*(x+1)+y]/1000000);
|
id2=core.status.checkBlock.map[13*(x+1)+y];
|
||||||
if (id1>0 && id1==id2)
|
if (core.isset(id1) && core.isset(id2) && id1==id2) {
|
||||||
|
var enemy = core.enemys.getEnemys(id1);
|
||||||
|
if (core.enemys.hasSpecial(enemy.special, 16)) {
|
||||||
has = true;
|
has = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (y>0 && y<12) {
|
if (y>0 && y<12) {
|
||||||
var id1=parseInt(core.status.checkBlockMap[13*x+y-1]/1000000),
|
var id1=core.status.checkBlock.map[13*x+y-1],
|
||||||
id2=parseInt(core.status.checkBlockMap[13*x+y+1]/1000000);
|
id2=core.status.checkBlock.map[13*x+y+1];
|
||||||
if (id1>0 && id1==id2)
|
if (core.isset(id1) && core.isset(id2) && id1==id2) {
|
||||||
|
var enemy = core.enemys.getEnemys(id1);
|
||||||
|
if (core.enemys.hasSpecial(enemy.special, 16)) {
|
||||||
has = true;
|
has = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 存在夹击
|
||||||
if (has) {
|
if (has) {
|
||||||
damage += parseInt((leftValue+1) / 2);
|
core.status.checkBlock.betweenAttack[13*x+y]=true;
|
||||||
|
var leftHp = core.status.hero.hp - core.status.checkBlock.damage[13*x+y];
|
||||||
|
if (leftHp>1)
|
||||||
|
core.status.checkBlock.damage[13*x+y] += parseInt((leftHp+1)/2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
core.status.checkBlock[13*x+y] = damage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.checkBlock = function () {
|
core.prototype.checkBlock = function () {
|
||||||
// 检查领域、夹击事件
|
// 检查领域、夹击事件
|
||||||
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
|
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
|
||||||
if (core.status.checkBlock[13*x+y]>0) {
|
var damage = core.status.checkBlock.damage[13*x+y];
|
||||||
core.status.hero.hp -= core.status.checkBlock[13*x+y];
|
if (damage>0) {
|
||||||
if (core.hasBetweenAttack(x,y)) {
|
core.status.hero.hp -= damage;
|
||||||
|
|
||||||
|
// 检查阻击事件
|
||||||
|
var snipe = [];
|
||||||
|
var scan = {
|
||||||
|
'up': {'x': 0, 'y': -1},
|
||||||
|
'left': {'x': -1, 'y': 0},
|
||||||
|
'down': {'x': 0, 'y': 1},
|
||||||
|
'right': {'x': 1, 'y': 0}
|
||||||
|
}
|
||||||
|
for (var direction in scan) {
|
||||||
|
var nx = x+scan[direction].x, ny=y+scan[direction].y;
|
||||||
|
if (nx<0 || nx>12 || ny<0 || ny>12) continue;
|
||||||
|
var id=core.status.checkBlock.map[13*nx+ny];
|
||||||
|
if (core.isset(id)) {
|
||||||
|
var enemy = core.enemys.getEnemys(id);
|
||||||
|
if (core.isset(enemy) && core.enemys.hasSpecial(enemy.special, 18)) {
|
||||||
|
snipe.push({'direction': direction, 'x': nx, 'y': ny});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (core.status.checkBlock.betweenAttack[13*x+y]) {
|
||||||
core.drawTip('受到夹击,生命变成一半');
|
core.drawTip('受到夹击,生命变成一半');
|
||||||
}
|
}
|
||||||
else if (core.hasZone(x,y)) {
|
// 阻击
|
||||||
core.drawTip('受到领域伤害'+core.status.checkBlock[13*x+y]+'点');
|
else if (snipe.length>0) {
|
||||||
|
core.drawTip('受到阻击伤害'+damage+'点');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.drawTip('受到领域伤害'+damage+'点');
|
||||||
}
|
}
|
||||||
if (core.status.hero.hp<=0) {
|
if (core.status.hero.hp<=0) {
|
||||||
core.status.hero.hp=0;
|
core.status.hero.hp=0;
|
||||||
@ -2389,43 +2548,125 @@ core.prototype.checkBlock = function () {
|
|||||||
core.events.lose('zone');
|
core.events.lose('zone');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
snipe = snipe.filter(function (t) {
|
||||||
|
var x=t.x, y=t.y, direction = t.direction;
|
||||||
|
var nx = x+scan[direction].x, ny=y+scan[direction].y;
|
||||||
|
|
||||||
|
return nx>=0 && nx<=12 && ny>=0 && ny<=12 && core.getBlock(nx, ny, core.status.floorId, false)==null;
|
||||||
|
});
|
||||||
core.updateStatusBar();
|
core.updateStatusBar();
|
||||||
|
if (snipe.length>0)
|
||||||
|
core.snipe(snipe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.hasZone = function (x,y) {
|
core.prototype.snipe = function (snipes) {
|
||||||
if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap();
|
core.waitHeroToStop(function() {
|
||||||
var isZone = false;
|
core.lockControl();
|
||||||
// 领域
|
|
||||||
[[-1,0],[0,-1],[1,0],[0,1]].forEach(function (dir) {
|
var scan = {
|
||||||
var nx = x+dir[0], ny = y+dir[1];
|
'up': {'x': 0, 'y': -1},
|
||||||
if (nx<0 || nx>12 || ny<0 || ny>12) return;
|
'left': {'x': -1, 'y': 0},
|
||||||
if (core.status.checkBlockMap[13*nx+ny]%1000000>0) {
|
'down': {'x': 0, 'y': 1},
|
||||||
isZone = true;
|
'right': {'x': 1, 'y': 0}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
snipes.forEach(function (snipe) {
|
||||||
|
var x=snipe.x, y=snipe.y, direction = snipe.direction;
|
||||||
|
snipe.nx = x+scan[snipe.direction].x;
|
||||||
|
snipe.ny = y+scan[snipe.direction].y;
|
||||||
|
|
||||||
|
core.removeGlobalAnimate(x, y);
|
||||||
|
|
||||||
|
var block = core.getBlock(x,y).block;
|
||||||
|
|
||||||
|
snipe.blockIcon = core.material.icons[block.event.cls][block.event.id];
|
||||||
|
snipe.blockImage = core.material.images[block.event.cls];
|
||||||
|
var damage = core.enemys.getDamage(block.event.id);
|
||||||
|
|
||||||
|
var color = "#000000";
|
||||||
|
if (damage <= 0) color = '#00FF00';
|
||||||
|
else if (damage < core.status.hero.hp / 3) color = '#FFFFFF';
|
||||||
|
else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00';
|
||||||
|
else if (damage < core.status.hero.hp) color = '#FF7F00';
|
||||||
|
else color = '#FF0000';
|
||||||
|
|
||||||
|
if (damage >= 999999999) damage = "???";
|
||||||
|
else if (damage > 100000) damage = (damage / 10000).toFixed(1) + "w";
|
||||||
|
|
||||||
|
snipe.damage = damage;
|
||||||
|
snipe.color = color;
|
||||||
|
snipe.block = core.clone(block);
|
||||||
})
|
})
|
||||||
return isZone;
|
|
||||||
}
|
|
||||||
|
|
||||||
core.prototype.hasBetweenAttack = function(x,y) {
|
var time = 500, step = 0;
|
||||||
if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap();
|
|
||||||
// 夹击
|
var animateValue = 2;
|
||||||
if (x>0 && x<12) {
|
var animateCurrent = 0;
|
||||||
var id1=parseInt(core.status.checkBlockMap[13*(x-1)+y]/1000000),
|
var animateTime = 0;
|
||||||
id2=parseInt(core.status.checkBlockMap[13*(x+1)+y]/1000000);
|
|
||||||
if (id1>0 && id1==id2)
|
core.canvas.fg.textAlign = 'left';
|
||||||
return true;
|
|
||||||
|
var animate=window.setInterval(function() {
|
||||||
|
|
||||||
|
step++;
|
||||||
|
animateTime += time / 16;
|
||||||
|
if (animateTime >= core.values.animateSpeed * 2 / animateValue) {
|
||||||
|
animateCurrent++;
|
||||||
|
animateTime = 0;
|
||||||
|
if (animateCurrent>=animateValue) animateCurrent=0;
|
||||||
}
|
}
|
||||||
if (y>0 && y<12) {
|
|
||||||
var id1=parseInt(core.status.checkBlockMap[13*x+y-1]/1000000),
|
snipes.forEach(function (snipe) {
|
||||||
id2=parseInt(core.status.checkBlockMap[13*x+y+1]/1000000);
|
var x=snipe.x, y=snipe.y, direction = snipe.direction;
|
||||||
if (id1>0 && id1==id2)
|
|
||||||
return true;
|
var nowX=32*x+scan[direction].x*2*step, nowY=32*y+scan[direction].y*2*step;
|
||||||
|
|
||||||
|
// 清空上一次
|
||||||
|
core.clearMap('event', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32);
|
||||||
|
core.clearMap('fg', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32);
|
||||||
|
|
||||||
|
core.canvas.event.drawImage(snipe.blockImage, animateCurrent*32, snipe.blockIcon*32, 32, 32, nowX, nowY, 32, 32);
|
||||||
|
|
||||||
|
if (core.hasItem('book')) {
|
||||||
|
// drawFG
|
||||||
|
core.setFillStyle('fg', '#000000');
|
||||||
|
core.canvas.fg.fillText(snipe.damage, nowX + 2, nowY + 30);
|
||||||
|
core.canvas.fg.fillText(snipe.damage, nowX, nowY + 30);
|
||||||
|
core.canvas.fg.fillText(snipe.damage, nowX + 2, nowY + 32);
|
||||||
|
core.canvas.fg.fillText(snipe.damage, nowX, nowY + 32);
|
||||||
|
|
||||||
|
core.setFillStyle('fg', snipe.color);
|
||||||
|
core.canvas.fg.fillText(snipe.damage, nowX + 1, nowY + 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
if (step==16) { // 移动完毕
|
||||||
|
clearInterval(animate);
|
||||||
|
snipes.forEach(function (t) {
|
||||||
|
core.removeBlock(t.x, t.y);
|
||||||
|
var nBlock = core.clone(t.block);
|
||||||
|
nBlock.x = t.nx; nBlock.y = t.ny;
|
||||||
|
core.status.thisMap.blocks.push(nBlock);
|
||||||
|
core.addGlobalAnimate(animateValue, 32*t.nx, 32*t.ny, t.blockIcon, t.blockImage);
|
||||||
|
});
|
||||||
|
core.syncGlobalAnimate();
|
||||||
|
core.updateStatusBar();
|
||||||
|
// 不存在自定义事件
|
||||||
|
if (core.status.event.id==null)
|
||||||
|
core.unLockControl();
|
||||||
|
}
|
||||||
|
}, time/16);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.setFg = function(color, time, callback) {
|
core.prototype.setFg = function(color, time, callback) {
|
||||||
time = time || 750;
|
if (!core.isset(time)) time=750;
|
||||||
|
if (time<=0) time=0;
|
||||||
|
|
||||||
if (!core.isset(core.status.curtainColor)) {
|
if (!core.isset(core.status.curtainColor)) {
|
||||||
core.status.curtainColor = [0,0,0,0];
|
core.status.curtainColor = [0,0,0,0];
|
||||||
@ -2440,6 +2681,18 @@ core.prototype.setFg = function(color, time, callback) {
|
|||||||
if (color[3]<0) color[3]=0;
|
if (color[3]<0) color[3]=0;
|
||||||
if (color[3]>1) color[3]=1;
|
if (color[3]>1) color[3]=1;
|
||||||
|
|
||||||
|
|
||||||
|
if (time==0) {
|
||||||
|
// 直接变色
|
||||||
|
var nowR = parseInt(color[0]), nowG = parseInt(color[1]), nowB = parseInt(color[2]);
|
||||||
|
var toRGB = "#"+((1<<24)+(nowR<<16)+(nowG<<8)+nowB).toString(16).slice(1);
|
||||||
|
core.dom.curtain.style.background = toRGB;
|
||||||
|
core.dom.curtain.style.opacity = color[3];
|
||||||
|
core.status.curtainColor = color;
|
||||||
|
if (core.isset(callback)) callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var step=0;
|
var step=0;
|
||||||
var changeAnimate = setInterval(function() {
|
var changeAnimate = setInterval(function() {
|
||||||
step++;
|
step++;
|
||||||
@ -2508,16 +2761,6 @@ core.prototype.nextY = function () {
|
|||||||
*/
|
*/
|
||||||
core.prototype.updateFg = function () {
|
core.prototype.updateFg = function () {
|
||||||
|
|
||||||
/*
|
|
||||||
// 如果存在颜色
|
|
||||||
if (core.isset(core.status.event.data) && core.isset(core.status.event.data.currentColor)) {
|
|
||||||
var color=core.status.event.data.currentColor;
|
|
||||||
core.setAlpha('fg', color[3]);
|
|
||||||
core.fillRect("fg",0,0,416,416,"#"+((1<<24)+(color[0]<<16)+(color[1]<<8)+color[2]).toString(16).slice(1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!core.isset(core.status.thisMap) || !core.isset(core.status.thisMap.blocks)) return;
|
if (!core.isset(core.status.thisMap) || !core.isset(core.status.thisMap.blocks)) return;
|
||||||
// 更新显伤
|
// 更新显伤
|
||||||
var mapBlocks = core.status.thisMap.blocks;
|
var mapBlocks = core.status.thisMap.blocks;
|
||||||
@ -2562,7 +2805,7 @@ core.prototype.updateFg = function () {
|
|||||||
core.canvas.fg.textAlign = 'center';
|
core.canvas.fg.textAlign = 'center';
|
||||||
for (var x=0;x<13;x++) {
|
for (var x=0;x<13;x++) {
|
||||||
for (var y=0;y<13;y++) {
|
for (var y=0;y<13;y++) {
|
||||||
var damage = core.status.checkBlock[13*x+y];
|
var damage = core.status.checkBlock.damage[13*x+y];
|
||||||
if (damage>0) {
|
if (damage>0) {
|
||||||
core.setFillStyle('fg', '#000000');
|
core.setFillStyle('fg', '#000000');
|
||||||
core.canvas.fg.fillText(damage, 32 * x + 17, 32 * (y + 1) - 13);
|
core.canvas.fg.fillText(damage, 32 * x + 17, 32 * (y + 1) - 13);
|
||||||
@ -2647,7 +2890,7 @@ core.prototype.getNextItem = function() {
|
|||||||
|
|
||||||
core.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) {
|
core.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) {
|
||||||
// core.getItemAnimate(itemId, itemNum, itemX, itemY);
|
// core.getItemAnimate(itemId, itemNum, itemX, itemY);
|
||||||
core.playSound('item', 'ogg');
|
core.playSound('item.ogg');
|
||||||
var itemCls = core.material.items[itemId].cls;
|
var itemCls = core.material.items[itemId].cls;
|
||||||
core.items.getItemEffect(itemId, itemNum);
|
core.items.getItemEffect(itemId, itemNum);
|
||||||
core.removeBlock(itemX, itemY);
|
core.removeBlock(itemX, itemY);
|
||||||
@ -3252,23 +3495,106 @@ core.prototype.isset = function (val) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.playSound = function (soundName, soundType) {
|
core.prototype.playBgm = function (bgm) {
|
||||||
if (!core.musicStatus.soundStatus || !core.musicStatus.loaded) {
|
|
||||||
|
// 如果不允许播放
|
||||||
|
if (!core.musicStatus.bgmStatus) return;
|
||||||
|
// 音频不存在
|
||||||
|
if (!core.isset(core.material.bgms[bgm])) return;
|
||||||
|
|
||||||
|
// 延迟播放
|
||||||
|
if (core.material.bgms[bgm] == 'loading') {
|
||||||
|
core.material.bgms[bgm] = 'starting';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!core.isset(core.material.sounds[soundType][soundName])) return;
|
|
||||||
core.musicStatus.playedSound = core.material.sounds[soundType][soundName];
|
try {
|
||||||
core.musicStatus.playedSound.play();
|
// 如果当前正在播放,且和本BGM相同,直接忽略
|
||||||
|
if (core.musicStatus.playingBgm == bgm && core.musicStatus.isPlaying) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 如果正在播放中,暂停
|
||||||
|
if (core.isset(core.musicStatus.playingBgm) && core.musicStatus.isPlaying) {
|
||||||
|
core.material.bgms[core.musicStatus.playingBgm].pause();
|
||||||
|
}
|
||||||
|
// 播放当前BGM
|
||||||
|
core.musicStatus.playingBgm = bgm;
|
||||||
|
core.material.bgms[bgm].play();
|
||||||
|
core.musicStatus.isPlaying = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log("无法播放BGM "+bgm);
|
||||||
|
console.log(e);
|
||||||
|
core.musicStatus.playingBgm = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.playBgm = function (bgmName, bgmType) {
|
core.prototype.pauseBgm = function () {
|
||||||
if (core.musicStatus.isIOS || !core.musicStatus.loaded) return;
|
// 直接暂停播放
|
||||||
if (core.isset(core.musicStatus.playedBgm)) {
|
try {
|
||||||
core.musicStatus.playedBgm.pause();
|
if (core.isset(core.musicStatus.playingBgm)) {
|
||||||
|
core.material.bgms[core.musicStatus.playingBgm].pause();
|
||||||
|
}
|
||||||
|
core.musicStatus.isPlaying = false;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log("无法暂停BGM "+bgm);
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
core.prototype.resumeBgm = function () {
|
||||||
|
// 恢复BGM
|
||||||
|
try {
|
||||||
|
if (core.isset(core.musicStatus.playingBgm)) {
|
||||||
|
core.material.bgms[core.musicStatus.playingBgm].play();
|
||||||
|
core.musicStatus.isPlaying = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (core.bgms.length>0) {
|
||||||
|
core.playBgm(core.bgms[0]);
|
||||||
|
core.musicStatus.isPlaying = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log("无法恢复BGM "+bgm);
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
core.prototype.playSound = function (sound) {
|
||||||
|
|
||||||
|
// 如果不允许播放
|
||||||
|
if (!core.musicStatus.soundStatus) return;
|
||||||
|
// 音频不存在
|
||||||
|
if (!core.isset(core.material.sounds[sound])) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (core.musicStatus.audioContext != null) {
|
||||||
|
var source = core.musicStatus.audioContext.createBufferSource();
|
||||||
|
source.buffer = core.material.sounds[sound];
|
||||||
|
source.connect(core.musicStatus.audioContext.destination);
|
||||||
|
try {
|
||||||
|
source.start(0);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
try {
|
||||||
|
source.noteOn(0);
|
||||||
|
}
|
||||||
|
catch (ee) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.material.sounds[sound].play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (eee) {
|
||||||
|
console.log("无法播放SE "+bgm);
|
||||||
|
console.log(eee);
|
||||||
}
|
}
|
||||||
core.musicStatus.playedBgm = core.material.sounds[bgmType][bgmName];
|
|
||||||
if (core.musicStatus.soundStatus)
|
|
||||||
core.musicStatus.playedBgm.play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
core.prototype.changeSoundStatus = function () {
|
core.prototype.changeSoundStatus = function () {
|
||||||
@ -3348,14 +3674,17 @@ core.prototype.clearStatusBar = function() {
|
|||||||
*/
|
*/
|
||||||
core.prototype.updateStatusBar = function () {
|
core.prototype.updateStatusBar = function () {
|
||||||
|
|
||||||
// 检查登记
|
// 检查等级
|
||||||
core.checkLvUp();
|
core.checkLvUp();
|
||||||
|
|
||||||
// 上限999999
|
// 检查HP上限
|
||||||
if (core.values.HPMAX>0) {
|
if (core.values.HPMAX>0) {
|
||||||
core.setStatus('hp', Math.min(core.values.HPMAX, core.getStatus('hp')));
|
core.setStatus('hp', Math.min(core.values.HPMAX, core.getStatus('hp')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新领域、阻击、显伤
|
||||||
|
core.updateCheckBlock();
|
||||||
|
|
||||||
var lvName = core.getLvName();
|
var lvName = core.getLvName();
|
||||||
core.statusBar.lv.innerHTML = lvName;
|
core.statusBar.lv.innerHTML = lvName;
|
||||||
if (/^[+-]?\d+$/.test(lvName))
|
if (/^[+-]?\d+$/.test(lvName))
|
||||||
@ -3393,7 +3722,6 @@ core.prototype.updateStatusBar = function () {
|
|||||||
} else {
|
} else {
|
||||||
core.statusBar.image.fly.style.opacity = 0.3;
|
core.statusBar.image.fly.style.opacity = 0.3;
|
||||||
}
|
}
|
||||||
core.updateCheckBlock();
|
|
||||||
core.updateFg();
|
core.updateFg();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3407,10 +3735,15 @@ core.prototype.checkLvUp = function () {
|
|||||||
core.status.hero.lv++;
|
core.status.hero.lv++;
|
||||||
var effect = core.firstData.levelUp[core.status.hero.lv-1].effect;
|
var effect = core.firstData.levelUp[core.status.hero.lv-1].effect;
|
||||||
if (typeof effect == "string") {
|
if (typeof effect == "string") {
|
||||||
|
if (effect.indexOf("function")==0) {
|
||||||
|
eval("("+effect+")()");
|
||||||
|
}
|
||||||
|
else {
|
||||||
effect.split(";").forEach(function (t) {
|
effect.split(";").forEach(function (t) {
|
||||||
core.doEffect(t);
|
core.doEffect(t);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (effect instanceof Function) {
|
else if (effect instanceof Function) {
|
||||||
effect();
|
effect();
|
||||||
}
|
}
|
||||||
@ -3605,8 +3938,8 @@ core.prototype.resize = function(clientWidth, clientHeight) {
|
|||||||
id: 'floorMsgGroup',
|
id: 'floorMsgGroup',
|
||||||
rules:{
|
rules:{
|
||||||
width: (canvasWidth - SPACE*2) + unit,
|
width: (canvasWidth - SPACE*2) + unit,
|
||||||
height:(canvasWidth - SPACE*2) + unit,
|
height: (gameGroupHeight - SPACE*2) + unit,
|
||||||
top: (canvasTop + SPACE) + unit,
|
top: SPACE + unit,
|
||||||
right: SPACE + unit,
|
right: SPACE + unit,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
12
libs/data.js
12
libs/data.js
@ -85,7 +85,7 @@ data.prototype.init = function() {
|
|||||||
"levelUp": [ // 经验升级所需要的数值,是一个数组
|
"levelUp": [ // 经验升级所需要的数值,是一个数组
|
||||||
{}, // 第一项为初始等级,可以简单留空,也可以写name
|
{}, // 第一项为初始等级,可以简单留空,也可以写name
|
||||||
|
|
||||||
// 每一个里面可以含有三个参数 name, need, effect
|
// 每一个里面可以含有三个参数 need, name, effect
|
||||||
// need为所需要的经验数值,是一个正整数。请确保need所需的依次递增
|
// need为所需要的经验数值,是一个正整数。请确保need所需的依次递增
|
||||||
// name为该等级的名称,也可以省略代表使用系统默认值;本项将显示在状态栏中
|
// name为该等级的名称,也可以省略代表使用系统默认值;本项将显示在状态栏中
|
||||||
// effect为本次升级所执行的操作,可由若干项组成,由分号分开
|
// effect为本次升级所执行的操作,可由若干项组成,由分号分开
|
||||||
@ -139,10 +139,9 @@ data.prototype.init = function() {
|
|||||||
}
|
}
|
||||||
// 系统FLAG,在游戏运行中中请不要修改它。
|
// 系统FLAG,在游戏运行中中请不要修改它。
|
||||||
this.flags = {
|
this.flags = {
|
||||||
/****** 角色状态相关 ******/
|
/****** 状态栏相关 ******/
|
||||||
"enableNegativeDamage": true, // 是否支持负伤害(回血)
|
"enableFloor": true, // 是否在状态栏显示当前楼层
|
||||||
"enableFloor": false, // 是否在状态栏显示当前楼层
|
"enableLv": false, // 是否在状态栏显示当前等级
|
||||||
"enableLv": true, // 是否在状态栏显示当前等级
|
|
||||||
"enableMDef": true, // 是否在状态栏及战斗界面显示魔防(护盾)
|
"enableMDef": true, // 是否在状态栏及战斗界面显示魔防(护盾)
|
||||||
"enableMoney": true, // 是否在状态栏、怪物手册及战斗界面显示金币
|
"enableMoney": true, // 是否在状态栏、怪物手册及战斗界面显示金币
|
||||||
"enableExperience": true, // 是否在状态栏、怪物手册及战斗界面显示经验
|
"enableExperience": true, // 是否在状态栏、怪物手册及战斗界面显示经验
|
||||||
@ -154,6 +153,9 @@ data.prototype.init = function() {
|
|||||||
"pickaxeFourDirections": true, // 使用破墙镐是否四个方向都破坏;如果false则只破坏面前的墙壁
|
"pickaxeFourDirections": true, // 使用破墙镐是否四个方向都破坏;如果false则只破坏面前的墙壁
|
||||||
"bombFourDirections": true, // 使用炸弹是否四个方向都会炸;如果false则只炸面前的怪物(即和圣锤等价)
|
"bombFourDirections": true, // 使用炸弹是否四个方向都会炸;如果false则只炸面前的怪物(即和圣锤等价)
|
||||||
"bigKeyIsBox": false, // 如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙
|
"bigKeyIsBox": false, // 如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙
|
||||||
|
/****** 怪物相关 ******/
|
||||||
|
"enableNegativeDamage": true, // 是否支持负伤害(回血)
|
||||||
|
"zoneSquare": false, // 领域类型。如果此项为true则为九宫格伤害,为false则为十字伤害
|
||||||
/****** 系统相关 ******/
|
/****** 系统相关 ******/
|
||||||
"startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面
|
"startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面
|
||||||
"canOpenBattleAnimate": true, // 是否允许用户开启战斗过程;如果此项为false,则下面两项均强制视为false
|
"canOpenBattleAnimate": true, // 是否允许用户开启战斗过程;如果此项为false,则下面两项均强制视为false
|
||||||
|
|||||||
104
libs/enemys.js
104
libs/enemys.js
@ -5,10 +5,10 @@ function enemys() {
|
|||||||
enemys.prototype.init = function () {
|
enemys.prototype.init = function () {
|
||||||
// 怪物属性初始化定义:
|
// 怪物属性初始化定义:
|
||||||
this.enemys = {
|
this.enemys = {
|
||||||
'greenSlime': {'name': '绿头怪', 'hp': 100, 'atk': 120, 'def': 0, 'money': 1, 'experience': 1, 'special': 0},
|
'greenSlime': {'name': '绿头怪', 'hp': 100, 'atk': 120, 'def': 0, 'money': 1, 'experience': 1, 'special': [1,5,7,8]},
|
||||||
'redSlime': {'name': '红头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'redSlime': {'name': '红头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'blackSlime': {'name': '青头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'blackSlime': {'name': '青头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'slimelord': {'name': '怪王', 'hp': 100, 'atk': 120, 'def': 0, 'money': 10, 'experience': 0, 'special': 9},
|
'slimelord': {'name': '怪王', 'hp': 100, 'atk': 120, 'def': 0, 'money': 10, 'experience': 0, 'special': [1,9]},
|
||||||
'bat': {'name': '小蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 2, 'experience': 0, 'special': 1},
|
'bat': {'name': '小蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 2, 'experience': 0, 'special': 1},
|
||||||
'bigBat': {'name': '大蝙蝠', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'bigBat': {'name': '大蝙蝠', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'redBat': {'name': '红蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 5, 'experience': 0, 'special': 4},
|
'redBat': {'name': '红蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 5, 'experience': 0, 'special': 4},
|
||||||
@ -23,8 +23,8 @@ enemys.prototype.init = function () {
|
|||||||
'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},
|
||||||
'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}, // 领域怪需要加value表示领域伤害的数值
|
'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},
|
'redWizard': {'name': '高级巫师', 'hp': 1000, 'atk': 1200, 'def': 0, 'money': 160, 'experience': 0, 'special': 15, 'value': 200, 'range': 2}, // range可选,代表领域伤害的范围;不加默认为1
|
||||||
'yellowGuard': {'name': '初级卫兵', 'hp': 100, 'atk': 120, 'def': 0, 'money': 10, 'experience': 0, 'special': 0},
|
'yellowGuard': {'name': '初级卫兵', 'hp': 100, 'atk': 120, 'def': 0, 'money': 10, 'experience': 0, 'special': 0},
|
||||||
'blueGuard': {'name': '中级卫兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'blueGuard': {'name': '中级卫兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'redGuard': {'name': '高级卫兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'redGuard': {'name': '高级卫兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
@ -41,7 +41,7 @@ enemys.prototype.init = function () {
|
|||||||
'poisonSkeleton': {'name': '紫骷髅', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'poisonSkeleton': {'name': '紫骷髅', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'poisonBat': {'name': '紫蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 14, 'experience': 0, 'special': 13},
|
'poisonBat': {'name': '紫蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 14, 'experience': 0, 'special': 13},
|
||||||
'steelRock': {'name': '铁面人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'steelRock': {'name': '铁面人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'skeletonPriest': {'name': '骷髅法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'skeletonPriest': {'name': '骷髅法师', 'hp': 100, 'atk': 100, 'def': 0, 'money': 0, 'experience': 0, 'special': 18, 'value': 20},
|
||||||
'skeletonKing': {'name': '骷髅王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'skeletonKing': {'name': '骷髅王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'skeletonWizard': {'name': '骷髅巫师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'skeletonWizard': {'name': '骷髅巫师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'redSkeletonCaption': {'name': '骷髅武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'special': 0},
|
'redSkeletonCaption': {'name': '骷髅武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'special': 0},
|
||||||
@ -58,7 +58,7 @@ enemys.prototype.init = function () {
|
|||||||
'badPrincess': {'name': '痛苦魔女', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'badPrincess': {'name': '痛苦魔女', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'badFairy': {'name': '黑暗仙子', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'badFairy': {'name': '黑暗仙子', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'grayPriest': {'name': '中级法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'grayPriest': {'name': '中级法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'redSwordsman': {'name': '剑王', 'hp': 100, 'atk': 120, 'def': 0, 'money': 7, 'experience': 0, 'special': 6},
|
'redSwordsman': {'name': '剑王', 'hp': 100, 'atk': 120, 'def': 0, 'money': 7, 'experience': 0, 'special': 6, 'n': 8}, // 多连击需要在后面指定n代表是几连击
|
||||||
'whiteGhost': {'name': '水银战士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'whiteGhost': {'name': '水银战士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
'poisonZombie': {'name': '绿兽人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 13, 'experience': 0, 'special': 12},
|
'poisonZombie': {'name': '绿兽人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 13, 'experience': 0, 'special': 12},
|
||||||
'magicDragon': {'name': '魔龙', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
'magicDragon': {'name': '魔龙', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||||
@ -81,14 +81,15 @@ enemys.prototype.hasSpecial = function (special, test) {
|
|||||||
|
|
||||||
enemys.prototype.getSpecialText = function (enemyId) {
|
enemys.prototype.getSpecialText = function (enemyId) {
|
||||||
if (enemyId == undefined) return "";
|
if (enemyId == undefined) return "";
|
||||||
var special = this.enemys[enemyId].special;
|
var enemy = this.enemys[enemyId];
|
||||||
|
var special = enemy.special;
|
||||||
var text = [];
|
var text = [];
|
||||||
if (this.hasSpecial(special, 1)) text.push("先攻");
|
if (this.hasSpecial(special, 1)) text.push("先攻");
|
||||||
if (this.hasSpecial(special, 2)) text.push("魔攻");
|
if (this.hasSpecial(special, 2)) text.push("魔攻");
|
||||||
if (this.hasSpecial(special, 3)) text.push("坚固");
|
if (this.hasSpecial(special, 3)) text.push("坚固");
|
||||||
if (this.hasSpecial(special, 4)) text.push("2连击");
|
if (this.hasSpecial(special, 4)) text.push("2连击");
|
||||||
if (this.hasSpecial(special, 5)) text.push("3连击");
|
if (this.hasSpecial(special, 5)) text.push("3连击");
|
||||||
if (this.hasSpecial(special, 6)) text.push("4连击");
|
if (this.hasSpecial(special, 6)) text.push((enemy.n||4)+"连击");
|
||||||
if (this.hasSpecial(special, 7)) text.push("破甲");
|
if (this.hasSpecial(special, 7)) text.push("破甲");
|
||||||
if (this.hasSpecial(special, 8)) text.push("反击");
|
if (this.hasSpecial(special, 8)) text.push("反击");
|
||||||
if (this.hasSpecial(special, 9)) text.push("净化");
|
if (this.hasSpecial(special, 9)) text.push("净化");
|
||||||
@ -100,14 +101,57 @@ enemys.prototype.getSpecialText = function (enemyId) {
|
|||||||
if (this.hasSpecial(special, 15)) text.push("领域");
|
if (this.hasSpecial(special, 15)) text.push("领域");
|
||||||
if (this.hasSpecial(special, 16)) text.push("夹击");
|
if (this.hasSpecial(special, 16)) text.push("夹击");
|
||||||
if (this.hasSpecial(special, 17)) text.push("仇恨");
|
if (this.hasSpecial(special, 17)) text.push("仇恨");
|
||||||
return text.join(" ");
|
if (this.hasSpecial(special, 18)) text.push("阻击");
|
||||||
|
if (this.hasSpecial(special, 19)) text.push("自爆");
|
||||||
|
if (this.hasSpecial(special, 20)) text.push("无敌");
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
////// 获得每个属性的文字提示 //////
|
||||||
|
enemys.prototype.getSpecialHint = function (enemy, special) {
|
||||||
|
if (!core.isset(special)) {
|
||||||
|
var hints = [];
|
||||||
|
for (var i=1;i<100;i++) {
|
||||||
|
if (this.hasSpecial(enemy.special, i)) {
|
||||||
|
var hint=this.getSpecialHint(enemy, i);
|
||||||
|
if (hint!='')
|
||||||
|
hints.push(hint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (special) {
|
||||||
|
case 1: return "先攻:怪物首先攻击";
|
||||||
|
case 2: return "魔攻:怪物无视勇士的魔防";
|
||||||
|
case 3: return "坚固:勇士每回合最多只能对怪物造成1点伤害";
|
||||||
|
case 4: return "2连击:怪物每回合攻击2次";
|
||||||
|
case 5: return "3连击:怪物每回合攻击3次";
|
||||||
|
case 6: return (enemy.n||4)+"连击: 怪物每回合攻击"+(enemy.n||4)+"次";
|
||||||
|
case 7: return "破甲:战斗前,怪物附加角色防御的"+parseInt(100*core.values.breakArmor)+"%作为伤害";
|
||||||
|
case 8: return "反击:战斗时,怪物每回合附加角色攻击的"+parseInt(100*core.values.counterAttack)+"%作为伤害,无视角色防御";
|
||||||
|
case 9: return "净化:战斗前,怪物附加勇士魔防的"+core.values.purify+"倍作为伤害";
|
||||||
|
case 10: return "模仿:怪物的攻防和勇士攻防相等";
|
||||||
|
case 11: return "吸血:战斗前,怪物首先吸取角色的"+parseInt(100*enemy.value)+"%生命作为伤害";
|
||||||
|
case 12: return "中毒:战斗后,勇士陷入中毒状态,每一步损失生命"+core.values.poisonDamage+"点";
|
||||||
|
case 13: return "衰弱:战斗后,勇士陷入衰弱状态,攻防暂时下降"+core.values.weakValue+"点";
|
||||||
|
case 14: return "诅咒:战斗后,勇士陷入诅咒状态,战斗无法获得金币和经验";
|
||||||
|
case 15: return "领域:经过怪物周围"+(enemy.range||1)+"格时自动减生命"+enemy.value+"点";
|
||||||
|
case 16: return "夹击:经过两只相同的怪物中间,勇士生命值变成一半";
|
||||||
|
case 17: return "仇恨:战斗前,怪物附加之前积累的仇恨值作为伤害;战斗后,释放一半的仇恨值。(每杀死一个怪物获得"+core.values.hatred+"点仇恨值)";
|
||||||
|
case 18: return "阻击:经过怪物的十字领域时自动减生命"+enemy.value+"点,同时怪物后退一格";
|
||||||
|
case 19: return "自爆:战斗后勇士的生命值变成1";
|
||||||
|
case 20: return "无敌:勇士无法打败怪物,除非拥有十字架";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
enemys.prototype.getDamage = function (monsterId) {
|
enemys.prototype.getDamage = function (monsterId) {
|
||||||
var monster = core.material.enemys[monsterId];
|
var monster = core.material.enemys[monsterId];
|
||||||
var hero_atk = core.status.hero.atk, hero_def = core.status.hero.def, hero_mdef = core.status.hero.mdef;
|
var hero_atk = core.status.hero.atk, hero_def = core.status.hero.def, hero_mdef = core.status.hero.mdef;
|
||||||
var mon_hp = monster.hp, mon_atk = monster.atk, mon_def = monster.def, mon_special = monster.special;
|
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);
|
var damage = this.calDamage(hero_atk, hero_def, hero_mdef, mon_hp, mon_atk, mon_def, mon_special, monster.n);
|
||||||
if (damage == 999999999) return damage;
|
if (damage == 999999999) return damage;
|
||||||
return damage + this.getExtraDamage(monster);
|
return damage + this.getExtraDamage(monster);
|
||||||
}
|
}
|
||||||
@ -130,12 +174,12 @@ enemys.prototype.getCritical = function (monsterId) {
|
|||||||
var monster = core.material.enemys[monsterId];
|
var monster = core.material.enemys[monsterId];
|
||||||
if (this.hasSpecial(monster.special, 3) || this.hasSpecial(monster.special, 10)) return "???";
|
if (this.hasSpecial(monster.special, 3) || this.hasSpecial(monster.special, 10)) return "???";
|
||||||
var last = this.calDamage(core.status.hero.atk, core.status.hero.def, core.status.hero.mdef,
|
var last = this.calDamage(core.status.hero.atk, core.status.hero.def, core.status.hero.mdef,
|
||||||
monster.hp, monster.atk, monster.def, monster.special);
|
monster.hp, monster.atk, monster.def, monster.special, monster.n);
|
||||||
if (last <= 0) return 0;
|
if (last <= 0) return 0;
|
||||||
|
|
||||||
for (var i = core.status.hero.atk + 1; i <= monster.hp + monster.def; i++) {
|
for (var i = core.status.hero.atk + 1; i <= monster.hp + monster.def; i++) {
|
||||||
var damage = this.calDamage(i, core.status.hero.def, core.status.hero.mdef,
|
var damage = this.calDamage(i, core.status.hero.def, core.status.hero.mdef,
|
||||||
monster.hp, monster.atk, monster.def, monster.special);
|
monster.hp, monster.atk, monster.def, monster.special, monster.n);
|
||||||
if (damage < last)
|
if (damage < last)
|
||||||
return i - core.status.hero.atk;
|
return i - core.status.hero.atk;
|
||||||
last = damage;
|
last = damage;
|
||||||
@ -150,32 +194,38 @@ enemys.prototype.getCriticalDamage = function (monsterId) {
|
|||||||
if (c <= 0) return 0;
|
if (c <= 0) return 0;
|
||||||
var monster = core.material.enemys[monsterId];
|
var monster = core.material.enemys[monsterId];
|
||||||
var last = this.calDamage(core.status.hero.atk, core.status.hero.def, core.status.hero.mdef,
|
var last = this.calDamage(core.status.hero.atk, core.status.hero.def, core.status.hero.mdef,
|
||||||
monster.hp, monster.atk, monster.def, monster.special);
|
monster.hp, monster.atk, monster.def, monster.special, monster.n);
|
||||||
if (last == 999999999) return '???';
|
if (last == 999999999) return '???';
|
||||||
|
|
||||||
return last - this.calDamage(core.status.hero.atk + c, core.status.hero.def, core.status.hero.mdef,
|
return last - this.calDamage(core.status.hero.atk + c, core.status.hero.def, core.status.hero.mdef,
|
||||||
monster.hp, monster.atk, monster.def, monster.special);
|
monster.hp, monster.atk, monster.def, monster.special, monster.n);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1防减伤计算
|
// 1防减伤计算
|
||||||
enemys.prototype.getDefDamage = function (monsterId) {
|
enemys.prototype.getDefDamage = function (monsterId) {
|
||||||
var monster = core.material.enemys[monsterId];
|
var monster = core.material.enemys[monsterId];
|
||||||
return this.calDamage(core.status.hero.atk, core.status.hero.def, core.status.hero.mdef,
|
var nowDamage = this.calDamage(core.status.hero.atk, core.status.hero.def, core.status.hero.mdef,
|
||||||
monster.hp, monster.atk, monster.def, monster.special) -
|
monster.hp, monster.atk, monster.def, monster.special, monster.n);
|
||||||
this.calDamage(core.status.hero.atk, core.status.hero.def + 1, core.status.hero.mdef,
|
var nextDamage = this.calDamage(core.status.hero.atk, core.status.hero.def + 1, core.status.hero.mdef,
|
||||||
monster.hp, monster.atk, monster.def, monster.special)
|
monster.hp, monster.atk, monster.def, monster.special, monster.n);
|
||||||
|
if (nowDamage == 999999999 || nextDamage == 999999999) return "???";
|
||||||
|
return nowDamage - nextDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
enemys.prototype.calDamage = function (hero_atk, hero_def, hero_mdef, mon_hp, mon_atk, mon_def, mon_special) {
|
enemys.prototype.calDamage = function (hero_atk, hero_def, hero_mdef, mon_hp, mon_atk, mon_def, mon_special, n) {
|
||||||
// 魔攻
|
|
||||||
if (this.hasSpecial(mon_special,2)) hero_def = 0;
|
if (this.hasSpecial(mon_special, 20) && !core.hasItem("cross")) // 如果是无敌属性,且勇士未持有十字架
|
||||||
// 坚固
|
return 999999999; // 返回无限大
|
||||||
if (this.hasSpecial(mon_special,3) && mon_def < hero_atk - 1) mon_def = hero_atk - 1;
|
|
||||||
// 模仿
|
// 模仿
|
||||||
if (this.hasSpecial(mon_special,10)) {
|
if (this.hasSpecial(mon_special,10)) {
|
||||||
mon_atk = hero_atk;
|
mon_atk = hero_atk;
|
||||||
mon_def = hero_def;
|
mon_def = hero_def;
|
||||||
}
|
}
|
||||||
|
// 魔攻
|
||||||
|
if (this.hasSpecial(mon_special,2)) hero_def = 0;
|
||||||
|
// 坚固
|
||||||
|
if (this.hasSpecial(mon_special,3) && mon_def < hero_atk - 1) mon_def = hero_atk - 1;
|
||||||
if (hero_atk <= mon_def) return 999999999; // 不可战斗时请直接返回999999999
|
if (hero_atk <= mon_def) return 999999999; // 不可战斗时请直接返回999999999
|
||||||
|
|
||||||
var per_damage = mon_atk - hero_def;
|
var per_damage = mon_atk - hero_def;
|
||||||
@ -184,7 +234,7 @@ enemys.prototype.calDamage = function (hero_atk, hero_def, hero_mdef, mon_hp, mo
|
|||||||
|
|
||||||
if (this.hasSpecial(mon_special, 4)) per_damage *= 2;
|
if (this.hasSpecial(mon_special, 4)) per_damage *= 2;
|
||||||
if (this.hasSpecial(mon_special, 5)) per_damage *= 3;
|
if (this.hasSpecial(mon_special, 5)) per_damage *= 3;
|
||||||
if (this.hasSpecial(mon_special, 6)) per_damage *= 4;
|
if (this.hasSpecial(mon_special, 6)) per_damage *= (n||4);
|
||||||
|
|
||||||
var counterDamage = 0;
|
var counterDamage = 0;
|
||||||
// 反击
|
// 反击
|
||||||
@ -224,6 +274,10 @@ enemys.prototype.getCurrentEnemys = function () {
|
|||||||
mon_def=core.status.hero.def;
|
mon_def=core.status.hero.def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var specialText = core.enemys.getSpecialText(monsterId);
|
||||||
|
if (specialText.length>=3) specialText = "多属性...";
|
||||||
|
else specialText = specialText.join(" ");
|
||||||
|
|
||||||
enemys.push({
|
enemys.push({
|
||||||
'id': monsterId,
|
'id': monsterId,
|
||||||
'name': monster.name,
|
'name': monster.name,
|
||||||
@ -232,7 +286,7 @@ enemys.prototype.getCurrentEnemys = function () {
|
|||||||
'def': mon_def,
|
'def': mon_def,
|
||||||
'money': monster.money,
|
'money': monster.money,
|
||||||
'experience': monster.experience,
|
'experience': monster.experience,
|
||||||
'special': core.enemys.getSpecialText(monsterId),
|
'special': specialText,
|
||||||
'damage': this.getDamage(monsterId),
|
'damage': this.getDamage(monsterId),
|
||||||
'critical': this.getCritical(monsterId),
|
'critical': this.getCritical(monsterId),
|
||||||
'criticalDamage': this.getCriticalDamage(monsterId),
|
'criticalDamage': this.getCriticalDamage(monsterId),
|
||||||
|
|||||||
215
libs/events.js
215
libs/events.js
@ -133,6 +133,17 @@ events.prototype.afterChangeFloor = function (floorId) {
|
|||||||
this.doEvents(core.floors[floorId].firstArrive);
|
this.doEvents(core.floors[floorId].firstArrive);
|
||||||
core.setFlag("visited_"+floorId, true);
|
core.setFlag("visited_"+floorId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 播放BGM
|
||||||
|
if (floorId == 'sample0') {
|
||||||
|
core.playBgm('bgm.mp3');
|
||||||
|
}
|
||||||
|
if (floorId == 'sample1') {
|
||||||
|
core.playBgm('star.mid');
|
||||||
|
}
|
||||||
|
if (floorId == 'sample2') {
|
||||||
|
core.playBgm('qianjin.mid');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 实际事件的处理 //////
|
////// 实际事件的处理 //////
|
||||||
@ -285,11 +296,6 @@ events.prototype.doAction = function() {
|
|||||||
block = block.block;
|
block = block.block;
|
||||||
if (core.isset(block.event) && block.event.trigger=='action') {
|
if (core.isset(block.event) && block.event.trigger=='action') {
|
||||||
// 触发
|
// 触发
|
||||||
/*
|
|
||||||
core.status.event = {'id': 'action', 'data': {
|
|
||||||
'list': core.clone(block.event.data), 'x': block.x, 'y': block.y, 'callback': core.status.event.data.callback
|
|
||||||
}}
|
|
||||||
*/
|
|
||||||
core.status.event.data.list = core.clone(block.event.data);
|
core.status.event.data.list = core.clone(block.event.data);
|
||||||
core.status.event.data.x=block.x;
|
core.status.event.data.x=block.x;
|
||||||
core.status.event.data.y=block.y;
|
core.status.event.data.y=block.y;
|
||||||
@ -298,11 +304,21 @@ events.prototype.doAction = function() {
|
|||||||
this.doAction();
|
this.doAction();
|
||||||
break;
|
break;
|
||||||
case "playSound":
|
case "playSound":
|
||||||
var name=data.name.split(".");
|
core.playSound(data.name);
|
||||||
if (name.length==2)
|
|
||||||
core.playSound(name[0],name[1]);
|
|
||||||
this.doAction();
|
this.doAction();
|
||||||
break;
|
break;
|
||||||
|
case "playBgm":
|
||||||
|
core.playBgm(data.name);
|
||||||
|
this.doAction();
|
||||||
|
break
|
||||||
|
case "pauseBgm":
|
||||||
|
core.pauseBgm();
|
||||||
|
this.doAction();
|
||||||
|
break
|
||||||
|
case "resumeBgm":
|
||||||
|
core.resumeBgm();
|
||||||
|
this.doAction();
|
||||||
|
break
|
||||||
case "setValue":
|
case "setValue":
|
||||||
try {
|
try {
|
||||||
var value=core.calValue(data.value);
|
var value=core.calValue(data.value);
|
||||||
@ -352,8 +368,14 @@ events.prototype.doAction = function() {
|
|||||||
core.events.lose(data.reason);
|
core.events.lose(data.reason);
|
||||||
break;
|
break;
|
||||||
case "function":
|
case "function":
|
||||||
if (core.isset(data["function"]))
|
var func = data["function"];
|
||||||
data["function"]();
|
if (core.isset(func)) {
|
||||||
|
if ((typeof func == "string") && func.indexOf("function")==0) {
|
||||||
|
eval('('+func+')()');
|
||||||
|
}
|
||||||
|
else if (func instanceof Function)
|
||||||
|
func();
|
||||||
|
}
|
||||||
this.doAction();
|
this.doAction();
|
||||||
break;
|
break;
|
||||||
case "update":
|
case "update":
|
||||||
@ -388,7 +410,12 @@ events.prototype.doAction = function() {
|
|||||||
|
|
||||||
////// 往当前事件列表之前添加一个或多个事件 //////
|
////// 往当前事件列表之前添加一个或多个事件 //////
|
||||||
events.prototype.insertAction = function (action) {
|
events.prototype.insertAction = function (action) {
|
||||||
|
if (core.status.event.id == null) {
|
||||||
|
this.doEvents(action);
|
||||||
|
}
|
||||||
|
else {
|
||||||
core.unshift(core.status.event.data.list, action)
|
core.unshift(core.status.event.data.list, action)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 打开商店 //////
|
////// 打开商店 //////
|
||||||
@ -495,6 +522,30 @@ events.prototype.useItem = function(itemId) {
|
|||||||
else core.drawTip("当前无法使用"+core.material.items[itemId].name);
|
else core.drawTip("当前无法使用"+core.material.items[itemId].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 加点 //////
|
||||||
|
events.prototype.addPoint = function (enemy) {
|
||||||
|
var point = enemy.point;
|
||||||
|
if (!core.isset(point) || point<=0) return [];
|
||||||
|
|
||||||
|
// 加点,返回一个choices事件
|
||||||
|
return [
|
||||||
|
{"type": "choices",
|
||||||
|
"choices": [
|
||||||
|
{"text": "生命+"+(200*point), "action": [
|
||||||
|
{"type": "setValue", "name": "status:hp", "value": "status:hp+"+(200*point)}
|
||||||
|
]},
|
||||||
|
{"text": "攻击+"+(1*point), "action": [
|
||||||
|
{"type": "setValue", "name": "status:atk", "value": "status:atk+"+(1*point)}
|
||||||
|
]},
|
||||||
|
{"text": "防御+"+(2*point), "action": [
|
||||||
|
{"type": "setValue", "name": "status:def", "value": "status:def+"+(2*point)}
|
||||||
|
]},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/****** 打完怪物 ******/
|
/****** 打完怪物 ******/
|
||||||
events.prototype.afterBattle = function(enemyId,x,y,callback) {
|
events.prototype.afterBattle = function(enemyId,x,y,callback) {
|
||||||
|
|
||||||
@ -518,47 +569,63 @@ events.prototype.afterBattle = function(enemyId,x,y,callback) {
|
|||||||
if (core.enemys.hasSpecial(special, 17)) {
|
if (core.enemys.hasSpecial(special, 17)) {
|
||||||
core.setFlag('hatred', parseInt(core.getFlag('hatred', 0)/2));
|
core.setFlag('hatred', parseInt(core.getFlag('hatred', 0)/2));
|
||||||
}
|
}
|
||||||
|
// 自爆
|
||||||
|
if (core.enemys.hasSpecial(special, 19)) {
|
||||||
|
core.status.hero.hp = 1;
|
||||||
|
}
|
||||||
// 增加仇恨值
|
// 增加仇恨值
|
||||||
core.setFlag('hatred', core.getFlag('hatred',0)+core.values.hatred);
|
core.setFlag('hatred', core.getFlag('hatred',0)+core.values.hatred);
|
||||||
core.updateStatusBar();
|
core.updateStatusBar();
|
||||||
|
|
||||||
// 如果已有事件正在处理中
|
|
||||||
if (core.status.lockControl) {
|
|
||||||
if (core.isset(callback)) callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查处理后的事件。
|
// 事件的处理
|
||||||
|
var todo = [];
|
||||||
|
// 如果不为阻击,且该点存在,且有事件
|
||||||
|
if (!core.enemys.hasSpecial(special, 18) && core.isset(x) && core.isset(y)) {
|
||||||
var event = core.floors[core.status.floorId].afterBattle[x+","+y];
|
var event = core.floors[core.status.floorId].afterBattle[x+","+y];
|
||||||
if (core.isset(event)) {
|
if (core.isset(event)) {
|
||||||
core.events.doEvents(event, x, y, callback);
|
// 插入事件
|
||||||
|
core.unshift(todo, event);
|
||||||
}
|
}
|
||||||
//继续行走
|
}
|
||||||
else {
|
// 如果有加点
|
||||||
|
var point = core.material.enemys[enemyId].point;
|
||||||
|
if (core.isset(point) && point>0) {
|
||||||
|
core.unshift(todo, core.events.addPoint(core.material.enemys[enemyId]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果事件不为空,将其插入
|
||||||
|
if (todo.length>0) {
|
||||||
|
this.insertAction(todo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已有事件正在处理中
|
||||||
|
if (core.status.event.id == null) {
|
||||||
core.continueAutomaticRoute();
|
core.continueAutomaticRoute();
|
||||||
if (core.isset(callback)) callback();
|
|
||||||
}
|
}
|
||||||
|
if (core.isset(callback)) callback();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** 开完门 ******/
|
/****** 开完门 ******/
|
||||||
events.prototype.afterOpenDoor = function(doorId,x,y,callback) {
|
events.prototype.afterOpenDoor = function(doorId,x,y,callback) {
|
||||||
|
|
||||||
// 如果已有事件正在处理中
|
var todo = [];
|
||||||
if (core.status.lockControl) {
|
if (core.isset(x) && core.isset(y)) {
|
||||||
if (core.isset(callback)) callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查处理后的事件。
|
|
||||||
var event = core.floors[core.status.floorId].afterOpenDoor[x+","+y];
|
var event = core.floors[core.status.floorId].afterOpenDoor[x+","+y];
|
||||||
if (core.isset(event)) {
|
if (core.isset(event)) {
|
||||||
core.events.doEvents(event, x, y, callback);
|
core.unshift(todo, event);
|
||||||
}
|
}
|
||||||
//继续行走
|
}
|
||||||
else {
|
|
||||||
|
if (todo.length>0) {
|
||||||
|
this.insertAction(todo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (core.status.event.id == null) {
|
||||||
core.continueAutomaticRoute();
|
core.continueAutomaticRoute();
|
||||||
if (core.isset(callback)) callback();
|
|
||||||
}
|
}
|
||||||
|
if (core.isset(callback)) callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** 经过路障 ******/
|
/****** 经过路障 ******/
|
||||||
@ -611,6 +678,12 @@ events.prototype.changeLight = function(x, y) {
|
|||||||
// 改变灯后的事件
|
// 改变灯后的事件
|
||||||
events.prototype.afterChangeLight = function(x,y) {
|
events.prototype.afterChangeLight = function(x,y) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用炸弹/圣锤后的事件
|
||||||
|
events.prototype.afterUseBomb = function () {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 存档事件前一刻的处理
|
// 存档事件前一刻的处理
|
||||||
@ -639,6 +712,13 @@ events.prototype.keyDownCtrl = function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
events.prototype.clickConfirmBox = function (x,y) {
|
||||||
|
if ((x == 4 || x == 5) && y == 7 && core.isset(core.status.event.data.yes))
|
||||||
|
core.status.event.data.yes();
|
||||||
|
if ((x == 7 || x == 8) && y == 7 && core.isset(core.status.event.data.no))
|
||||||
|
core.status.event.data.no();
|
||||||
|
}
|
||||||
|
|
||||||
events.prototype.keyUpConfirmBox = function (keycode) {
|
events.prototype.keyUpConfirmBox = function (keycode) {
|
||||||
if (keycode==37) {
|
if (keycode==37) {
|
||||||
core.status.event.selection=0;
|
core.status.event.selection=0;
|
||||||
@ -661,12 +741,6 @@ events.prototype.keyUpConfirmBox = function (keycode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
events.prototype.clickConfirmBox = function (x,y) {
|
|
||||||
if ((x == 4 || x == 5) && y == 7 && core.isset(core.status.event.data.yes))
|
|
||||||
core.status.event.data.yes();
|
|
||||||
if ((x == 7 || x == 8) && y == 7 && core.isset(core.status.event.data.no))
|
|
||||||
core.status.event.data.no();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 正在处理事件时的点击操作...
|
// 正在处理事件时的点击操作...
|
||||||
events.prototype.clickAction = function (x,y) {
|
events.prototype.clickAction = function (x,y) {
|
||||||
@ -731,22 +805,38 @@ events.prototype.keyUpAction = function (keycode) {
|
|||||||
events.prototype.clickBook = function(x,y) {
|
events.prototype.clickBook = function(x,y) {
|
||||||
// 上一页
|
// 上一页
|
||||||
if ((x == 3 || x == 4) && y == 12) {
|
if ((x == 3 || x == 4) && y == 12) {
|
||||||
core.ui.drawEnemyBook(core.status.event.data - 1);
|
core.ui.drawEnemyBook(core.status.event.data - 6);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// 下一页
|
// 下一页
|
||||||
if ((x == 8 || x == 9) && y == 12) {
|
if ((x == 8 || x == 9) && y == 12) {
|
||||||
core.ui.drawEnemyBook(core.status.event.data + 1);
|
core.ui.drawEnemyBook(core.status.event.data + 6);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// 返回
|
// 返回
|
||||||
if (x>=10 && x<=12 && y==12) {
|
if (x>=10 && x<=12 && y==12) {
|
||||||
core.ui.closePanel(true);
|
core.ui.closePanel(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 怪物信息
|
||||||
|
// var index = parseInt(y/2);
|
||||||
|
var data = core.status.event.data;
|
||||||
|
if (core.isset(data) && y<12) {
|
||||||
|
var page=parseInt(data/6);
|
||||||
|
var index=6*page+parseInt(y/2);
|
||||||
|
core.ui.drawEnemyBook(index);
|
||||||
|
core.ui.drawBookDetail(index);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
events.prototype.keyDownBook = function (keycode) {
|
events.prototype.keyDownBook = function (keycode) {
|
||||||
if (keycode==37 || keycode==38) core.ui.drawEnemyBook(core.status.event.data - 1);
|
if (keycode==37) core.ui.drawEnemyBook(core.status.event.data-6);
|
||||||
else if (keycode==39 || keycode==40) core.ui.drawEnemyBook(core.status.event.data + 1);
|
if (keycode==38) core.ui.drawEnemyBook(core.status.event.data-1);
|
||||||
|
if (keycode==39) core.ui.drawEnemyBook(core.status.event.data+6);
|
||||||
|
if (keycode==40) core.ui.drawEnemyBook(core.status.event.data+1);
|
||||||
|
if (keycode==33) core.ui.drawEnemyBook(core.status.event.data-6);
|
||||||
|
if (keycode==34) core.ui.drawEnemyBook(core.status.event.data+6);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,9 +845,22 @@ events.prototype.keyUpBook = function (keycode) {
|
|||||||
core.ui.closePanel(true);
|
core.ui.closePanel(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (keycode==13 || keycode==32 || keycode==67) {
|
||||||
|
var data=core.status.event.data;
|
||||||
|
if (core.isset(data)) {
|
||||||
|
this.clickBook(6, 2*(data%6));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
events.prototype.clickBookDetail = function (x,y) {
|
||||||
|
core.clearMap('data', 0, 0, 416, 416);
|
||||||
|
|
||||||
|
core.status.event.id = 'book';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 飞行器
|
|
||||||
events.prototype.clickFly = function(x,y) {
|
events.prototype.clickFly = function(x,y) {
|
||||||
if ((x==10 || x==11) && y==9) core.ui.drawFly(core.status.event.data-1);
|
if ((x==10 || x==11) && y==9) core.ui.drawFly(core.status.event.data-1);
|
||||||
if ((x==10 || x==11) && y==5) core.ui.drawFly(core.status.event.data+1);
|
if ((x==10 || x==11) && y==5) core.ui.drawFly(core.status.event.data+1);
|
||||||
@ -1103,21 +1206,27 @@ events.prototype.keyUpSL = function (keycode) {
|
|||||||
events.prototype.clickSwitchs = function (x,y) {
|
events.prototype.clickSwitchs = function (x,y) {
|
||||||
if (x<5 || x>7) return;
|
if (x<5 || x>7) return;
|
||||||
var choices = [
|
var choices = [
|
||||||
"背景音乐", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单"
|
"背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单"
|
||||||
];
|
];
|
||||||
var topIndex = 6 - parseInt((choices.length - 1) / 2);
|
var topIndex = 6 - parseInt((choices.length - 1) / 2);
|
||||||
if (y>=topIndex && y<topIndex+choices.length) {
|
if (y>=topIndex && y<topIndex+choices.length) {
|
||||||
var selection = y-topIndex;
|
var selection = y-topIndex;
|
||||||
switch (selection) {
|
switch (selection) {
|
||||||
case 0:
|
case 0:
|
||||||
if (core.musicStatus.isIOS) {
|
core.musicStatus.bgmStatus = !core.musicStatus.bgmStatus;
|
||||||
core.drawTip("iOS设备不支持播放音乐");
|
if (core.musicStatus.bgmStatus)
|
||||||
return;
|
core.resumeBgm();
|
||||||
}
|
else
|
||||||
core.changeSoundStatus();
|
core.pauseBgm();
|
||||||
|
core.setLocalStorage('bgmStatus', core.musicStatus.bgmStatus);
|
||||||
core.ui.drawSwitchs();
|
core.ui.drawSwitchs();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
core.musicStatus.soundStatus = !core.musicStatus.soundStatus;
|
||||||
|
core.setLocalStorage('soundStatus', core.musicStatus.soundStatus);
|
||||||
|
core.ui.drawSwitchs();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
if (!core.flags.canOpenBattleAnimate) {
|
if (!core.flags.canOpenBattleAnimate) {
|
||||||
core.drawTip("本塔不能开启战斗动画!");
|
core.drawTip("本塔不能开启战斗动画!");
|
||||||
}
|
}
|
||||||
@ -1127,19 +1236,19 @@ events.prototype.clickSwitchs = function (x,y) {
|
|||||||
core.ui.drawSwitchs();
|
core.ui.drawSwitchs();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 3:
|
||||||
core.flags.displayEnemyDamage=!core.flags.displayEnemyDamage;
|
core.flags.displayEnemyDamage=!core.flags.displayEnemyDamage;
|
||||||
core.updateFg();
|
core.updateFg();
|
||||||
core.setLocalStorage('enemyDamage', core.flags.displayEnemyDamage);
|
core.setLocalStorage('enemyDamage', core.flags.displayEnemyDamage);
|
||||||
core.ui.drawSwitchs();
|
core.ui.drawSwitchs();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 4:
|
||||||
core.flags.displayExtraDamage=!core.flags.displayExtraDamage;
|
core.flags.displayExtraDamage=!core.flags.displayExtraDamage;
|
||||||
core.updateFg();
|
core.updateFg();
|
||||||
core.setLocalStorage('extraDamage', core.flags.displayExtraDamage);
|
core.setLocalStorage('extraDamage', core.flags.displayExtraDamage);
|
||||||
core.ui.drawSwitchs();
|
core.ui.drawSwitchs();
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 5:
|
||||||
core.status.event.selection=0;
|
core.status.event.selection=0;
|
||||||
core.ui.drawSettings(false);
|
core.ui.drawSettings(false);
|
||||||
break;
|
break;
|
||||||
@ -1149,7 +1258,7 @@ events.prototype.clickSwitchs = function (x,y) {
|
|||||||
|
|
||||||
events.prototype.keyDownSwitchs = function (keycode) {
|
events.prototype.keyDownSwitchs = function (keycode) {
|
||||||
var choices = [
|
var choices = [
|
||||||
"背景音乐", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单"
|
"背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单"
|
||||||
];
|
];
|
||||||
if (keycode==38) {
|
if (keycode==38) {
|
||||||
core.status.event.selection--;
|
core.status.event.selection--;
|
||||||
@ -1170,7 +1279,7 @@ events.prototype.keyUpSwitchs = function (keycode) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var choices = [
|
var choices = [
|
||||||
"背景音乐", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单"
|
"背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单"
|
||||||
];
|
];
|
||||||
if (keycode==13 || keycode==32 || keycode==67) {
|
if (keycode==13 || keycode==32 || keycode==67) {
|
||||||
var topIndex = 6 - parseInt((choices.length - 1) / 2);
|
var topIndex = 6 - parseInt((choices.length - 1) / 2);
|
||||||
|
|||||||
@ -16,8 +16,8 @@ main.floors.sample0 = {
|
|||||||
[216, 247, 256, 235, 248, 6, 0, 3, 49, 50, 51, 52, 38],
|
[216, 247, 256, 235, 248, 6, 0, 3, 49, 50, 51, 52, 38],
|
||||||
[6, 6, 125, 6, 6, 6, 0, 1, 45, 46, 47, 48, 37],
|
[6, 6, 125, 6, 6, 6, 0, 1, 45, 46, 47, 48, 37],
|
||||||
[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, 50, 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, 50, 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, 0, 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],
|
||||||
@ -102,7 +102,6 @@ main.floors.sample0 = {
|
|||||||
"炸弹是只能炸面前的怪物还是四个方向的怪物,由data.js中的系统Flag所决定。\n如只能炸前方怪物则和上面的圣锤等价。\n不能被炸的怪物在enemys中可以定义,可参见样板里黑衣魔王和黑暗大法师的写法。",
|
"炸弹是只能炸面前的怪物还是四个方向的怪物,由data.js中的系统Flag所决定。\n如只能炸前方怪物则和上面的圣锤等价。\n不能被炸的怪物在enemys中可以定义,可参见样板里黑衣魔王和黑暗大法师的写法。",
|
||||||
],
|
],
|
||||||
"10,4": ["“上楼”和“下楼”的目标层由 main.js 的 floorIds顺序所决定。"],
|
"10,4": ["“上楼”和“下楼”的目标层由 main.js 的 floorIds顺序所决定。"],
|
||||||
"10,3": ["十字架目前未被定义,可能需要自行实现功能。\n有关如何实现一个道具功能参见doc文档。"],
|
|
||||||
"9,2": ["该道具默认是大黄门钥匙,如需改为钥匙盒直接修改 data.js 中的系统Flag即可。"],
|
"9,2": ["该道具默认是大黄门钥匙,如需改为钥匙盒直接修改 data.js 中的系统Flag即可。"],
|
||||||
"10,2": ["屠龙匕首目前未被定义,可能需要自行实现功能。\n有关如何实现一个道具功能参见doc文档。"],
|
"10,2": ["屠龙匕首目前未被定义,可能需要自行实现功能。\n有关如何实现一个道具功能参见doc文档。"],
|
||||||
},
|
},
|
||||||
|
|||||||
@ -31,8 +31,9 @@ main.floors.sample1 = {
|
|||||||
"4,10": [ // 走到中间时的提示
|
"4,10": [ // 走到中间时的提示
|
||||||
"\t[样板提示]本层楼将会对各类事件进行介绍。",
|
"\t[样板提示]本层楼将会对各类事件进行介绍。",
|
||||||
"左边是一个仿50层的陷阱做法,上方是商店、快捷商店的使用方法,右上是一个典型的杀怪开门的例子,右下是各类可能的NPC事件。",
|
"左边是一个仿50层的陷阱做法,上方是商店、快捷商店的使用方法,右上是一个典型的杀怪开门的例子,右下是各类可能的NPC事件。",
|
||||||
"本样板目前支持的事件列表大致有:\ntext: 显示一段文字(比如你现在正在看到的)\ntip: 左上角显示提示\nshow: 使一个事件有效(可见、可被交互)\nhide: 使一个事件失效(不可见、不可被交互)\ntrigger: 触发另一个地点的事件\nbattle: 强制和某怪物战斗\nopenDoor: 无需钥匙开门(例如机关门、暗墙)\nopenShop: 打开一个全局商店\ndisableShop: 禁用一个全局商店\nchangeFloor: 传送勇士到某层某位置\nchangePos: 传送勇士到当层某位置;转向\nsetFg: 更改画面色调",
|
"本样板目前支持的事件列表大致有:\ntext: 显示一段文字(比如你现在正在看到的)\ntip: 左上角显示提示\nshow: 使一个事件有效(可见、可被交互)\nhide: 使一个事件失效(不可见、不可被交互)\ntrigger: 触发另一个地点的事件\nbattle: 强制和某怪物战斗\nopenDoor: 无需钥匙开门(例如机关门、暗墙)",
|
||||||
"move: 移动事件效果\nmoveHero: 移动勇士效果\nplaySound: 播放某个音频\nif: 条件判断\nchoices: 提供选项\nsetValue: 设置勇士属性道具,或某个变量/flag\nupdate: 更新状态栏和地图显伤\nwin: 获得胜利(游戏通关)\nlose: 游戏失败\nsleep: 等待多少毫秒\nexit: 立刻结束当前事件\nrevisit: 立刻结束事件并重新触发\nfunction: 自定义JS脚本\n更多支持的事件还在编写中,欢迎您宝贵的意见。",
|
"openShop: 打开一个全局商店\ndisableShop: 禁用一个全局商店\nchangeFloor: 传送勇士到某层某位置\nchangePos: 传送勇士到当层某位置;转向\nsetFg: 更改画面色调\nmove: 移动事件效果\nmoveHero: 移动勇士效果\nplayBgm: 播放某个背景音乐\npauseBgm: 暂停背景音乐\nresumeBgm: 恢复背景音乐的播放\nplaySound: 播放某个音频",
|
||||||
|
"if: 条件判断\nchoices: 提供选项\nsetValue: 设置勇士属性道具,或某个变量/flag\nupdate: 更新状态栏和地图显伤\nwin: 获得胜利(游戏通关)\nlose: 游戏失败\nsleep: 等待多少毫秒\nexit: 立刻结束当前事件\nrevisit: 立刻结束事件并重新触发\nfunction: 自定义JS脚本\n\n更多支持的事件还在编写中,欢迎您宝贵的意见。",
|
||||||
"有关各事件的样例,可参见本层一些NPC的写法。\n所有事件样例本层都有介绍。\n\n一个自定义事件处理完后,需要调用{\"type\": \"hide\"}该事件才不会再次出现。",
|
"有关各事件的样例,可参见本层一些NPC的写法。\n所有事件样例本层都有介绍。\n\n一个自定义事件处理完后,需要调用{\"type\": \"hide\"}该事件才不会再次出现。",
|
||||||
{"type": "hide"}
|
{"type": "hide"}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -8,6 +8,7 @@ main.floors.sample2 = {
|
|||||||
"canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
"canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||||
"defaultGround": "snowGround", // 默认地面的图块ID(terrains中)
|
"defaultGround": "snowGround", // 默认地面的图块ID(terrains中)
|
||||||
|
"color": [255,0,0,0.3], // 可以设置该层的默认背景色调(RGBA);本项可省略
|
||||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||||
[5, 5, 5, 5, 5, 5, 87, 5, 5, 5, 5, 5, 5],
|
[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],
|
[5, 4, 4, 4, 4, 1, 0, 1, 4, 4, 4, 4, 5],
|
||||||
|
|||||||
@ -1,45 +0,0 @@
|
|||||||
// 这里需要改楼层名,请和文件名及下面的floorId保持完全一致
|
|
||||||
// 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头
|
|
||||||
// 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等
|
|
||||||
main.floors.test = {
|
|
||||||
"floorId": "test", // 楼层唯一标识符,需要和名字完全一致
|
|
||||||
"title": "test", // 楼层中文名
|
|
||||||
"name": "", // 显示在状态栏中的层数
|
|
||||||
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
|
||||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
|
||||||
"defaultGround": "ground", // 默认地面的图块ID(terrains中)
|
|
||||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201,201,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201, 45,201,201,201,201,201,201],
|
|
||||||
[201,201,201,201,201,201, 0,201,201,201,201,201,201]
|
|
||||||
],
|
|
||||||
"firstArrive": [ // 第一次到该楼层触发的事件
|
|
||||||
|
|
||||||
],
|
|
||||||
"events": { // 该楼的所有可能事件列表
|
|
||||||
|
|
||||||
},
|
|
||||||
"changeFloor": { // 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖
|
|
||||||
|
|
||||||
},
|
|
||||||
"afterBattle": { // 战斗后可能触发的事件列表
|
|
||||||
|
|
||||||
},
|
|
||||||
"afterGetItem": { // 获得道具后可能触发的事件列表
|
|
||||||
|
|
||||||
},
|
|
||||||
"afterOpenDoor": { // 开完门后可能触发的事件列表
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ items.prototype.init = function () {
|
|||||||
'fly': {'cls': 'constants', 'name': '楼层传送器', 'text': '可以自由往来去过的楼层'},
|
'fly': {'cls': 'constants', 'name': '楼层传送器', 'text': '可以自由往来去过的楼层'},
|
||||||
'coin': {'cls': 'constants', 'name': '幸运金币', 'text': '持有时打败怪物可得双倍金币'},
|
'coin': {'cls': 'constants', 'name': '幸运金币', 'text': '持有时打败怪物可得双倍金币'},
|
||||||
'snow': {'cls': 'constants', 'name': '冰冻徽章', 'text': '可以将四周的熔岩变成平地'},
|
'snow': {'cls': 'constants', 'name': '冰冻徽章', 'text': '可以将四周的熔岩变成平地'},
|
||||||
'cross': {'cls': 'constants', 'name': '十字架', 'text': '该道具尚未被定义'},
|
'cross': {'cls': 'constants', 'name': '十字架', 'text': '持有后无视怪物的无敌属性'},
|
||||||
'knife': {'cls': 'constants', 'name': '屠龙匕首', 'text': '该道具尚未被定义'},
|
'knife': {'cls': 'constants', 'name': '屠龙匕首', 'text': '该道具尚未被定义'},
|
||||||
'shoes': {'cls': 'constants', 'name': '绿鞋', 'text': '持有时无视负面地形'},
|
'shoes': {'cls': 'constants', 'name': '绿鞋', 'text': '持有时无视负面地形'},
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ items.prototype.useItem = function (itemId) {
|
|||||||
if (!this.canUseItem(itemId)) return;
|
if (!this.canUseItem(itemId)) return;
|
||||||
var itemCls = core.material.items[itemId].cls;
|
var itemCls = core.material.items[itemId].cls;
|
||||||
|
|
||||||
if (itemId=='book') core.ui.drawEnemyBook(1);
|
if (itemId=='book') core.ui.drawEnemyBook(0);
|
||||||
if (itemId=='fly') core.ui.drawFly(core.status.hero.flyRange.indexOf(core.status.floorId));
|
if (itemId=='fly') core.ui.drawFly(core.status.hero.flyRange.indexOf(core.status.floorId));
|
||||||
if (itemId == 'earthquake' || itemId == 'bomb' || itemId == 'pickaxe' || itemId=='icePickaxe'
|
if (itemId == 'earthquake' || itemId == 'bomb' || itemId == 'pickaxe' || itemId=='icePickaxe'
|
||||||
|| itemId == 'snow' || itemId == 'hammer' || itemId=='bigKey') {
|
|| itemId == 'snow' || itemId == 'hammer' || itemId=='bigKey') {
|
||||||
@ -157,6 +157,9 @@ items.prototype.useItem = function (itemId) {
|
|||||||
core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
|
core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
|
||||||
core.updateFg();
|
core.updateFg();
|
||||||
core.drawTip(core.material.items[itemId].name + "使用成功");
|
core.drawTip(core.material.items[itemId].name + "使用成功");
|
||||||
|
|
||||||
|
if (itemId == 'bomb' || itemId == 'hammer')
|
||||||
|
core.events.afterUseBomb();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (itemId == 'centerFly') {
|
if (itemId == 'centerFly') {
|
||||||
|
|||||||
701
libs/thirdparty/mid.js
vendored
Normal file
701
libs/thirdparty/mid.js
vendored
Normal file
@ -0,0 +1,701 @@
|
|||||||
|
var sampleRate = 44100; /* hard-coded in Flash player */
|
||||||
|
|
||||||
|
function AudioPlayer(context, generator, loop) {
|
||||||
|
|
||||||
|
// Uses Webkit Web Audio API if available
|
||||||
|
sampleRate = context.sampleRate;
|
||||||
|
|
||||||
|
var channelCount = 2;
|
||||||
|
var bufferSize = 4096*4; // Higher for less gitches, lower for less latency
|
||||||
|
|
||||||
|
var node = context.createScriptProcessor(bufferSize, 0, channelCount);
|
||||||
|
|
||||||
|
node.onaudioprocess = function(e) { process(e) };
|
||||||
|
|
||||||
|
function process(e) {
|
||||||
|
if (generator.finished) {
|
||||||
|
if (loop) {
|
||||||
|
generator.reset();
|
||||||
|
generator.finished = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var dataLeft = e.outputBuffer.getChannelData(0);
|
||||||
|
var dataRight = e.outputBuffer.getChannelData(1);
|
||||||
|
|
||||||
|
var generate = generator.generate(bufferSize);
|
||||||
|
|
||||||
|
for (var i = 0; i < bufferSize; ++i) {
|
||||||
|
dataLeft[i] = generate[i*2];
|
||||||
|
dataRight[i] = generate[i*2+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// start
|
||||||
|
// node.connect(context.destination);
|
||||||
|
|
||||||
|
return {
|
||||||
|
'play': function () {
|
||||||
|
node.connect(context.destination);
|
||||||
|
},
|
||||||
|
'pause': function() {
|
||||||
|
node.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
class to parse the .mid file format
|
||||||
|
(depends on stream.js)
|
||||||
|
*/
|
||||||
|
function MidiFile(data) {
|
||||||
|
function readChunk(stream) {
|
||||||
|
var id = stream.read(4);
|
||||||
|
var length = stream.readInt32();
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'length': length,
|
||||||
|
'data': stream.read(length)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastEventTypeByte;
|
||||||
|
|
||||||
|
function readEvent(stream) {
|
||||||
|
var event = {};
|
||||||
|
event.deltaTime = stream.readVarInt();
|
||||||
|
var eventTypeByte = stream.readInt8();
|
||||||
|
if ((eventTypeByte & 0xf0) == 0xf0) {
|
||||||
|
/* system / meta event */
|
||||||
|
if (eventTypeByte == 0xff) {
|
||||||
|
/* meta event */
|
||||||
|
event.type = 'meta';
|
||||||
|
var subtypeByte = stream.readInt8();
|
||||||
|
var length = stream.readVarInt();
|
||||||
|
switch(subtypeByte) {
|
||||||
|
case 0x00:
|
||||||
|
event.subtype = 'sequenceNumber';
|
||||||
|
if (length != 2) throw "Expected length for sequenceNumber event is 2, got " + length;
|
||||||
|
event.number = stream.readInt16();
|
||||||
|
return event;
|
||||||
|
case 0x01:
|
||||||
|
event.subtype = 'text';
|
||||||
|
event.text = stream.read(length);
|
||||||
|
return event;
|
||||||
|
case 0x02:
|
||||||
|
event.subtype = 'copyrightNotice';
|
||||||
|
event.text = stream.read(length);
|
||||||
|
return event;
|
||||||
|
case 0x03:
|
||||||
|
event.subtype = 'trackName';
|
||||||
|
event.text = stream.read(length);
|
||||||
|
return event;
|
||||||
|
case 0x04:
|
||||||
|
event.subtype = 'instrumentName';
|
||||||
|
event.text = stream.read(length);
|
||||||
|
return event;
|
||||||
|
case 0x05:
|
||||||
|
event.subtype = 'lyrics';
|
||||||
|
event.text = stream.read(length);
|
||||||
|
return event;
|
||||||
|
case 0x06:
|
||||||
|
event.subtype = 'marker';
|
||||||
|
event.text = stream.read(length);
|
||||||
|
return event;
|
||||||
|
case 0x07:
|
||||||
|
event.subtype = 'cuePoint';
|
||||||
|
event.text = stream.read(length);
|
||||||
|
return event;
|
||||||
|
case 0x20:
|
||||||
|
event.subtype = 'midiChannelPrefix';
|
||||||
|
if (length != 1) throw "Expected length for midiChannelPrefix event is 1, got " + length;
|
||||||
|
event.channel = stream.readInt8();
|
||||||
|
return event;
|
||||||
|
case 0x2f:
|
||||||
|
event.subtype = 'endOfTrack';
|
||||||
|
if (length != 0) throw "Expected length for endOfTrack event is 0, got " + length;
|
||||||
|
return event;
|
||||||
|
case 0x51:
|
||||||
|
event.subtype = 'setTempo';
|
||||||
|
if (length != 3) throw "Expected length for setTempo event is 3, got " + length;
|
||||||
|
event.microsecondsPerBeat = (
|
||||||
|
(stream.readInt8() << 16)
|
||||||
|
+ (stream.readInt8() << 8)
|
||||||
|
+ stream.readInt8()
|
||||||
|
)
|
||||||
|
return event;
|
||||||
|
case 0x54:
|
||||||
|
event.subtype = 'smpteOffset';
|
||||||
|
if (length != 5) throw "Expected length for smpteOffset event is 5, got " + length;
|
||||||
|
var hourByte = stream.readInt8();
|
||||||
|
event.frameRate = {
|
||||||
|
0x00: 24, 0x20: 25, 0x40: 29, 0x60: 30
|
||||||
|
}[hourByte & 0x60];
|
||||||
|
event.hour = hourByte & 0x1f;
|
||||||
|
event.min = stream.readInt8();
|
||||||
|
event.sec = stream.readInt8();
|
||||||
|
event.frame = stream.readInt8();
|
||||||
|
event.subframe = stream.readInt8();
|
||||||
|
return event;
|
||||||
|
case 0x58:
|
||||||
|
event.subtype = 'timeSignature';
|
||||||
|
if (length != 4) throw "Expected length for timeSignature event is 4, got " + length;
|
||||||
|
event.numerator = stream.readInt8();
|
||||||
|
event.denominator = Math.pow(2, stream.readInt8());
|
||||||
|
event.metronome = stream.readInt8();
|
||||||
|
event.thirtyseconds = stream.readInt8();
|
||||||
|
return event;
|
||||||
|
case 0x59:
|
||||||
|
event.subtype = 'keySignature';
|
||||||
|
if (length != 2) throw "Expected length for keySignature event is 2, got " + length;
|
||||||
|
event.key = stream.readInt8(true);
|
||||||
|
event.scale = stream.readInt8();
|
||||||
|
return event;
|
||||||
|
case 0x7f:
|
||||||
|
event.subtype = 'sequencerSpecific';
|
||||||
|
event.data = stream.read(length);
|
||||||
|
return event;
|
||||||
|
default:
|
||||||
|
// console.log("Unrecognised meta event subtype: " + subtypeByte);
|
||||||
|
event.subtype = 'unknown'
|
||||||
|
event.data = stream.read(length);
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
event.data = stream.read(length);
|
||||||
|
return event;
|
||||||
|
} else if (eventTypeByte == 0xf0) {
|
||||||
|
event.type = 'sysEx';
|
||||||
|
var length = stream.readVarInt();
|
||||||
|
event.data = stream.read(length);
|
||||||
|
return event;
|
||||||
|
} else if (eventTypeByte == 0xf7) {
|
||||||
|
event.type = 'dividedSysEx';
|
||||||
|
var length = stream.readVarInt();
|
||||||
|
event.data = stream.read(length);
|
||||||
|
return event;
|
||||||
|
} else {
|
||||||
|
throw "Unrecognised MIDI event type byte: " + eventTypeByte;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* channel event */
|
||||||
|
var param1;
|
||||||
|
if ((eventTypeByte & 0x80) == 0) {
|
||||||
|
/* running status - reuse lastEventTypeByte as the event type.
|
||||||
|
eventTypeByte is actually the first parameter
|
||||||
|
*/
|
||||||
|
param1 = eventTypeByte;
|
||||||
|
eventTypeByte = lastEventTypeByte;
|
||||||
|
} else {
|
||||||
|
param1 = stream.readInt8();
|
||||||
|
lastEventTypeByte = eventTypeByte;
|
||||||
|
}
|
||||||
|
var eventType = eventTypeByte >> 4;
|
||||||
|
event.channel = eventTypeByte & 0x0f;
|
||||||
|
event.type = 'channel';
|
||||||
|
switch (eventType) {
|
||||||
|
case 0x08:
|
||||||
|
event.subtype = 'noteOff';
|
||||||
|
event.noteNumber = param1;
|
||||||
|
event.velocity = stream.readInt8();
|
||||||
|
return event;
|
||||||
|
case 0x09:
|
||||||
|
event.noteNumber = param1;
|
||||||
|
event.velocity = stream.readInt8();
|
||||||
|
if (event.velocity == 0) {
|
||||||
|
event.subtype = 'noteOff';
|
||||||
|
} else {
|
||||||
|
event.subtype = 'noteOn';
|
||||||
|
}
|
||||||
|
return event;
|
||||||
|
case 0x0a:
|
||||||
|
event.subtype = 'noteAftertouch';
|
||||||
|
event.noteNumber = param1;
|
||||||
|
event.amount = stream.readInt8();
|
||||||
|
return event;
|
||||||
|
case 0x0b:
|
||||||
|
event.subtype = 'controller';
|
||||||
|
event.controllerType = param1;
|
||||||
|
event.value = stream.readInt8();
|
||||||
|
return event;
|
||||||
|
case 0x0c:
|
||||||
|
event.subtype = 'programChange';
|
||||||
|
event.programNumber = param1;
|
||||||
|
return event;
|
||||||
|
case 0x0d:
|
||||||
|
event.subtype = 'channelAftertouch';
|
||||||
|
event.amount = param1;
|
||||||
|
return event;
|
||||||
|
case 0x0e:
|
||||||
|
event.subtype = 'pitchBend';
|
||||||
|
event.value = param1 + (stream.readInt8() << 7);
|
||||||
|
return event;
|
||||||
|
default:
|
||||||
|
throw "Unrecognised MIDI event type: " + eventType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = Stream(data);
|
||||||
|
var headerChunk = readChunk(stream);
|
||||||
|
if (headerChunk.id != 'MThd' || headerChunk.length != 6) {
|
||||||
|
throw "Bad .mid file - header not found";
|
||||||
|
}
|
||||||
|
var headerStream = Stream(headerChunk.data);
|
||||||
|
var formatType = headerStream.readInt16();
|
||||||
|
var trackCount = headerStream.readInt16();
|
||||||
|
var timeDivision = headerStream.readInt16();
|
||||||
|
|
||||||
|
if (timeDivision & 0x8000) {
|
||||||
|
throw "Expressing time division in SMTPE frames is not supported yet"
|
||||||
|
} else {
|
||||||
|
ticksPerBeat = timeDivision;
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = {
|
||||||
|
'formatType': formatType,
|
||||||
|
'trackCount': trackCount,
|
||||||
|
'ticksPerBeat': ticksPerBeat
|
||||||
|
}
|
||||||
|
var tracks = [];
|
||||||
|
for (var i = 0; i < header.trackCount; i++) {
|
||||||
|
tracks[i] = [];
|
||||||
|
var trackChunk = readChunk(stream);
|
||||||
|
if (trackChunk.id != 'MTrk') {
|
||||||
|
throw "Unexpected chunk - expected MTrk, got "+ trackChunk.id;
|
||||||
|
}
|
||||||
|
var trackStream = Stream(trackChunk.data);
|
||||||
|
while (!trackStream.eof()) {
|
||||||
|
var event = readEvent(trackStream);
|
||||||
|
tracks[i].push(event);
|
||||||
|
//console.log(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'header': header,
|
||||||
|
'tracks': tracks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function Replayer(midiFile, synth) {
|
||||||
|
var trackStates = [];
|
||||||
|
var beatsPerMinute = 120;
|
||||||
|
var ticksPerBeat = midiFile.header.ticksPerBeat;
|
||||||
|
var channelCount = 16;
|
||||||
|
var channels = [];
|
||||||
|
var nextEventInfo;
|
||||||
|
var samplesToNextEvent;
|
||||||
|
|
||||||
|
function Channel() {
|
||||||
|
|
||||||
|
var generatorsByNote = {};
|
||||||
|
var currentProgram = PianoProgram;
|
||||||
|
|
||||||
|
function noteOn(note, velocity) {
|
||||||
|
if (generatorsByNote[note] && !generatorsByNote[note].released) {
|
||||||
|
/* playing same note before releasing the last one. BOO */
|
||||||
|
generatorsByNote[note].noteOff(); /* TODO: check whether we ought to be passing a velocity in */
|
||||||
|
}
|
||||||
|
generator = currentProgram.createNote(note, velocity);
|
||||||
|
synth.addGenerator(generator);
|
||||||
|
generatorsByNote[note] = generator;
|
||||||
|
}
|
||||||
|
function noteOff(note, velocity) {
|
||||||
|
if (generatorsByNote[note] && !generatorsByNote[note].released) {
|
||||||
|
generatorsByNote[note].noteOff(velocity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function setProgram(programNumber) {
|
||||||
|
currentProgram = PROGRAMS[programNumber] || PianoProgram;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'noteOn': noteOn,
|
||||||
|
'noteOff': noteOff,
|
||||||
|
'setProgram': setProgram
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNextEvent() {
|
||||||
|
var ticksToNextEvent = null;
|
||||||
|
var nextEventTrack = null;
|
||||||
|
var nextEventIndex = null;
|
||||||
|
|
||||||
|
for (var i = 0; i < trackStates.length; i++) {
|
||||||
|
if (
|
||||||
|
trackStates[i].ticksToNextEvent != null
|
||||||
|
&& (ticksToNextEvent == null || trackStates[i].ticksToNextEvent < ticksToNextEvent)
|
||||||
|
) {
|
||||||
|
ticksToNextEvent = trackStates[i].ticksToNextEvent;
|
||||||
|
nextEventTrack = i;
|
||||||
|
nextEventIndex = trackStates[i].nextEventIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nextEventTrack != null) {
|
||||||
|
/* consume event from that track */
|
||||||
|
var nextEvent = midiFile.tracks[nextEventTrack][nextEventIndex];
|
||||||
|
if (midiFile.tracks[nextEventTrack][nextEventIndex + 1]) {
|
||||||
|
trackStates[nextEventTrack].ticksToNextEvent += midiFile.tracks[nextEventTrack][nextEventIndex + 1].deltaTime;
|
||||||
|
} else {
|
||||||
|
trackStates[nextEventTrack].ticksToNextEvent = null;
|
||||||
|
}
|
||||||
|
trackStates[nextEventTrack].nextEventIndex += 1;
|
||||||
|
/* advance timings on all tracks by ticksToNextEvent */
|
||||||
|
for (var i = 0; i < trackStates.length; i++) {
|
||||||
|
if (trackStates[i].ticksToNextEvent != null) {
|
||||||
|
trackStates[i].ticksToNextEvent -= ticksToNextEvent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nextEventInfo = {
|
||||||
|
'ticksToEvent': ticksToNextEvent,
|
||||||
|
'event': nextEvent,
|
||||||
|
'track': nextEventTrack
|
||||||
|
}
|
||||||
|
var beatsToNextEvent = ticksToNextEvent / ticksPerBeat;
|
||||||
|
var secondsToNextEvent = beatsToNextEvent / (beatsPerMinute / 60);
|
||||||
|
samplesToNextEvent += secondsToNextEvent * synth.sampleRate;
|
||||||
|
} else {
|
||||||
|
nextEventInfo = null;
|
||||||
|
samplesToNextEvent = null;
|
||||||
|
self.finished = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generate(samples) {
|
||||||
|
var data = new Array(samples*2);
|
||||||
|
var samplesRemaining = samples;
|
||||||
|
var dataOffset = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (samplesToNextEvent != null && samplesToNextEvent <= samplesRemaining) {
|
||||||
|
/* generate samplesToNextEvent samples, process event and repeat */
|
||||||
|
var samplesToGenerate = Math.ceil(samplesToNextEvent);
|
||||||
|
if (samplesToGenerate > 0) {
|
||||||
|
synth.generateIntoBuffer(samplesToGenerate, data, dataOffset);
|
||||||
|
dataOffset += samplesToGenerate * 2;
|
||||||
|
samplesRemaining -= samplesToGenerate;
|
||||||
|
samplesToNextEvent -= samplesToGenerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEvent();
|
||||||
|
getNextEvent();
|
||||||
|
} else {
|
||||||
|
/* generate samples to end of buffer */
|
||||||
|
if (samplesRemaining > 0) {
|
||||||
|
synth.generateIntoBuffer(samplesRemaining, data, dataOffset);
|
||||||
|
samplesToNextEvent -= samplesRemaining;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEvent() {
|
||||||
|
var event = nextEventInfo.event;
|
||||||
|
switch (event.type) {
|
||||||
|
case 'meta':
|
||||||
|
switch (event.subtype) {
|
||||||
|
case 'setTempo':
|
||||||
|
beatsPerMinute = 60000000 / event.microsecondsPerBeat
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'channel':
|
||||||
|
switch (event.subtype) {
|
||||||
|
case 'noteOn':
|
||||||
|
channels[event.channel].noteOn(event.noteNumber, event.velocity);
|
||||||
|
break;
|
||||||
|
case 'noteOff':
|
||||||
|
channels[event.channel].noteOff(event.noteNumber, event.velocity);
|
||||||
|
break;
|
||||||
|
case 'programChange':
|
||||||
|
//console.log('program change to ' + event.programNumber);
|
||||||
|
channels[event.channel].setProgram(event.programNumber);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
for (var i = 0; i < midiFile.tracks.length; i++) {
|
||||||
|
trackStates[i] = {
|
||||||
|
'nextEventIndex': 0,
|
||||||
|
'ticksToNextEvent': (
|
||||||
|
midiFile.tracks[i].length ?
|
||||||
|
midiFile.tracks[i][0].deltaTime :
|
||||||
|
null
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (var i = 0; i < channelCount; i++) {
|
||||||
|
channels[i] = Channel();
|
||||||
|
}
|
||||||
|
samplesToNextEvent = 0;
|
||||||
|
getNextEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
var self = {
|
||||||
|
'reset': reset,
|
||||||
|
'generate': generate,
|
||||||
|
'finished': false
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
/* Wrapper for accessing strings through sequential reads */
|
||||||
|
function Stream(str) {
|
||||||
|
var position = 0;
|
||||||
|
|
||||||
|
function read(length) {
|
||||||
|
var result = str.substr(position, length);
|
||||||
|
position += length;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read a big-endian 32-bit integer */
|
||||||
|
function readInt32() {
|
||||||
|
var result = (
|
||||||
|
(str.charCodeAt(position) << 24)
|
||||||
|
+ (str.charCodeAt(position + 1) << 16)
|
||||||
|
+ (str.charCodeAt(position + 2) << 8)
|
||||||
|
+ str.charCodeAt(position + 3));
|
||||||
|
position += 4;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read a big-endian 16-bit integer */
|
||||||
|
function readInt16() {
|
||||||
|
var result = (
|
||||||
|
(str.charCodeAt(position) << 8)
|
||||||
|
+ str.charCodeAt(position + 1));
|
||||||
|
position += 2;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read an 8-bit integer */
|
||||||
|
function readInt8(signed) {
|
||||||
|
var result = str.charCodeAt(position);
|
||||||
|
if (signed && result > 127) result -= 256;
|
||||||
|
position += 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function eof() {
|
||||||
|
return position >= str.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read a MIDI-style variable-length integer
|
||||||
|
(big-endian value in groups of 7 bits,
|
||||||
|
with top bit set to signify that another byte follows)
|
||||||
|
*/
|
||||||
|
function readVarInt() {
|
||||||
|
var result = 0;
|
||||||
|
while (true) {
|
||||||
|
var b = readInt8();
|
||||||
|
if (b & 0x80) {
|
||||||
|
result += (b & 0x7f);
|
||||||
|
result <<= 7;
|
||||||
|
} else {
|
||||||
|
/* b is the last byte */
|
||||||
|
return result + b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'eof': eof,
|
||||||
|
'read': read,
|
||||||
|
'readInt32': readInt32,
|
||||||
|
'readInt16': readInt16,
|
||||||
|
'readInt8': readInt8,
|
||||||
|
'readVarInt': readVarInt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function SineGenerator(freq) {
|
||||||
|
var self = {'alive': true};
|
||||||
|
var period = sampleRate / freq;
|
||||||
|
var t = 0;
|
||||||
|
|
||||||
|
self.generate = function(buf, offset, count) {
|
||||||
|
for (; count; count--) {
|
||||||
|
var phase = t / period;
|
||||||
|
var result = Math.sin(phase * 2 * Math.PI);
|
||||||
|
buf[offset++] += result;
|
||||||
|
buf[offset++] += result;
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SquareGenerator(freq, phase) {
|
||||||
|
var self = {'alive': true};
|
||||||
|
var period = sampleRate / freq;
|
||||||
|
var t = 0;
|
||||||
|
|
||||||
|
self.generate = function(buf, offset, count) {
|
||||||
|
for (; count; count--) {
|
||||||
|
var result = ( (t / period) % 1 > phase ? 1 : -1);
|
||||||
|
buf[offset++] += result;
|
||||||
|
buf[offset++] += result;
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ADSRGenerator(child, attackAmplitude, sustainAmplitude, attackTimeS, decayTimeS, releaseTimeS) {
|
||||||
|
var self = {'alive': true}
|
||||||
|
var attackTime = sampleRate * attackTimeS;
|
||||||
|
var decayTime = sampleRate * (attackTimeS + decayTimeS);
|
||||||
|
var decayRate = (attackAmplitude - sustainAmplitude) / (decayTime - attackTime);
|
||||||
|
var releaseTime = null; /* not known yet */
|
||||||
|
var endTime = null; /* not known yet */
|
||||||
|
var releaseRate = sustainAmplitude / (sampleRate * releaseTimeS);
|
||||||
|
var t = 0;
|
||||||
|
|
||||||
|
self.noteOff = function() {
|
||||||
|
if (self.released) return;
|
||||||
|
releaseTime = t;
|
||||||
|
self.released = true;
|
||||||
|
endTime = releaseTime + sampleRate * releaseTimeS;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.generate = function(buf, offset, count) {
|
||||||
|
if (!self.alive) return;
|
||||||
|
var input = new Array(count * 2);
|
||||||
|
for (var i = 0; i < count*2; i++) {
|
||||||
|
input[i] = 0;
|
||||||
|
}
|
||||||
|
child.generate(input, 0, count);
|
||||||
|
|
||||||
|
childOffset = 0;
|
||||||
|
while(count) {
|
||||||
|
if (releaseTime != null) {
|
||||||
|
if (t < endTime) {
|
||||||
|
/* release */
|
||||||
|
while(count && t < endTime) {
|
||||||
|
var ampl = sustainAmplitude - releaseRate * (t - releaseTime);
|
||||||
|
buf[offset++] += input[childOffset++] * ampl;
|
||||||
|
buf[offset++] += input[childOffset++] * ampl;
|
||||||
|
t++;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* dead */
|
||||||
|
self.alive = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (t < attackTime) {
|
||||||
|
/* attack */
|
||||||
|
while(count && t < attackTime) {
|
||||||
|
var ampl = attackAmplitude * t / attackTime;
|
||||||
|
buf[offset++] += input[childOffset++] * ampl;
|
||||||
|
buf[offset++] += input[childOffset++] * ampl;
|
||||||
|
t++;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
} else if (t < decayTime) {
|
||||||
|
/* decay */
|
||||||
|
while(count && t < decayTime) {
|
||||||
|
var ampl = attackAmplitude - decayRate * (t - attackTime);
|
||||||
|
buf[offset++] += input[childOffset++] * ampl;
|
||||||
|
buf[offset++] += input[childOffset++] * ampl;
|
||||||
|
t++;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* sustain */
|
||||||
|
while(count) {
|
||||||
|
buf[offset++] += input[childOffset++] * sustainAmplitude;
|
||||||
|
buf[offset++] += input[childOffset++] * sustainAmplitude;
|
||||||
|
t++;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
function midiToFrequency(note) {
|
||||||
|
return 440 * Math.pow(2, (note-69)/12);
|
||||||
|
}
|
||||||
|
|
||||||
|
PianoProgram = {
|
||||||
|
'attackAmplitude': 0.2,
|
||||||
|
'sustainAmplitude': 0.1,
|
||||||
|
'attackTime': 0.02,
|
||||||
|
'decayTime': 0.3,
|
||||||
|
'releaseTime': 0.02,
|
||||||
|
'createNote': function(note, velocity) {
|
||||||
|
var frequency = midiToFrequency(note);
|
||||||
|
return ADSRGenerator(
|
||||||
|
SineGenerator(frequency),
|
||||||
|
this.attackAmplitude * (velocity / 128), this.sustainAmplitude * (velocity / 128),
|
||||||
|
this.attackTime, this.decayTime, this.releaseTime
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringProgram = {
|
||||||
|
'createNote': function(note, velocity) {
|
||||||
|
var frequency = midiToFrequency(note);
|
||||||
|
return ADSRGenerator(
|
||||||
|
SineGenerator(frequency),
|
||||||
|
0.5 * (velocity / 128), 0.2 * (velocity / 128),
|
||||||
|
0.4, 0.8, 0.4
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PROGRAMS = {
|
||||||
|
41: StringProgram,
|
||||||
|
42: StringProgram,
|
||||||
|
43: StringProgram,
|
||||||
|
44: StringProgram,
|
||||||
|
45: StringProgram,
|
||||||
|
46: StringProgram,
|
||||||
|
47: StringProgram,
|
||||||
|
49: StringProgram,
|
||||||
|
50: StringProgram
|
||||||
|
};
|
||||||
|
|
||||||
|
function Synth(sampleRate) {
|
||||||
|
|
||||||
|
var generators = [];
|
||||||
|
|
||||||
|
function addGenerator(generator) {
|
||||||
|
generators.push(generator);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generate(samples) {
|
||||||
|
var data = new Array(samples*2);
|
||||||
|
generateIntoBuffer(samples, data, 0);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateIntoBuffer(samplesToGenerate, buffer, offset) {
|
||||||
|
for (var i = offset; i < offset + samplesToGenerate * 2; i++) {
|
||||||
|
buffer[i] = 0;
|
||||||
|
}
|
||||||
|
for (var i = generators.length - 1; i >= 0; i--) {
|
||||||
|
generators[i].generate(buffer, offset, samplesToGenerate);
|
||||||
|
if (!generators[i].alive) generators.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'sampleRate': sampleRate,
|
||||||
|
'addGenerator': addGenerator,
|
||||||
|
'generate': generate,
|
||||||
|
'generateIntoBuffer': generateIntoBuffer
|
||||||
|
}
|
||||||
|
}
|
||||||
91
libs/ui.js
91
libs/ui.js
@ -334,7 +334,8 @@ ui.prototype.drawSwitchs = function() {
|
|||||||
core.status.event.id = 'switchs';
|
core.status.event.id = 'switchs';
|
||||||
|
|
||||||
var choices = [
|
var choices = [
|
||||||
"背景音乐:"+(core.musicStatus.soundStatus ? "[ON]" : "[OFF]"),
|
"背景音乐:"+(core.musicStatus.bgmStatus ? "[ON]" : "[OFF]"),
|
||||||
|
"背景音效:"+(core.musicStatus.soundStatus ? "[ON]" : "[OFF]"),
|
||||||
"战斗动画: " + (core.flags.battleAnimate ? "[ON]" : "[OFF]"),
|
"战斗动画: " + (core.flags.battleAnimate ? "[ON]" : "[OFF]"),
|
||||||
"怪物显伤: " + (core.flags.displayEnemyDamage ? "[ON]" : "[OFF]"),
|
"怪物显伤: " + (core.flags.displayEnemyDamage ? "[ON]" : "[OFF]"),
|
||||||
"领域显伤: " + (core.flags.displayExtraDamage ? "[ON]" : "[OFF]"),
|
"领域显伤: " + (core.flags.displayExtraDamage ? "[ON]" : "[OFF]"),
|
||||||
@ -389,12 +390,12 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
|||||||
|
|
||||||
hero_hp -= core.enemys.getExtraDamage(monster);
|
hero_hp -= core.enemys.getExtraDamage(monster);
|
||||||
|
|
||||||
if (core.enemys.hasSpecial(mon_special, 2)) hero_def=0; // 魔攻
|
|
||||||
if (core.enemys.hasSpecial(mon_special, 3) && mon_def<hero_atk) mon_def=hero_atk-1; // 坚固
|
|
||||||
if (core.enemys.hasSpecial(mon_special, 10)) { // 模仿
|
if (core.enemys.hasSpecial(mon_special, 10)) { // 模仿
|
||||||
mon_atk=hero_atk;
|
mon_atk=hero_atk;
|
||||||
mon_def=hero_def;
|
mon_def=hero_def;
|
||||||
}
|
}
|
||||||
|
if (core.enemys.hasSpecial(mon_special, 2)) hero_def=0; // 魔攻
|
||||||
|
if (core.enemys.hasSpecial(mon_special, 3) && mon_def<hero_atk) mon_def=hero_atk-1; // 坚固
|
||||||
|
|
||||||
// 实际操作
|
// 实际操作
|
||||||
var turn = 0; // 0为勇士攻击
|
var turn = 0; // 0为勇士攻击
|
||||||
@ -404,7 +405,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
|||||||
var turns = 2;
|
var turns = 2;
|
||||||
if (core.enemys.hasSpecial(mon_special, 4)) turns=3;
|
if (core.enemys.hasSpecial(mon_special, 4)) turns=3;
|
||||||
if (core.enemys.hasSpecial(mon_special, 5)) turns=4;
|
if (core.enemys.hasSpecial(mon_special, 5)) turns=4;
|
||||||
if (core.enemys.hasSpecial(mon_special, 6)) turns=5;
|
if (core.enemys.hasSpecial(mon_special, 6)) turns=1+(monster.n||4);
|
||||||
|
|
||||||
|
|
||||||
// 初始伤害
|
// 初始伤害
|
||||||
@ -422,7 +423,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
|||||||
hero_mdef=0;
|
hero_mdef=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var specialText = core.enemys.getSpecialText(monsterId);
|
var specialTexts = core.enemys.getSpecialText(monsterId);
|
||||||
|
|
||||||
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||||
|
|
||||||
@ -465,7 +466,6 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
|||||||
core.canvas.ui.textAlign='center';
|
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', 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', "怪物", left+right-margin-boxWidth/2, top+margin+32+40);
|
||||||
var specialTexts = specialText.split(" ");
|
|
||||||
for (var i=0, j=0; i<specialTexts.length;i++) {
|
for (var i=0, j=0; i<specialTexts.length;i++) {
|
||||||
if (specialTexts[i]!='') {
|
if (specialTexts[i]!='') {
|
||||||
core.fillText('ui', specialTexts[i], left+right-margin-boxWidth/2, top+margin+32+44+20*(++j), '#FF6A6A', '15px Verdana');
|
core.fillText('ui', specialTexts[i], left+right-margin-boxWidth/2, top+margin+32+44+20*(++j), '#FF6A6A', '15px Verdana');
|
||||||
@ -571,7 +571,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
|||||||
core.fillText("ui", "S", right_start-8, 208+15, "#FFFFFF", "italic bold 40px Verdana");
|
core.fillText("ui", "S", right_start-8, 208+15, "#FFFFFF", "italic bold 40px Verdana");
|
||||||
|
|
||||||
var battleInterval = setInterval(function() {
|
var battleInterval = setInterval(function() {
|
||||||
core.playSound("attack", "ogg");
|
core.playSound("attack.ogg");
|
||||||
|
|
||||||
if (turn==0) {
|
if (turn==0) {
|
||||||
// 勇士攻击
|
// 勇士攻击
|
||||||
@ -726,9 +726,9 @@ ui.prototype.drawPagination = function (page, totalPage) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 绘制怪物手册
|
* 绘制怪物手册
|
||||||
* @param page 页数
|
* @param index 怪物索引
|
||||||
*/
|
*/
|
||||||
ui.prototype.drawEnemyBook = function (page) {
|
ui.prototype.drawEnemyBook = function (index) {
|
||||||
|
|
||||||
var enemys = core.enemys.getCurrentEnemys();
|
var enemys = core.enemys.getCurrentEnemys();
|
||||||
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
|
||||||
@ -758,11 +758,12 @@ ui.prototype.drawEnemyBook = function (page) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (index<0) index=0;
|
||||||
|
if (index>=enemys.length) index=enemys.length-1;
|
||||||
var perpage = 6;
|
var perpage = 6;
|
||||||
|
var page=parseInt(index/perpage)+1;
|
||||||
var totalPage = parseInt((enemys.length - 1) / perpage) + 1;
|
var totalPage = parseInt((enemys.length - 1) / perpage) + 1;
|
||||||
if (page < 1) page = 1;
|
core.status.event.data = index;
|
||||||
if (page > totalPage) page = totalPage;
|
|
||||||
core.status.event.data = page;
|
|
||||||
var start = (page - 1) * perpage, end = Math.min(page * perpage, enemys.length);
|
var start = (page - 1) * perpage, end = Math.min(page * perpage, enemys.length);
|
||||||
|
|
||||||
enemys = enemys.slice(start, end);
|
enemys = enemys.slice(start, end);
|
||||||
@ -834,11 +835,77 @@ ui.prototype.drawEnemyBook = function (page) {
|
|||||||
core.fillText('ui', '1防', 335, 62 * i + 68, '#DDDDDD', '13px Verdana');
|
core.fillText('ui', '1防', 335, 62 * i + 68, '#DDDDDD', '13px Verdana');
|
||||||
core.fillText('ui', enemy.defDamage, 365, 62 * i + 68, '#DDDDDD', 'bold 13px Verdana');
|
core.fillText('ui', enemy.defDamage, 365, 62 * i + 68, '#DDDDDD', 'bold 13px Verdana');
|
||||||
|
|
||||||
|
if (index == start+i) {
|
||||||
|
core.strokeRect('ui', 10, 62 * i + 13, 416-10*2, 62, '#FFD700');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
core.setBoxAnimate();
|
core.setBoxAnimate();
|
||||||
this.drawPagination(page, totalPage);
|
this.drawPagination(page, totalPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui.prototype.drawBookDetail = function (index) {
|
||||||
|
var enemys = core.enemys.getCurrentEnemys();
|
||||||
|
if (enemys.length==0) return;
|
||||||
|
if (index<0) index=0;
|
||||||
|
if (index>=enemys.length) index=enemys.length-1;
|
||||||
|
|
||||||
|
var enemy = enemys[index];
|
||||||
|
var enemyId=enemy.id;
|
||||||
|
var hints=core.enemys.getSpecialHint(core.enemys.getEnemys(enemyId));
|
||||||
|
|
||||||
|
if (hints.length==0) {
|
||||||
|
core.drawTip("该怪物无特殊属性!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var content=hints.join("\n");
|
||||||
|
|
||||||
|
core.status.event.id = 'book-detail';
|
||||||
|
clearInterval(core.interval.tipAnimate);
|
||||||
|
|
||||||
|
core.clearMap('data', 0, 0, 416, 416);
|
||||||
|
core.setOpacity('data', 1);
|
||||||
|
|
||||||
|
var left=10, right=416-2*left;
|
||||||
|
var content_left = left + 25;
|
||||||
|
|
||||||
|
var validWidth = right-(content_left-left)-13;
|
||||||
|
var contents = core.splitLines("data", content, validWidth, '16px Verdana');
|
||||||
|
|
||||||
|
var height = 416 - 10 - Math.min(416-24*(contents.length+1)-65, 250);
|
||||||
|
var top = (416-height)/2, bottom = height;
|
||||||
|
|
||||||
|
// var left = 97, top = 64, right = 416 - 2 * left, bottom = 416 - 2 * top;
|
||||||
|
core.setAlpha('data', 0.9);
|
||||||
|
core.fillRect('data', left, top, right, bottom, '#000000');
|
||||||
|
core.setAlpha('data', 1);
|
||||||
|
core.strokeRect('data', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
|
||||||
|
|
||||||
|
// 名称
|
||||||
|
core.canvas.data.textAlign = "left";
|
||||||
|
|
||||||
|
core.fillText('data', enemy.name, content_left, top + 30, '#FFD700', 'bold 22px Verdana');
|
||||||
|
var content_top = top + 57;
|
||||||
|
|
||||||
|
for (var i=0;i<contents.length;i++) {
|
||||||
|
// core.fillText('data', contents[i], content_left, content_top, '#FFFFFF', '16px Verdana');
|
||||||
|
var text=contents[i];
|
||||||
|
var index=text.indexOf(":");
|
||||||
|
if (index>=0) {
|
||||||
|
var x1 = text.substring(0, index+1);
|
||||||
|
core.fillText('data', x1, content_left, content_top, '#FF6A6A', 'bold 16px Verdana');
|
||||||
|
var len=core.canvas.data.measureText(x1).width;
|
||||||
|
core.fillText('data', text.substring(index+1), content_left+len, content_top, '#FFFFFF', '16px Verdana');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.fillText('data', contents[i], content_left, content_top, '#FFFFFF', '16px Verdana');
|
||||||
|
}
|
||||||
|
content_top+=24;
|
||||||
|
}
|
||||||
|
|
||||||
|
core.fillText('data', '<点击任意位置继续>', 270, top+height-13, '#CCCCCC', '13px Verdana');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绘制楼传器
|
* 绘制楼传器
|
||||||
* @param page
|
* @param page
|
||||||
|
|||||||
29
main.js
29
main.js
@ -45,12 +45,15 @@ function main() {
|
|||||||
];
|
];
|
||||||
this.images = [
|
this.images = [
|
||||||
'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains'
|
'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains'
|
||||||
// Autotile 动态添加
|
|
||||||
];
|
];
|
||||||
this.sounds = {
|
this.bgms = [ // 在此存放所有的bgm,和文件名一致。第一项为默认播放项
|
||||||
'mp3': ['bgm-loop', 'floor'],
|
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||||
'ogg': ['attack', 'door', 'item']
|
'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'),
|
||||||
@ -97,7 +100,7 @@ function main() {
|
|||||||
// 如果要进行剧本的修改请务必将其改成false。
|
// 如果要进行剧本的修改请务必将其改成false。
|
||||||
|
|
||||||
this.floorIds = [ // 在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器的顺序和上楼器/下楼器的顺序
|
this.floorIds = [ // 在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器的顺序和上楼器/下楼器的顺序
|
||||||
"sample0", "sample1", "sample2", "test"
|
"sample0", "sample1", "sample2"
|
||||||
]
|
]
|
||||||
//------------------------ 用户修改内容 END ------------------------//
|
//------------------------ 用户修改内容 END ------------------------//
|
||||||
|
|
||||||
@ -119,7 +122,7 @@ main.prototype.init = function () {
|
|||||||
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.sounds, main.floorIds, main.floors, coreData);
|
main.core.init(main.dom, main.statusBar, main.canvas, main.images, 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);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -222,18 +225,6 @@ main.dom.body.onselectstart = function () {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.onmousemove = function() {
|
|
||||||
try {
|
|
||||||
main.core.loadSound();
|
|
||||||
}catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.ontouchstart = function() {
|
|
||||||
try {
|
|
||||||
main.core.loadSound();
|
|
||||||
}catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
main.dom.data.onmousedown = function (e) {
|
main.dom.data.onmousedown = function (e) {
|
||||||
try {
|
try {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|||||||
BIN
sounds/058-Slow01.mid
Normal file
BIN
sounds/058-Slow01.mid
Normal file
Binary file not shown.
BIN
sounds/qianjin.mid
Normal file
BIN
sounds/qianjin.mid
Normal file
Binary file not shown.
BIN
sounds/star.mid
Normal file
BIN
sounds/star.mid
Normal file
Binary file not shown.
BIN
常用工具/便捷PS工具.exe
BIN
常用工具/便捷PS工具.exe
Binary file not shown.
9
更新说明.txt
9
更新说明.txt
@ -1,11 +1,12 @@
|
|||||||
全键盘操作 √
|
全键盘操作 √
|
||||||
进阶 √
|
经验升级(进阶) √
|
||||||
|
增加阻击、多连击等属性;属性显示;加点; √
|
||||||
|
九宫格领域、大范围领域 √
|
||||||
Ctrl快速跳过对话 √
|
Ctrl快速跳过对话 √
|
||||||
增加负伤 √
|
增加负伤 √
|
||||||
|
背景音乐 √
|
||||||
支持不同层使用不同的地面素材 √
|
支持不同层使用不同的地面素材 √
|
||||||
支持多个Autotile同时存在 √
|
支持多个Autotile同时存在 √
|
||||||
直接内嵌了诸多默认的terrains素材 √
|
直接内嵌了诸多默认的terrains素材 √
|
||||||
自动定位到上次存/读档位置 √
|
自动定位到上次存/读档位置 √
|
||||||
设置储存 √
|
每一层可以默认色调 √
|
||||||
修改setFg的实现方法 √
|
|
||||||
大范围领域伤害
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user