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));
            }
        });
    }
}
相关推荐
EndingCoder6 分钟前
案例研究:从 JavaScript 迁移到 TypeScript
开发语言·前端·javascript·性能优化·typescript
Amumu121382 小时前
Vue脚手架(二)
前端·javascript·vue.js
lichenyang4533 小时前
从零开始构建 React 文档系统 - 完整实现指南
前端·javascript·react.js
比特森林探险记3 小时前
Hooks、状态管理
前端·javascript·react.js
比特森林探险记3 小时前
组件通信 与 ⏳ 生命周期
前端·javascript·vue.js
海绵宝龙3 小时前
Vue中nextTick
前端·javascript·vue.js
H_z_q24014 小时前
Web前端制作一个评论发布案例
前端·javascript·css
摘星编程4 小时前
React Native + OpenHarmony:useId唯一标识生成
javascript·react native·react.js
IT利刃出鞘4 小时前
WebStorm--配置并运行TypeScript项目
typescript·webstorm
2603_949462104 小时前
Flutter for OpenHarmony社团管理App实战:消息中心实现
android·javascript·flutter