mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-30 00:31:29 +08:00
feat(inventory) 添加背包物品移动、拾取到背包、丢弃背包物品功能
This commit is contained in:
1 parent
ae26209a24
commit
35e10a2abc
6 files changed
+408
-115
No files matched your search
+84
-54
@@ -26,25 +26,29 @@ export class Inventory {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查物品是否可以放置在指定位置
|
||||
* 检查物品是否可以放置在指定位置(以物品中心为基础点)
|
||||
* @param {Object} item - 要放置的物品
|
||||
* @param {number} x - 起始X坐标
|
||||
* @param {number} y - 起始Y坐标
|
||||
* @param {number} centerX - 中心X坐标
|
||||
* @param {number} centerY - 中心Y坐标
|
||||
* @returns {boolean} 是否可以放置
|
||||
*/
|
||||
canPlaceItem(item, x, y) {
|
||||
canPlaceItem(item, centerX, centerY) {
|
||||
const { gridSize } = item;
|
||||
|
||||
// 将中心坐标转换为左上角坐标
|
||||
const topLeftX = Math.floor(centerX - (gridSize.width - 1) / 2);
|
||||
const topLeftY = Math.floor(centerY - (gridSize.height - 1) / 2);
|
||||
|
||||
// 检查物品尺寸是否在背包范围内
|
||||
if (x < 0 || y < 0 || x + gridSize.width > this.width || y + gridSize.height > this.height) {
|
||||
if (topLeftX < 0 || topLeftY < 0 || topLeftX + gridSize.width > this.width || topLeftY + gridSize.height > this.height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查物品占用的所有格子是否都是空的或属于物品自身
|
||||
for (let dy = 0; dy < gridSize.height; dy++) {
|
||||
for (let dx = 0; dx < gridSize.width; dx++) {
|
||||
const gridX = x + dx;
|
||||
const gridY = y + dy;
|
||||
const gridX = topLeftX + dx;
|
||||
const gridY = topLeftY + dy;
|
||||
const cellItemId = this.grid[gridY][gridX];
|
||||
|
||||
// 如果格子不是空的,且不是物品自身,则不能放置
|
||||
@@ -58,29 +62,39 @@ export class Inventory {
|
||||
}
|
||||
|
||||
/**
|
||||
* 放置物品到背包中
|
||||
* 放置物品到背包中(以物品中心为基础点)
|
||||
* @param {Object} item - 要放置的物品
|
||||
* @param {number} x - 起始X坐标
|
||||
* @param {number} y - 起始Y坐标
|
||||
* @param {number} centerX - 中心X坐标
|
||||
* @param {number} centerY - 中心Y坐标
|
||||
* @returns {boolean} 是否放置成功
|
||||
*/
|
||||
placeItem(item, x, y) {
|
||||
if (!this.canPlaceItem(item, x, y)) {
|
||||
placeItem(item, centerX, centerY) {
|
||||
if (!this.canPlaceItem(item, centerX, centerY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { gridSize } = item;
|
||||
|
||||
// 将中心坐标转换为左上角坐标
|
||||
const topLeftX = Math.floor(centerX - (gridSize.width - 1) / 2);
|
||||
const topLeftY = Math.floor(centerY - (gridSize.height - 1) / 2);
|
||||
|
||||
// 计算物品中心坐标(用于物品信息)
|
||||
const centerPos = {
|
||||
x: centerX,
|
||||
y: centerY
|
||||
};
|
||||
|
||||
// 记录物品在背包中的位置信息 - 同时设置position和positionInInventory确保一致性
|
||||
item.position = { x, y };
|
||||
item.positionInInventory = { x, y };
|
||||
item.position = centerPos;
|
||||
item.positionInInventory = centerPos;
|
||||
item.inventory = this;
|
||||
item.inInventory = true;
|
||||
|
||||
// 更新网格和物品列表
|
||||
for (let dy = 0; dy < gridSize.height; dy++) {
|
||||
for (let dx = 0; dx < gridSize.width; dx++) {
|
||||
this.grid[y + dy][x + dx] = item.id;
|
||||
this.grid[topLeftY + dy][topLeftX + dx] = item.id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,10 +134,14 @@ export class Inventory {
|
||||
|
||||
const { position, gridSize } = item;
|
||||
|
||||
// 计算物品占用的左上角坐标(从中心坐标转换)
|
||||
const topLeftX = Math.floor(position.x - (gridSize.width - 1) / 2);
|
||||
const topLeftY = Math.floor(position.y - (gridSize.height - 1) / 2);
|
||||
|
||||
// 清空网格
|
||||
for (let dy = 0; dy < gridSize.height; dy++) {
|
||||
for (let dx = 0; dx < gridSize.width; dx++) {
|
||||
this.grid[position.y + dy][position.x + dx] = null;
|
||||
this.grid[topLeftY + dy][topLeftX + dx] = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,59 +158,65 @@ export class Inventory {
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动背包中的物品
|
||||
* 移动背包中的物品(以物品中心为基础点)
|
||||
* @param {string} itemId - 物品ID
|
||||
* @param {number} newX - 新的X坐标
|
||||
* @param {number} newY - 新的Y坐标
|
||||
* @param {number} newCenterX - 新的中心X坐标
|
||||
* @param {number} newCenterY - 新的中心Y坐标
|
||||
* @returns {boolean} 是否移动成功
|
||||
*/
|
||||
moveItem(itemId, newX, newY) {
|
||||
console.log('moveItem called:', itemId, 'to position:', { newX, newY });
|
||||
moveItem(itemId, newCenterX, newCenterY) {
|
||||
console.log('moveItem called:', itemId, 'to center position:', { newCenterX, newCenterY });
|
||||
const item = this.items.get(itemId);
|
||||
if (!item) {
|
||||
console.log('moveItem failed: 物品不存在');
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('移动物品:', item.name, '当前位置:', item.position, '目标位置:', { newX, newY });
|
||||
console.log('移动物品:', item.name, '当前中心位置:', item.position, '目标中心位置:', { newCenterX, newCenterY });
|
||||
|
||||
// 检查新位置是否可以放置
|
||||
if (!this.canPlaceItem(item, newX, newY)) {
|
||||
if (!this.canPlaceItem(item, newCenterX, newCenterY)) {
|
||||
console.log('moveItem failed: 新位置无法放置物品');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 保存旧位置信息
|
||||
const oldX = item.position.x;
|
||||
const oldY = item.position.y;
|
||||
const { gridSize } = item;
|
||||
|
||||
console.log('清空旧位置网格:', { oldX, oldY }, '尺寸:', gridSize);
|
||||
// 清空旧位置的网格
|
||||
// 清空旧位置的网格(需要先计算旧位置的左上角坐标)
|
||||
const oldCenterX = item.position.x;
|
||||
const oldCenterY = item.position.y;
|
||||
const oldTopLeftX = Math.floor(oldCenterX - (gridSize.width - 1) / 2);
|
||||
const oldTopLeftY = Math.floor(oldCenterY - (gridSize.height - 1) / 2);
|
||||
|
||||
console.log('清空旧位置网格:', { oldTopLeftX, oldTopLeftY }, '尺寸:', gridSize);
|
||||
for (let dy = 0; dy < gridSize.height; dy++) {
|
||||
for (let dx = 0; dx < gridSize.width; dx++) {
|
||||
this.grid[oldY + dy][oldX + dx] = null;
|
||||
this.grid[oldTopLeftY + dy][oldTopLeftX + dx] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新物品位置
|
||||
item.position = { x: newX, y: newY };
|
||||
item.positionInInventory = { x: newX, y: newY };
|
||||
console.log('更新物品位置:', item.position);
|
||||
// 更新物品位置为新的中心坐标
|
||||
const newCenterPos = { x: newCenterX, y: newCenterY };
|
||||
item.position = newCenterPos;
|
||||
item.positionInInventory = newCenterPos;
|
||||
console.log('更新物品中心位置:', item.position);
|
||||
|
||||
// 更新新位置的网格(需要计算新位置的左上角坐标)
|
||||
const newTopLeftX = Math.floor(newCenterX - (gridSize.width - 1) / 2);
|
||||
const newTopLeftY = Math.floor(newCenterY - (gridSize.height - 1) / 2);
|
||||
|
||||
// 更新新位置的网格
|
||||
for (let dy = 0; dy < gridSize.height; dy++) {
|
||||
for (let dx = 0; dx < gridSize.width; dx++) {
|
||||
this.grid[newY + dy][newX + dx] = item.id;
|
||||
this.grid[newTopLeftY + dy][newTopLeftX + dx] = item.id;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('moveItem success:', item.name, '已移动到', { newX, newY });
|
||||
console.log('moveItem success:', item.name, '已移动到中心位置', { newCenterX, newCenterY });
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 交换两个物品的位置
|
||||
* 交换两个物品的位置(以物品中心为基础点)
|
||||
* @param {string} itemId1 - 第一个物品ID
|
||||
* @param {string} itemId2 - 第二个物品ID
|
||||
* @returns {boolean} 是否交换成功
|
||||
@@ -208,33 +232,34 @@ export class Inventory {
|
||||
}
|
||||
|
||||
console.log('交换物品:', item1.name, '与', item2.name);
|
||||
console.log('物品1位置:', item1.position, '物品2位置:', item2.position);
|
||||
console.log('物品1中心位置:', item1.position, '物品2中心位置:', item2.position);
|
||||
|
||||
const pos1 = { ...item1.position };
|
||||
const pos2 = { ...item2.position };
|
||||
// 保存两个物品的中心位置
|
||||
const centerPos1 = { ...item1.position };
|
||||
const centerPos2 = { ...item2.position };
|
||||
|
||||
// 移除两个物品
|
||||
console.log('移除两个物品');
|
||||
this.removeItem(itemId1);
|
||||
this.removeItem(itemId2);
|
||||
|
||||
// 尝试在对方位置放置
|
||||
console.log('尝试将物品1放置到物品2的位置:', pos2);
|
||||
if (!this.placeItem(item1, pos2.x, pos2.y)) {
|
||||
// 尝试在对方位置放置(使用中心坐标)
|
||||
console.log('尝试将物品1放置到物品2的中心位置:', centerPos2);
|
||||
if (!this.placeItem(item1, centerPos2.x, centerPos2.y)) {
|
||||
// 回滚:将两个物品放回原位置
|
||||
console.log('swapItems failed: 物品1无法放置到物品2的位置,回滚');
|
||||
this.placeItem(item1, pos1.x, pos1.y);
|
||||
this.placeItem(item2, pos2.x, pos2.y);
|
||||
this.placeItem(item1, centerPos1.x, centerPos1.y);
|
||||
this.placeItem(item2, centerPos2.x, centerPos2.y);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('尝试将物品2放置到物品1的位置:', pos1);
|
||||
if (!this.placeItem(item2, pos1.x, pos1.y)) {
|
||||
console.log('尝试将物品2放置到物品1的中心位置:', centerPos1);
|
||||
if (!this.placeItem(item2, centerPos1.x, centerPos1.y)) {
|
||||
// 回滚:将第一个物品放回原位置,第二个物品也放回原位置
|
||||
console.log('swapItems failed: 物品2无法放置到物品1的位置,回滚');
|
||||
this.removeItem(itemId1);
|
||||
this.placeItem(item1, pos1.x, pos1.y);
|
||||
this.placeItem(item2, pos2.x, pos2.y);
|
||||
this.placeItem(item1, centerPos1.x, centerPos1.y);
|
||||
this.placeItem(item2, centerPos2.x, centerPos2.y);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -243,9 +268,9 @@ export class Inventory {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找第一个可用的空位
|
||||
* 查找第一个可用的空位(返回中心坐标)
|
||||
* @param {Object} item - 要放置的物品
|
||||
* @returns {Object|null} 可用位置
|
||||
* @returns {Object|null} 可用中心位置
|
||||
*/
|
||||
findEmptySpot(item) {
|
||||
const { gridSize } = item;
|
||||
@@ -256,11 +281,16 @@ export class Inventory {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 遍历背包网格,寻找可用位置
|
||||
// 遍历背包网格,寻找可用位置(以左上角为起点)
|
||||
for (let y = 0; y <= this.height - gridSize.height; y++) {
|
||||
for (let x = 0; x <= this.width - gridSize.width; x++) {
|
||||
if (this.canPlaceItem(item, x, y)) {
|
||||
return { x, y };
|
||||
// 计算该左上角位置对应的中心坐标
|
||||
// 注意:这里需要确保与canPlaceItem方法中的坐标转换对称
|
||||
const centerX = x + (gridSize.width - 1) / 2;
|
||||
const centerY = y + (gridSize.height - 1) / 2;
|
||||
|
||||
if (this.canPlaceItem(item, centerX, centerY)) {
|
||||
return { x: centerX, y: centerY };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user