Project1

标题: 像素移动 [打印本页]

作者: moe2333    时间: 2016-6-7 17:25
标题: 像素移动
本帖最后由 moe2333 于 2016-6-7 17:35 编辑

暂时不支持座驾。
JAVASCRIPT 代码复制下载
  1. //=============================================================================
  2. // PixelMovement.js
  3. //=============================================================================
  4.  
  5. /*:
  6.  * @plugindesc Like you don't know what this does.
  7.  */
  8.  
  9. (function () {
  10.     //-----------------------------------------------------------------------------
  11.  
  12.     // An even number between 2 and 48, inclusive
  13.     var tileSection = 4;
  14.     // Gives you precise collision mask but can significantly compromise the performance
  15.     var analyzeTilesetBitmap = true;
  16.     // A section of the bitmap will be masked impassable if the valid pixel rate reaches this threshold
  17.     var bitmapAnalysisThreshold = 0.5;
  18.     // (x, y, width, height)
  19.     var characterCollisionBox = new Rectangle(1, 2, 2, 2);
  20.     // Tiles with this terrain tag are forced to be passable
  21.     var forcePassableTerrainTag = 3;
  22.     // Max distance between two followers
  23.     var followerDistance = 1;
  24.     // For debugging
  25.     var drawCollisionMask = true;
  26.     // [map, ladder, bush, counter, damageFloor, boat, ship], for debugging
  27.     var collisionMaskLayerColors = ['red', 'grey', 'green', 'yellow', 'crimson', 'lightBlue', 'blue'];
  28.  
  29.     //-----------------------------------------------------------------------------
  30.     var toPixel = function (t) {
  31.         return t * tileSection;
  32.     };
  33.  
  34.     var toTile = function (p) {
  35.         return p / tileSection;
  36.     };
  37.  
  38.     //-----------------------------------------------------------------------------
  39.     // Table2
  40.  
  41.     function Table2(xSize, ySize) {
  42.         this.initialize.apply(this, arguments);
  43.     }
  44.  
  45.     Table2.prototype.initialize = function (xSize, ySize) {
  46.         this.xSize = xSize;
  47.         this.ySize = ySize;
  48.         this.data = [];
  49.     };
  50.  
  51.     Table2.prototype.get = function (x, y) {
  52.         return this.data[y * this.xSize + x];
  53.     };
  54.  
  55.     Table2.prototype.set = function (x, y, data) {
  56.         this.data[y * this.xSize + x] = data;
  57.     };
  58.  
  59.     //-----------------------------------------------------------------------------
  60.     // Table3
  61.  
  62.     function Table3() {
  63.         this.initialize.apply(this, arguments);
  64.     }
  65.  
  66.     Table3.prototype.initialize = function (xSize, ySize, zSize) {
  67.         this.xSize = xSize;
  68.         this.ySize = ySize;
  69.         this.zSize = zSize;
  70.         this.data = [];
  71.     };
  72.  
  73.     Table3.prototype.get = function (x, y, z) {
  74.         return this.data[z * this.ySize * this.xSize + y * this.xSize + x];
  75.     };
  76.  
  77.     Table3.prototype.set = function (x, y, z, data) {
  78.         return this.data[z * this.ySize * this.xSize + y * this.xSize + x] = data;
  79.     };
  80.  
  81.     //-----------------------------------------------------------------------------
  82.     // Bitmap
  83.  
  84.     Bitmap.prototype.isOccupied = function (x, y, w, h, threshold) {
  85.         var data = this._context.getImageData(x, y, w, h).data;
  86.         var occupied = 0;
  87.         for (var i = 3; i < data.length; i += 4) {
  88.             if (data[i] === 255) {
  89.                 occupied++;
  90.             }
  91.         }
  92.         return (occupied / (data.length / 4)) > threshold;
  93.     };
  94.  
  95.     //-----------------------------------------------------------------------------
  96.     // Tilemap
  97.  
  98.     var aliasTilemapPrototypeUpdate = Tilemap.prototype.update;
  99.     Tilemap.prototype.update = function () {
  100.         aliasTilemapPrototypeUpdate.apply(this, arguments);
  101.         if (this._needRefreshCollisionMask && this.isReady()) {
  102.             this._needRefreshCollisionMask = false;
  103.             this.refreshCollisionMask();
  104.         }
  105.     };
  106.  
  107.     var aliasTilemapPrototypeRefresh = Tilemap.prototype.refresh;
  108.     Tilemap.prototype.refresh = function () {
  109.         aliasTilemapPrototypeRefresh.apply(this, arguments);
  110.         this._needRefreshCollisionMask = true;
  111.     };
  112.  
  113.     Tilemap.prototype.refreshCollisionMask = function () {
  114.         console.time('Collision Mask Generation');
  115.         $gameMap.collisionMask = new Table3($gameMap.widthPx(), $gameMap.heightPx(), 8);
  116.         this._tileCollisionMaskCaches = {};
  117.         for (var tx = 0; tx < this._mapWidth; tx++) {
  118.             for (var ty = 0; ty < this._mapHeight; ty++) {
  119.                 this.drawTileCollisionMask(tx, ty);
  120.             }
  121.         }
  122.         this._tileCollisionMaskCaches = null;
  123.         console.timeEnd('Collision Mask Generation');
  124.         if (drawCollisionMask) {
  125.             this.debugDrawCollisionMask();
  126.         }
  127.     };
  128.  
  129.     Tilemap.prototype.drawTileCollisionMask = function (tx, ty) {
  130.         var forcePassable = $gameMap.terrainTag(tx, ty) === forcePassableTerrainTag;
  131.  
  132.         var mcm = $gameMap.collisionMask;
  133.  
  134.         var flags = this.flags;
  135.         var tileIds = $gameMap.layeredTiles(tx, ty);
  136.  
  137.         var impassableSections = [];
  138.         var totalSections = tileSection * tileSection;
  139.  
  140.         for (var tileId, flag, i = 0; i < tileIds.length; i++) {
  141.             tileId = tileIds[i];
  142.  
  143.             if (!Tilemap.isVisibleTile(tileId)) {
  144.                 continue;
  145.             }
  146.  
  147.             var tcm = this._tileCollisionMaskCaches[tileId];
  148.             if (tcm) {
  149.                 if (!forcePassable) {
  150.                     for (var sx = 0; sx < tileSection; sx++) {
  151.                         for (var sy = 0; sy < tileSection; sy++) {
  152.                             for (var z = 0; z < 8; z++) {
  153.                                 var bit = tcm.get(sx, sy, z);
  154.                                 if (bit === 1) {
  155.                                     mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, z, bit);
  156.                                     if (z === 0) { // tile collision layer
  157.                                         var sectionId = sy * tileSection + sx;
  158.                                         if (!impassableSections.contains(sectionId)) {
  159.                                             impassableSections.push(sectionId);
  160.                                         }
  161.                                     }
  162.                                 }
  163.                             }
  164.                         }
  165.                     }
  166.                     if (impassableSections.length >= totalSections) {
  167.                         break;
  168.                     } else {
  169.                         continue;
  170.                     }
  171.                 }
  172.             } else {
  173.                 tcm = new Table3(tileSection, tileSection, 8);
  174.                 this._tileCollisionMaskCaches[tileId] = tcm;
  175.             }
  176.  
  177.             flag = flags[tileId];
  178.  
  179.             // other layers of the collision mask
  180.             for (var bp = 5; bp < 9; bp++) { // ladder, bush, counter, damageFloor
  181.                 if ((flag & (1 << bp)) !== 0) {
  182.                     for (var sx = 0; sx < tileSection; sx++) {
  183.                         for (var sy = 0; sy < tileSection; sy++) {
  184.                             var z = bp - 4;
  185.                             mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, z, 1);
  186.                             tcm.set(sx, sy, z, 1);
  187.                         }
  188.                     }
  189.                 }
  190.             }
  191.             if (!forcePassable) {
  192.                 for (var bp = 9; bp < 12; bp++) { // boat, ship, airship
  193.                     if ((flag & (1 << bp)) === 0) {
  194.                         for (var sx = 0; sx < tileSection; sx++) {
  195.                             for (var sy = 0; sy < tileSection; sy++) {
  196.                                 var z = bp - 4;
  197.                                 mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, z, 1);
  198.                                 tcm.set(sx, sy, z, 1);
  199.                             }
  200.                         }
  201.                     }
  202.                 }
  203.             }
  204.  
  205.             if (forcePassable) {
  206.                 break;
  207.             }
  208.  
  209.             // 0th layer of the collision mask
  210.             if ((flag & 0xf) === 0xf) { // all dirs are not passable
  211.                 if (analyzeTilesetBitmap) {
  212.                     if (Tilemap.isAutotile(tileId)) { // TODO: need to check the collision masks for autotiles too
  213.                         for (var sx = 0; sx < tileSection; sx++) {
  214.                             for (var sy = 0; sy < tileSection; sy++) {
  215.                                 mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, 0, 1);
  216.                                 tcm.set(sx, sy, 0, 1);
  217.                             }
  218.                         }
  219.                         break;
  220.                     } else {
  221.                         var bitmap = this.bitmaps[Tilemap.isTileA5(tileId) ? 4 : 5 + Math.floor(tileId / 256)];
  222.                         var tw = this._tileWidth;
  223.                         var th = this._tileHeight;
  224.                         var sw = $gameMap.tileWidthPx();
  225.                         var sh = $gameMap.tileHeightPx();
  226.                         var bx = (Math.floor(tileId / 128) % 2 * 8 + tileId % 8) * tw;
  227.                         var by = (Math.floor(tileId % 256 / 8) % 16) * th;
  228.                         for (var sx = 0; sx < tileSection; sx++) {
  229.                             for (var sy = 0; sy < tileSection; sy++) {
  230.                                 if (bitmap.isOccupied(bx + sx * sw, by + sy * sh, sw, sh, bitmapAnalysisThreshold)) {
  231.                                     mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, 0, 1);
  232.                                     tcm.set(sx, sy, 0, 1);
  233.                                     var sectionId = sy * tileSection + sx;
  234.                                     if (!impassableSections.contains(sectionId)) {
  235.                                         impassableSections.push(sectionId);
  236.                                     }
  237.                                 }
  238.                             }
  239.                         }
  240.                         if (impassableSections.length >= totalSections) {
  241.                             break;
  242.                         }
  243.                     }
  244.                 } else {
  245.                     for (var sx = 0; sx < tileSection; sx++) {
  246.                         for (var sy = 0; sy < tileSection; sy++) {
  247.                             mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, 0, 1);
  248.                             tcm.set(sx, sy, 0, 1);
  249.                         }
  250.                     }
  251.                     break;
  252.                 }
  253.             } else if ((flag & 0xf) !== 0) { // some dirs are passable, but not all
  254.                 for (var bp = 0; bp < 4; bp++) {
  255.                     if ((flag & (1 << bp)) !== 0) {
  256.                         switch (bp) {
  257.                             case 0: // down
  258.                                 for (var sx = 0; sx < tileSection; sx++) {
  259.                                     mcm.set(toPixel(tx) + sx, toPixel(ty) + tileSection - 1, 0, 1);
  260.                                     tcm.set(sx, tileSection - 1, 0, 1)
  261.                                 }
  262.                                 break;
  263.                             case 1: // left
  264.                                 for (var sy = 0; sy < tileSection; sy++) {
  265.                                     mcm.set(toPixel(tx), toPixel(ty) + sy, 0, 1);
  266.                                     tcm.set(0, sy, 0, 1)
  267.                                 }
  268.                                 break;
  269.                             case 2: // right
  270.                                 for (var sy = 0; sy < tileSection; sy++) {
  271.                                     mcm.set(toPixel(tx) + tileSection - 1, toPixel(ty) + sy, 0, 1);
  272.                                     tcm.set(tileSection - 1, sy, 0, 1)
  273.                                 }
  274.                                 break;
  275.                             case 3: // up
  276.                                 for (var sx = 0; sx < tileSection; sx++) {
  277.                                     mcm.set(toPixel(tx) + sx, toPixel(ty), 0, 1);
  278.                                     tcm.set(sx, 0, 0, 1)
  279.                                 }
  280.                                 break;
  281.                         }
  282.                     }
  283.                 }
  284.             }
  285.         }
  286.     };
  287.  
  288.     Tilemap.prototype.debugDrawCollisionMask = function () {
  289.         var cm = $gameMap.collisionMask;
  290.         var sw = $gameMap.tileWidthPx();
  291.         var sh = $gameMap.tileHeightPx();
  292.         for (var layerIndex = 0; layerIndex < 7; layerIndex++) {
  293.             var sprite = new Sprite(new Bitmap(this._mapWidth * this._tileWidth, this._mapHeight * this._tileHeight));
  294.             sprite.pivot = this.origin;
  295.             sprite.opacity = 80;
  296.             for (var px = 0; px < cm.xSize; px++) {
  297.                 for (var py = 0; py < cm.ySize; py++) {
  298.                     if (cm.get(px, py, layerIndex) === 1) {
  299.                         sprite.bitmap.fillRect(px * sw, py * sh, sw, sh, collisionMaskLayerColors[layerIndex]);
  300.                     }
  301.                 }
  302.             }
  303.             this.parent.addChild(sprite);
  304.         }
  305.     };
  306.  
  307.     //------------------------------------------------------------
  308.     // Game_Temp
  309.  
  310.     var aliasGameTempPrototypeInitialize = Game_Temp.prototype.initialize;
  311.     Game_Temp.prototype.initialize = function () {
  312.         aliasGameTempPrototypeInitialize.apply(this, arguments);
  313.         this._destinationPx = null;
  314.         this._destinationPy = null;
  315.         this._route = null;
  316.     };
  317.  
  318.     Game_Temp.prototype.isDestinationValid = function () {
  319.         return this._route && this._route.length > 0;
  320.     };
  321.  
  322.     Game_Temp.prototype.setDestination = function (px, py) {
  323.         if (!this._route || px !== this._destinationPx || py !== this._destinationPy) {
  324.             this._destinationPx = px;
  325.             this._destinationPy = py;
  326.             this._route = $gamePlayer.findRouteTo(px, py);
  327.         }
  328.     };
  329.  
  330.     Game_Temp.prototype.clearDestination = function () {
  331.         this._destinationPx = null;
  332.         this._destinationPy = null;
  333.         this._route = null;
  334.     };
  335.  
  336.     Game_Temp.prototype.destinationPx = function () {
  337.         return this._destinationPx;
  338.     };
  339.  
  340.     Game_Temp.prototype.destinationPy = function () {
  341.         return this._destinationPy;
  342.     };
  343.  
  344.     Game_Temp.prototype.nextDirection = function () {
  345.         return this._route ? this._route.pop() : 0;
  346.     };
  347.  
  348.     //------------------------------------------------------------
  349.     // Game_Actor
  350.  
  351.     /* TODO: Only damage characters that are on the damage floor
  352.     Game_Actor.prototype.checkFloorEffect = function () {
  353.         if ($gamePlayer.isOnDamageFloor()) {
  354.             this.executeFloorDamage();
  355.         }
  356.     };
  357.     */
  358.  
  359.     //------------------------------------------------------------
  360.     // Game_Map
  361.  
  362.     Object.defineProperty(Game_Map.prototype, 'collisionMask', {
  363.         get: function () {
  364.             return this._collisionMask;
  365.         },
  366.         set: function (value) {
  367.             this._collisionMask = value;
  368.         },
  369.         configurable: true
  370.     });
  371.  
  372.     Game_Map.prototype.isCollisionMaskSet = function () {
  373.         return this._collisionMask !== null;
  374.     };
  375.  
  376.     var aliasGameMapPrototypeInitialize = Game_Map.prototype.initialize;
  377.     Game_Map.prototype.initialize = function () {
  378.         aliasGameMapPrototypeInitialize.apply(this, arguments);
  379.         this._collisionMask = null;
  380.     };
  381.  
  382.     Game_Map.prototype.tileWidthPx = function () {
  383.         return this.tileWidth() / tileSection;
  384.     };
  385.  
  386.     Game_Map.prototype.tileHeightPx = function () {
  387.         return this.tileHeight() / tileSection;
  388.     };
  389.  
  390.     Game_Map.prototype.widthPx = function () {
  391.         return $dataMap.width * tileSection;
  392.     };
  393.  
  394.     Game_Map.prototype.heightPx = function () {
  395.         return $dataMap.height * tileSection;
  396.     };
  397.  
  398.     Game_Map.prototype.adjustPx = function (px) {
  399.         return toPixel(this.adjustX(toTile(px)));
  400.     };
  401.  
  402.     Game_Map.prototype.adjustPy = function (py) {
  403.         return toPixel(this.adjustY(toTile(py)));
  404.     };
  405.  
  406.     Game_Map.prototype.roundPx = function (px) {
  407.         return this.isLoopHorizontal() ? px.mod(this.widthPx()) : px;
  408.     };
  409.  
  410.     Game_Map.prototype.roundPy = function (py) {
  411.         return this.isLoopVertical() ? py.mod(this.heightPx()) : py;
  412.     };
  413.  
  414.     Game_Map.prototype.pxWithDirection = function (px, d) {
  415.         return px + (d === 6 ? 1 : d === 4 ? -1 : 0);
  416.     };
  417.  
  418.     Game_Map.prototype.pyWithDirection = function (py, d) {
  419.         return py + (d === 2 ? 1 : d === 8 ? -1 : 0);
  420.     };
  421.  
  422.     Game_Map.prototype.roundPxWithDirection = function (px, d) {
  423.         return this.roundPx(px + (d === 6 ? 1 : d === 4 ? -1 : 0));
  424.     };
  425.  
  426.     Game_Map.prototype.roundPyWithDirection = function (py, d) {
  427.         return this.roundPy(py + (d === 2 ? 1 : d === 8 ? -1 : 0));
  428.     };
  429.  
  430.     Game_Map.prototype.deltaPx = function (px1, px2) {
  431.         var result = px1 - px2;
  432.         if (this.isLoopHorizontal() && Math.abs(result) > this.widthPx() / 2) {
  433.             result += result < 0 ? this.widthPx() : -this.widthPx();
  434.         }
  435.         return result;
  436.     };
  437.  
  438.     Game_Map.prototype.deltaPy = function (py1, py2) {
  439.         var result = py1 - py2;
  440.         if (this.isLoopVertical() && Math.abs(result) > this.heightPx() / 2) {
  441.             result += result < 0 ? this.heightPx() : -this.heightPx();
  442.         }
  443.         return result;
  444.     };
  445.  
  446.     Game_Map.prototype.distancePx = function (px1, py1, px2, py2) {
  447.         return Math.abs(this.deltaPx(px1, px2)) + Math.abs(this.deltaPy(py1, py2));
  448.     };
  449.  
  450.     Game_Map.prototype.canvasToMapPx = function (x) {
  451.         return this.roundPx(Math.round((this._displayX * this.tileWidth() + x) / $gameMap.tileWidthPx()));
  452.     };
  453.  
  454.     Game_Map.prototype.canvasToMapPy = function (y) {
  455.         return this.roundPy(Math.round((this._displayY * this.tileHeight() + y) / $gameMap.tileHeightPx()));
  456.     };
  457.  
  458.     Game_Map.prototype.collidedEventsPx = function (px, py, cm) {
  459.         return this.events().filter(function (event) {
  460.             return $gameMap.areTwoCollisionMasksCollided(px, py, cm, event.px, event.py, event.collisionMask);
  461.         });
  462.     };
  463.  
  464.     Game_Map.prototype.areTwoCollisionMasksCollided = function (px1, py1, cm1, px2, py2, cm2) {
  465.         var xs1 = cm1.xSize;
  466.         var ys1 = cm1.ySize;
  467.         var xs2 = cm2.xSize;
  468.         var ys2 = cm2.ySize;
  469.         var spx1 = px1 - xs1 / 2;
  470.         var spy1 = py1 - ys1;
  471.         var spx2 = px2 - xs2 / 2;
  472.         var spy2 = py2 - ys2;
  473.         if (spx1 > spx2 + xs2 || spx1 + xs1 < spx2 || spy1 > spy2 + ys2 || spy1 + ys1 < spy2) {
  474.             return false;
  475.         }
  476.         var mpw = this.widthPx();
  477.         var poses1 = [];
  478.         var poses2 = [];
  479.         for (var cmx1 = 0; cmx1 < xs1; cmx1++) {
  480.             for (var cmy1 = 0; cmy1 < ys1; cmy1++) {
  481.                 cm1.get(cmx1, cmy1) && poses1.push(this.roundPy(spy1 + cmy1) * mpw + this.roundPx(spx1 + cmx1));
  482.             }
  483.         }
  484.         for (var cmx2 = 0; cmx2 < xs2; cmx2++) {
  485.             for (var cmy2 = 0; cmy2 < ys2; cmy2++) {
  486.                 cm2.get(cmx2, cmy2) && poses2.push(this.roundPy(spy2 + cmy2) * mpw + this.roundPx(spx2 + cmx2));
  487.             }
  488.         }
  489.         for (var i = 0; i < poses1.length; i++) {
  490.             for (var j = 0; j < poses2.length; j++) {
  491.                 if (poses1[i] === poses2[j]) {
  492.                     return true;
  493.                 }
  494.             }
  495.         }
  496.         return false;
  497.     };
  498.  
  499.     Game_Map.prototype.isValidPx = function (px, py) {
  500.         return px > -1 && px < this.widthPx() && py > -1 && py < this.heightPx();
  501.     };
  502.  
  503.     Game_Map.prototype.isPassablePx = function (px, py) {
  504.         return !this._collisionMask.get(px, py, 0);
  505.     };
  506.  
  507.     Game_Map.prototype.isPassableWithCollisionMask = function (px, py, cm) {
  508.         var spx = px - cm.xSize / 2;
  509.         var spy = py - cm.ySize;
  510.         for (var cmx = 0; cmx < cm.xSize; cmx++) {
  511.             for (var cmy = 0; cmy < cm.ySize; cmy++) {
  512.                 if (cm.get(cmx, cmy)) {
  513.                     var apx = this.roundPx(spx + cmx);
  514.                     var apy = this.roundPy(spy + cmy);
  515.                     if (!this.isValidPx(apx, apy) || !this.isPassablePx(apx, apy)) {
  516.                         return false;
  517.                     }
  518.                 }
  519.             }
  520.         }
  521.         return true;
  522.     };
  523.  
  524.     Game_Map.prototype.isBoatPassablePx = function (px, py) {
  525.         return false;
  526.     };
  527.  
  528.     Game_Map.prototype.isShipPassablePx = function (px, py) {
  529.         return false;
  530.     };
  531.  
  532.     Game_Map.prototype.isAirshipLandOkPx = function (px, py) {
  533.         return false;
  534.     };
  535.  
  536.     Game_Map.prototype.isLadderPx = function (px, py) {
  537.         if (!this.isCollisionMaskSet()) {
  538.             return false;
  539.         }
  540.         return this.isValidPx(px, py) && this._collisionMask.get(px, py, 1);
  541.     };
  542.  
  543.     Game_Map.prototype.isBushPx = function (px, py) {
  544.         if (!this.isCollisionMaskSet()) {
  545.             return false;
  546.         }
  547.         return this.isValidPx(px, py) && this._collisionMask.get(px, py, 2);
  548.     };
  549.  
  550.     Game_Map.prototype.isCounterPx = function (px, py) {
  551.         if (!this.isCollisionMaskSet()) {
  552.             return false;
  553.         }
  554.         return this.isValidPx(px, py) && this._collisionMask.get(px, py, 3);
  555.     };
  556.  
  557.     Game_Map.prototype.isDamageFloorPx = function (px, py) {
  558.         if (!this.isCollisionMaskSet()) {
  559.             return false;
  560.         }
  561.         return this.isValidPx(px, py) && this._collisionMask.get(px, py, 4);
  562.     };
  563.  
  564.     //------------------------------------------------------------
  565.     // Game_CharacterBase
  566.  
  567.     Object.defineProperty(Game_CharacterBase.prototype, 'collisionMask', {
  568.         get: function () {
  569.             return this._collisionMask
  570.         },
  571.         set: function (value) {
  572.             this._collisionMask = value
  573.         },
  574.         configurable: true
  575.     });
  576.  
  577.     Object.defineProperty(Game_CharacterBase.prototype, 'px', {
  578.         get: function () {
  579.             return this._px
  580.         },
  581.         configurable: true
  582.     });
  583.  
  584.     Object.defineProperty(Game_CharacterBase.prototype, 'py', {
  585.         get: function () {
  586.             return this._py
  587.         },
  588.         configurable: true
  589.     });
  590.  
  591.     var aliasGameCharacterBasePrototypeInitMembers = Game_CharacterBase.prototype.initMembers;
  592.     Game_CharacterBase.prototype.initMembers = function () {
  593.         aliasGameCharacterBasePrototypeInitMembers.apply(this, arguments);
  594.         this._px = 0;
  595.         this._py = 0;
  596.         this._realPx = 0;
  597.         this._realPy = 0;
  598.         this.createCollisionMask();
  599.     };
  600.  
  601.     Game_CharacterBase.prototype.createCollisionMask = function () { // TODO: Support bitmap analysis and custom collision box
  602.         this._collisionMask = new Table2(tileSection, tileSection);
  603.         var box = characterCollisionBox;
  604.         for (var x = box.x; x < box.x + box.width; x++) {
  605.             for (var y = box.y; y < box.y + box.height; y++) {
  606.                 this._collisionMask.set(x, y, 1);
  607.             }
  608.         }
  609.     };
  610.  
  611.     Game_CharacterBase.prototype.synchronizeTileCoordinate = function () {
  612.         this._realX = toTile(this._realPx);
  613.         this._realY = toTile(this._realPy);
  614.         this._x = Math.floor(this._realX);
  615.         this._y = Math.floor(this._realY);
  616.     };
  617.  
  618.     Game_CharacterBase.prototype.isMoving = function () {
  619.         return this._realPx !== this._px || this._realPy !== this._py;
  620.     };
  621.  
  622.     Game_CharacterBase.prototype.canPassPx = function (px, py, d) {
  623.         var npx = $gameMap.roundPxWithDirection(px, d);
  624.         var npy = $gameMap.roundPyWithDirection(py, d);
  625.         if (this.isThrough() || this.isDebugThrough()) {
  626.             return true;
  627.         }
  628.         if (!this.isMapPassablePx(px, py, d)) {
  629.             return false;
  630.         }
  631.         if (this.isCollidedWithCharactersPx(npx, npy)) {
  632.             return false;
  633.         }
  634.         return true;
  635.     };
  636.  
  637.     Game_CharacterBase.prototype.canPassDiagonallyPx = function (px, py, horz, vert) {
  638.         var npx = $gameMap.roundPxWithDirection(px, horz);
  639.         var npy = $gameMap.roundPyWithDirection(py, vert);
  640.         if (this.canPassPx(px, py, vert) && this.canPassPx(px, npy, horz)) {
  641.             return true;
  642.         }
  643.         if (this.canPassPx(px, py, horz) && this.canPassPx(npx, py, vert)) {
  644.             return true;
  645.         }
  646.         return false;
  647.     };
  648.  
  649.     Game_CharacterBase.prototype.isMapPassablePx = function (px, py, d) {
  650.         /*
  651.          var px2 = $gameMap.roundPxWithDirection(px, d);
  652.          var py2 = $gameMap.roundPyWithDirection(py, d);
  653.          return $gameMap.isPassableWithCollisionMask(px, py, this._collisionMask) && $gameMap.isPassableWithCollisionMask(px2, py2, this._collisionMask);
  654.          */
  655.         return $gameMap.isPassableWithCollisionMask($gameMap.roundPxWithDirection(px, d), $gameMap.roundPyWithDirection(py, d), this._collisionMask);
  656.     };
  657.  
  658.     Game_CharacterBase.prototype.isCollidedWithCharactersPx = function (px, py) {
  659.         return this.isCollidedWithEventsPx(px, py) || this.isCollidedWithVehiclesPx(px, py);
  660.     };
  661.  
  662.     Game_CharacterBase.prototype.isCollidedWithEventsPx = function (px, py) {
  663.         var events = $gameMap.events();
  664.         var cm = this._collisionMask;
  665.         var self = this;
  666.         return events.some(function (event) {
  667.             return event !== self && !event.isThrough() && event.isNormalPriority() && $gameMap.areTwoCollisionMasksCollided(px, py, cm, event.px, event.py, event.collisionMask);
  668.         });
  669.     };
  670.  
  671.     Game_CharacterBase.prototype.isCollidedWithVehiclesPx = function (px, py) {
  672.         return false;
  673.     };
  674.  
  675.     Game_CharacterBase.prototype.setPosition = function (tx, ty) {
  676.         this.setPositionPx(toPixel(tx) + tileSection / 2, toPixel(ty) + tileSection);
  677.     };
  678.     Game_CharacterBase.prototype.setPositionPx = function (px, py) {
  679.         this._px = Math.round(px);
  680.         this._py = Math.round(py);
  681.         this._realPx = px;
  682.         this._realPy = py;
  683.         this.synchronizeTileCoordinate();
  684.     };
  685.  
  686.     Game_CharacterBase.prototype.copyPosition = function (character) {
  687.         this._direction = character._direction;
  688.         this._px = character._px;
  689.         this._py = character._py;
  690.         this._realPx = character._realPx;
  691.         this._realPy = character._realPy;
  692.         this.synchronizeTileCoordinate();
  693.     };
  694.  
  695.     Game_CharacterBase.prototype.locate = function (tx, ty) {
  696.         this.locatePx(toPixel(tx) + tileSection / 2, toPixel(ty) + tileSection);
  697.     };
  698.     Game_CharacterBase.prototype.locatePx = function (px, py) {
  699.         this.setPositionPx(px, py);
  700.         this.straighten();
  701.         this.refreshBushDepth();
  702.     };
  703.  
  704.     Game_CharacterBase.prototype.screenX = function () {
  705.         return Math.round(toPixel(this.scrolledX()) * $gameMap.tileWidthPx());
  706.     };
  707.  
  708.     Game_CharacterBase.prototype.screenY = function () {
  709.         return Math.round(toPixel(this.scrolledY()) * $gameMap.tileHeightPx() - this.shiftY() - this.jumpHeight());
  710.     };
  711.  
  712.     Game_CharacterBase.prototype.update = function() {
  713.         this.updateAnimation();
  714.         if (this.isStopping()) {
  715.             this.updateStop();
  716.         }
  717.         if (this.isJumping()) {
  718.             this.updateJump();
  719.         } else if (this.isMoving()) {
  720.             this.updateMove();
  721.         }
  722.     };
  723.  
  724.     Game_CharacterBase.prototype.updateJump = function () {
  725.         this._jumpCount--;
  726.         this._realPx = (this._realPx * this._jumpCount + this._px) / (this._jumpCount + 1.0);
  727.         this._realPy = (this._realPy * this._jumpCount + this._py) / (this._jumpCount + 1.0);
  728.         this.refreshBushDepth();
  729.         if (this._jumpCount === 0) {
  730.             this._realPx = this._px = $gameMap.roundPx(this._px);
  731.             this._realPy = this._py = $gameMap.roundPy(this._py);
  732.         }
  733.         this.synchronizeTileCoordinate();
  734.     };
  735.  
  736.     Game_CharacterBase.prototype.updateMove = function () {
  737.         var dpf = toPixel(this.distancePerFrame());
  738.         if (this._px < this._realPx) {
  739.             this._realPx = Math.max(this._realPx - dpf, this._px);
  740.         }
  741.         if (this._px > this._realPx) {
  742.             this._realPx = Math.min(this._realPx + dpf, this._px);
  743.         }
  744.         if (this._py < this._realPy) {
  745.             this._realPy = Math.max(this._realPy - dpf, this._py);
  746.         }
  747.         if (this._py > this._realPy) {
  748.             this._realPy = Math.min(this._realPy + dpf, this._py);
  749.         }
  750.         this.synchronizeTileCoordinate();
  751.         if (!this.isMoving()) {
  752.             this.refreshBushDepth();
  753.         }
  754.     };
  755.  
  756.     Game_CharacterBase.prototype.isOnLadder = function () {
  757.         var cm = this._collisionMask;
  758.         var xs = cm.xSize;
  759.         var ys = cm.ySize;
  760.         var spx = this._px - xs / 2;
  761.         var spy = this._py - ys;
  762.         for (var cmx = 0; cmx < xs; cmx++) {
  763.             for (var cmy = 0; cmy < ys; cmy++) {
  764.                 if ($gameMap.isLadderPx(spx + cmx, spy + cmy)) {
  765.                     return true;
  766.                 }
  767.             }
  768.         }
  769.         return false;
  770.     };
  771.  
  772.     Game_CharacterBase.prototype.isOnBush = function () {
  773.         var cm = this._collisionMask;
  774.         var xs = cm.xSize;
  775.         var ys = cm.ySize;
  776.         var spx = this._px - xs / 2;
  777.         var spy = this._py - ys;
  778.         for (var cmx = 0; cmx < xs; cmx++) {
  779.             for (var cmy = 0; cmy < ys; cmy++) {
  780.                 if (!$gameMap.isBushPx(spx + cmx, spy + cmy)) {
  781.                     return false;
  782.                 }
  783.             }
  784.         }
  785.         return true;
  786.     };
  787.  
  788.     Game_CharacterBase.prototype.isOnDamageFloor = function () {
  789.         var cm = this._collisionMask;
  790.         var xs = cm.xSize;
  791.         var ys = cm.ySize;
  792.         var spx = this._px - xs / 2;
  793.         var spy = this._py - ys;
  794.         for (var cmx = 0; cmx < xs; cmx++) {
  795.             for (var cmy = 0; cmy < ys; cmy++) {
  796.                 if ($gameMap.isDamageFloorPx(spx + cmx, spy + cmy)) {
  797.                     return true;
  798.                 }
  799.             }
  800.         }
  801.         return false;
  802.     };
  803.  
  804.     Game_CharacterBase.prototype.isFacingCounter = function () {
  805.         var cm = this._collisionMask;
  806.         var direction = this.direction();
  807.         var npx = $gameMap.roundPxWithDirection(this._px, direction);
  808.         var npy = $gameMap.roundPyWithDirection(this._py, direction);
  809.         var xs = cm.xSize;
  810.         var ys = cm.ySize;
  811.         var spx = npx - xs / 2;
  812.         var spy = npy - ys;
  813.         for (var cmx = 0; cmx < xs; cmx++) {
  814.             for (var cmy = 0; cmy < ys; cmy++) {
  815.                 if ($gameMap.isCounterPx(spx + cmx, spy + cmy)) {
  816.                     return true;
  817.                 }
  818.             }
  819.         }
  820.         return false;
  821.     };
  822.  
  823.     Game_CharacterBase.prototype.checkEventTriggerTouchFrontPx = function (d) {
  824.         this.checkEventTriggerTouchPx($gameMap.roundPxWithDirection(this._px, d), $gameMap.roundPyWithDirection(this._py, d));
  825.     };
  826.  
  827.     Game_CharacterBase.prototype.checkEventTriggerTouchPx = function (px, py) {
  828.         return false;
  829.     };
  830.  
  831.     Game_CharacterBase.prototype.moveStraight = function (d) {
  832.         this.setMovementSuccess(this.canPassPx(this._px, this._py, d));
  833.         if (this.isMovementSucceeded()) {
  834.             this.setDirection(d);
  835.             this._px = $gameMap.roundPxWithDirection(this._px, d);
  836.             this._py = $gameMap.roundPyWithDirection(this._py, d);
  837.             this._realPx = $gameMap.pxWithDirection(this._px, this.reverseDir(d));
  838.             this._realPy = $gameMap.pyWithDirection(this._py, this.reverseDir(d));
  839.             this.increaseSteps();
  840.         } else {
  841.             this.setDirection(d);
  842.             this.checkEventTriggerTouchFrontPx(d);
  843.         }
  844.     };
  845.  
  846.     Game_CharacterBase.prototype.moveDiagonally = function (horz, vert) {
  847.         this.setMovementSuccess(this.canPassDiagonallyPx(this._px, this._py, horz, vert));
  848.         if (this.isMovementSucceeded()) {
  849.             this._px = $gameMap.roundPxWithDirection(this._px, horz);
  850.             this._py = $gameMap.roundPyWithDirection(this._py, vert);
  851.             this._realPx = $gameMap.pxWithDirection(this._px, this.reverseDir(horz));
  852.             this._realPy = $gameMap.pyWithDirection(this._py, this.reverseDir(vert));
  853.             this.increaseSteps();
  854.         }
  855.         if (this._direction === this.reverseDir(horz)) this.setDirection(horz);
  856.         if (this._direction === this.reverseDir(vert)) this.setDirection(vert);
  857.     };
  858.  
  859.     Game_CharacterBase.prototype.moveDir8 = function (d) {
  860.         switch (d) {
  861.             case 2:
  862.             case 4:
  863.             case 6:
  864.             case 8:
  865.                 this.moveStraight(d);
  866.                 break;
  867.             case 1:
  868.                 this.moveDiagonally(4, 2);
  869.                 break;
  870.             case 3:
  871.                 this.moveDiagonally(6, 2);
  872.                 break;
  873.             case 7:
  874.                 this.moveDiagonally(4, 8);
  875.                 break;
  876.             case 9:
  877.                 this.moveDiagonally(6, 8);
  878.                 break;
  879.         }
  880.     };
  881.  
  882.     Game_CharacterBase.prototype.jump = function (xPlus, yPlus) {
  883.         if (Math.abs(xPlus) > Math.abs(yPlus)) {
  884.             if (xPlus !== 0) {
  885.                 this.setDirection(xPlus < 0 ? 4 : 6);
  886.             }
  887.         } else {
  888.             if (yPlus !== 0) {
  889.                 this.setDirection(yPlus < 0 ? 8 : 2);
  890.             }
  891.         }
  892.         this._px += toPixel(xPlus);
  893.         this._py += toPixel(yPlus);
  894.         var distance = Math.round(Math.sqrt(xPlus * xPlus + yPlus * yPlus));
  895.         this._jumpPeak = 10 + distance - this._moveSpeed;
  896.         this._jumpCount = this._jumpPeak * 2;
  897.         this.resetStopCount();
  898.         this.straighten();
  899.     };
  900.  
  901.     //------------------------------------------------------------
  902.     // Game_Character
  903.     Game_Character.prototype.deltaPxFrom = function (px) {
  904.         return $gameMap.deltaPx(this._px, px);
  905.     };
  906.  
  907.     Game_Character.prototype.deltaPyFrom = function (py) {
  908.         return $gameMap.deltaPy(this._py, py);
  909.     };
  910.  
  911.     Game_Character.prototype.moveRandom = function () {
  912.         var d = 2 + Math.randomInt(4) * 2;
  913.         if (this.canPassPx(this.px, this.py, d)) {
  914.             this.moveStraight(d);
  915.         }
  916.     };
  917.  
  918.     Game_Character.prototype.moveTowardCharacter = function (character) {
  919.         var dpx = this.deltaPxFrom(character.px);
  920.         var dpy = this.deltaPyFrom(character.py);
  921.         if (Math.abs(dpx) > Math.abs(dpy)) {
  922.             this.moveStraight(dpx > 0 ? 4 : 6);
  923.             if (!this.isMovementSucceeded() && dpy !== 0) {
  924.                 this.moveStraight(dpy > 0 ? 8 : 2);
  925.             }
  926.         } else if (dpy !== 0) {
  927.             this.moveStraight(dpy > 0 ? 8 : 2);
  928.             if (!this.isMovementSucceeded() && dpx !== 0) {
  929.                 this.moveStraight(dpx > 0 ? 4 : 6);
  930.             }
  931.         }
  932.     };
  933.  
  934.     Game_Character.prototype.moveAwayFromCharacter = function (character) {
  935.         var dpx = this.deltaPxFrom(character.px);
  936.         var dpy = this.deltaPyFrom(character.py);
  937.         if (Math.abs(dpx) > Math.abs(dpy)) {
  938.             this.moveStraight(dpx > 0 ? 6 : 4);
  939.             if (!this.isMovementSucceeded() && dpy !== 0) {
  940.                 this.moveStraight(dpy > 0 ? 2 : 8);
  941.             }
  942.         } else if (dpy !== 0) {
  943.             this.moveStraight(dpy > 0 ? 2 : 8);
  944.             if (!this.isMovementSucceeded() && dpx !== 0) {
  945.                 this.moveStraight(dpx > 0 ? 6 : 4);
  946.             }
  947.         }
  948.     };
  949.  
  950.     Game_Character.prototype.turnTowardCharacter = function (character) {
  951.         var dpx = this.deltaPxFrom(character.px);
  952.         var dpy = this.deltaPyFrom(character.py);
  953.         if (Math.abs(dpx) > Math.abs(dpy)) {
  954.             this.setDirection(dpx > 0 ? 4 : 6);
  955.         } else if (dpy !== 0) {
  956.             this.setDirection(dpy > 0 ? 8 : 2);
  957.         }
  958.     };
  959.  
  960.     Game_Character.prototype.turnAwayFromCharacter = function (character) {
  961.         var dpx = this.deltaPxFrom(character.px);
  962.         var dpy = this.deltaPyFrom(character.py);
  963.         if (Math.abs(dpx) > Math.abs(dpy)) {
  964.             this.setDirection(dpx > 0 ? 6 : 4);
  965.         } else if (dpy !== 0) {
  966.             this.setDirection(dpy > 0 ? 2 : 8);
  967.         }
  968.     };
  969.  
  970.     Game_Character.prototype.findRouteTo = function (goalPx, goalPy) {
  971.         var searchLimit = toPixel(Math.max($gameMap.screenTileX(), $gameMap.screenTileY()));
  972.  
  973.         var px = this._px;
  974.         var py = this._py;
  975.  
  976.         if (px === goalPx && py === goalPy) {
  977.             return [];
  978.         }
  979.  
  980.         var makeNode = function (parent, px, py, gScore, fScore, direction) {
  981.             return {
  982.                 parent: parent,
  983.                 px: px,
  984.                 py: py,
  985.                 gScore: gScore,
  986.                 fScore: fScore,
  987.                 direction: direction
  988.             };
  989.         };
  990.         var makeId = function (px, py) {
  991.             return py * $gameMap.widthPx() + px;
  992.         };
  993.         var estimateCost = function (px1, py1, px2, py2) {
  994.             return $gameMap.distancePx(px1, py1, px2, py2);
  995.         };
  996.  
  997.         var reconstructPath = function (node) {
  998.             var current = node;
  999.             var path = [current.direction];
  1000.             while (current.parent !== start) {
  1001.                 current = current.parent;
  1002.                 path.push(current.direction);
  1003.             }
  1004.             return path;
  1005.         };
  1006.  
  1007.         var start = makeNode(null, px, py, 0, estimateCost(px, py, goalPx, goalPy), 0);
  1008.  
  1009.         var openSet = [start];
  1010.         var closedSet = [];
  1011.  
  1012.         var reserveSet = []; // used when failed
  1013.  
  1014.         while (openSet.length > 0) {
  1015.             var current = openSet[0];
  1016.             var currentIndex = 0;
  1017.  
  1018.             for (var i = 1; i < openSet.length; i++) {
  1019.                 if (openSet[i].fScore < current.fScore) {
  1020.                     current = openSet[i];
  1021.                     currentIndex = i;
  1022.                 }
  1023.             }
  1024.  
  1025.             if (current.px === goalPx && current.py === goalPy) {
  1026.                 return reconstructPath(current);
  1027.             }
  1028.  
  1029.             openSet.splice(currentIndex, 1);
  1030.             closedSet.push(makeId(current.px, current.py));
  1031.  
  1032.             reserveSet.push(current);
  1033.  
  1034.             if (current.gScore > searchLimit) {
  1035.                 continue;
  1036.             }
  1037.  
  1038.             for (var direction = 2; direction <= 8; direction += 2) {
  1039.                 var npx = $gameMap.roundPxWithDirection(current.px, direction);
  1040.                 var npy = $gameMap.roundPyWithDirection(current.py, direction);
  1041.  
  1042.                 if (closedSet.indexOf(makeId(npx, npy)) > -1) {
  1043.                     continue;
  1044.                 }
  1045.  
  1046.                 if (!this.canPassPx(current.px, current.py, direction)) {
  1047.                     closedSet.push(makeId(npx, npy));
  1048.                     continue;
  1049.                 }
  1050.  
  1051.                 var tentativeGScore = current.gScore + 1;
  1052.  
  1053.                 var nodeFound = null;
  1054.                 for (var i = 0; i < openSet.length; i++) {
  1055.                     var node = openSet[i];
  1056.                     if (node.px === npx && node.py === npy) {
  1057.                         nodeFound = node;
  1058.                     }
  1059.                 }
  1060.  
  1061.                 if (!nodeFound || tentativeGScore < nodeFound.gScore) {
  1062.                     var neighbor;
  1063.                     if (!nodeFound) {
  1064.                         neighbor = {
  1065.                             px: npx,
  1066.                             py: npy
  1067.                         };
  1068.                         openSet.push(neighbor);
  1069.                     } else {
  1070.                         neighbor = nodeFound;
  1071.                     }
  1072.  
  1073.                     neighbor.parent = current;
  1074.                     neighbor.gScore = tentativeGScore;
  1075.                     neighbor.fScore = tentativeGScore + estimateCost(npx, npy, goalPx, goalPy);
  1076.                     neighbor.direction = direction;
  1077.                 }
  1078.             }
  1079.         }
  1080.  
  1081.         // when failed
  1082.         var closest = reserveSet[0];
  1083.         for (var i = 1; i < reserveSet.length; i++) {
  1084.             var current = reserveSet[i];
  1085.             if (current.fScore - current.gScore < closest.fScore - closest.gScore) {
  1086.                 closest = current;
  1087.             }
  1088.         }
  1089.  
  1090.         var goalDirection;
  1091.         var dpx = $gameMap.deltaPx(closest.px, goalPx);
  1092.         var dpy = $gameMap.deltaPy(closest.py, goalPy);
  1093.         if (Math.abs(dpx) > Math.abs(dpy)) {
  1094.             goalDirection = dpx > 0 ? 4 : 6;
  1095.         } else if (dpy !== 0) {
  1096.             goalDirection = dpy > 0 ? 8 : 2;
  1097.         }
  1098.  
  1099.         if (closest === start) {
  1100.             return [goalDirection];
  1101.         } else {
  1102.             var path = reconstructPath(closest);
  1103.             path.unshift(goalDirection);
  1104.             return path;
  1105.         }
  1106.     };
  1107.  
  1108.     //------------------------------------------------------------
  1109.     // Game_Player
  1110.  
  1111.     Game_Player.prototype.moveByInput = function () {
  1112.         if (!this.isMoving() && this.canMove()) {
  1113.             var direction = this.getInputDirection();
  1114.             if (direction > 0) {
  1115.                 $gameTemp.clearDestination();
  1116.             } else if ($gameTemp.isDestinationValid()) {
  1117.                 direction = $gameTemp.nextDirection();
  1118.             }
  1119.             if (direction > 0) {
  1120.                 this.executeMove(direction);
  1121.                 if (!this.isMovementSucceeded()) {
  1122.                     switch (direction) {
  1123.                         case 2:
  1124.                             this.executeMove(1);
  1125.                             if (!this.isMovementSucceeded()) {
  1126.                                 this.executeMove(3)
  1127.                             }
  1128.                             break;
  1129.                         case 4:
  1130.                             this.executeMove(1);
  1131.                             if (!this.isMovementSucceeded()) {
  1132.                                 this.executeMove(7)
  1133.                             }
  1134.                             break;
  1135.                         case 6:
  1136.                             this.executeMove(3);
  1137.                             if (!this.isMovementSucceeded()) {
  1138.                                 this.executeMove(9)
  1139.                             }
  1140.                             break;
  1141.                         case 8:
  1142.                             this.executeMove(7);
  1143.                             if (!this.isMovementSucceeded()) {
  1144.                                 this.executeMove(9)
  1145.                             }
  1146.                             break;
  1147.                     }
  1148.                 }
  1149.             }
  1150.         }
  1151.     };
  1152.  
  1153.     Game_Player.prototype.getInputDirection = function () {
  1154.         return Input.dir8;
  1155.     };
  1156.  
  1157.     Game_Player.prototype.executeMove = function (direction) {
  1158.         this.moveDir8(direction);
  1159.     };
  1160.  
  1161.     Game_Player.prototype.updateNonmoving = function (wasMoving) {
  1162.         if (!$gameMap.isEventRunning()) {
  1163.             if (wasMoving) {
  1164.                 $gameParty.onPlayerWalk();
  1165.                 this.checkEventTriggerHere([1, 2]);
  1166.                 if ($gameMap.setupStartingEvent()) {
  1167.                     return;
  1168.                 }
  1169.             }
  1170.             if (this.triggerAction()) {
  1171.                 return;
  1172.             }
  1173.             if (wasMoving) {
  1174.                 this.updateEncounterCount();
  1175.             } else if (!$gameTemp.isDestinationValid()) {
  1176.                 $gameTemp.clearDestination();
  1177.             }
  1178.         }
  1179.     };
  1180.  
  1181.     Game_Player.prototype.triggerTouchAction = function () {
  1182.         return false;
  1183.     };
  1184.  
  1185.     Game_Player.prototype.checkEventTriggerHere = function (triggers) {
  1186.         if (this.canStartLocalEvents()) {
  1187.             this.startCollidedEventsPx(this._px, this._py, triggers, false);
  1188.         }
  1189.     };
  1190.  
  1191.     Game_Player.prototype.checkEventTriggerThere = function (triggers) { // front, literally
  1192.         if (this.canStartLocalEvents()) {
  1193.             var direction = this.direction();
  1194.             var npx = $gameMap.roundPxWithDirection(this._px, direction);
  1195.             var npy = $gameMap.roundPyWithDirection(this._py, direction);
  1196.             this.startCollidedEventsPx(npx, npy, triggers, true);
  1197.             if (!$gameMap.isEventRunning() && this.isFacingCounter()) {
  1198.                 if (direction === 2 || direction === 8) {
  1199.                     this.startCollidedEventsPx(npx, npy + (direction === 2 ? tileSection : -tileSection), triggers, true);
  1200.                 } else if (direction === 4 || direction === 6) {
  1201.                     this.startCollidedEventsPx(npx + (direction === 4 ? -tileSection : tileSection), npy, triggers, true);
  1202.                 }
  1203.             }
  1204.         }
  1205.     };
  1206.  
  1207.     Game_Player.prototype.checkEventTriggerTouchPx = function (px, py) {
  1208.         if (this.canStartLocalEvents()) {
  1209.             this.startCollidedEventsPx(px, py, [1, 2], true);
  1210.         }
  1211.     };
  1212.  
  1213.     Game_Player.prototype.startCollidedEventsPx = function (px, py, triggers, normal) {
  1214.         if (!$gameMap.isEventRunning()) {
  1215.             $gameMap.collidedEventsPx(px, py, this._collisionMask).forEach(function (event) {
  1216.                 if (event.isTriggerIn(triggers) && event.isNormalPriority() === normal) {
  1217.                     event.start();
  1218.                 }
  1219.             });
  1220.         }
  1221.     };
  1222.  
  1223.     Game_Player.prototype.isOnDamageFloor = function () {
  1224.         var cm = this._collisionMask;
  1225.         var xs = cm.xSize;
  1226.         var ys = cm.ySize;
  1227.         var spx = this._px - xs / 2;
  1228.         var spy = this._py - ys;
  1229.         for (var cmx = 0; cmx < xs; cmx++) {
  1230.             for (var cmy = 0; cmy < ys; cmy++) {
  1231.                 if ($gameMap.isDamageFloorPx(spx + cmx, spy + cmy)) {
  1232.                     return true;
  1233.                 }
  1234.             }
  1235.         }
  1236.         return false;
  1237.     };
  1238.  
  1239.     Game_Player.prototype.moveStraight = function (d) {
  1240.         Game_Character.prototype.moveStraight.call(this, d);
  1241.         if (this.isMovementSucceeded()) {
  1242.             this._followers.updateMove();
  1243.         }
  1244.     };
  1245.  
  1246.     Game_Player.prototype.moveDiagonally = function (horz, vert) {
  1247.         Game_Character.prototype.moveDiagonally.call(this, horz, vert);
  1248.         if (this.isMovementSucceeded()) {
  1249.             this._followers.updateMove();
  1250.         }
  1251.     };
  1252.  
  1253.     //------------------------------------------------------------
  1254.     // Game_Follower
  1255.  
  1256.     Game_Follower.prototype.canPassPx = function (px, py, d) {
  1257.         /*
  1258.          if (this.isThrough() || this.isDebugThrough()) {
  1259.          return true;
  1260.          }
  1261.          */
  1262.         if (!this.isMapPassablePx(px, py, d)) {
  1263.             return false;
  1264.         }
  1265.         if (this.isCollidedWithCharactersPx($gameMap.roundPxWithDirection(px, d), $gameMap.roundPyWithDirection(py, d))) {
  1266.             return false;
  1267.         }
  1268.         return true;
  1269.     };
  1270.  
  1271.     Game_Follower.prototype.chaseCharacter = function (character) {
  1272.         var dpx = this.deltaPxFrom(character.px);
  1273.         var dpy = this.deltaPyFrom(character.py);
  1274.         dpx = Math.abs(dpx) > followerDistance ? dpx : 0;
  1275.         dpy = Math.abs(dpy) > followerDistance ? dpy : 0;
  1276.         if (dpx !== 0 || dpy !== 0) {
  1277.             if (dpx !== 0 && dpy !== 0) {
  1278.                 this.moveDiagonally(dpx > 0 ? 4 : 6, dpy > 0 ? 8 : 2);
  1279.             } else if (dpx !== 0) {
  1280.                 this.moveStraight(dpx > 0 ? 4 : 6);
  1281.             } else if (dpy !== 0) {
  1282.                 this.moveStraight(dpy > 0 ? 8 : 2);
  1283.             }
  1284.             if (!this.isMovementSucceeded()) {
  1285.                 this.moveDir8(this.findChaseDirection(character));
  1286.             }
  1287.             this.setMoveSpeed($gamePlayer.realMoveSpeed());
  1288.         }
  1289.     };
  1290.  
  1291.     Game_Follower.prototype.findChaseDirection = function (character) {
  1292.         var nodes = [];
  1293.  
  1294.         var px = this._px;
  1295.         var py = this._py;
  1296.  
  1297.         var makeNode = function (px, py, gScore, fScore, direction) {
  1298.             return {
  1299.                 px: px,
  1300.                 py: py,
  1301.                 g: gScore,
  1302.                 f: fScore,
  1303.                 direction: direction
  1304.             };
  1305.         };
  1306.  
  1307.         for (var direction = 1; direction <= 9; direction++) {
  1308.             if (direction === 5) {
  1309.                 continue;
  1310.             }
  1311.             var npx = px;
  1312.             var npy = py;
  1313.             switch (direction) {
  1314.                 case 2:
  1315.                 case 4:
  1316.                 case 6:
  1317.                 case 8:
  1318.                     npx = $gameMap.roundPxWithDirection(npx, direction);
  1319.                     npy = $gameMap.roundPyWithDirection(npy, direction);
  1320.                     break;
  1321.                 case 1:
  1322.                     npx--;
  1323.                     npy++;
  1324.                     break;
  1325.                 case 3:
  1326.                     npx++;
  1327.                     npy++;
  1328.                     break;
  1329.                 case 7:
  1330.                     npx--;
  1331.                     npy--;
  1332.                     break;
  1333.                 case 9:
  1334.                     npx++;
  1335.                     npy--;
  1336.                     break;
  1337.             }
  1338.             if (direction % 2 === 0) {
  1339.                 if (!this.canPassPx(px, py, direction)) {
  1340.                     continue;
  1341.                 }
  1342.             } else {
  1343.                 if (!this.canPassDiagonallyPx(px, py, npx - px > 0 ? 6 : 4, npy - py > 0 ? 2 : 8)) {
  1344.                     continue;
  1345.                 }
  1346.             }
  1347.             nodes.push(makeNode(npx, npy, 1, 1 + $gameMap.distancePx(npx, npy, character.px, character.py), direction));
  1348.         }
  1349.  
  1350.         if (nodes.length < 1) {
  1351.             return 0;
  1352.         }
  1353.  
  1354.         var best = nodes[0];
  1355.         for (var i = 1; i < nodes.length; i++) {
  1356.             var current = nodes[i];
  1357.             if (current.f < best.f) {
  1358.                 best = current;
  1359.             }
  1360.         }
  1361.         return best.direction;
  1362.     };
  1363.  
  1364.     //-----------------------------------------------------------------------------
  1365.     // Game_Followers
  1366.  
  1367.     Game_Followers.prototype.jumpAll = function () {
  1368.         if ($gamePlayer.isJumping()) {
  1369.             for (var i = 0; i < this._data.length; i++) {
  1370.                 var follower = this._data[i];
  1371.                 var sx = toTile($gamePlayer.deltaPxFrom(follower.px));
  1372.                 var sy = toTile($gamePlayer.deltaPyFrom(follower.py));
  1373.                 follower.jump(sx, sy);
  1374.             }
  1375.         }
  1376.     };
  1377.  
  1378.     /*
  1379.      Game_Followers.prototype.isSomeoneCollided = function(x, y) {
  1380.      return this.visibleFollowers().some(function(follower) {
  1381.      return follower.pos(x, y);
  1382.      }, this);
  1383.      };
  1384.      */
  1385.  
  1386.     //-----------------------------------------------------------------------------
  1387.     // Game_Vehicle
  1388.  
  1389.     // TODO: Support vehicles
  1390.  
  1391.     //-----------------------------------------------------------------------------
  1392.     // Sprite_Character
  1393.  
  1394.     var aliasSpriteCharacterPrototypeSetCharacter = Sprite_Character.prototype.setCharacter;
  1395.     Sprite_Character.prototype.setCharacter = function () {
  1396.         aliasSpriteCharacterPrototypeSetCharacter.apply(this, arguments);
  1397.         if (drawCollisionMask && this._character) {
  1398.             this.debugDrawCollisionMask();
  1399.         }
  1400.     };
  1401.  
  1402.     Sprite_Character.prototype.debugDrawCollisionMask = function () {
  1403.         var sprite = new Sprite(new Bitmap($gameMap.tileWidth(), $gameMap.tileHeight()));
  1404.         sprite.anchor = this.anchor;
  1405.         sprite.opacity = 80;
  1406.         var cm = this._character.collisionMask;
  1407.         var sw = $gameMap.tileWidthPx();
  1408.         var sh = $gameMap.tileHeightPx();
  1409.         for (var sx = 0; sx < cm.xSize; sx++) {
  1410.             for (var sy = 0; sy < cm.ySize; sy++) {
  1411.                 if (cm.get(sx, sy)) {
  1412.                     sprite.bitmap.fillRect(sx * sw, sy * sh, sw, sh, this._character.isThrough() || !this._character.isNormalPriority() ? 'green' : 'red');
  1413.                 }
  1414.             }
  1415.         }
  1416.         this.addChild(sprite);
  1417.     };
  1418.  
  1419.     //------------------------------------------------------------
  1420.     // Sprite_Destination
  1421.  
  1422.     Sprite_Destination.prototype.updatePosition = function () {
  1423.         var dpx = $gameTemp.destinationPx();
  1424.         var dpy = $gameTemp.destinationPy();
  1425.         this.x = $gameMap.adjustX(toTile(dpx)) * tileSection * $gameMap.tileWidthPx();
  1426.         this.y = ($gameMap.adjustY(toTile(dpy)) * tileSection - 1) * $gameMap.tileHeightPx();
  1427.     };
  1428.  
  1429.     //------------------------------------------------------------
  1430.     // Scene_Map
  1431.     Scene_Map.prototype.processMapTouch = function () {
  1432.         if (TouchInput.isTriggered()) {
  1433.             $gameTemp.setDestination($gameMap.canvasToMapPx(TouchInput.x), $gameMap.canvasToMapPy(TouchInput.y));
  1434.         }
  1435.     };
  1436.  
  1437.     var aliasSceneMapPrototypeUpdate = Scene_Map.prototype.update;
  1438.     Scene_Map.prototype.update = function () {
  1439.         if ($gameMap.isCollisionMaskSet()) {
  1440.             aliasSceneMapPrototypeUpdate.apply(this, arguments);
  1441.         } else {
  1442.             Scene_Base.prototype.update.call(this);
  1443.         }
  1444.     };
  1445. })();

作者: 超音速    时间: 2016-6-8 18:05
这个。。。有什么用?解释一下
作者: 西姐    时间: 2016-6-8 21:30
现在的难道不是像素移动?
作者: MeowSnow    时间: 2016-6-9 00:48

_(:з」∠)_啊喏,虽然像素移动的效果很棒,但是火车队列变成了扭曲的效果呢……还有行走图上出现了不明的小方块,即使关了火车队列或者队伍中只有一个角色时,这些小方块也存在。
作者: moe2333    时间: 2016-6-9 02:03
本帖最后由 moe2333 于 2016-6-9 02:25 编辑
MeowSnow 发表于 2016-6-9 00:48
_(:з」∠)_啊喏,虽然像素移动的效果很棒,但是火车队列变成了扭曲的效果呢……还有行走图上出现了不明的 ...


是我把火车队列定义成这样的:
只要一个跟随者跟随的角色的X距离或者Y距离不超过followerDistance这个follower就不会移动,我觉得这样会让队列更自然
关于小方块,那是角色的碰撞面具,把25行的drawCollisionMask设置为false就可以了。
因为测试的时候需要绘制碰撞面具所以默认是true的状态
至于为什么关了火车还会有是因为不管队伍里有多少队员默认状态下都会有3个follower跟着主角,队员不足或者不显示follower的时候MV做的只是把那几个follower的sprite隐藏掉了而已

哦,对了
告诉你一下还有什么是我没有做的:
1. 虽然优化了寻路的算法但是鼠标不能触发事件了(现在懒得弄所以直接禁用掉了,不过以后会弄的)
2. 暂时不支持交通工具,关于交通工具的一切(乘坐,移动...)都可能会有bug,不过bug长什么样子我没去看,总之即使坐上去了也不能移动。(其实交通工具需要的碰撞检测数据已经在refreshCollisionMask方法里生成了,所以要做应该也不是难事)
3. 暂时不支持autotile的位图分析,所以只要autotile的flag是0x0f的话那整个autotile都会被mask掉,不管位图长什么样子
4. 其他肯定还有很多bug和兼容的问题
5. 我好懒

最近pewdiepie有在搞一个rpg maker competition,我其实想参加的,但是一个人好像没什么动力,你们想不想一起来?如果有人帮忙的话我就去参加了

作者: moe2333    时间: 2016-6-9 02:07
西姐 发表于 2016-6-8 21:30
现在的难道不是像素移动?

像素移动只是相对像素而已
默认状态下MV是48像素一个tile,这个脚本允许你把tile size设置得更小
具体参照tileSection
另外这个脚本还加入了更精确的碰撞检测以及自动分析tileset bitmap的功能
你可以新建一个工程看看效果
作者: moe2333    时间: 2016-6-9 02:09
超音速 发表于 2016-6-8 18:05
这个。。。有什么用?解释一下

默认状态下MV一按方向键就走一整个大格,你想不想让移动更自由一点,比如说一小格一小格的移动呢?
作者: taroxd    时间: 2016-6-9 07:42
Quasi Movement 这个插件我觉得挺不错的,楼主可以参考一下
作者: tseyik    时间: 2016-6-9 08:34
本帖最后由 tseyik 于 2016-6-9 08:37 编辑
SAN_AnalogMove

也不錯

作者: moe2333    时间: 2016-6-9 08:49
本帖最后由 moe2333 于 2016-6-9 08:51 编辑
taroxd 发表于 2016-6-9 07:42
Quasi Movement 这个插件我觉得挺不错的,楼主可以参考一下


quasi movement如果想要更精确的collision mask需要给每张地图制作一张额外的collision map...然而我不希望这样

如果我找得到合适的也就不会自己写了...我的游戏里不需要交通工具和鼠标操作,于是就变成现在这个样子了
作者: moe2333    时间: 2016-6-9 11:34
本帖最后由 moe2333 于 2016-6-9 11:41 编辑
MeowSnow 发表于 2016-6-9 00:48
_(:з」∠)_啊喏,虽然像素移动的效果很棒,但是火车队列变成了扭曲的效果呢……还有行走图上出现了不明的 ...


又不是只有弹幕游戏才用得着碰撞面具...
其实弹幕游戏我也用MV做过,和undertale类似

f.gif (1.34 MB, 下载次数: 28)

f.gif

g.gif (257.46 KB, 下载次数: 23)

g.gif

作者: tseyik    时间: 2016-6-9 12:24
射撃挿件
http://hikimoki.sakura.ne.jp/plugin/plugin_system.html#TMShooting
射撃範本
https://yunpan.cn/cRVcshpCNcQ74  访问密码 e802
作者: 547895913    时间: 2016-6-27 17:22
请问一下 我读取存档的时候出错了 把像素移动脚本关掉就没事了 我在游戏里存档再读档是没事 但是重新打开游戏读取后 刚走一步就出错了
作者: 汪汪    时间: 2016-6-27 21:05
感觉会有很好的效果
作者: chenyilindzh    时间: 2016-8-1 20:35
还不错~不过,走一格所需要的步数是4步····所以其实是把基础移动大小变成了原来的1/16么··还没仔细看过脚本··
作者: lirn    时间: 2016-8-2 22:03
似乎很有用,先MARK,看看以后是不是有需要
作者: 鼠尾草    时间: 2016-8-11 11:17
大大我有两个问题想问下,首先这代码是用在哪的……萌新看着一脸懵逼,第二个问题是这个像素移动是4方向的还是8方向的?
作者: Zeldashu    时间: 2020-3-13 13:43
貌似最新版MV使用这个插件会直接卡死?




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1