赞 | 65 |
VIP | 231 |
好人卡 | 2 |
积分 | 19 |
经验 | 35171 |
最后登录 | 2024-9-15 |
在线时间 | 1554 小时 |
Lv3.寻梦者
- 梦石
- 0
- 星屑
- 1912
- 在线时间
- 1554 小时
- 注册时间
- 2013-4-13
- 帖子
- 917
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 沉滞的剑 于 2020-5-28 20:49 编辑
脚本功能: 允许角色自由移动
适用于: 需要让主角更自然地在场景中进行移动
支持键盘/鼠标和手柄
如果有类似成熟的脚本话 请给个链接好不好 我去学习一下 谢谢~
如果有bug欢迎反馈~
更新日志:
5.8 重做, 将人物改为矩形碰撞检测
const Base = {}; // Check if it is an object { Base.isObject = (object) => { return ["object", "function"].includes(typeof object) && object !== null; }; } // Get value from object by path { const _get = (_object, _path, defaultValue) => { if (_path.length) { if (!Base.isObject(_object)) { return defaultValue; } const currentPath = _path.shift(); return _get(_object[currentPath], _path, defaultValue); } return _object === undefined ? defaultValue : _object; }; Base.get = (object, path, defaultValue) => { return _get(object, path.split("."), defaultValue); }; } // Set value from object by path { const _set = (_object, _path, value) => { const currentPath = _path.shift(); if (_path.length) { if (!Base.isObject(_object[currentPath])) { _object[currentPath] = {}; } _set(_object[currentPath], _path, value); } else { _object[currentPath] = value; } }; Base.set = (object, path, value) => { return _set(object, path.split("."), value); }; } // Filter small values within a range { Base.stair = (num, threadhold, offset = 0) => (Math.abs(num + offset) < threadhold ? offset : num); } // Input { const { get, stair } = Base; Input._axesX = []; Input._axesY = []; Input._updateGamepadState = function (gamepad) { const { buttons, axes, index } = gamepad; const newState = []; const lastState = get(this, `_gamepadStates.${index}`, []); const threshold = 0.3; buttons.forEach((v, i) => { newState[i] = v.pressed; }); newState[12] = axes[1] < -threshold; newState[13] = axes[1] > threshold; newState[14] = axes[0] < -threshold; newState[15] = axes[0] > threshold; newState.forEach((v, i) => { if (lastState[i] !== v) { const buttonName = this.gamepadMapper[i]; this._currentState[buttonName] = !!newState[i]; } }); this._gamepadStates[index] = newState; Input._axesX[index] = stair(axes[0], threshold); Input._axesY[index] = stair(axes[1], threshold); }; Object.defineProperties(Input, { axesX: { get: () => Input._axesX.find(Boolean) || 0, }, axesY: { get: () => Input._axesY.find(Boolean) || 0, }, keyX: { get: () => { let x = 0; if (Input._currentState["left"]) x -= 1; if (Input._currentState["right"]) x += 1; return x; }, }, keyY: { get: () => { let y = 0; if (Input._currentState["up"]) y -= 1; if (Input._currentState["down"]) y += 1; return y; }, }, velocity: { get: () => Math.min(Math.sqrt(Input.axesX ** 2 + Input.axesY ** 2), 100), }, inputX: { get: () => (Input.velocity ? Input.axesX : Input.keyX), }, inputY: { get: () => (Input.velocity ? Input.axesY : Input.keyY), }, }); } // Touch Input { Scene_Map.prototype.processMapTouch = function () { if (TouchInput.isTriggered() || this._touchCount > 0) { if (TouchInput.isPressed()) { if (this._touchCount === 0 || this._touchCount >= 15) { var x = $gameMap.canvasToMapXTouch(TouchInput.x); var y = $gameMap.canvasToMapYTouch(TouchInput.y); $gameTemp.setDestination(x, y); } this._touchCount++; } else { this._touchCount = 0; } } }; Scene_Map.prototype.updateDestination = function () { if (this.isMapTouchOk()) { this.processMapTouch(); } else { this._touchCount = 0; } }; Game_Map.prototype.canvasToMapXTouch = function (x) { var tileWidth = this.tileWidth(); var originX = this._displayX * tileWidth; var mapX = (originX + x) / tileWidth - 0.5; return mapX; }; Game_Map.prototype.canvasToMapYTouch = function (y) { var tileHeight = this.tileHeight(); var originY = this._displayY * tileHeight; var mapY = (originY + y) / tileHeight - 0.5; return mapY; }; } // Player { const DIR = { DOWN_LEFT: 1, DOWN: 2, DOWN_RIGHT: 3, LEFT: 4, IDLE: 0, RIGHT: 6, UP_LEFT: 7, UP: 8, UP_RIGHT: 9, }; const UNIT_STEP = 0.1; Game_Player.prototype.getInputDirection = function () { return Input.dir8; }; Game_Player.prototype.reverseDir = function (d) { return (10 - d) % 10; }; Game_Player.prototype.executeMove = function (dx, dy) { if (Math.abs(dx) > Math.abs(dy)) { if (dx > 0) { this.setDirection(DIR.RIGHT); } else { this.setDirection(DIR.LEFT); } } else { if (dy > 0) { this.setDirection(DIR.DOWN); } else { this.setDirection(DIR.UP); } } const check = []; if (dx > 0) check.push(DIR.RIGHT); if (dx < 0) check.push(DIR.LEFT); if (dy > 0) check.push(DIR.DOWN); if (dy < 0) check.push(DIR.UP); for (let i of check) { if (!this.rectCanPass(dx, dy, i)) { if ([DIR.RIGHT, DIR.LEFT].includes(i)) dx = 0; if ([DIR.DOWN, DIR.UP].includes(i)) dy = 0; } } if (!Math.abs(dx) && !Math.abs(dy)) { $gameTemp.clearDestination(); return; } this._realX = this._x; this._realY = this._y; this._x += dx; this._y += dy; }; Object.defineProperties(Game_Player.prototype, { rect: { get: function () { return new Rectangle(this._x + 0.06, this._y + 0.06, 0.75, 0.75); }, }, }); Game_Player.prototype.rectCanPass = function (dx, dy, direction) { const { left, right, top, bottom } = this.rect; const rd = this.reverseDir(direction); if (!this.canPass(left, top, rd)) return false; if (!this.canPass(left, bottom, rd)) return false; if (!this.canPass(right, top, rd)) return false; if (!this.canPass(right, bottom, rd)) return false; if (!this.canPass(left + dx, top + dy, direction)) return false; if (!this.canPass(left + dx, bottom + dy, direction)) return false; if (!this.canPass(right + dx, top + dy, direction)) return false; if (!this.canPass(right + dx, bottom + dy, direction)) return false; return true; }; Game_Player.prototype.canPass = function (x, y, d) { x = Math.floor(x); y = Math.floor(y); if (!$gameMap.isValid(x, y)) { return false; } if (this.isThrough() || this.isDebugThrough()) { return true; } if (!this.isMapPassable(x, y, d)) { return false; } if (this.isCollidedWithCharacters(x, y)) { return false; } return true; }; Game_Player.prototype.isMapPassable = function (x, y, d) { return $gameMap.isPassable(x, y, d); }; Game_Player.prototype.moveByInput = function () { if (!this.isMoving() && this.canMove()) { var direction = this.getInputDirection(); let dx, dy; if (direction > 0) { $gameTemp.clearDestination(); dx = +(Input.inputX * UNIT_STEP).toFixed(3); dy = +(Input.inputY * UNIT_STEP).toFixed(3); } else if ($gameTemp.isDestinationValid()) { dx = $gameTemp.destinationX() - this._x; dy = $gameTemp.destinationY() - this._y; if (Math.abs(dx) < 0.1 && Math.abs(dy) < 0.1) { $gameTemp.clearDestination(); return; } if (Math.abs(dx) > Math.abs(dy)) { dx = dx / Math.abs(dx); dy = dy / Math.abs(dx); } else { dx = dx / Math.abs(dy); dy = dy / Math.abs(dy); } dx *= UNIT_STEP; dy *= UNIT_STEP; } if (dx || dy) { this.executeMove(dx, dy); } } }; 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(); } } }; Game_Player.prototype.distancePerFrame = function () { return Math.pow(2, this.realMoveSpeed()) / 256 / 2; }; } // NPC { Game_CharacterBase.prototype.pos = function (x, y) { return Math.abs(this._x - x) <= 0.5 && Math.abs(this._y - y) <= 0.5; }; Game_Event.prototype.isCollidedWithEvents = function (x, y) { var events = $gameMap.eventsXyNt(x, y).filter((item) => item !== this); return events.length > 0; }; }
const Base = {};
// Check if it is an object
{
Base.isObject = (object) => {
return ["object", "function"].includes(typeof object) && object !== null;
};
}
// Get value from object by path
{
const _get = (_object, _path, defaultValue) => {
if (_path.length) {
if (!Base.isObject(_object)) {
return defaultValue;
}
const currentPath = _path.shift();
return _get(_object[currentPath], _path, defaultValue);
}
return _object === undefined ? defaultValue : _object;
};
Base.get = (object, path, defaultValue) => {
return _get(object, path.split("."), defaultValue);
};
}
// Set value from object by path
{
const _set = (_object, _path, value) => {
const currentPath = _path.shift();
if (_path.length) {
if (!Base.isObject(_object[currentPath])) {
_object[currentPath] = {};
}
_set(_object[currentPath], _path, value);
} else {
_object[currentPath] = value;
}
};
Base.set = (object, path, value) => {
return _set(object, path.split("."), value);
};
}
// Filter small values within a range
{
Base.stair = (num, threadhold, offset = 0) => (Math.abs(num + offset) < threadhold ? offset : num);
}
// Input
{
const { get, stair } = Base;
Input._axesX = [];
Input._axesY = [];
Input._updateGamepadState = function (gamepad) {
const { buttons, axes, index } = gamepad;
const newState = [];
const lastState = get(this, `_gamepadStates.${index}`, []);
const threshold = 0.3;
buttons.forEach((v, i) => {
newState[i] = v.pressed;
});
newState[12] = axes[1] < -threshold;
newState[13] = axes[1] > threshold;
newState[14] = axes[0] < -threshold;
newState[15] = axes[0] > threshold;
newState.forEach((v, i) => {
if (lastState[i] !== v) {
const buttonName = this.gamepadMapper[i];
this._currentState[buttonName] = !!newState[i];
}
});
this._gamepadStates[index] = newState;
Input._axesX[index] = stair(axes[0], threshold);
Input._axesY[index] = stair(axes[1], threshold);
};
Object.defineProperties(Input, {
axesX: {
get: () => Input._axesX.find(Boolean) || 0,
},
axesY: {
get: () => Input._axesY.find(Boolean) || 0,
},
keyX: {
get: () => {
let x = 0;
if (Input._currentState["left"]) x -= 1;
if (Input._currentState["right"]) x += 1;
return x;
},
},
keyY: {
get: () => {
let y = 0;
if (Input._currentState["up"]) y -= 1;
if (Input._currentState["down"]) y += 1;
return y;
},
},
velocity: {
get: () => Math.min(Math.sqrt(Input.axesX ** 2 + Input.axesY ** 2), 100),
},
inputX: {
get: () => (Input.velocity ? Input.axesX : Input.keyX),
},
inputY: {
get: () => (Input.velocity ? Input.axesY : Input.keyY),
},
});
}
// Touch Input
{
Scene_Map.prototype.processMapTouch = function () {
if (TouchInput.isTriggered() || this._touchCount > 0) {
if (TouchInput.isPressed()) {
if (this._touchCount === 0 || this._touchCount >= 15) {
var x = $gameMap.canvasToMapXTouch(TouchInput.x);
var y = $gameMap.canvasToMapYTouch(TouchInput.y);
$gameTemp.setDestination(x, y);
}
this._touchCount++;
} else {
this._touchCount = 0;
}
}
};
Scene_Map.prototype.updateDestination = function () {
if (this.isMapTouchOk()) {
this.processMapTouch();
} else {
this._touchCount = 0;
}
};
Game_Map.prototype.canvasToMapXTouch = function (x) {
var tileWidth = this.tileWidth();
var originX = this._displayX * tileWidth;
var mapX = (originX + x) / tileWidth - 0.5;
return mapX;
};
Game_Map.prototype.canvasToMapYTouch = function (y) {
var tileHeight = this.tileHeight();
var originY = this._displayY * tileHeight;
var mapY = (originY + y) / tileHeight - 0.5;
return mapY;
};
}
// Player
{
const DIR = {
DOWN_LEFT: 1,
DOWN: 2,
DOWN_RIGHT: 3,
LEFT: 4,
IDLE: 0,
RIGHT: 6,
UP_LEFT: 7,
UP: 8,
UP_RIGHT: 9,
};
const UNIT_STEP = 0.1;
Game_Player.prototype.getInputDirection = function () {
return Input.dir8;
};
Game_Player.prototype.reverseDir = function (d) {
return (10 - d) % 10;
};
Game_Player.prototype.executeMove = function (dx, dy) {
if (Math.abs(dx) > Math.abs(dy)) {
if (dx > 0) {
this.setDirection(DIR.RIGHT);
} else {
this.setDirection(DIR.LEFT);
}
} else {
if (dy > 0) {
this.setDirection(DIR.DOWN);
} else {
this.setDirection(DIR.UP);
}
}
const check = [];
if (dx > 0) check.push(DIR.RIGHT);
if (dx < 0) check.push(DIR.LEFT);
if (dy > 0) check.push(DIR.DOWN);
if (dy < 0) check.push(DIR.UP);
for (let i of check) {
if (!this.rectCanPass(dx, dy, i)) {
if ([DIR.RIGHT, DIR.LEFT].includes(i)) dx = 0;
if ([DIR.DOWN, DIR.UP].includes(i)) dy = 0;
}
}
if (!Math.abs(dx) && !Math.abs(dy)) {
$gameTemp.clearDestination();
return;
}
this._realX = this._x;
this._realY = this._y;
this._x += dx;
this._y += dy;
};
Object.defineProperties(Game_Player.prototype, {
rect: {
get: function () {
return new Rectangle(this._x + 0.06, this._y + 0.06, 0.75, 0.75);
},
},
});
Game_Player.prototype.rectCanPass = function (dx, dy, direction) {
const { left, right, top, bottom } = this.rect;
const rd = this.reverseDir(direction);
if (!this.canPass(left, top, rd)) return false;
if (!this.canPass(left, bottom, rd)) return false;
if (!this.canPass(right, top, rd)) return false;
if (!this.canPass(right, bottom, rd)) return false;
if (!this.canPass(left + dx, top + dy, direction)) return false;
if (!this.canPass(left + dx, bottom + dy, direction)) return false;
if (!this.canPass(right + dx, top + dy, direction)) return false;
if (!this.canPass(right + dx, bottom + dy, direction)) return false;
return true;
};
Game_Player.prototype.canPass = function (x, y, d) {
x = Math.floor(x);
y = Math.floor(y);
if (!$gameMap.isValid(x, y)) {
return false;
}
if (this.isThrough() || this.isDebugThrough()) {
return true;
}
if (!this.isMapPassable(x, y, d)) {
return false;
}
if (this.isCollidedWithCharacters(x, y)) {
return false;
}
return true;
};
Game_Player.prototype.isMapPassable = function (x, y, d) {
return $gameMap.isPassable(x, y, d);
};
Game_Player.prototype.moveByInput = function () {
if (!this.isMoving() && this.canMove()) {
var direction = this.getInputDirection();
let dx, dy;
if (direction > 0) {
$gameTemp.clearDestination();
dx = +(Input.inputX * UNIT_STEP).toFixed(3);
dy = +(Input.inputY * UNIT_STEP).toFixed(3);
} else if ($gameTemp.isDestinationValid()) {
dx = $gameTemp.destinationX() - this._x;
dy = $gameTemp.destinationY() - this._y;
if (Math.abs(dx) < 0.1 && Math.abs(dy) < 0.1) {
$gameTemp.clearDestination();
return;
}
if (Math.abs(dx) > Math.abs(dy)) {
dx = dx / Math.abs(dx);
dy = dy / Math.abs(dx);
} else {
dx = dx / Math.abs(dy);
dy = dy / Math.abs(dy);
}
dx *= UNIT_STEP;
dy *= UNIT_STEP;
}
if (dx || dy) {
this.executeMove(dx, dy);
}
}
};
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();
}
}
};
Game_Player.prototype.distancePerFrame = function () {
return Math.pow(2, this.realMoveSpeed()) / 256 / 2;
};
}
// NPC
{
Game_CharacterBase.prototype.pos = function (x, y) {
return Math.abs(this._x - x) <= 0.5 && Math.abs(this._y - y) <= 0.5;
};
Game_Event.prototype.isCollidedWithEvents = function (x, y) {
var events = $gameMap.eventsXyNt(x, y).filter((item) => item !== this);
return events.length > 0;
};
}
|
评分
-
查看全部评分
|