“模组:常用方法”的版本间的差异
小 |
小 |
||
第13行: | 第13行: | ||
物品 代表那些能够放在背包里的东西,比如说工具、农作物等等。 | 物品 代表那些能够放在背包里的东西,比如说工具、农作物等等。 | ||
− | ===创建一个物品的实例 | + | ===创建一个物品 (Object) 的实例=== |
Object中所有的构造函数: | Object中所有的构造函数: | ||
2021年6月9日 (三) 14:25的版本
← 目录
页面仍需完善
该页面不完善且缺少信息。您可以通过扩充内容来帮助我们。 |
此页面展示了制作SMAPI模组时常见的任务。在阅读时,请结合参考模组制作入门和游戏基本架构。
基础技巧
追踪一个值的变化
在写模组时,你可能常常需要了解一个值的变化(什么时候变,变化前后的值分别是多少,等等)。如果该值没有包括在SMAPI内置的事件 (event)中,那么你可以为该值创建一个私有变量,然后在SMAPI的update tick事件中刷新此变量,以达到追踪值变化的目的。
示例见:[模组:制作指南/APIs/Events#变化监控]
物品 (Items)
物品 代表那些能够放在背包里的东西,比如说工具、农作物等等。
创建一个物品 (Object) 的实例
Object中所有的构造函数:
public Object(Vector2 tileLocation, int parentSheetIndex, int initialStack);
public Object(Vector2 tileLocation, int parentSheetIndex, bool isRecipe = false);
public Object(int parentSheetIndex, int initialStack, bool isRecipe = false, int price = -1, int quality = 0);
public Object(Vector2 tileLocation, int parentSheetIndex, string Givenname, bool canBeSetDown, bool canBeGrabbed, bool isHoedirt, bool isSpawnedObject);
参数parentSheetIndex表示该物品的ID(储存在 ObjectInformation.xnb 文件中)。
在地上生成物品
public virtual bool dropObject(Object obj, Vector2 dropLocation, xTile.Dimensions.Rectangle viewport, bool initialPlacement, Farmer who = null);
// 调用:
Game1.getLocationFromName("Farm").dropObject(new StardewValley.Object(itemId, 1, false, -1, 0), new Vector2(x, y) * 64f, Game1.viewport, true, (Farmer)null);
添加物品到背包 (Inventory)
// You can add items found in ObjectInformation using:
Game1.player.addItemByMenuIfNecessary((Item)new StardewValley.Object(int parentSheetIndex, int initialStack, [bool isRecipe = false], [int price = -1], [int quality = 0]));
例2:
// Add a weapon directly into player's inventory
const int WEAP_ID = 19; // Shadow Dagger -- see Data/weapons
Item weapon = new MeleeWeapon(WEAP_ID); // MeleeWeapon is a class in StardewValley.Tools
Game1.player.addItemByMenuIfNecessary(weapon);
// Note: This code WORKS.
从背包移除物品
取决于你背包的具体情况。很少有情况需要你亲自来调用,因为相关的方法在Farmer类中已经有了。
在大多数情况下,仅需调用 .removeItemFromInventory(Item) 方法。
地点 (Locations)
见 游戏基本架构#地点。
获取所有地点
Game1.locations
属性中虽然储存着主要的地点,但是不包括建筑的室内(constructed building interiors)。以下这个方法提供了主玩家的所有地点。
/// <summary>Get all game locations.</summary>
public static IEnumerable<GameLocation> GetLocations()
{
return Game1.locations
.Concat(
from location in Game1.locations.OfType<BuildableGameLocation>()
from building in location.buildings
where building.indoors.Value != null
select building.indoors.Value
);
}
遍历:
foreach (GameLocation location in this.GetLocations())
{
// ...
}
注意:在联机模式中,客机是拿不到上述所有地点的。要解决这一问题,见获取有效的地点。
编辑地图
见模组:地图数据。
玩家 (Player)
自定义精灵 (Custom Sprite)
位置 (Position)
角色(Character) 的位置(Position) 表示他在当前地点(Location) 的坐标。
相对于地图 (Map)
每个地点(location) 都有一个对应的xTile地图(map)。如果以像素(pixel) 为单位,地图左上角坐标代表(0, 0),坐下角则代表(location.Map.DisplayWidth, location.Map.DisplayHeight)。 角色在当前地点的位置有两种表达方式:
- 以像素(pixel) 为单位的绝对(absoulte) 坐标:
Position.X
与Position.Y
。 - 以图块(tile) 为单位的图块(tile) 坐标:
getTileX()
与getTileY()
。
常量Game1.tileSize
规定,游戏内每个图块(tile) 大小为64x64像素。于是有以下单位换算:
// 绝对坐标 → 图块坐标
Math.Floor(Game1.player.Position.X / Game1.tileSize)
Math.Floor(Game1.player.Position.Y / Game1.tileSize)
// 图块坐标 → 绝对坐标
Game1.player.getTileX() * Game1.tileSize
Game1.player.getTileY() * Game1.tileSize
// 地图大小(以图块为单位)
Math.Floor(Game1.player.currentLocation.Map.DisplayWidth / Game1.tileSize)
Math.Floor(Game1.player.currentLocation.Map.DisplayHeight / Game1.tileSize)
相对于视野 (Viewport)
视野、视口、视窗(Viewport) 代表在当前屏幕上的区域。若以像素计算,其宽高应该与游戏的屏幕分辨率相等,分别为Game1.viewport.Width
和Game1.viewport.Height
。
玩家相对于视野的位置(像素)可表示为:
Game1.player.Position.X - Game1.viewport.X
Game1.player.Position.Y - Game1.viewport.Y