Cocos Creator3.x设置动态加载背景图并且循环移动

效果图

项目结构

项目层级结构:

预制:

代码

typescript 复制代码
import { _decorator, CCFloat, Component, Node, Sprite, instantiate, Prefab, assert, UITransform } from 'cc';
const { ccclass, property } = _decorator;

/**
 * 背景脚本
 */
@ccclass('Background')
export class Background extends Component {
    /** 背景图片预制体 */
    @property(Prefab)
    backgroundPrefab: Prefab;

    /** 背景图片移动速度 */
    @property(CCFloat)
    speed: number = 400;

    /** 背景图片高度 */
    private bgHeight: number;

    /** 背景节点数组 */
    private backgroundNodeArray: Node[] = [];

    /** 背景图片数量 */
    private readonly bgPicNum = 2;

    /**
     * 初始化背景图片数组
     */
    private initBackgroundNodeArray() {
        for (let i = 0; i < this.bgPicNum; i++) {
            // 实例化预制体
            let bgNode = instantiate(this.backgroundPrefab);
            // 推入背景图片数组
            this.backgroundNodeArray.push(bgNode);
            // 挂载到背景根节点下
            this.node.addChild(bgNode);
            // 初始化背景图片高度
            this.initBackgroundHeight(bgNode);
        }
    }

    /**
     *  初始化背景图片高度
     */
    private initBackgroundHeight(bgNode: Node) {
        // 如果已初始化高度则返回
        if (!!this.bgHeight) {
            return;
        }
        // 获取背景图片精灵
        let bgSprite = bgNode.getComponent(Sprite);
        assert(!!bgSprite, "背景图片精灵未设置");
        // 动态读取背景图片高度
        this.bgHeight = bgSprite.spriteFrame.height;
    }

    /**
     * 初始化每个背景图片的位置
     */
    private initEachBackgroundNodePosition() {
        for (let i = 0; i < this.backgroundNodeArray.length; i++) {
            let bgNode = this.backgroundNodeArray[i];
            // 图片位置按图片高度叠加
            bgNode.setPosition(bgNode.position.x, this.bgHeight * i);
        }
    }

    start() {
        assert(!!this.backgroundPrefab, "背景图片预制体未设置");
        // 初始化背景图片数组
        this.initBackgroundNodeArray();
        // 初始化背景图片位置
        this.initEachBackgroundNodePosition();
    }

    update(deltaTime: number) {
        // 更新背景图片位置
        this.updateBackgroundPosition(deltaTime);
    }

    /**
     * 更新背景图片位置
     * @param deltaTime 时间间隔
     */
    private updateBackgroundPosition(deltaTime: number) {
        this.backgroundNodeArray.forEach(bgNode => {
            // 背景图片随时间下移
            bgNode.setPosition(bgNode.position.x, bgNode.position.y - this.speed * deltaTime);
            // 如果背景图片超出屏幕高度,则重置位置,接在上方
            if (bgNode.getPosition().y < -this.bgHeight) {
                // 计算帧运行到这里时,节点实际位置和背景图片高度的余数(如果图片下边界是-425,那么节点实际运行到这里时可能是-427了,就要把差值-2给补到平移的距离上去)
                let diff = bgNode.getPosition().y % this.bgHeight;
                // 重置图片位置
                bgNode.setPosition(bgNode.position.x, diff + this.bgHeight * (this.bgPicNum - 1));
            }
        });
    }
}
相关推荐
页面仔Dony1 小时前
绝对路径与相对路径的区别及作用
前端·javascript
林太白1 小时前
Zustand状态库(简洁、强大、易用的React状态管理工具)
前端·javascript·react.js
YuJie1 小时前
vue3 无缝滚动
前端·javascript·vue.js
小野鲜1 小时前
前端打开新的独立标签页面,并且指定标签页的大小,管理新标签页面的打开和关闭(包含源码和使用文档)
前端·javascript
十五_在努力2 小时前
参透 JavaScript —— 解析浅拷贝、深拷贝及手写实现
前端·javascript
王六岁2 小时前
JavaScript值和引用详解:从栈堆内存到面试实战
javascript·面试
ikonan3 小时前
译:Chrome DevTools 实用技巧和窍门清单
前端·javascript
小高0073 小时前
⚡️ Vue 3.5 正式发布:10× 响应式性能、SSR 水合黑科技、告别 .value!
前端·javascript·vue.js
葡萄城技术团队3 小时前
【前沿解析】JavaScript 的未来,将迎来哪些新特性?
javascript