关于jumpby动作让我费解的地方

我想实现人物的跳跃动作,跳跃的轨迹类似于抛物线,所以分了是个小动作来完成整个大动作,每个小动作之前都先检查有没有与地图上设计好的位置碰撞(checkCollision()函数),如果碰撞就跳出循环,不在进行之后的小动作,代码如下:

  for (int i = 0; i < 10; i++)
 {
      if (!checkCollision(player->getPosition()))
     {
	 if (i < 5)
	 {
		auto jump1 = JumpBy::create(0.8f, Vec2(10.7, 25.6), 25.6, 1);
		  int x1 = player->getPositionX();
		 int y1 = player->getPositionY();
		 log("x = %d", x1);
		  log("y = %d", y1);
		 player->runAction(jump1);
    }
   else 
  {
	 auto jump2 = JumpBy::create(0.2f, Vec2(10.7, -25.6), 0, 1);
	 int x2 = player->getPositionX();
	 int y2 = player->getPositionY();
	log("x2 = %d", x2);
	log("y2 = %d", y2);
	player->runAction(jump2);
 }
  }
   else
 {
   break;
 } 

}
那么按照我的设想,每一个打印出来的x值应该比前面一个大,y也应该不一样,可是打印结果如下:
y = 72
x = 50
y = 72
x = 50
y = 72
x = 50
y = 72
x = 50
y = 72
x2 = 50
y2 = 72
x2 = 50
y2 = 72
x2 = 50
y2 = 72
x2 = 50
y2 = 72
x2 = 50
y2 = 72
说明根本没有变化,我觉得很费解。

这个编程最基础的一个问题啊,你的for循环是在游戏的一帧里调用的,也就是说引擎还没有进行下一帧的渲染,位置怎么可能有变化,你这么调用完全没有意义

对哦,可是我试过让他在一跳起来就会碰到碰撞的地方跳,完了他还是跳了一整个动作,这是为什么?

对哦,可是我试过让他在一跳起来就会碰到碰撞的地方跳,,我调试发现他确实碰到了,而且也运行了else{},完了他还是跳了一整个动作,这是为什么?

你所说的检测碰撞是在哪儿检测的,一个schedule里吗?
做跳跃的话,还是不要用jump了吧,很难控制啊,用schedule比较好控制

不是的,监测的话是checkCollision()函数,返回bool值,在每一次循环的时候执行,上面代码有。按照我的摄像的话,应该是碰到了的情况下就执行else{break;},我调试发现也确实执行了,但他还是跳了整个动作

我大概明白了,你的写法就有问题,如果你想做到你想要的效果的话,就不要用for循环了,for循环不能用来做检测碰撞,你需要一个schedule计时器,for循环只会在一帧里执行,schedule是每帧执行

啊我试试

引擎自带的例子里应该有关于检测碰撞的代码吧,研究一下吧

刚刚测试了一下,似乎是成功了,非诚感谢。不过我还是不明白,为什么for循环实现不了?

你可以尝试一下,写一个永远不会到达边界的for循环,看看会发生什么,程序会永远走不到下一帧。走不到下一帧就没有位移,没有位移怎么检测碰撞

不过你还是先理解一下游戏引擎的一些基本原理比较好

没有时延,整个for循环的内容,一瞬间就执行完了。引擎已经实现了带时延的循环,每次循环就是一帧,正常每秒循环60次,就是60帧

补充: 楼下说的有道理,执行顺序的问题,runAction的时候,并不是真的,就在代码执行到这里的时候,就能看到动作发生了,而是设置了这样一个动作,引擎接下来每帧去处理这个事情

单线程,跟for循环的执行时间并没有关系,只是一个执行顺序的问题

1赞

听懂了,谢啦。