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;
    }
}
上一篇下一篇

猜你喜欢

热点阅读