查看: 8655|回复: 17

[原创发布] 像素移动

[复制链接]
梦石
0
星屑
50
在线时间
46 小时
注册时间
2014-3-14
回帖
32
发表于 2016-6-7 17:25:25 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 moe2333 于 2016-6-7 17:35 编辑

暂时不支持座驾。
[pre lang="javascript" line="1" file="PixelMovement.js"]//=============================================================================
// PixelMovement.js
//=============================================================================

/*:
* @plugindesc Like you don't know what this does.
*/

(function () {
    //-----------------------------------------------------------------------------

    // An even number between 2 and 48, inclusive
    var tileSection = 4;
    // Gives you precise collision mask but can significantly compromise the performance
    var analyzeTilesetBitmap = true;
    // A section of the bitmap will be masked impassable if the valid pixel rate reaches this threshold
    var bitmapAnalysisThreshold = 0.5;
    // (x, y, width, height)
    var characterCollisionBox = new Rectangle(1, 2, 2, 2);
    // Tiles with this terrain tag are forced to be passable
    var forcePassableTerrainTag = 3;
    // Max distance between two followers
    var followerDistance = 1;
    // For debugging
    var drawCollisionMask = true;
    // [map, ladder, bush, counter, damageFloor, boat, ship], for debugging
    var collisionMaskLayerColors = ['red', 'grey', 'green', 'yellow', 'crimson', 'lightBlue', 'blue'];

    //-----------------------------------------------------------------------------
    var toPixel = function (t) {
        return t * tileSection;
    };

    var toTile = function (p) {
        return p / tileSection;
    };

    //-----------------------------------------------------------------------------
    // Table2

    function Table2(xSize, ySize) {
        this.initialize.apply(this, arguments);
    }

    Table2.prototype.initialize = function (xSize, ySize) {
        this.xSize = xSize;
        this.ySize = ySize;
        this.data = [];
    };

    Table2.prototype.get = function (x, y) {
        return this.data[y * this.xSize + x];
    };

    Table2.prototype.set = function (x, y, data) {
        this.data[y * this.xSize + x] = data;
    };

    //-----------------------------------------------------------------------------
    // Table3

    function Table3() {
        this.initialize.apply(this, arguments);
    }

    Table3.prototype.initialize = function (xSize, ySize, zSize) {
        this.xSize = xSize;
        this.ySize = ySize;
        this.zSize = zSize;
        this.data = [];
    };

    Table3.prototype.get = function (x, y, z) {
        return this.data[z * this.ySize * this.xSize + y * this.xSize + x];
    };

    Table3.prototype.set = function (x, y, z, data) {
        return this.data[z * this.ySize * this.xSize + y * this.xSize + x] = data;
    };

    //-----------------------------------------------------------------------------
    // Bitmap

    Bitmap.prototype.isOccupied = function (x, y, w, h, threshold) {
        var data = this._context.getImageData(x, y, w, h).data;
        var occupied = 0;
        for (var i = 3; i < data.length; i += 4) {
            if (data === 255) {
                occupied++;
            }
        }
        return (occupied / (data.length / 4)) > threshold;
    };

    //-----------------------------------------------------------------------------
    // Tilemap

    var aliasTilemapPrototypeUpdate = Tilemap.prototype.update;
    Tilemap.prototype.update = function () {
        aliasTilemapPrototypeUpdate.apply(this, arguments);
        if (this._needRefreshCollisionMask && this.isReady()) {
            this._needRefreshCollisionMask = false;
            this.refreshCollisionMask();
        }
    };

    var aliasTilemapPrototypeRefresh = Tilemap.prototype.refresh;
    Tilemap.prototype.refresh = function () {
        aliasTilemapPrototypeRefresh.apply(this, arguments);
        this._needRefreshCollisionMask = true;
    };

    Tilemap.prototype.refreshCollisionMask = function () {
        console.time('Collision Mask Generation');
        $gameMap.collisionMask = new Table3($gameMap.widthPx(), $gameMap.heightPx(), 8);
        this._tileCollisionMaskCaches = {};
        for (var tx = 0; tx < this._mapWidth; tx++) {
            for (var ty = 0; ty < this._mapHeight; ty++) {
                this.drawTileCollisionMask(tx, ty);
            }
        }
        this._tileCollisionMaskCaches = null;
        console.timeEnd('Collision Mask Generation');
        if (drawCollisionMask) {
            this.debugDrawCollisionMask();
        }
    };

    Tilemap.prototype.drawTileCollisionMask = function (tx, ty) {
        var forcePassable = $gameMap.terrainTag(tx, ty) === forcePassableTerrainTag;

        var mcm = $gameMap.collisionMask;

        var flags = this.flags;
        var tileIds = $gameMap.layeredTiles(tx, ty);

        var impassableSections = [];
        var totalSections = tileSection * tileSection;

        for (var tileId, flag, i = 0; i < tileIds.length; i++) {
            tileId = tileIds;

            if (!Tilemap.isVisibleTile(tileId)) {
                continue;
            }

            var tcm = this._tileCollisionMaskCaches[tileId];
            if (tcm) {
                if (!forcePassable) {
                    for (var sx = 0; sx < tileSection; sx++) {
                        for (var sy = 0; sy < tileSection; sy++) {
                            for (var z = 0; z < 8; z++) {
                                var bit = tcm.get(sx, sy, z);
                                if (bit === 1) {
                                    mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, z, bit);
                                    if (z === 0) { // tile collision layer
                                        var sectionId = sy * tileSection + sx;
                                        if (!impassableSections.contains(sectionId)) {
                                            impassableSections.push(sectionId);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (impassableSections.length >= totalSections) {
                        break;
                    } else {
                        continue;
                    }
                }
            } else {
                tcm = new Table3(tileSection, tileSection, 8);
                this._tileCollisionMaskCaches[tileId] = tcm;
            }

            flag = flags[tileId];

            // other layers of the collision mask
            for (var bp = 5; bp < 9; bp++) { // ladder, bush, counter, damageFloor
                if ((flag & (1 << bp)) !== 0) {
                    for (var sx = 0; sx < tileSection; sx++) {
                        for (var sy = 0; sy < tileSection; sy++) {
                            var z = bp - 4;
                            mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, z, 1);
                            tcm.set(sx, sy, z, 1);
                        }
                    }
                }
            }
            if (!forcePassable) {
                for (var bp = 9; bp < 12; bp++) { // boat, ship, airship
                    if ((flag & (1 << bp)) === 0) {
                        for (var sx = 0; sx < tileSection; sx++) {
                            for (var sy = 0; sy < tileSection; sy++) {
                                var z = bp - 4;
                                mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, z, 1);
                                tcm.set(sx, sy, z, 1);
                            }
                        }
                    }
                }
            }

            if (forcePassable) {
                break;
            }

            // 0th layer of the collision mask
            if ((flag & 0xf) === 0xf) { // all dirs are not passable
                if (analyzeTilesetBitmap) {
                    if (Tilemap.isAutotile(tileId)) { // TODO: need to check the collision masks for autotiles too
                        for (var sx = 0; sx < tileSection; sx++) {
                            for (var sy = 0; sy < tileSection; sy++) {
                                mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, 0, 1);
                                tcm.set(sx, sy, 0, 1);
                            }
                        }
                        break;
                    } else {
                        var bitmap = this.bitmaps[Tilemap.isTileA5(tileId) ? 4 : 5 + Math.floor(tileId / 256)];
                        var tw = this._tileWidth;
                        var th = this._tileHeight;
                        var sw = $gameMap.tileWidthPx();
                        var sh = $gameMap.tileHeightPx();
                        var bx = (Math.floor(tileId / 128) % 2 * 8 + tileId % 8) * tw;
                        var by = (Math.floor(tileId % 256 / 8) % 16) * th;
                        for (var sx = 0; sx < tileSection; sx++) {
                            for (var sy = 0; sy < tileSection; sy++) {
                                if (bitmap.isOccupied(bx + sx * sw, by + sy * sh, sw, sh, bitmapAnalysisThreshold)) {
                                    mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, 0, 1);
                                    tcm.set(sx, sy, 0, 1);
                                    var sectionId = sy * tileSection + sx;
                                    if (!impassableSections.contains(sectionId)) {
                                        impassableSections.push(sectionId);
                                    }
                                }
                            }
                        }
                        if (impassableSections.length >= totalSections) {
                            break;
                        }
                    }
                } else {
                    for (var sx = 0; sx < tileSection; sx++) {
                        for (var sy = 0; sy < tileSection; sy++) {
                            mcm.set(toPixel(tx) + sx, toPixel(ty) + sy, 0, 1);
                            tcm.set(sx, sy, 0, 1);
                        }
                    }
                    break;
                }
            } else if ((flag & 0xf) !== 0) { // some dirs are passable, but not all
                for (var bp = 0; bp < 4; bp++) {
                    if ((flag & (1 << bp)) !== 0) {
                        switch (bp) {
                            case 0: // down
                                for (var sx = 0; sx < tileSection; sx++) {
                                    mcm.set(toPixel(tx) + sx, toPixel(ty) + tileSection - 1, 0, 1);
                                    tcm.set(sx, tileSection - 1, 0, 1)
                                }
                                break;
                            case 1: // left
                                for (var sy = 0; sy < tileSection; sy++) {
                                    mcm.set(toPixel(tx), toPixel(ty) + sy, 0, 1);
                                    tcm.set(0, sy, 0, 1)
                                }
                                break;
                            case 2: // right
                                for (var sy = 0; sy < tileSection; sy++) {
                                    mcm.set(toPixel(tx) + tileSection - 1, toPixel(ty) + sy, 0, 1);
                                    tcm.set(tileSection - 1, sy, 0, 1)
                                }
                                break;
                            case 3: // up
                                for (var sx = 0; sx < tileSection; sx++) {
                                    mcm.set(toPixel(tx) + sx, toPixel(ty), 0, 1);
                                    tcm.set(sx, 0, 0, 1)
                                }
                                break;
                        }
                    }
                }
            }
        }
    };

    Tilemap.prototype.debugDrawCollisionMask = function () {
        var cm = $gameMap.collisionMask;
        var sw = $gameMap.tileWidthPx();
        var sh = $gameMap.tileHeightPx();
        for (var layerIndex = 0; layerIndex < 7; layerIndex++) {
            var sprite = new Sprite(new Bitmap(this._mapWidth * this._tileWidth, this._mapHeight * this._tileHeight));
            sprite.pivot = this.origin;
            sprite.opacity = 80;
            for (var px = 0; px < cm.xSize; px++) {
                for (var py = 0; py < cm.ySize; py++) {
                    if (cm.get(px, py, layerIndex) === 1) {
                        sprite.bitmap.fillRect(px * sw, py * sh, sw, sh, collisionMaskLayerColors[layerIndex]);
                    }
                }
            }
            this.parent.addChild(sprite);
        }
    };

    //------------------------------------------------------------
    // Game_Temp

    var aliasGameTempPrototypeInitialize = Game_Temp.prototype.initialize;
    Game_Temp.prototype.initialize = function () {
        aliasGameTempPrototypeInitialize.apply(this, arguments);
        this._destinationPx = null;
        this._destinationPy = null;
        this._route = null;
    };

    Game_Temp.prototype.isDestinationValid = function () {
        return this._route && this._route.length > 0;
    };

    Game_Temp.prototype.setDestination = function (px, py) {
        if (!this._route || px !== this._destinationPx || py !== this._destinationPy) {
            this._destinationPx = px;
            this._destinationPy = py;
            this._route = $gamePlayer.findRouteTo(px, py);
        }
    };

    Game_Temp.prototype.clearDestination = function () {
        this._destinationPx = null;
        this._destinationPy = null;
        this._route = null;
    };

    Game_Temp.prototype.destinationPx = function () {
        return this._destinationPx;
    };

    Game_Temp.prototype.destinationPy = function () {
        return this._destinationPy;
    };

    Game_Temp.prototype.nextDirection = function () {
        return this._route ? this._route.pop() : 0;
    };

    //------------------------------------------------------------
    // Game_Actor
   
    /* TODO: Only damage characters that are on the damage floor
    Game_Actor.prototype.checkFloorEffect = function () {
        if ($gamePlayer.isOnDamageFloor()) {
            this.executeFloorDamage();
        }
    };
    */

    //------------------------------------------------------------
    // Game_Map

    Object.defineProperty(Game_Map.prototype, 'collisionMask', {
        get: function () {
            return this._collisionMask;
        },
        set: function (value) {
            this._collisionMask = value;
        },
        configurable: true
    });

    Game_Map.prototype.isCollisionMaskSet = function () {
        return this._collisionMask !== null;
    };

    var aliasGameMapPrototypeInitialize = Game_Map.prototype.initialize;
    Game_Map.prototype.initialize = function () {
        aliasGameMapPrototypeInitialize.apply(this, arguments);
        this._collisionMask = null;
    };

    Game_Map.prototype.tileWidthPx = function () {
        return this.tileWidth() / tileSection;
    };

    Game_Map.prototype.tileHeightPx = function () {
        return this.tileHeight() / tileSection;
    };

    Game_Map.prototype.widthPx = function () {
        return $dataMap.width * tileSection;
    };

    Game_Map.prototype.heightPx = function () {
        return $dataMap.height * tileSection;
    };

    Game_Map.prototype.adjustPx = function (px) {
        return toPixel(this.adjustX(toTile(px)));
    };

    Game_Map.prototype.adjustPy = function (py) {
        return toPixel(this.adjustY(toTile(py)));
    };

    Game_Map.prototype.roundPx = function (px) {
        return this.isLoopHorizontal() ? px.mod(this.widthPx()) : px;
    };

    Game_Map.prototype.roundPy = function (py) {
        return this.isLoopVertical() ? py.mod(this.heightPx()) : py;
    };

    Game_Map.prototype.pxWithDirection = function (px, d) {
        return px + (d === 6 ? 1 : d === 4 ? -1 : 0);
    };

    Game_Map.prototype.pyWithDirection = function (py, d) {
        return py + (d === 2 ? 1 : d === 8 ? -1 : 0);
    };

    Game_Map.prototype.roundPxWithDirection = function (px, d) {
        return this.roundPx(px + (d === 6 ? 1 : d === 4 ? -1 : 0));
    };

    Game_Map.prototype.roundPyWithDirection = function (py, d) {
        return this.roundPy(py + (d === 2 ? 1 : d === 8 ? -1 : 0));
    };

    Game_Map.prototype.deltaPx = function (px1, px2) {
        var result = px1 - px2;
        if (this.isLoopHorizontal() && Math.abs(result) > this.widthPx() / 2) {
            result += result < 0 ? this.widthPx() : -this.widthPx();
        }
        return result;
    };

    Game_Map.prototype.deltaPy = function (py1, py2) {
        var result = py1 - py2;
        if (this.isLoopVertical() && Math.abs(result) > this.heightPx() / 2) {
            result += result < 0 ? this.heightPx() : -this.heightPx();
        }
        return result;
    };

    Game_Map.prototype.distancePx = function (px1, py1, px2, py2) {
        return Math.abs(this.deltaPx(px1, px2)) + Math.abs(this.deltaPy(py1, py2));
    };

    Game_Map.prototype.canvasToMapPx = function (x) {
        return this.roundPx(Math.round((this._displayX * this.tileWidth() + x) / $gameMap.tileWidthPx()));
    };

    Game_Map.prototype.canvasToMapPy = function (y) {
        return this.roundPy(Math.round((this._displayY * this.tileHeight() + y) / $gameMap.tileHeightPx()));
    };

    Game_Map.prototype.collidedEventsPx = function (px, py, cm) {
        return this.events().filter(function (event) {
            return $gameMap.areTwoCollisionMasksCollided(px, py, cm, event.px, event.py, event.collisionMask);
        });
    };

    Game_Map.prototype.areTwoCollisionMasksCollided = function (px1, py1, cm1, px2, py2, cm2) {
        var xs1 = cm1.xSize;
        var ys1 = cm1.ySize;
        var xs2 = cm2.xSize;
        var ys2 = cm2.ySize;
        var spx1 = px1 - xs1 / 2;
        var spy1 = py1 - ys1;
        var spx2 = px2 - xs2 / 2;
        var spy2 = py2 - ys2;
        if (spx1 > spx2 + xs2 || spx1 + xs1 < spx2 || spy1 > spy2 + ys2 || spy1 + ys1 < spy2) {
            return false;
        }
        var mpw = this.widthPx();
        var poses1 = [];
        var poses2 = [];
        for (var cmx1 = 0; cmx1 < xs1; cmx1++) {
            for (var cmy1 = 0; cmy1 < ys1; cmy1++) {
                cm1.get(cmx1, cmy1) && poses1.push(this.roundPy(spy1 + cmy1) * mpw + this.roundPx(spx1 + cmx1));
            }
        }
        for (var cmx2 = 0; cmx2 < xs2; cmx2++) {
            for (var cmy2 = 0; cmy2 < ys2; cmy2++) {
                cm2.get(cmx2, cmy2) && poses2.push(this.roundPy(spy2 + cmy2) * mpw + this.roundPx(spx2 + cmx2));
            }
        }
        for (var i = 0; i < poses1.length; i++) {
            for (var j = 0; j < poses2.length; j++) {
                if (poses1 === poses2[j]) {
                    return true;
                }
            }
        }
        return false;
    };

    Game_Map.prototype.isValidPx = function (px, py) {
        return px > -1 && px < this.widthPx() && py > -1 && py < this.heightPx();
    };

    Game_Map.prototype.isPassablePx = function (px, py) {
        return !this._collisionMask.get(px, py, 0);
    };

    Game_Map.prototype.isPassableWithCollisionMask = function (px, py, cm) {
        var spx = px - cm.xSize / 2;
        var spy = py - cm.ySize;
        for (var cmx = 0; cmx < cm.xSize; cmx++) {
            for (var cmy = 0; cmy < cm.ySize; cmy++) {
                if (cm.get(cmx, cmy)) {
                    var apx = this.roundPx(spx + cmx);
                    var apy = this.roundPy(spy + cmy);
                    if (!this.isValidPx(apx, apy) || !this.isPassablePx(apx, apy)) {
                        return false;
                    }
                }
            }
        }
        return true;
    };

    Game_Map.prototype.isBoatPassablePx = function (px, py) {
        return false;
    };

    Game_Map.prototype.isShipPassablePx = function (px, py) {
        return false;
    };

    Game_Map.prototype.isAirshipLandOkPx = function (px, py) {
        return false;
    };

    Game_Map.prototype.isLadderPx = function (px, py) {
        if (!this.isCollisionMaskSet()) {
            return false;
        }
        return this.isValidPx(px, py) && this._collisionMask.get(px, py, 1);
    };

    Game_Map.prototype.isBushPx = function (px, py) {
        if (!this.isCollisionMaskSet()) {
            return false;
        }
        return this.isValidPx(px, py) && this._collisionMask.get(px, py, 2);
    };

    Game_Map.prototype.isCounterPx = function (px, py) {
        if (!this.isCollisionMaskSet()) {
            return false;
        }
        return this.isValidPx(px, py) && this._collisionMask.get(px, py, 3);
    };

    Game_Map.prototype.isDamageFloorPx = function (px, py) {
        if (!this.isCollisionMaskSet()) {
            return false;
        }
        return this.isValidPx(px, py) && this._collisionMask.get(px, py, 4);
    };

    //------------------------------------------------------------
    // Game_CharacterBase

    Object.defineProperty(Game_CharacterBase.prototype, 'collisionMask', {
        get: function () {
            return this._collisionMask
        },
        set: function (value) {
            this._collisionMask = value
        },
        configurable: true
    });

    Object.defineProperty(Game_CharacterBase.prototype, 'px', {
        get: function () {
            return this._px
        },
        configurable: true
    });

    Object.defineProperty(Game_CharacterBase.prototype, 'py', {
        get: function () {
            return this._py
        },
        configurable: true
    });

    var aliasGameCharacterBasePrototypeInitMembers = Game_CharacterBase.prototype.initMembers;
    Game_CharacterBase.prototype.initMembers = function () {
        aliasGameCharacterBasePrototypeInitMembers.apply(this, arguments);
        this._px = 0;
        this._py = 0;
        this._realPx = 0;
        this._realPy = 0;
        this.createCollisionMask();
    };

    Game_CharacterBase.prototype.createCollisionMask = function () { // TODO: Support bitmap analysis and custom collision box
        this._collisionMask = new Table2(tileSection, tileSection);
        var box = characterCollisionBox;
        for (var x = box.x; x < box.x + box.width; x++) {
            for (var y = box.y; y < box.y + box.height; y++) {
                this._collisionMask.set(x, y, 1);
            }
        }
    };

    Game_CharacterBase.prototype.synchronizeTileCoordinate = function () {
        this._realX = toTile(this._realPx);
        this._realY = toTile(this._realPy);
        this._x = Math.floor(this._realX);
        this._y = Math.floor(this._realY);
    };

    Game_CharacterBase.prototype.isMoving = function () {
        return this._realPx !== this._px || this._realPy !== this._py;
    };

    Game_CharacterBase.prototype.canPassPx = function (px, py, d) {
        var npx = $gameMap.roundPxWithDirection(px, d);
        var npy = $gameMap.roundPyWithDirection(py, d);
        if (this.isThrough() || this.isDebugThrough()) {
            return true;
        }
        if (!this.isMapPassablePx(px, py, d)) {
            return false;
        }
        if (this.isCollidedWithCharactersPx(npx, npy)) {
            return false;
        }
        return true;
    };

    Game_CharacterBase.prototype.canPassDiagonallyPx = function (px, py, horz, vert) {
        var npx = $gameMap.roundPxWithDirection(px, horz);
        var npy = $gameMap.roundPyWithDirection(py, vert);
        if (this.canPassPx(px, py, vert) && this.canPassPx(px, npy, horz)) {
            return true;
        }
        if (this.canPassPx(px, py, horz) && this.canPassPx(npx, py, vert)) {
            return true;
        }
        return false;
    };

    Game_CharacterBase.prototype.isMapPassablePx = function (px, py, d) {
        /*
         var px2 = $gameMap.roundPxWithDirection(px, d);
         var py2 = $gameMap.roundPyWithDirection(py, d);
         return $gameMap.isPassableWithCollisionMask(px, py, this._collisionMask) && $gameMap.isPassableWithCollisionMask(px2, py2, this._collisionMask);
         */
        return $gameMap.isPassableWithCollisionMask($gameMap.roundPxWithDirection(px, d), $gameMap.roundPyWithDirection(py, d), this._collisionMask);
    };

    Game_CharacterBase.prototype.isCollidedWithCharactersPx = function (px, py) {
        return this.isCollidedWithEventsPx(px, py) || this.isCollidedWithVehiclesPx(px, py);
    };

    Game_CharacterBase.prototype.isCollidedWithEventsPx = function (px, py) {
        var events = $gameMap.events();
        var cm = this._collisionMask;
        var self = this;
        return events.some(function (event) {
            return event !== self && !event.isThrough() && event.isNormalPriority() && $gameMap.areTwoCollisionMasksCollided(px, py, cm, event.px, event.py, event.collisionMask);
        });
    };

    Game_CharacterBase.prototype.isCollidedWithVehiclesPx = function (px, py) {
        return false;
    };

    Game_CharacterBase.prototype.setPosition = function (tx, ty) {
        this.setPositionPx(toPixel(tx) + tileSection / 2, toPixel(ty) + tileSection);
    };
    Game_CharacterBase.prototype.setPositionPx = function (px, py) {
        this._px = Math.round(px);
        this._py = Math.round(py);
        this._realPx = px;
        this._realPy = py;
        this.synchronizeTileCoordinate();
    };

    Game_CharacterBase.prototype.copyPosition = function (character) {
        this._direction = character._direction;
        this._px = character._px;
        this._py = character._py;
        this._realPx = character._realPx;
        this._realPy = character._realPy;
        this.synchronizeTileCoordinate();
    };

    Game_CharacterBase.prototype.locate = function (tx, ty) {
        this.locatePx(toPixel(tx) + tileSection / 2, toPixel(ty) + tileSection);
    };
    Game_CharacterBase.prototype.locatePx = function (px, py) {
        this.setPositionPx(px, py);
        this.straighten();
        this.refreshBushDepth();
    };

    Game_CharacterBase.prototype.screenX = function () {
        return Math.round(toPixel(this.scrolledX()) * $gameMap.tileWidthPx());
    };

    Game_CharacterBase.prototype.screenY = function () {
        return Math.round(toPixel(this.scrolledY()) * $gameMap.tileHeightPx() - this.shiftY() - this.jumpHeight());
    };

    Game_CharacterBase.prototype.update = function() {
        this.updateAnimation();
        if (this.isStopping()) {
            this.updateStop();
        }
        if (this.isJumping()) {
            this.updateJump();
        } else if (this.isMoving()) {
            this.updateMove();
        }
    };

    Game_CharacterBase.prototype.updateJump = function () {
        this._jumpCount--;
        this._realPx = (this._realPx * this._jumpCount + this._px) / (this._jumpCount + 1.0);
        this._realPy = (this._realPy * this._jumpCount + this._py) / (this._jumpCount + 1.0);
        this.refreshBushDepth();
        if (this._jumpCount === 0) {
            this._realPx = this._px = $gameMap.roundPx(this._px);
            this._realPy = this._py = $gameMap.roundPy(this._py);
        }
        this.synchronizeTileCoordinate();
    };

    Game_CharacterBase.prototype.updateMove = function () {
        var dpf = toPixel(this.distancePerFrame());
        if (this._px < this._realPx) {
            this._realPx = Math.max(this._realPx - dpf, this._px);
        }
        if (this._px > this._realPx) {
            this._realPx = Math.min(this._realPx + dpf, this._px);
        }
        if (this._py < this._realPy) {
            this._realPy = Math.max(this._realPy - dpf, this._py);
        }
        if (this._py > this._realPy) {
            this._realPy = Math.min(this._realPy + dpf, this._py);
        }
        this.synchronizeTileCoordinate();
        if (!this.isMoving()) {
            this.refreshBushDepth();
        }
    };

    Game_CharacterBase.prototype.isOnLadder = function () {
        var cm = this._collisionMask;
        var xs = cm.xSize;
        var ys = cm.ySize;
        var spx = this._px - xs / 2;
        var spy = this._py - ys;
        for (var cmx = 0; cmx < xs; cmx++) {
            for (var cmy = 0; cmy < ys; cmy++) {
                if ($gameMap.isLadderPx(spx + cmx, spy + cmy)) {
                    return true;
                }
            }
        }
        return false;
    };

    Game_CharacterBase.prototype.isOnBush = function () {
        var cm = this._collisionMask;
        var xs = cm.xSize;
        var ys = cm.ySize;
        var spx = this._px - xs / 2;
        var spy = this._py - ys;
        for (var cmx = 0; cmx < xs; cmx++) {
            for (var cmy = 0; cmy < ys; cmy++) {
                if (!$gameMap.isBushPx(spx + cmx, spy + cmy)) {
                    return false;
                }
            }
        }
        return true;
    };

    Game_CharacterBase.prototype.isOnDamageFloor = function () {
        var cm = this._collisionMask;
        var xs = cm.xSize;
        var ys = cm.ySize;
        var spx = this._px - xs / 2;
        var spy = this._py - ys;
        for (var cmx = 0; cmx < xs; cmx++) {
            for (var cmy = 0; cmy < ys; cmy++) {
                if ($gameMap.isDamageFloorPx(spx + cmx, spy + cmy)) {
                    return true;
                }
            }
        }
        return false;
    };

    Game_CharacterBase.prototype.isFacingCounter = function () {
        var cm = this._collisionMask;
        var direction = this.direction();
        var npx = $gameMap.roundPxWithDirection(this._px, direction);
        var npy = $gameMap.roundPyWithDirection(this._py, direction);
        var xs = cm.xSize;
        var ys = cm.ySize;
        var spx = npx - xs / 2;
        var spy = npy - ys;
        for (var cmx = 0; cmx < xs; cmx++) {
            for (var cmy = 0; cmy < ys; cmy++) {
                if ($gameMap.isCounterPx(spx + cmx, spy + cmy)) {
                    return true;
                }
            }
        }
        return false;
    };

    Game_CharacterBase.prototype.checkEventTriggerTouchFrontPx = function (d) {
        this.checkEventTriggerTouchPx($gameMap.roundPxWithDirection(this._px, d), $gameMap.roundPyWithDirection(this._py, d));
    };

    Game_CharacterBase.prototype.checkEventTriggerTouchPx = function (px, py) {
        return false;
    };

    Game_CharacterBase.prototype.moveStraight = function (d) {
        this.setMovementSuccess(this.canPassPx(this._px, this._py, d));
        if (this.isMovementSucceeded()) {
            this.setDirection(d);
            this._px = $gameMap.roundPxWithDirection(this._px, d);
            this._py = $gameMap.roundPyWithDirection(this._py, d);
            this._realPx = $gameMap.pxWithDirection(this._px, this.reverseDir(d));
            this._realPy = $gameMap.pyWithDirection(this._py, this.reverseDir(d));
            this.increaseSteps();
        } else {
            this.setDirection(d);
            this.checkEventTriggerTouchFrontPx(d);
        }
    };

    Game_CharacterBase.prototype.moveDiagonally = function (horz, vert) {
        this.setMovementSuccess(this.canPassDiagonallyPx(this._px, this._py, horz, vert));
        if (this.isMovementSucceeded()) {
            this._px = $gameMap.roundPxWithDirection(this._px, horz);
            this._py = $gameMap.roundPyWithDirection(this._py, vert);
            this._realPx = $gameMap.pxWithDirection(this._px, this.reverseDir(horz));
            this._realPy = $gameMap.pyWithDirection(this._py, this.reverseDir(vert));
            this.increaseSteps();
        }
        if (this._direction === this.reverseDir(horz)) this.setDirection(horz);
        if (this._direction === this.reverseDir(vert)) this.setDirection(vert);
    };

    Game_CharacterBase.prototype.moveDir8 = function (d) {
        switch (d) {
            case 2:
            case 4:
            case 6:
            case 8:
                this.moveStraight(d);
                break;
            case 1:
                this.moveDiagonally(4, 2);
                break;
            case 3:
                this.moveDiagonally(6, 2);
                break;
            case 7:
                this.moveDiagonally(4, 8);
                break;
            case 9:
                this.moveDiagonally(6, 8);
                break;
        }
    };

    Game_CharacterBase.prototype.jump = function (xPlus, yPlus) {
        if (Math.abs(xPlus) > Math.abs(yPlus)) {
            if (xPlus !== 0) {
                this.setDirection(xPlus < 0 ? 4 : 6);
            }
        } else {
            if (yPlus !== 0) {
                this.setDirection(yPlus < 0 ? 8 : 2);
            }
        }
        this._px += toPixel(xPlus);
        this._py += toPixel(yPlus);
        var distance = Math.round(Math.sqrt(xPlus * xPlus + yPlus * yPlus));
        this._jumpPeak = 10 + distance - this._moveSpeed;
        this._jumpCount = this._jumpPeak * 2;
        this.resetStopCount();
        this.straighten();
    };

    //------------------------------------------------------------
    // Game_Character
    Game_Character.prototype.deltaPxFrom = function (px) {
        return $gameMap.deltaPx(this._px, px);
    };

    Game_Character.prototype.deltaPyFrom = function (py) {
        return $gameMap.deltaPy(this._py, py);
    };

    Game_Character.prototype.moveRandom = function () {
        var d = 2 + Math.randomInt(4) * 2;
        if (this.canPassPx(this.px, this.py, d)) {
            this.moveStraight(d);
        }
    };

    Game_Character.prototype.moveTowardCharacter = function (character) {
        var dpx = this.deltaPxFrom(character.px);
        var dpy = this.deltaPyFrom(character.py);
        if (Math.abs(dpx) > Math.abs(dpy)) {
            this.moveStraight(dpx > 0 ? 4 : 6);
            if (!this.isMovementSucceeded() && dpy !== 0) {
                this.moveStraight(dpy > 0 ? 8 : 2);
            }
        } else if (dpy !== 0) {
            this.moveStraight(dpy > 0 ? 8 : 2);
            if (!this.isMovementSucceeded() && dpx !== 0) {
                this.moveStraight(dpx > 0 ? 4 : 6);
            }
        }
    };

    Game_Character.prototype.moveAwayFromCharacter = function (character) {
        var dpx = this.deltaPxFrom(character.px);
        var dpy = this.deltaPyFrom(character.py);
        if (Math.abs(dpx) > Math.abs(dpy)) {
            this.moveStraight(dpx > 0 ? 6 : 4);
            if (!this.isMovementSucceeded() && dpy !== 0) {
                this.moveStraight(dpy > 0 ? 2 : 8);
            }
        } else if (dpy !== 0) {
            this.moveStraight(dpy > 0 ? 2 : 8);
            if (!this.isMovementSucceeded() && dpx !== 0) {
                this.moveStraight(dpx > 0 ? 6 : 4);
            }
        }
    };

    Game_Character.prototype.turnTowardCharacter = function (character) {
        var dpx = this.deltaPxFrom(character.px);
        var dpy = this.deltaPyFrom(character.py);
        if (Math.abs(dpx) > Math.abs(dpy)) {
            this.setDirection(dpx > 0 ? 4 : 6);
        } else if (dpy !== 0) {
            this.setDirection(dpy > 0 ? 8 : 2);
        }
    };

    Game_Character.prototype.turnAwayFromCharacter = function (character) {
        var dpx = this.deltaPxFrom(character.px);
        var dpy = this.deltaPyFrom(character.py);
        if (Math.abs(dpx) > Math.abs(dpy)) {
            this.setDirection(dpx > 0 ? 6 : 4);
        } else if (dpy !== 0) {
            this.setDirection(dpy > 0 ? 2 : 8);
        }
    };

    Game_Character.prototype.findRouteTo = function (goalPx, goalPy) {
        var searchLimit = toPixel(Math.max($gameMap.screenTileX(), $gameMap.screenTileY()));

        var px = this._px;
        var py = this._py;

        if (px === goalPx && py === goalPy) {
            return [];
        }

        var makeNode = function (parent, px, py, gScore, fScore, direction) {
            return {
                parent: parent,
                px: px,
                py: py,
                gScore: gScore,
                fScore: fScore,
                direction: direction
            };
        };
        var makeId = function (px, py) {
            return py * $gameMap.widthPx() + px;
        };
        var estimateCost = function (px1, py1, px2, py2) {
            return $gameMap.distancePx(px1, py1, px2, py2);
        };

        var reconstructPath = function (node) {
            var current = node;
            var path = [current.direction];
            while (current.parent !== start) {
                current = current.parent;
                path.push(current.direction);
            }
            return path;
        };

        var start = makeNode(null, px, py, 0, estimateCost(px, py, goalPx, goalPy), 0);

        var openSet = [start];
        var closedSet = [];

        var reserveSet = []; // used when failed

        while (openSet.length > 0) {
            var current = openSet[0];
            var currentIndex = 0;

            for (var i = 1; i < openSet.length; i++) {
                if (openSet.fScore < current.fScore) {
                    current = openSet;
                    currentIndex = i;
                }
            }

            if (current.px === goalPx && current.py === goalPy) {
                return reconstructPath(current);
            }

            openSet.splice(currentIndex, 1);
            closedSet.push(makeId(current.px, current.py));

            reserveSet.push(current);

            if (current.gScore > searchLimit) {
                continue;
            }

            for (var direction = 2; direction <= 8; direction += 2) {
                var npx = $gameMap.roundPxWithDirection(current.px, direction);
                var npy = $gameMap.roundPyWithDirection(current.py, direction);

                if (closedSet.indexOf(makeId(npx, npy)) > -1) {
                    continue;
                }

                if (!this.canPassPx(current.px, current.py, direction)) {
                    closedSet.push(makeId(npx, npy));
                    continue;
                }

                var tentativeGScore = current.gScore + 1;

                var nodeFound = null;
                for (var i = 0; i < openSet.length; i++) {
                    var node = openSet;
                    if (node.px === npx && node.py === npy) {
                        nodeFound = node;
                    }
                }

                if (!nodeFound || tentativeGScore < nodeFound.gScore) {
                    var neighbor;
                    if (!nodeFound) {
                        neighbor = {
                            px: npx,
                            py: npy
                        };
                        openSet.push(neighbor);
                    } else {
                        neighbor = nodeFound;
                    }

                    neighbor.parent = current;
                    neighbor.gScore = tentativeGScore;
                    neighbor.fScore = tentativeGScore + estimateCost(npx, npy, goalPx, goalPy);
                    neighbor.direction = direction;
                }
            }
        }

        // when failed
        var closest = reserveSet[0];
        for (var i = 1; i < reserveSet.length; i++) {
            var current = reserveSet;
            if (current.fScore - current.gScore < closest.fScore - closest.gScore) {
                closest = current;
            }
        }

        var goalDirection;
        var dpx = $gameMap.deltaPx(closest.px, goalPx);
        var dpy = $gameMap.deltaPy(closest.py, goalPy);
        if (Math.abs(dpx) > Math.abs(dpy)) {
            goalDirection = dpx > 0 ? 4 : 6;
        } else if (dpy !== 0) {
            goalDirection = dpy > 0 ? 8 : 2;
        }

        if (closest === start) {
            return [goalDirection];
        } else {
            var path = reconstructPath(closest);
            path.unshift(goalDirection);
            return path;
        }
    };

    //------------------------------------------------------------
    // Game_Player

    Game_Player.prototype.moveByInput = function () {
        if (!this.isMoving() && this.canMove()) {
            var direction = this.getInputDirection();
            if (direction > 0) {
                $gameTemp.clearDestination();
            } else if ($gameTemp.isDestinationValid()) {
                direction = $gameTemp.nextDirection();
            }
            if (direction > 0) {
                this.executeMove(direction);
                if (!this.isMovementSucceeded()) {
                    switch (direction) {
                        case 2:
                            this.executeMove(1);
                            if (!this.isMovementSucceeded()) {
                                this.executeMove(3)
                            }
                            break;
                        case 4:
                            this.executeMove(1);
                            if (!this.isMovementSucceeded()) {
                                this.executeMove(7)
                            }
                            break;
                        case 6:
                            this.executeMove(3);
                            if (!this.isMovementSucceeded()) {
                                this.executeMove(9)
                            }
                            break;
                        case 8:
                            this.executeMove(7);
                            if (!this.isMovementSucceeded()) {
                                this.executeMove(9)
                            }
                            break;
                    }
                }
            }
        }
    };

    Game_Player.prototype.getInputDirection = function () {
        return Input.dir8;
    };

    Game_Player.prototype.executeMove = function (direction) {
        this.moveDir8(direction);
    };

    Game_Player.prototype.updateNonmoving = function (wasMoving) {
        if (!$gameMap.isEventRunning()) {
            if (wasMoving) {
                $gameParty.onPlayerWalk();
                this.checkEventTriggerHere([1, 2]);
                if ($gameMap.setupStartingEvent()) {
                    return;
                }
            }
            if (this.triggerAction()) {
                return;
            }
            if (wasMoving) {
                this.updateEncounterCount();
            } else if (!$gameTemp.isDestinationValid()) {
                $gameTemp.clearDestination();
            }
        }
    };

    Game_Player.prototype.triggerTouchAction = function () {
        return false;
    };

    Game_Player.prototype.checkEventTriggerHere = function (triggers) {
        if (this.canStartLocalEvents()) {
            this.startCollidedEventsPx(this._px, this._py, triggers, false);
        }
    };

    Game_Player.prototype.checkEventTriggerThere = function (triggers) { // front, literally
        if (this.canStartLocalEvents()) {
            var direction = this.direction();
            var npx = $gameMap.roundPxWithDirection(this._px, direction);
            var npy = $gameMap.roundPyWithDirection(this._py, direction);
            this.startCollidedEventsPx(npx, npy, triggers, true);
            if (!$gameMap.isEventRunning() && this.isFacingCounter()) {
                if (direction === 2 || direction === 8) {
                    this.startCollidedEventsPx(npx, npy + (direction === 2 ? tileSection : -tileSection), triggers, true);
                } else if (direction === 4 || direction === 6) {
                    this.startCollidedEventsPx(npx + (direction === 4 ? -tileSection : tileSection), npy, triggers, true);
                }
            }
        }
    };

    Game_Player.prototype.checkEventTriggerTouchPx = function (px, py) {
        if (this.canStartLocalEvents()) {
            this.startCollidedEventsPx(px, py, [1, 2], true);
        }
    };

    Game_Player.prototype.startCollidedEventsPx = function (px, py, triggers, normal) {
        if (!$gameMap.isEventRunning()) {
            $gameMap.collidedEventsPx(px, py, this._collisionMask).forEach(function (event) {
                if (event.isTriggerIn(triggers) && event.isNormalPriority() === normal) {
                    event.start();
                }
            });
        }
    };

    Game_Player.prototype.isOnDamageFloor = function () {
        var cm = this._collisionMask;
        var xs = cm.xSize;
        var ys = cm.ySize;
        var spx = this._px - xs / 2;
        var spy = this._py - ys;
        for (var cmx = 0; cmx < xs; cmx++) {
            for (var cmy = 0; cmy < ys; cmy++) {
                if ($gameMap.isDamageFloorPx(spx + cmx, spy + cmy)) {
                    return true;
                }
            }
        }
        return false;
    };

    Game_Player.prototype.moveStraight = function (d) {
        Game_Character.prototype.moveStraight.call(this, d);
        if (this.isMovementSucceeded()) {
            this._followers.updateMove();
        }
    };

    Game_Player.prototype.moveDiagonally = function (horz, vert) {
        Game_Character.prototype.moveDiagonally.call(this, horz, vert);
        if (this.isMovementSucceeded()) {
            this._followers.updateMove();
        }
    };

    //------------------------------------------------------------
    // Game_Follower

    Game_Follower.prototype.canPassPx = function (px, py, d) {
        /*
         if (this.isThrough() || this.isDebugThrough()) {
         return true;
         }
         */
        if (!this.isMapPassablePx(px, py, d)) {
            return false;
        }
        if (this.isCollidedWithCharactersPx($gameMap.roundPxWithDirection(px, d), $gameMap.roundPyWithDirection(py, d))) {
            return false;
        }
        return true;
    };

    Game_Follower.prototype.chaseCharacter = function (character) {
        var dpx = this.deltaPxFrom(character.px);
        var dpy = this.deltaPyFrom(character.py);
        dpx = Math.abs(dpx) > followerDistance ? dpx : 0;
        dpy = Math.abs(dpy) > followerDistance ? dpy : 0;
        if (dpx !== 0 || dpy !== 0) {
            if (dpx !== 0 && dpy !== 0) {
                this.moveDiagonally(dpx > 0 ? 4 : 6, dpy > 0 ? 8 : 2);
            } else if (dpx !== 0) {
                this.moveStraight(dpx > 0 ? 4 : 6);
            } else if (dpy !== 0) {
                this.moveStraight(dpy > 0 ? 8 : 2);
            }
            if (!this.isMovementSucceeded()) {
                this.moveDir8(this.findChaseDirection(character));
            }
            this.setMoveSpeed($gamePlayer.realMoveSpeed());
        }
    };

    Game_Follower.prototype.findChaseDirection = function (character) {
        var nodes = [];

        var px = this._px;
        var py = this._py;

        var makeNode = function (px, py, gScore, fScore, direction) {
            return {
                px: px,
                py: py,
                g: gScore,
                f: fScore,
                direction: direction
            };
        };

        for (var direction = 1; direction <= 9; direction++) {
            if (direction === 5) {
                continue;
            }
            var npx = px;
            var npy = py;
            switch (direction) {
                case 2:
                case 4:
                case 6:
                case 8:
                    npx = $gameMap.roundPxWithDirection(npx, direction);
                    npy = $gameMap.roundPyWithDirection(npy, direction);
                    break;
                case 1:
                    npx--;
                    npy++;
                    break;
                case 3:
                    npx++;
                    npy++;
                    break;
                case 7:
                    npx--;
                    npy--;
                    break;
                case 9:
                    npx++;
                    npy--;
                    break;
            }
            if (direction % 2 === 0) {
                if (!this.canPassPx(px, py, direction)) {
                    continue;
                }
            } else {
                if (!this.canPassDiagonallyPx(px, py, npx - px > 0 ? 6 : 4, npy - py > 0 ? 2 : 8)) {
                    continue;
                }
            }
            nodes.push(makeNode(npx, npy, 1, 1 + $gameMap.distancePx(npx, npy, character.px, character.py), direction));
        }

        if (nodes.length < 1) {
            return 0;
        }

        var best = nodes[0];
        for (var i = 1; i < nodes.length; i++) {
            var current = nodes;
            if (current.f < best.f) {
                best = current;
            }
        }
        return best.direction;
    };

    //-----------------------------------------------------------------------------
    // Game_Followers

    Game_Followers.prototype.jumpAll = function () {
        if ($gamePlayer.isJumping()) {
            for (var i = 0; i < this._data.length; i++) {
                var follower = this._data;
                var sx = toTile($gamePlayer.deltaPxFrom(follower.px));
                var sy = toTile($gamePlayer.deltaPyFrom(follower.py));
                follower.jump(sx, sy);
            }
        }
    };

    /*
     Game_Followers.prototype.isSomeoneCollided = function(x, y) {
     return this.visibleFollowers().some(function(follower) {
     return follower.pos(x, y);
     }, this);
     };
     */

    //-----------------------------------------------------------------------------
    // Game_Vehicle
   
    // TODO: Support vehicles
   
    //-----------------------------------------------------------------------------
    // Sprite_Character

    var aliasSpriteCharacterPrototypeSetCharacter = Sprite_Character.prototype.setCharacter;
    Sprite_Character.prototype.setCharacter = function () {
        aliasSpriteCharacterPrototypeSetCharacter.apply(this, arguments);
        if (drawCollisionMask && this._character) {
            this.debugDrawCollisionMask();
        }
    };

    Sprite_Character.prototype.debugDrawCollisionMask = function () {
        var sprite = new Sprite(new Bitmap($gameMap.tileWidth(), $gameMap.tileHeight()));
        sprite.anchor = this.anchor;
        sprite.opacity = 80;
        var cm = this._character.collisionMask;
        var sw = $gameMap.tileWidthPx();
        var sh = $gameMap.tileHeightPx();
        for (var sx = 0; sx < cm.xSize; sx++) {
            for (var sy = 0; sy < cm.ySize; sy++) {
                if (cm.get(sx, sy)) {
                    sprite.bitmap.fillRect(sx * sw, sy * sh, sw, sh, this._character.isThrough() || !this._character.isNormalPriority() ? 'green' : 'red');
                }
            }
        }
        this.addChild(sprite);
    };

    //------------------------------------------------------------
    // Sprite_Destination

    Sprite_Destination.prototype.updatePosition = function () {
        var dpx = $gameTemp.destinationPx();
        var dpy = $gameTemp.destinationPy();
        this.x = $gameMap.adjustX(toTile(dpx)) * tileSection * $gameMap.tileWidthPx();
        this.y = ($gameMap.adjustY(toTile(dpy)) * tileSection - 1) * $gameMap.tileHeightPx();
    };

    //------------------------------------------------------------
    // Scene_Map
    Scene_Map.prototype.processMapTouch = function () {
        if (TouchInput.isTriggered()) {
            $gameTemp.setDestination($gameMap.canvasToMapPx(TouchInput.x), $gameMap.canvasToMapPy(TouchInput.y));
        }
    };

    var aliasSceneMapPrototypeUpdate = Scene_Map.prototype.update;
    Scene_Map.prototype.update = function () {
        if ($gameMap.isCollisionMaskSet()) {
            aliasSceneMapPrototypeUpdate.apply(this, arguments);
        } else {
            Scene_Base.prototype.update.call(this);
        }
    };
})();[/pre]

评分

参与人数 1星屑 +66 收起 理由
MeowSnow + 66 叼叼叼

查看全部评分

梦石
0
星屑
97
在线时间
308 小时
注册时间
2014-1-16
回帖
397
发表于 2016-6-8 18:05:39 | 显示全部楼层
这个。。。有什么用?解释一下
回复

使用道具 举报

梦石
0
星屑
50
在线时间
491 小时
注册时间
2015-1-7
回帖
110
发表于 2016-6-8 21:30:43 | 显示全部楼层
现在的难道不是像素移动?

点评

明显不是。。。RM一直都是跑格子  发表于 2016-6-9 04:07
回复

使用道具 举报

梦石
0
星屑
1446
在线时间
6552 小时
注册时间
2010-12-30
回帖
8655
发表于 2016-6-9 00:48:37 | 显示全部楼层
傲游截图20160609004322.png 傲游截图20160609004733.png
_(:з」∠)_啊喏,虽然像素移动的效果很棒,但是火车队列变成了扭曲的效果呢……还有行走图上出现了不明的小方块,即使关了火车队列或者队伍中只有一个角色时,这些小方块也存在。
回复

使用道具 举报

梦石
0
星屑
50
在线时间
46 小时
注册时间
2014-3-14
回帖
32
 楼主| 发表于 2016-6-9 02:03:10 | 显示全部楼层
本帖最后由 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,我其实想参加的,但是一个人好像没什么动力,你们想不想一起来?如果有人帮忙的话我就去参加了

点评

之前一直在折腾碰撞检测引擎,看到也在折腾这块的感觉好亲切!!!【https://coding.net/u/shitake/p/box2d-ruby/git/blob/master/box2d.rb 以前折腾个一个  发表于 2016-6-9 16:58
你说的这些东西我都没有用上。也许你可以帮我改进一下  发表于 2016-6-9 15:52
你说的这些东西我都没有用上。也许你可以帮我改进一下  发表于 2016-6-9 15:51
话说难倒不是脏矩阵么。以及貌似是有AABB?OBB和sphere呢?有实现吗?  发表于 2016-6-9 13:20
(っ´ω`c) 要是做一个素材量不大的弹幕游戏的话,我愿意帮助菊苣做像素美术  发表于 2016-6-9 11:04
回复

使用道具 举报

梦石
0
星屑
50
在线时间
46 小时
注册时间
2014-3-14
回帖
32
 楼主| 发表于 2016-6-9 02:07:00 | 显示全部楼层
西姐 发表于 2016-6-8 21:30
现在的难道不是像素移动?

像素移动只是相对像素而已
默认状态下MV是48像素一个tile,这个脚本允许你把tile size设置得更小
具体参照tileSection
另外这个脚本还加入了更精确的碰撞检测以及自动分析tileset bitmap的功能
你可以新建一个工程看看效果
回复

使用道具 举报

梦石
0
星屑
50
在线时间
46 小时
注册时间
2014-3-14
回帖
32
 楼主| 发表于 2016-6-9 02:09:04 | 显示全部楼层
超音速 发表于 2016-6-8 18:05
这个。。。有什么用?解释一下

默认状态下MV一按方向键就走一整个大格,你想不想让移动更自由一点,比如说一小格一小格的移动呢?

点评

明白了  发表于 2016-6-9 12:14
回复

使用道具 举报

…あたしは天

梦石
0
星屑
2308
在线时间
4033 小时
注册时间
2010-10-4
回帖
10548

开拓者贵宾

发表于 2016-6-9 07:42:20 | 显示全部楼层
Quasi Movement 这个插件我觉得挺不错的,楼主可以参考一下
回复

使用道具 举报

梦石
0
星屑
22879
在线时间
8598 小时
注册时间
2011-12-31
回帖
3270
发表于 2016-6-9 08:34:36 | 显示全部楼层
本帖最后由 tseyik 于 2016-6-9 08:37 编辑

SAN_AnalogMove[pre lang="javascript"]//=============================================================================
// SAN_AnalogMove.js
//=============================================================================
// Copyright (c) 2015-2016 Sanshiro
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
* @plugindesc SAN_AnalogMove ver1.34 : Movement of 1 pixel unit.
* Analog Stick and Touch Pad are supported.
* @author Sanshiro https://twitter.com/rev2nym
*
* @help
* Change player's movement to 1 pixel movement that isn't depend tiles.
* Arrow Key, Analog Stick and Touch Pad are supported.
*
* It's possible to commercial use, distribute, and modify under the MIT license.
* But, don't eliminate and don't alter a comment of the beginning.
* If it's good, please indicate an author name on credit.
*
* Author doesn't shoulder any responsibility in all kind of damage by using this.
* And please don't expect support. X(
*
* Plugin Command
*   AnalogMove ON            # Allow AnalogMove system working.
*   AnalogMove OFF           # Disallow AnalogMove system working.
*   AnalogMove Player ON     # Allow player and followers analog moving.
*   AnalogMove Player OFF    # Disallow player and followers analog moving.
*   
* @param Valid
* @desc Initial valid flag of AnalogMove system. ('ON' is valid)
* @default OFF
*
* @param Player
* @desc Initial valid flag of player and followers analog moving. ('ON' is valid)
* @default OFF
*
*/

/*:ja
* @plugindesc アナログムーブ ver1.34
* 1ピクセル単位の移動 アナログスティック・タッチパッド対応
* @author サンシロ https://twitter.com/rev2nym
* @version 1.34 2016/03/30 並んだプライオリティの異なる接触イベントの間をすり抜ける不具合を修正、1フレーム内に起動するイベントを1つだけにするよう変更
* 1.33 2015/11/29 プラグインパラメータが反映されない不具合を修正
* 1.32 2015/11/29 スルー有効時の挙動に関連してフォロワーの挙動を修正
* 1.31 2015/11/28 コード整理、プレイヤーのスルー有効時の挙動、飛行艇時に決定ボタン・接触イベントが起動する不具合を修正
* 1.30 2015/11/26 モジュール名をSAN_AnalogMove.jsに変更、名前空間の追加、乗り物に対応
* 1.27a 2015/11/25 英語ドキュメント追加
* 1.27 2015/11/24 MITライセンスに変更、セーブファイルから衝突マップを除外、ルート指定時の向き反映の不具合を修正
* 1.26 2015/11/20 フォロワーの位置反映、イベント中の歩行アニメ、通行判定を暫定修正
* 1.25 2015/11/16 フォロワーの向き固定移動の不具合と初期ON起動時にエラー終了する不具合を修正
* 1.24 2015/11/15 機能有効フラグの状態をセーブファイルに保存するよう修正
* 1.23 2015/11/14 通行不能タイルの接触イベント起動を追加、ルート指定移動の向き反映を修正
* 1.22 2015/11/12 ウィンドウを閉じた後のマウス・タッチパッドの感度、座標指定移動の終了条件を調整
* 1.21 2015/11/11 茂み表示、向き反映、プライオリティの異なるイベントの起動の不具合を修正
* 1.20 2015/11/10 タッチパッドに対応、向き反映、イベント中の移動、マップ端の通行判定の不具合を修正
* 1.10 2015/11/09 ランダムエンカウントに対応、プラグインパラメータ読込みの不具合を修正
* 1.01 2015/11/08 角度の誤計算を修正、ループマップ使用可能
* 1.00 2015/11/08 フォロワーの移動速度を微調整、リリースバージョンにアップ
* 0.90 2015/11/08 プラグインパラメータ・コマンド、移動ルートの指定、フォロワー表示・集合などに対応
* 0.12 2015/11/08 セーブ&ロードに暫定対応
* 0.11 2015/11/07 複数のイベントに同時に接触したときエラー終了する不具合を修正
* 0.10 2015/11/06 公開
*
* @help
* プレイヤーキャラクターの移動をタイルによらない1ピクセル単位の移動に変更します。
* 方向キー、アナログスティック、タッチパッド入力に対応しています。
*
* MITライセンスのもと、商用利用、改変、再配布が可能です。
* ただし冒頭のコメントは削除や改変をしないでください。
* よかったらクレジットに作者名を記載してください。
*
* これを利用したことによるいかなる損害にも作者は責任を負いません。
* サポートは期待しないでください><。
*
* プラグインコマンド
*   AnalogMove ON            # アナログムーブ機能有効化
*   AnalogMove OFF           # アナログムーブ機能無効化
*   AnalogMove Player ON     # プレイヤーとフォロワーのアナログムーブ有効化
*   AnalogMove Player OFF    # プレイヤーとフォロワーのアナログムーブ無効化
*
* @param Valid
* @desc アナログムーブ機能の有効フラグの初期値です。(ONで有効)
* @default OFF
*
* @param Player
* @desc プレイヤーとフォロワーのアナログムーブ有効フラグの初期値です。(ONで有効)
* @default OFF
*
*/

var Imported = Imported || {};
Imported.SAN_AnalogMove = true;

var Sanshiro = Sanshiro || {};
Sanshiro.Game_AnalogMove = Sanshiro.Game_AnalogMove || {};

//-----------------------------------------------------------------------------
// Game_AnalogMove
//
// アナログムーブクラス
function Game_AnalogMove() {
    this.initialize.apply(this, arguments);
};

// アナログムーブクラス初期化
Game_AnalogMove.prototype.initialize = function(thisCharacter) {
    this._crntRealX    = thisCharacter._realX;        // 現在マップ実 X 座標
    this._nextRealX    = thisCharacter._realX;        // 次回マップ実 X 座標
    this._crntRealY    = thisCharacter._realY;        // 現在マップ実 Y 座標
    this._nextRealY    = thisCharacter._realY;        // 次回マップ実 Y 座標
    this._targRealX    = undefined;                   // 目標マップ実 X 座標
    this._targRealY    = undefined;                   // 目標マップ実 Y 座標
    this._dir4         = thisCharacter.direction();   // キャラクターの向き
    this._distancePerFrame = 0.0;                     // フレーム間移動距離(ピクセル)
    this._directionRadian  = this.dir8ToRadian(thisCharacter.direction()); // 現在進行方位
    this._targetRadian     = this.dir8ToRadian(thisCharacter.direction()); // 目標進行方位
    this._directionRadianVariate = Math.PI*2.0;       // 進行方位変化量
    this._encounterCount   = 0.0;                     // エンカウント歩数
    this._collideEvents    = new Array();             // 接触イベント
    this._isMoving         = false;                   // 移動中判定
    this._isThrough        = false;                   // すり抜け判定
    this._valid            = false;                   // アナログムーブ個別キャラクター有効フラグ
};

// アナログムーブ個別キャラクター有効フラグの設定
Game_AnalogMove.prototype.setValid = function(valid) {
    this._valid = valid;
};

// アナログムーブ個別キャラクター有効判定
Game_AnalogMove.prototype.isValid = function() {
    return $gameSystem.analogMoveValid() && this._valid;
};

// アナログムーブ移動可能判定
Game_AnalogMove.canMove = function() {
    return $gamePlayer.canMove() && !SceneManager.isSceneChanging();
};

// フレーム更新
Game_AnalogMove.prototype.update = function(thisCharacter) {
    this._crntRealX = thisCharacter._realX;
    this._crntRealY = thisCharacter._realY;
    this._nextRealX = thisCharacter._realX;
    this._nextRealY = thisCharacter._realY;
    this.updateDirectionRadian();
    this.updateDir4(thisCharacter);
    this.updateNextRealXY(thisCharacter);
    this.updateTargetRealXY(thisCharacter);
    this.updateIsMoving(thisCharacter);
    this.updateIsThrough(thisCharacter);
    this.updateEncounterCount(thisCharacter);
    this.updateCharacterPosition(thisCharacter);
};

// 目標座標の更新
Game_AnalogMove.prototype.updateTargetRealXY = function(thisCharacter) {
    if (!Game_AnalogMove.canMove() ||
            this.deltaXY(thisCharacter._realX, thisCharacter._realY, this._nextRealX, this._nextRealY) < this._distancePerFrame / 16.0) {
        this._targRealX = undefined;
        this._targRealY = undefined;
    }
}

// エンカウント歩数の更新
Game_AnalogMove.prototype.updateEncounterCount = function(thisCharacter) {
    if (thisCharacter === $gamePlayer && Game_AnalogMove.canMove() && $gamePlayer.canEncounter()) {
        this._encounterCount += Math.sqrt(
                Math.pow((thisCharacter._realX - this._nextRealX), 2) +
                Math.pow((thisCharacter._realY - this._nextRealY), 2));
    }
};

// エンカウント歩数
Game_AnalogMove.prototype.encounterCount = function() {
    var encounterCount = this._encounterCount;
    this._encounterCount = 0.0;
    return encounterCount;
};

// キャラクター位置の更新
Game_AnalogMove.prototype.updateCharacterPosition = function(thisCharacter) {
    thisCharacter.setDirectionAnalog(this.dir4());
    if (Game_AnalogMove.canMove() && this.isMoving()) {
        thisCharacter._realX = this._nextRealX;
        thisCharacter._realY = this._nextRealY;
        thisCharacter._x = Math.round(thisCharacter._realX);
        thisCharacter._y = Math.round(thisCharacter._realY);
        thisCharacter.resetStopCount();
    }
};

// キー入力による目標方位角度と移動速度の更新
Game_AnalogMove.prototype.moveByInput = function(thisCharacter) {
    if (!$gamePlayer.canMove()) {
        this._distancePerFrame = 0.0;
        return;
    }
    var stick = Input.leftStick();
    if (TouchInput.isTriggered() || TouchInput.isRepeated()) {
        this._targRealX = this.canvasToMapX(TouchInput.x);
        this._targRealY = this.canvasToMapY(TouchInput.y);
    }
    if (stick !== undefined && stick.tilt !== 0.0) {
        this._targetRadian = this.normalizeRadian(stick.direction);
        this._distancePerFrame = thisCharacter.distancePerFrame() * stick.tilt;
        this._targRealX = undefined;
        this._targRealY = undefined;
    } else if (this.dir8ToRadian(Input.dir8) !== undefined) {
        this._targetRadian = this.dir8ToRadian(Input.dir8);
        this._distancePerFrame = thisCharacter.distancePerFrame();
        this._targRealX = undefined;
        this._targRealY = undefined;
    } else if (this._targRealX !== undefined && this._targRealY !== undefined) {
        var distanceRate = Math.min(this.deltaXYFrom(this._targRealX, this._targRealY), 1.0);
        distanceRate = (distanceRate < 0.1 ? 0.0 : distanceRate);
        this._targetRadian = this.towardDirectionRadian(this._targRealX, this._targRealY);
        this._distancePerFrame = thisCharacter.distancePerFrame() * distanceRate;
        if (distanceRate === 0.0) {
            this._targRealX = undefined;
            this._targRealY = undefined;
        }
    } else {
        this._distancePerFrame = 0.0;
    }
};

// 画面 X 座標をマップ X 座標に変換
Game_AnalogMove.prototype.canvasToMapX = function(x) {
    var tileWidth = $gameMap.tileWidth();
    var originX = $gameMap._displayX * tileWidth;
    var mapX = (originX + x) / tileWidth;
    return $gameMap.roundX(mapX);
};

// 画面 Y 座標をマップ Y 座標に変換
Game_AnalogMove.prototype.canvasToMapY = function(y) {
    var tileHeight = $gameMap.tileHeight();
    var originY = $gameMap._displayY * tileHeight;
    var mapY = (originY + y) / tileHeight;
    return $gameMap.roundY(mapY);
};

// キャラクター追従による目標方位角度と移動速度の更新
Game_AnalogMove.prototype.followCharacter = function(thisCharacter, targetCharacter) {
    this._crntRealX = thisCharacter._realX;
    this._crntRealY = thisCharacter._realY;
    var deltaXYFromTarget = this.deltaXYFrom(targetCharacter._realX + 0.5, targetCharacter._realY + 0.5);
    this._targetRadian = this.towardDirectionRadian(targetCharacter._realX + 0.5, targetCharacter._realY + 0.5);
    if (deltaXYFromTarget <= 1.0) {
        this._distancePerFrame = thisCharacter.distancePerFrame() * 0.0;
    } else {
        var distanceRate = deltaXYFromTarget;
        distanceRate += Math.pow(distanceRate - 1.0, 2) - 0.125;
        distanceRate = distanceRate > 2.0 ? 2.0 : distanceRate;
        this._distancePerFrame = thisCharacter.distancePerFrame() * distanceRate;
    }
};

// 目標方向に向けて進行方位を更新
Game_AnalogMove.prototype.updateDirectionRadian = function() {
    if (this._directionRadian === this._targetRadian) {
        return;
    }
    var differentialRadian = this.normalizeRadian(this._targetRadian - this._directionRadian);
    if (differentialRadian >= Math.PI) {
        differentialRadian -= Math.PI * 2.0;
    }
    differentialRadian < 0 ?
        this._directionRadian += Math.max(differentialRadian, -this._directionRadianVariate) :
        this._directionRadian += Math.min(differentialRadian,  this._directionRadianVariate);
    this._directionRadian = this.normalizeRadian(this._directionRadian);
};

// ラジアン角度を整形
Game_AnalogMove.prototype.normalizeRadian = function(radian) {
    while (radian < 0) radian += (Math.PI * 2.0);
    return radian % (Math.PI * 2.0);
};

// クラス内部の実座標の更新
Game_AnalogMove.prototype.updateNextRealXY = function(thisCharacter) {
    this._collideEvents = new Array();
    this._isMoving = false;
    var evadeDirectionRadian = this._directionRadian;
    var splitDistances = this.splitDistances();
    splitDistances.forEach(function(splitDistance) {
        this.calculateNextRealXY(splitDistance, this._directionRadian);
        var collideCharacters = this.collideCharacters(thisCharacter, splitDistance);
        var collideWallXY = this.collideWallXY(thisCharacter, splitDistance);
        var collideCornerXY = this.collideCornerXY(thisCharacter, splitDistance);
        if (collideCharacters.length === 0) {
            if (collideCornerXY !== undefined) {
                evadeDirectionRadian = this.evadeDirectionRadian(collideCornerXY.x, collideCornerXY.y, this._directionRadian);
                splitDistance *= Math.abs(Math.cos(evadeDirectionRadian - this._directionRadian));
                this.calculateNextRealXY(splitDistance, evadeDirectionRadian);
            }
            if (collideWallXY.x !== undefined) {
                this._nextRealX = Math.round(this._nextRealX);
            }
            if (collideWallXY.y !== undefined) {
                this._nextRealY = Math.round(this._nextRealY);
            }
        } else if (collideCharacters.length === 1 && collideWallXY.x === undefined && collideWallXY.y === undefined && collideCornerXY === undefined) {
            evadeDirectionRadian = this.evadeDirectionRadian(collideCharacters[0]._realX + 0.5, collideCharacters[0]._realY + 0.5, this._directionRadian);
            splitDistance *= Math.abs(Math.cos(evadeDirectionRadian - this._directionRadian));
            this.calculateNextRealXY(splitDistance, evadeDirectionRadian);
            if (this.collideCharacters(thisCharacter, splitDistance).length !== 0) {
                this._nextRealX = this._crntRealX;
                this._nextRealY = this._crntRealY;
            }
        } else {
            this._nextRealX = this._crntRealX;
            this._nextRealY = this._crntRealY;
        }
        this._crntRealX = this._nextRealX = ((this._nextRealX + $gameMap.width())  % $gameMap.width());
        this._crntRealY = this._nextRealY = ((this._nextRealY + $gameMap.height()) % $gameMap.height());
    }, this);
    // 衝突するイベントの更新
    this._collideEvents = this._collideEvents.filter(function(character, i, characters) {
        var eventId = $gameMap.events().indexOf(character);
        return (characters.indexOf(character) === i && $gameMap.events().indexOf(character) !== -1);
    });
};

// 分割フレーム間移動距離
Game_AnalogMove.prototype.splitDistances = function() {
    var unitDistanceVelocity = 1.0 / 4.0;
    var distancePerFrame = this._distancePerFrame;
    var distances = new Array();
    while (distancePerFrame > 0.0) {
        distances.push(Math.min(distancePerFrame, unitDistanceVelocity));
        distancePerFrame -= unitDistanceVelocity;
    }
    return distances;
};

// クラス内部の次移動座標の計算
Game_AnalogMove.prototype.calculateNextRealXY = function(distancePerFrame, directionRadian) {
    var distanceX = - distancePerFrame * Math.sin(directionRadian);
    var distanceY = - distancePerFrame * Math.cos(directionRadian);
    this._nextRealX = this._crntRealX + distanceX;
    this._nextRealY = this._crntRealY + distanceY;
};

// 指定座標への方位
Game_AnalogMove.prototype.towardDirectionRadian = function(x, y) {
    var deltaX = this.deltaXFrom(x);
    var deltaY = this.deltaYFrom(y);
    if (deltaX === 0.0) {
        return (deltaY > 0 ? Math.PI * 0.0 : Math.PI * 1.0);
    } else if (deltaY === 0.0) {
        return (deltaX > 0 ? Math.PI * 0.5 : Math.PI * 1.5);
    } else {
        return Math.atan2(deltaX, deltaY);
    }
};

// 指定座標を避ける方位角度
Game_AnalogMove.prototype.evadeDirectionRadian = function(x, y, directionRadian) {
    var towardDirectionRadian = this.towardDirectionRadian(x, y);
    var differentialRadian = this.normalizeRadian(towardDirectionRadian - directionRadian);
    if (differentialRadian > Math.PI) differentialRadian -= (Math.PI * 2.0);
    towardDirectionRadian += (differentialRadian < 0 ? Math.PI / 2.0 : - Math.PI / 2.0);
    return this.normalizeRadian(towardDirectionRadian);
};

// 衝突する全てのキャラクター
Game_AnalogMove.prototype.collideCharacters = function(thisCharacter, distancePerFrame) {
    if ($gamePlayer.isInAirship()) {
        return [];
    }
    var collideCharacters = this.allCharacters();
    collideCharacters = collideCharacters.filter(function(character) {
        return character !== thisCharacter && !character.isThrough();
    });
    collideCharacters = collideCharacters.filter(function(character) {
        var crntDistance = this.deltaXY(this._crntRealX, this._crntRealY, character._realX, character._realY)
        var nextDistance = this.deltaXY(this._nextRealX, this._nextRealY, character._realX, character._realY);
        if (nextDistance < crntDistance) {
            if (nextDistance < 0.5 + distancePerFrame) {
                this._collideEvents.push(character);
            } else if (nextDistance < 1.0 - distancePerFrame &&
                character._priorityType === thisCharacter._priorityType) {
                this._collideEvents.push(character);
                return true;
            }
        }
        return false;
    }, this);
    var self = this;
    collideCharacters.sort(function(character1, character2) {
        var distance1 = self.deltaXYFrom(character1._realX + 0.5, character1._realY + 0.5);
        var distance2 = self.deltaXYFrom(character2._realX + 0.5, character2._realY + 0.5);
        return (distance2 - distance1);
    });
    if (this.isThrough()) {
        return [];
    }
    return collideCharacters;
};

// マップ上の全てのキャラクター
Game_AnalogMove.prototype.allCharacters = function() {
    var player = [$gamePlayer];
    var events = $gameMap.events();
    var followers = $gamePlayer.followers().visibleFollowers();
    return ([$gamePlayer].concat($gameMap.events(), $gamePlayer.followers().visibleFollowers()));
};

// 衝突するイベント
Game_AnalogMove.prototype.collideEvents = function() {
    return this._collideEvents;
}

// 衝突する壁の座標
Game_AnalogMove.prototype.collideWallXY = function(thisCharacter, distancePerFrame) {
    var nextCenterX = this._nextRealX + 0.5;
    var nextCenterY = this._nextRealY + 0.5;
    var x = (Math.floor(nextCenterX) + $gameMap.width()).mod($gameMap.width());
    var y = (Math.floor(nextCenterY) + $gameMap.height()).mod($gameMap.height());
    var tile5 = Game_CollideMap._tiles[x][y];
    var wallX = undefined;
    var wallY = undefined;
    if (this._crntRealX >= this._nextRealX) {
        // 左の壁
        var x2 = $gameMap.roundX(Math.floor(nextCenterX - 0.5));
        if (!$gameMap.isValid(x2, y)) {
            wallX = tile5._x4;
        } else {
            var tile4 = Game_CollideMap._tiles[x2][y];
            if (tile4._e6 && Math.abs(this.deltaX(nextCenterX, tile5._x4)) < 0.5 + distancePerFrame) {
                this._collideEvents.push.apply(this._collideEvents, $gameMap.eventsXy(x2, y));
                if (!this.isThrough()) {
                    wallX = tile4._x6;
                }
            }
        }
    } else {
        // 右の壁
        var x2 = $gameMap.roundX(Math.floor(nextCenterX + 0.5));
        if (!$gameMap.isValid(x2, y)) {
            wallX = tile5._x6;
        } else {
            var tile6 = Game_CollideMap._tiles[x2][y];
            if (tile6._e4 && Math.abs(this.deltaX(nextCenterX, tile5._x6)) < 0.5 + distancePerFrame) {
                this._collideEvents.push.apply(this._collideEvents, $gameMap.eventsXy(x2, y));
                if (!this.isThrough()) {
                    wallX = tile6._x4;
                }
            }
        }
    }
    if (this._crntRealY >= this._nextRealY) {
        // 上の壁
        var y2 = $gameMap.roundY(Math.floor(nextCenterY - 0.5));
        if (!$gameMap.isValid(x, y2)) {
            wallY = tile5._y8;
        } else {
            var tile8 = Game_CollideMap._tiles[x][y2];
            if (tile8._e2 && Math.abs(this.deltaY(nextCenterY, tile5._y8)) < 0.5 + distancePerFrame) {
                this._collideEvents.push.apply(this._collideEvents, $gameMap.eventsXy(x, y2));
                if (!this.isThrough()) {
                    wallY = tile8._y2;
                }
            }
        }
    } else {
        // 下の壁
        var y2 = $gameMap.roundY(Math.floor(nextCenterY + 0.5));
        if (!$gameMap.isValid(x, y2)) {
            wallY = tile5._y2;
        } else {
            var tile2 = Game_CollideMap._tiles[x][y2];
            if (tile2._e8 && Math.abs(this.deltaY(nextCenterY, tile5._y2)) < 0.5 + distancePerFrame) {
                this._collideEvents.push.apply(this._collideEvents, $gameMap.eventsXy(x, y2));
                if (!this.isThrough()) {
                    wallY = tile2._y8;
                }
            }
        }
    }
    return {x: wallX, y: wallY};
};

// 衝突する角の座標
Game_AnalogMove.prototype.collideCornerXY = function(thisCharacter, distancePerFrame) {
    if (this.isThrough()) {
        return undefined;
    }
    var nextCenterX = this._nextRealX + 0.5
    var nextCenterY = this._nextRealY + 0.5
    if (this._nextRealX < this._crntRealX || this._nextRealY < this._crntRealY) {
        // 左上の角
        var x = (Math.floor(nextCenterX - 0.5) + $gameMap.width()).mod($gameMap.width());
        var y = (Math.floor(nextCenterY - 0.5) + $gameMap.height()).mod($gameMap.height());
        var tile7 = Game_CollideMap._tiles[x][y];
        if (tile7._a3 && this.deltaXY(nextCenterX, nextCenterY, tile7._x3, tile7._y3) < 0.5 - distancePerFrame) {
            return { x: tile7._x3, y: tile7._y3 };
        }
    }
    if (this._nextRealX < this._crntRealX || this._nextRealY > this._crntRealY) {
        // 左下の角
        var x = (Math.floor(nextCenterX - 0.5) + $gameMap.width()).mod($gameMap.width());
        var y = (Math.floor(nextCenterY + 0.5) + $gameMap.height()).mod($gameMap.height());
        var tile1 = Game_CollideMap._tiles[x][y];
        if (tile1._a9 && this.deltaXY(nextCenterX, nextCenterY, tile1._x9, tile1._y9) < 0.5 - distancePerFrame) {
            return { x: tile1._x9, y: tile1._y9 };
        }
    }
    if (this._nextRealX > this._crntRealX || this._nextRealY < this._crntRealY) {
        // 右上の角
        var x = (Math.floor(nextCenterX + 0.5) + $gameMap.width()).mod($gameMap.width());
        var y = (Math.floor(nextCenterY - 0.5) + $gameMap.height()).mod($gameMap.height());
        var tile9 = Game_CollideMap._tiles[x][y];
        if (tile9._a1 && this.deltaXY(nextCenterX, nextCenterY, tile9._x1, tile9._y1) < 0.5 - distancePerFrame) {
            return { x: tile9._x1, y: tile9._y1 };
        }
    }
    if (this._nextRealX > this._crntRealX || this._nextRealY > this._crntRealY) {
        // 右下の角
        var x = (Math.floor(nextCenterX + 0.5) + $gameMap.width()).mod($gameMap.width());
        var y = (Math.floor(nextCenterY + 0.5) + $gameMap.height()).mod($gameMap.height());
        var tile3 = Game_CollideMap._tiles[x][y];
        if (tile3._a7 && this.deltaXY(nextCenterX, nextCenterY, tile3._x7, tile3._y7) < 0.5 - distancePerFrame) {
            return { x: tile3._x7, y: tile3._y7 };
        }
    }
    return undefined;
};

// 移動中判定の更新
Game_AnalogMove.prototype.updateIsMoving = function(thisCharacter) {
    this._isMoving = (thisCharacter._realX !== this._nextRealX || thisCharacter._realY !== this._nextRealY);
};

// 移動中判定
Game_AnalogMove.prototype.isMoving = function() {
    return this._isMoving;
};

// すり抜け判定の更新
Game_AnalogMove.prototype.updateIsThrough = function(thisCharacter) {
    this._isThrough = thisCharacter.isThrough() && (thisCharacter.constructor !== Game_Follower || $gamePlayer.isThrough());
};

// すり抜け判定
Game_AnalogMove.prototype.isThrough = function() {
    return this._isThrough;
};

// 目標方位角度の設定
Game_AnalogMove.prototype.setTargetRadian = function(targetRadian) {
    this._targetRadian = targetRadian;
}

// 水平方向の距離
Game_AnalogMove.prototype.deltaX = function(x1, x2) {
    return $gameMap.deltaX(x1, x2)
};

// 垂直方向の距離
Game_AnalogMove.prototype.deltaY = function(y1, y2) {
    return $gameMap.deltaY(y1, y2)
};

// 座標間の距離
Game_AnalogMove.prototype.deltaXY = function(x1, y1, x2, y2) {
    return Math.sqrt(Math.pow(this.deltaX(x1, x2), 2) + Math.pow(this.deltaY(y1, y2), 2));
};

// 現在座標との水平方向の距離
Game_AnalogMove.prototype.deltaXFrom = function(x) {
    return this.deltaX(this._crntRealX + 0.5, x);
};

// 現在座標との垂直方向の距離
Game_AnalogMove.prototype.deltaYFrom = function(y) {
    return this.deltaY(this._crntRealY + 0.5, y);
};

// 現在座標との距離
Game_AnalogMove.prototype.deltaXYFrom = function(x, y) {
    return this.deltaXY(this._crntRealX + 0.5, this._crntRealY + 0.5, x, y);
};

// 内部4方向を更新
Game_AnalogMove.prototype.updateDir4 = function(thisCharacter) {
    this._dir4 = thisCharacter.direction();
    this._dir4 = this.dir8ToDir4(this.radianToDir8(this._directionRadian));
};

// 内部4方向を取得
Game_AnalogMove.prototype.dir4 = function() {
    return this._dir4;
};

// 8方向による方位角度の設定
Game_AnalogMove.prototype.setDirectionRadianByDir8 = function(dir8) {
    this._targetRadian = this.dir8ToRadian(dir8);
    this._directionRadian = this._targetRadian;
};

// 8方向を4方向に変換
Game_AnalogMove.prototype.dir8ToDir4 = function(dir8) {
    if (dir8 % 2 === 0) {
        return dir8;
    }
    switch (this._dir4) {
    case 8:
        switch (dir8) {
        case 3:  return 6;
        case 1:  return 4;
        default: return 8;
        }
    case 6:
        switch (dir8) {
        case 1:  return 2;
        case 7:  return 8;
        default: return 6;
        }
    case 2:
        switch (dir8) {
        case 7:  return 4;
        case 9:  return 6;
        default: return 2;
        }
    case 4:
        switch (dir8) {
        case 9:  return 8;
        case 3:  return 2;
        default: return 4;
        }
    }
    return undefined;
};

// 方向角度を8方向に変換
Game_AnalogMove.prototype.radianToDir8 = function(radian) {
    radian = this.normalizeRadian(radian);
    return (
        radian < Math.PI / 8.0 *  1.0 ? 8 :
        radian < Math.PI / 8.0 *  3.0 ? 7 :
        radian < Math.PI / 8.0 *  5.0 ? 4 :
        radian < Math.PI / 8.0 *  7.0 ? 1 :
        radian < Math.PI / 8.0 *  9.0 ? 2 :
        radian < Math.PI / 8.0 * 11.0 ? 3 :
        radian < Math.PI / 8.0 * 13.0 ? 6 :
        radian < Math.PI / 8.0 * 15.0 ? 9 : 8
    )
};

// 8方向を方向角度に変換
Game_AnalogMove.prototype.dir8ToRadian = function(dir8) {
    return (
        dir8 === 8 ? Math.PI / 4.0  * 0.0 :
        dir8 === 7 ? Math.PI / 4.0  * 1.0 :
        dir8 === 4 ? Math.PI / 4.0  * 2.0 :
        dir8 === 1 ? Math.PI / 4.0  * 3.0 :
        dir8 === 2 ? Math.PI / 4.0  * 4.0 :
        dir8 === 3 ? Math.PI / 4.0  * 5.0 :
        dir8 === 6 ? Math.PI / 4.0  * 6.0 :
        dir8 === 9 ? Math.PI / 4.0  * 7.0 : undefined
    )
};

//-----------------------------------------------------------------------------
// Game_CollideMap
//
// 衝突マップ
Game_CollideMap = {};

// 衝突マップのセットアップ
Game_CollideMap.setup = function() {
    this._mapId = $gameMap.mapId()
    this._tiles = new Array();
    for (var x = 0; x < $gameMap.width(); x++) {
        this._tiles.push([]);
        for (var y = 0; y < $gameMap.height(); y++) {
            this._tiles[x].push(new Game_CollideTile(x, y));
        }
    }
};

//-----------------------------------------------------------------------------
// Game_CollideTile
//
// 衝突タイルクラス
function Game_CollideTile () {
    this.initialize.apply(this, arguments);
};

// 衝突タイルクラスの初期化
Game_CollideTile.prototype.initialize = function(x, y) {
    this._x = Math.floor(x);
    this._y = Math.floor(y);
    this._x5 = this._x + 0.5;
    this._y5 = this._y + 0.5;
    this._x4 = this._x1 = this._x7 = this._x;
    this._x6 = this._x3 = this._x9 = x + 1.0;
    this._y8 = this._y7 = this._y9 = this._y;
    this._y2 = this._y1 = this._y3 = y + 1;
    this._e8 = !this.isPassable(this._x, this._y, 8);
    this._e6 = !this.isPassable(this._x, this._y, 6);
    this._e2 = !this.isPassable(this._x, this._y, 2);
    this._e4 = !this.isPassable(this._x, this._y, 4);
    this._a9 = (this._e8 || this._e6) && this.isCorner(9);
    this._a3 = (this._e6 || this._e2) && this.isCorner(3);
    this._a1 = (this._e2 || this._e4) && this.isCorner(1);
    this._a7 = (this._e4 || this._e8) && this.isCorner(7);
};

// 衝突タイルクラス通行可能判定 辺
Game_CollideTile.prototype.isPassable = function(x, y, d) {
    var x2 = $gameMap.roundXWithDirection(x, d);
    var y2 = $gameMap.roundYWithDirection(y, d);
    var d2 = $gamePlayer.reverseDir(d);
    return $gamePlayer.isMapPassable(x, y, d) && $gamePlayer.isMapPassable(x2, y2, d2) && $gameMap.isValid(x2, y2);
};

// 衝突タイルクラス通行可能判定 角
Game_CollideTile.prototype.isCorner = function(d) {
    switch (d) {
    case 9:  return this.isPassable(this._x, this._y - 1, 6) && this.isPassable(this._x + 1, this._y, 8);
    case 3:  return this.isPassable(this._x, this._y + 1, 6) && this.isPassable(this._x + 1, this._y, 2);
    case 1:  return this.isPassable(this._x, this._y + 1, 4) && this.isPassable(this._x - 1, this._y, 2);
    case 7:  return this.isPassable(this._x, this._y - 1, 4) && this.isPassable(this._x - 1, this._y, 8);
    default: return false;
    }
};

//-----------------------------------------------------------------------------
// Game_Map
//
// マップクラス

// マップクラスのセットアップ
Sanshiro.Game_AnalogMove.Game_Map_setup = Game_Map.prototype.setup;
Game_Map.prototype.setup = function(mapId) {
    Sanshiro.Game_AnalogMove.Game_Map_setup.call(this, mapId);
    Game_CollideMap.setup();
};

//-----------------------------------------------------------------------------
// Game_System
//
// システムクラス

// システムの初期化
Sanshiro.Game_AnalogMove.Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function() {
    Sanshiro.Game_AnalogMove.Game_System_initialize.call(this);
    this.setAnalogMoveValid(PluginManager.parameters('SAN_AnalogMove')['Valid'] === 'ON');
};

// システムの個別のアナログムーブ有効化フラグの設定
Game_System.prototype.setAnalogMoveValid = function(valid) {
    this._analogMoveValid = valid;
};

// システムの個別のアナログムーブ有効判定
Game_System.prototype.analogMoveValid = function() {
    return this._analogMoveValid;
};

//-----------------------------------------------------------------------------
// Input
//
// インプットクラス

// ゲームパッドステータスの更新
Sanshiro.Game_AnalogMove.Input_updateGamepadState = Input._updateGamepadState;
Input._updateGamepadState = function(gamepad) {
    Sanshiro.Game_AnalogMove.Input_updateGamepadState.call(this, gamepad);
    this._updateGamepadAxes(gamepad);
};

// アナログスティック値の更新
Input._updateGamepadAxes = function(gamepad) {
    this._axes = gamepad.axes;
};

// 左アナログスティック
Input.leftStick = function() {
    if (this._axes === undefined) {
        return undefined;
    }
    var threshold = 0.1;
    var x = this._axes[0];
    var y = this._axes[1];
    var tilt = (Math.pow(x, 2) + Math.pow(y, 2));
    if (tilt < threshold) {
        tilt = 0.0;
    } else if (tilt > 1.0) {
        tilt = 1.0;
    }
    var direction = 0.0
    if (x === 0.0) {
        direction = (-y > 0 ? Math.PI * 0.0 : Math.PI * 1.0);
    } else if (y === 0.0) {
        direction = (-x > 0 ? Math.PI * 0.5 : Math.PI * 1.5);
    } else {
        direction = Math.atan2(-x, -y);
    }
    return {tilt: tilt, direction: direction};
};

// 右アナログスティック
Input.rightStick = function() {
    if (this._axes === undefined) {
        return undefined;
    }
    var threshold = 0.1;
    var x = this._axes[2];
    var y = this._axes[3];
    var tilt = (Math.pow(x, 2) + Math.pow(y, 2));
    if (tilt < threshold) {
        tilt = 0.0;
    } else if (tilt > 1.0) {
        tilt = 1.0;
    }
    var direction = 0.0
    if (x === 0.0) {
        direction = (-y > 0 ? Math.PI * 0.0 : Math.PI * 1.0);
    } else if (y === 0.0) {
        direction = (-x > 0 ? Math.PI * 0.5 : Math.PI * 1.5);
    } else {
        direction = Math.atan2(-x, -y);
    }
    return {tilt: tilt, direction: direction};
};

//-----------------------------------------------------------------------------
// Scene_Map
//
// マップシーンクラス

// マップシーンクラスのメニューシーン呼び出し更新
Sanshiro.Game_AnalogMove.Scene_Map_updateCallMenu = Scene_Map.prototype.updateCallMenu;
Scene_Map.prototype.updateCallMenu = function() {
    var isMoving = $gamePlayer.isMoving;
    $gamePlayer.isMoving = function() { return false; };
    Sanshiro.Game_AnalogMove.Scene_Map_updateCallMenu.call(this);
    $gamePlayer.isMoving = isMoving;
};

// マップシーンクラスの開始処理
Sanshiro.Game_AnalogMove.Scene_Map_start = Scene_Map.prototype.start;
Scene_Map.prototype.start = function() {
    Sanshiro.Game_AnalogMove.Scene_Map_start.call(this);
    Game_CollideMap.setup();
};

//-----------------------------------------------------------------------------
// Game_CharacterBase
//
// キャラクターベースクラス

// キャラクターベースクラスのプロパティ初期化
Sanshiro.Game_AnalogMove.Game_CharacterBase_initMembers = Game_CharacterBase.prototype.initMembers;
Game_CharacterBase.prototype.initMembers = function() {
    Sanshiro.Game_AnalogMove.Game_CharacterBase_initMembers.call(this);
    this._analogMove = new Game_AnalogMove(this);
};

// キャラクターベースクラスの方向設定
Sanshiro.Game_AnalogMove.Game_CharacterBase_setDirection = Game_CharacterBase.prototype.setDirection;
Game_CharacterBase.prototype.setDirection = function(d) {
    Sanshiro.Game_AnalogMove.Game_CharacterBase_setDirection.call(this, d);
    if (!this.isDirectionFixed()) {
        this._analogMove.setDirectionRadianByDir8(this._direction);
    }
};

// キャラクターベースクラスのアナログムーブによる方向設定
Game_CharacterBase.prototype.setDirectionAnalog = function(d) {
    if (!this.isDirectionFixed()) {
        this._direction = d;
    }
};
   
// キャラクターベースクラスの移動中判定
Sanshiro.Game_AnalogMove.Game_CharacterBase_isMoving = Game_CharacterBase.prototype.isMoving;
Game_CharacterBase.prototype.isMoving = function() {
    if (this.isAnalogMoveValid()) {
        return this._analogMove.isMoving() && Game_AnalogMove.canMove();
    }
    return Sanshiro.Game_AnalogMove.Game_CharacterBase_isMoving.call(this);
};

// キャラクターベースクラスのフレーム更新
Sanshiro.Game_AnalogMove.Game_CharacterBase_update = Game_CharacterBase.prototype.update;
Game_CharacterBase.prototype.update = function() {
    if (this.isAnalogMoveValid()) {
        this._analogMove.update(this);
        var isMoving = this.isMoving;
        this.isMoving = function() { return false; };
        this.refreshBushDepth();
        this.isMoving = isMoving;
    }
    return Sanshiro.Game_AnalogMove.Game_CharacterBase_update.call(this);
};

// キャラクターベースクラスの移動更新
Sanshiro.Game_AnalogMove.Game_CharacterBase_updateMove = Game_CharacterBase.prototype.updateMove;
Game_CharacterBase.prototype.updateMove = function() {
    if (this.isAnalogMoveValid()) {
        return;
    }
    return Sanshiro.Game_AnalogMove.Game_CharacterBase_updateMove.call(this)
};

// キャラクターベースクラスの個別のアナログムーブ有効化フラグの設定
Game_CharacterBase.prototype.setAnalogMoveValid = function(valid) {
    this._analogMove.setValid(valid);
};

// キャラクターベースクラスの個別のアナログムーブ有効判定
Game_CharacterBase.prototype.isAnalogMoveValid = function() {
    return this._analogMove.isValid();
};

//-----------------------------------------------------------------------------
// Game_Character
//
// キャラクタークラス

// キャラクタークラスのルート指定移動
Sanshiro.Game_AnalogMove.Game_Character_updateRoutineMove = Game_Character.prototype.updateRoutineMove;
Game_Character.prototype.updateRoutineMove = function() {
    if (this.isAnalogMoveValid()) {
        return;
    }
    return Sanshiro.Game_AnalogMove.Game_Character_updateRoutineMove.call(this);
};

// キャラクタークラスの個別のアナログムーブ有効判定
Game_Character.prototype.isAnalogMoveValid = function() {
    return Game_CharacterBase.prototype.isAnalogMoveValid.call(this) && !this._moveRouteForcing;
};

//-----------------------------------------------------------------------------
// Game_Player
//
// プレイヤークラス

// プレイヤークラスのプロパティ初期化
Sanshiro.Game_AnalogMove.Game_Player_initMembers = Game_Player.prototype.initMembers;
Game_Player.prototype.initMembers = function() {
    Sanshiro.Game_AnalogMove.Game_Player_initMembers.call(this);
    this.setAnalogMoveValid(PluginManager.parameters('SAN_AnalogMove')['Player'] === 'ON');
    this._encounterCountAnalog = 0.0;
};

// プレイヤークラスのキー入力による移動
Sanshiro.Game_AnalogMove.Game_Player_moveByInput = Game_Player.prototype.moveByInput;
Game_Player.prototype.moveByInput = function() {
    if (this.isAnalogMoveValid()) {
        this._analogMove.moveByInput(this);
        this.checkEventTriggerTouchAnalog();
        this.checkEventTriggerActionAnalog();
        return;
    }
    return Sanshiro.Game_AnalogMove.Game_Player_moveByInput.call(this);
};

// プレイヤークラスのダッシュ状態の更新
Sanshiro.Game_AnalogMove.Game_Player_updateDashing = Game_Player.prototype.updateDashing;
Game_Player.prototype.updateDashing = function() {
    var isMoving = this.isMoving;
    this.isMoving = function() { return false };
    Sanshiro.Game_AnalogMove.Game_Player_updateDashing.call(this);
    this.isMoving = isMoving;
};

// プレイヤークラスのアナログムーブ時の接触イベント起動処理
Game_Player.prototype.checkEventTriggerTouchAnalog = function() {
    if (!this.isThrough() && !$gameMap.isEventRunning()) {
        var event = this._analogMove.collideEvents()[0];
        if (!!event && event.isTriggerIn([1, 2])) {
            event.start();
        }
    }
};

// プレイヤークラスのアナログムーブ時の決定ボタンイベント起動処理
Game_Player.prototype.checkEventTriggerActionAnalog = function() {
    this.triggerAction();
};

// プレイヤークラスの移動更新
Sanshiro.Game_AnalogMove.Game_Player_updateMove = Game_Player.prototype.updateMove;
Game_Player.prototype.updateMove = function() {
    if (this.isAnalogMoveValid()) {
        this.updateEncounterCountAnalog();
    }
    Sanshiro.Game_AnalogMove.Game_Player_updateMove.call(this);
};

// プレイヤークラスのアナログ移動エンカウント歩数カウントダウン
Game_Player.prototype.updateEncounterCountAnalog = function() {
    if (this.canEncounter()) {
        this._encounterCount -= this.encounterProgressValue() * this._analogMove.encounterCount();
    }
};

// プレイヤークラスの乗り物搭乗中のフレーム更新
Sanshiro.Game_AnalogMove.Game_Player_updateVehicleGetOn = Game_Player.prototype.updateVehicleGetOn;
Game_Player.prototype.updateVehicleGetOn = function() {
    Sanshiro.Game_AnalogMove.Game_Player_updateVehicleGetOn.call(this);
    if (!this._vehicleGettingOn) {
        Game_CollideMap.setup();
    }
};

// プレイヤークラスの乗り物下乗中のフレーム更新
Sanshiro.Game_AnalogMove.Game_Player_updateVehicleGetOff = Game_Player.prototype.updateVehicleGetOff;
Game_Player.prototype.updateVehicleGetOff = function() {
    Sanshiro.Game_AnalogMove.Game_Player_updateVehicleGetOff.call(this);
    if (!this._vehicleGettingOff) {
        Game_CollideMap.setup();
    }
};

// プレイヤークラスの個別のアナログムーブ有効判定
Game_Player.prototype.isAnalogMoveValid = function() {
    return Game_Character.prototype.isAnalogMoveValid.call(this) &&
        !this._followers.areGathering();
};

//-----------------------------------------------------------------------------
// Game_Follower
//
// フォロワークラス

// フォロワークラスの目標キャラクター追尾
Game_Follower.prototype.chaseCharacterAnalog = function(character) {
    this._analogMove.followCharacter(this, character);
};

// フォロワークラスのアナログムーブ有効判定
Game_Follower.prototype.isAnalogMoveValid = function() {
    return $gamePlayer.isAnalogMoveValid();
};

// フォロワークラスの移動更新
Sanshiro.Game_AnalogMove.Game_Follower_updateMove = Game_Follower.prototype.updateMove;
Game_Follower.prototype.updateMove = function() {
    Sanshiro.Game_AnalogMove.Game_Follower_updateMove.call(this);
};

//-----------------------------------------------------------------------------
// Game_Followers
//
// フォロワーズクラス

// フォロワーズクラスのフレーム更新
Sanshiro.Game_AnalogMove.Game_Followers_update = Game_Followers.prototype.update;
Game_Followers.prototype.update = function() {
    if ($gamePlayer.isAnalogMoveValid()) {
        this.updateMoveAnalog();
        this.forEach(function(follower) {
            follower.update();
        }, this);
        return;
    }
    Sanshiro.Game_AnalogMove.Game_Followers_update.call(this);
};

// フォロワーズクラスのアナログ移動の更新
Game_Followers.prototype.updateMoveAnalog = function() {
    for (var i = this._data.length - 1; i >= 0; i--) {
        var precedingCharacter = (i > 0 ? this._data[i - 1] : $gamePlayer);
        this._data.chaseCharacterAnalog(precedingCharacter);
    }
};

//-----------------------------------------------------------------------------
// Game_Interpreter
//
// インタープリタークラス

// プラグインコマンド
Sanshiro.Game_AnalogMove.Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
    Sanshiro.Game_AnalogMove.Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === 'AnalogMove') {
        switch (args[0]) {
        case 'ON':
            $gameSystem.setAnalogMoveValid(true);
            break;
        case 'OFF':
            $gameSystem.setAnalogMoveValid(false);
            break;
        case 'Player':
            switch (args[1]) {
            case 'ON':
                $gamePlayer.setAnalogMoveValid(true);
                break;
            case 'OFF':
                $gamePlayer.setAnalogMoveValid(false);
                break;
            }
        break;
        }
    $gamePlayer.refresh();
    }
};
[/pre]

也不錯

点评

呃,谢谢  发表于 2016-6-9 09:06
回复

使用道具 举报

梦石
0
星屑
50
在线时间
46 小时
注册时间
2014-3-14
回帖
32
 楼主| 发表于 2016-6-9 08:49:48 | 显示全部楼层
本帖最后由 moe2333 于 2016-6-9 08:51 编辑
taroxd 发表于 2016-6-9 07:42
Quasi Movement 这个插件我觉得挺不错的,楼主可以参考一下


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

如果我找得到合适的也就不会自己写了...我的游戏里不需要交通工具和鼠标操作,于是就变成现在这个样子了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部