CocosCreator中,显示SpriteFrame的一部分
2022-10-28 本文已影响0人
全新的饭
说明
将一个SpriteFrame横向均分x份,纵向均分成y份,显示其中的第n份。
image.png
如图,横向均分成3份,纵向均分成4份,显示(右侧小方块中)其中的第(2,1)个。(从0开始数,起点是左上,终点是右下)。
// 左边显示的完整图
this._sprite.spriteFrame = spriteFrame;
// 将给定图片分成若干份,显示其中的一份。
const width = spriteFrame.width / 3;
const height = spriteFrame.height / 4;
const x = width*2;
const y = height;
const rect = new Rect(x, y, width, height);
const sectionSprite = spriteFrame.clone();
sectionSprite.rect = rect;
this._sectionSprite.spriteFrame = sectionSprite;
应用
传入完整图片(SpriteFrame)、区域(宽、高、中心位置),将其划分成若干方块显示:CreateElements
DivideImg.ts
import { _decorator, Component, Node, SpriteFrame, CCInteger, Vec3, MATH_FLOAT_ARRAY, Rect, instantiate, Sprite } from 'cc';
import { ImgElement } from './ImgElement';
const { ccclass, property } = _decorator;
@ccclass('DivideImg')
export class DivideImg extends Component
{
@property({ type: ImgElement, visible: true, displayName: 'Element模板' })
private _elementTemplate: ImgElement;
@property({ type: CCInteger, visible: true, displayName: '最小份数' })
private _minCnt: number = 3;
private _rowCnt: number;
private _columnCnt: number;
private _elementWidth: number;
private _elementHeight: number;
// 左下
private _originalPos: Vec3;
private _elements: ImgElement[];
start()
{
this.init();
}
onDestroy()
{
this.myDestroy();
}
private init(): void
{
this._elementTemplate.hide();
this._elements = new Array<ImgElement>();
}
private myDestroy(): void
{
this.clearElements();
this._elements = null;
}
public CreateElements(spriteFrame: SpriteFrame, width:number, height:number, centerPos:Vec3):void
{
// 删除原有Elements
this.clearElements();
// 算得数据:行份数、列份数、width,height,原点(左下)的位置
this.refreshData(width, height, centerPos);
// 创建各元素
for (let index = 0; index < this._rowCnt * this._columnCnt; index++)
{
const curElement = instantiate(this._elementTemplate.node).getComponent(ImgElement);
curElement.node.setParent(this._elementTemplate.node.parent);
curElement.init(index, this.createElementSprite(spriteFrame, index), this._elementWidth, this._elementHeight);
this._elements.push(curElement);
}
// 设置各元素的位置(先都设置到原位)并显示
for (const e of this._elements)
{
e.setPos(e.index, this.getPos(e.index));
e.show();
}
}
private clearElements(): void
{
if (this._elements)
{
for (const e of this._elements)
{
e.myDestroy();
}
this._elements.splice(0, this._elements.length);
}
}
private refreshData(width: number, height: number, centerPos: Vec3): void
{
if (width > height)
{
this._rowCnt = this._minCnt;
this._elementHeight = height / this._rowCnt;
this._columnCnt = Math.round(width / this._elementHeight);
this._elementWidth = width / this._columnCnt;
}
else
{
this._columnCnt = this._minCnt;
this._elementWidth = width / this._columnCnt;
this._rowCnt = Math.round(height / this._elementWidth);
this._elementHeight = height / this._rowCnt;
}
this._originalPos = new Vec3(centerPos.x - width / 2 + this._elementWidth / 2, centerPos.y - height / 2 + this._elementHeight / 2, centerPos.z);
}
private createElementSprite(spriteFrame: SpriteFrame, index: number): SpriteFrame
{
const width = spriteFrame.width / this._columnCnt;
const height = spriteFrame.height / this._rowCnt;
const x = index % this._columnCnt;
const y = this._rowCnt - 1 - Math.floor(index / this._columnCnt);
const rect = new Rect(x*width, y*height, width, height);
const elementSprite = spriteFrame.clone();
elementSprite.rect = rect;
return elementSprite;
}
// index方向:从左到右,从下到上,一行一行填充
private getPos(index: number): Vec3
{
const y = Math.floor(index / this._columnCnt);
const x = index % this._columnCnt;
const pos = new Vec3(this._originalPos.x + x * this._elementWidth, this._originalPos.y + y * this._elementHeight, this._originalPos.z);
return pos;
}
}
ImgElement.ts
import { _decorator, Component, Node, Sprite, UITransform, SpriteFrame, Vec3, size, Size, rect, Rect } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('ImgElement')
export class ImgElement extends Component
{
private _index: number;
public get index(): number
{
return this._index;
}
public _posIndex: number;
public get posIndex(): number
{
return this._posIndex;
}
@property({ type: Node, visible: true, displayName: '根节点' })
private _root: Node;
@property({ type: Sprite, visible: true, displayName: '图片' })
private _sprite: Sprite;
@property({ type: UITransform, visible: true, displayName: 'UITrans' })
private _spriteTrans: UITransform;
public init(index:number, spriteFrame:SpriteFrame, width:number, height:number): void
{
this._index = index;
this._posIndex = -1;
this._sprite.spriteFrame = spriteFrame;
this._spriteTrans.setContentSize(new Size(width, height));
}
public myDestroy(): void
{
this._index = -1;
this._posIndex = -1;
this._sprite.spriteFrame = null;
this._spriteTrans = null;
this._root.destroy();
}
public setPos(posIndex:number, pos: Vec3)
{
this._posIndex = posIndex;
this._root.setWorldPosition(pos);
}
public isAtRightPos(): boolean
{
return this._index == this.posIndex;
}
public hide(): void
{
this._root.active = false;
}
public show(): void
{
this._root.active = true;
}
}