节点水平移动-抖动问题

目前需要节点从手机的右侧移动到左侧,但是存在一个问题就是移动的过程中会出现轻微抖动的情况,这是为什么呢?之前移动使用的scrollView,这次是类似于弹幕的情况,使用的sprite节点,然后就出现这个抖动的情况。
declare const ks: any;

@ccclass(“comment”)

export class comment extends Component {

@property(Node)

private commentNode: Node = null;

@property(Node)

private firstNode: Node = null;

@property(Node)

private secondNode: Node = null;

@property(Node)

private thirdNode: Node = null;

@property(Node)

private fourthNode: Node = null;

// 统一移动速度(像素/秒)

@property

private moveSpeed: number = 30;

// 固定时间步长(秒),用于补帧,保证移动速度恒定

// 设置为 1/60 秒,相当于 60fps 的更新频率

private readonly FIXED_TIME_STEP: number = 1 / 60;

// 累积的时间,用于固定时间步长更新

private accumulatedTime: number = 0;

private exampleNode: Node = null;

// 当前在屏幕上移动的评论节点

private runningComments: CommentState[] = [];

// 缓存已加载的图片,避免重复请求

private imageCache: Map<string, SpriteFrame> = new Map();

start() {}

/**

  • 创建一条从右到左移动的评论节点

  • @param data 评论数据,包含用户信息和幸运值

*/

addComment(data?: CommentData) {

if (!this.commentNode) return;

console.log("添加评论");

const key = this.getCurrentRuleList(data.typeName);

console.log("key", key);

if (key) {

  switch (key) {

    case "firstRule":

      this.exampleNode = this.firstNode;

      break;

    case "secondRule":

      this.exampleNode = this.secondNode;

      break;

    case "thirdRule":

      this.exampleNode = this.thirdNode;

      break;

    case "fourthRule":

      this.exampleNode = this.fourthNode;

      break;

    default:

      this.exampleNode = this.firstNode;

      break;

  }

}

const node = instantiate(this.exampleNode);

node.active = true;

node.parent = this.commentNode;

// y 在 -70 ~ 70 之间随机一个位置

const randomY = -70 + Math.random() * 140;

// 初始位置:x 在 320 ~ 350 之间随机,y = randomY

const randomX = 320 + Math.random() * 30; // 320 ~ 350

node.setPosition(new Vec3(randomX, randomY, 0));

// 如果有数据,更新节点内容

if (data) {

  this.updateCommentNode(node, data);

}

this.runningComments.push({ node });

}

/**

  • 更新评论节点的内容(头像、昵称、幸运值等)

*/

private updateCommentNode(node: Node, data: CommentData) {
这里是添加文字的多余代码
}

/**

  • 动态加载网络图片到Sprite组件

*/

private loadNetworkImage(url: string, sprite: Sprite) {
}

update(deltaTime: number) {

if (!this.commentNode) return;

// 限制 deltaTime 最大值,防止卡顿导致的大幅跳跃

const clampedDeltaTime = Math.min(deltaTime, 0.1);



// 累积时间,用于固定时间步长更新

this.accumulatedTime += clampedDeltaTime;

// 固定时间步长更新:当累积时间达到固定步长时执行更新

// 这样可以保证无论帧率如何,移动速度都是恒定的

while (this.accumulatedTime >= this.FIXED_TIME_STEP) {

  this.accumulatedTime -= this.FIXED_TIME_STEP;

  this.fixedUpdate(this.FIXED_TIME_STEP);

}

}

/**

  • 固定时间步长更新,保证移动速度恒定

*/

private fixedUpdate(fixedDeltaTime: number) {

// 从后往前遍历,方便移除已经离开屏幕的节点

for (let i = this.runningComments.length - 1; i >= 0; i--) {

  const state = this.runningComments[i];

  const node = state.node;

  if (!node || !node.isValid) {

    this.runningComments.splice(i, 1);

    continue;

  }

  // 获取当前位置,创建新的 Vec3 避免引用问题

  const pos = node.getPosition();

  // 使用固定时间步长计算新位置,保证移动速度恒定

  const newX = pos.x - this.moveSpeed * fixedDeltaTime;

  // 像素对齐:将位置对齐到整数像素,减少高分屏上的抖动

  const snappedX = Math.round(newX);

 

  // 使用 setPosition 设置新位置,传入新 Vec3 避免引用问题

  node.setPosition(new Vec3(snappedX, pos.y, pos.z));

  // 当移动到 x <= -350 时,销毁或停用

  if (snappedX <= -350) {

    node.destroy(); // 如果后面需要复用,可以改成 node.active = false;

    this.runningComments.splice(i, 1);

  }

}

}

// 获取当前的位置

getCurrentRuleList(text) {

}

}

image 你将这个Math.round去掉试试看