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));
            }
        });
    }
}
相关推荐
阿伟来咯~24 分钟前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端29 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱32 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai41 分钟前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨42 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
王哲晓2 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云2 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
aPurpleBerry3 小时前
JS常用数组方法 reduce filter find forEach
javascript
ZL不懂前端4 小时前
Content Security Policy (CSP)
前端·javascript·面试