游戏组件:精灵
用于2d游戏的基本精灵组件,带有动画和方向。
安装
npm install @basementuniverse/sprite
对于直接的浏览器使用,包括UMD构建与脚本标签:
<script src="build/index.js"></script>
控件公开其导出 BasementUniverseSprite 浏览器
名称空间。它不会将每个导出直接添加到 window.
如何使用
创建精灵:
import { Sprite } from '@basementuniverse/sprite';
const sprite = new Sprite({
// options here...
});
当直接从浏览器脚本中使用库时,使用
BasementUniverseSprite:
<script src="build/index.js"></script>
<script>
const sprite = new BasementUniverseSprite.Sprite({
// options here...
});
</script>
每帧更新精灵:
sprite.update(dt);
随时设置精灵的属性:
sprite.position = vec(100, 100);
sprite.scale = 1;
sprite.rotation = 0; // radians
(见 在这里 用于 vec 库)
获取或设置精灵的方向和动画:
sprite.animation = 'walk';
sprite.direction = 'right';
启动/暂停/重置当前动画:
sprite.playAnimation();
sprite.pauseAnimation();
sprite.resetAnimation();
每帧渲染精灵:
sprite.draw(context);
获取当前帧的图像:
sprite.image; // the image that draw() will use, updated by sprite.update()
在不改变精灵方向的情况下,在另一个方向获得相同的帧:
sprite.getImage('left');
从动画的一个图层中获取图像:
sprite.getImage(sprite.direction, 'normal');
选项
export type SpriteOptions = {
/**
* The position of the sprite
*
* Defaults to (0, 0)
*/
position?: vec;
/**
* The base size of the sprite
*
* If omitted, use the base image size, or fall back to the size of the
* first image found in available directions for the default animation
*
* If a size still can't be found, default to (0, 0)
*/
size?: vec;
/**
* Origin offset from top-left corner, used for rotation and scaling
*
* If omitted, this will be placed in the center of the sprite (based on
* size, noting that size will be calculated first)
*
* @see SpriteOptions.size
*/
origin?: vec;
/**
* The scale factor of the sprite
*
* Default is 1
*/
scale?: number;
/**
* The sprite rotation, measured in radians
*
* Default is 0
*/
rotation?: number;
/**
* An array of valid direction names
*
* By default a sprite will have one available direction: 'default'
*/
directions: string[];
/**
* The initial direction of the sprite
*
* Default is 'default'
*/
defaultDirection: string;
/**
* An optional base image
*
* If an animation frame doesn't exist (for example an animation has been
* configured with 5 frames but only 3 images exist in the animation's
* images array), we fall back to this image
*
* If an animation frame image can't be found and this base image doesn't
* exist, we can still render the sprite - it will just have an empty image
*
* (this can be useful for sprites that act purely as hosts for attachment
* points, for example)
*/
image?: HTMLImageElement | HTMLCanvasElement;
/**
* A dictionary of animations
*
* Each animation can have multiple variants for different directions
*
* Use '*' as a direction name to indicate that a variant is available for
* all directions and can be used as a fallback if the current direction
* can't be found
*/
animations: {
[name: string]: {
[direction: string]: SpriteAnimationOptions;
};
};
/**
* The initial animation for the sprite
*/
defaultAnimation: string;
/**
* A list of attachment points
*/
attachmentPoints?: SpriteAttachmentPointOptions[];
/**
* Optional hook called before rendering the sprite image
*/
preRender?: (
context: CanvasRenderingContext2D,
sprite: Sprite
) => void;
/**
* Optional hook called after rendering the sprite image
*/
postRender?: (
context: CanvasRenderingContext2D,
sprite: Sprite
) => void;
/**
* Optional debug options
*
* Can be a boolean value (in which case all sub-options will be set to the
* same value), or an object allowing specific debug options to be enabled
* individually
*/
debug?: Partial<SpriteDebugOptions> | boolean;
};
export type SpriteAnimationOptions = {
/**
* The name of this animation
*/
name: string;
/**
* The number of frames in this animation
*/
frameCount: number;
/**
* The number of frames per second when playing this animation
*/
frameRate: number;
/**
* The repeat mode for this animation
*/
mode: SpriteAnimationRepeatMode;
/**
* A list of images to use for each frame
*
* If this list is longer than frameCount, some images won't be used
*
* If this list if shorter than frameCount, we fall back to the base image
* or don't show an image for some frames
*/
images?: (HTMLImageElement | HTMLCanvasElement)[];
/**
* Named lists of extra images to go with each frame, for example normal maps
*
* These aren't drawn by the sprite, use `getImage()` to read them. Unlike
* `images` there's no fallback to the base image, if a layer doesn't have an
* image for a frame then `getImage()` will return null
*/
layers?: {
[layerName: string]: (HTMLImageElement | HTMLCanvasElement)[];
};
/**
* Keyframes for attachment points
*/
attachmentPointKeyframes?: {
[attachmentPointName: string]: SpriteAttachmentPointKeyframe[];
};
};
(见 build/index.d.ts 欲知详情)
附件分
精灵可以有多个命名的附着点。这些附点可以被赋予一个默认位置,并且位置可以通过每个动画中的关键帧来修改。
按名称获取附着点:
sprite.getAttachmentPoint('weapon-left-hand');
// returns a vec: { x: number; y: number } or null
这对于将多个精灵连接在一起非常有用。
内容处理器
提供了一个内容处理器函数,以便与 内容管理器.
import { spriteOptionsContentProcessor } from '@basementuniverse/sprite';
这个函数将接受一个JSON对象 SpriteOptions 类型(见下面对差异的解释)并返回a SpriteOptions 对象,该对象可以传递到 Sprite 构造函数。
-
JSON对象可能有
imageName: string字段而不是image. 图像名称将用于从内容管理器中获取图像,而imageName字段将被替换为image字段,包含已获取的图像。 -
类似地,JSON对象可能有
imageNames: string[]字段而不是images在每个动画中。这些图像将从内容管理器和imageNames字段将被替换为images字段,包含获取的图像。 -
每个动画也可以有
layerImageNames: { [layerName: string]: string[] }字段而不是layers,其转换方式相同。