碰撞图像问题,触摸前碰撞

发布于 2024-11-08 00:18:09 字数 1069 浏览 5 评论 0原文

大家好,我是法国人,请原谅我的英语。我的问题如下:我在屏幕中央有一个名为 viewToRotate 的图像,然后我有一个在屏幕外部创建的名为 flakeView 的图像,然后它是移动到中心,每秒都有一个计时器执行此操作(在屏幕外创建一个 flakeView,然后将其移动到屏幕中心)。

我想做的是:如果 flakeView 和 viewToRotate 发生碰撞,则将 viewToRotate 的 alpha 值减小到 0.5。但是当 flakeView 出现在屏幕上时,会调用减少 alpha 的动作,而不会发生 viewToRotate 和 flakeView 的碰撞,因此它们在接触之前就发生了碰撞。我不知道为什么。请问我该如何解决这个问题。这是代码:

UIImageView* flakeView = [[[UIImageView alloc] initWithImage:flakeImage] autorelease];

// use the random() function to randomize up our flake attributes
int startY = round(random() % 320);

// set the flake start position
flakeView.center = CGPointMake(490, startY);
flakeView.alpha = 1;

// put the flake in our main view
[self.view addSubview:flakeView];

[UIView animateWithDuration:7
                 animations:^{
                     // set the postion where flake will move to
                     flakeView.center = viewToRotate.center;
                 }];
}


-(void)checkCollision{

if(CGRectIntersectsRect(flakeView.frame, viewToRotate.frame) == 1)  
{
    viewToRotate.alpha=0.5;
}
}

Hi everyone I'm french so scuse me for my english.My problem is the following: I have an image in the center of the screen called viewToRotate, then I have an image called flakeView that is created outside of the screen and then it is moving to the center, and every second a Timer does this(create a flakeView outside the screen and then move it to the center of the screen).

What I wanted to do was : if flakeView and viewToRotate collide reduce the alpha of viewToRotate to 0.5. But when flakeView appears on the screen the action of reducing the alpha is called without the collision of viewToRotate and flakeView, so they collide before they touches. I don't know why. How can I solve this please . Here is the code :

UIImageView* flakeView = [[[UIImageView alloc] initWithImage:flakeImage] autorelease];

// use the random() function to randomize up our flake attributes
int startY = round(random() % 320);

// set the flake start position
flakeView.center = CGPointMake(490, startY);
flakeView.alpha = 1;

// put the flake in our main view
[self.view addSubview:flakeView];

[UIView animateWithDuration:7
                 animations:^{
                     // set the postion where flake will move to
                     flakeView.center = viewToRotate.center;
                 }];
}


-(void)checkCollision{

if(CGRectIntersectsRect(flakeView.frame, viewToRotate.frame) == 1)  
{
    viewToRotate.alpha=0.5;
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

娜些时光,永不杰束 2024-11-15 00:18:09

我不建议在 viewDidLoad 上使用计时器。我认为您应该将计时器设置为其他功能。即使您不将 viewDidLoad 用于其他任何用途。

另一件事是 UIView 动画。即使您有一个每 60 fps 的计时器,动画对象的属性也不会因动画而改变。因此,在创建动画之前,请先设置这些属性一次。当您创建动画时,您将第二次设置相同的属性。就是这样。从现在开始,当动画运行时,如果您检查属性,您将始终获得第二个值。

要获得有效的代码,一种选择是在特定时间间隔为每个步骤创建 UIView 动画(并执行属性检查)。或者使用OpenGL。

I would not suggest using a timer on viewDidLoad. I believe that you should set the timer at some other function. Even if you do not use viewDidLoad for anything else.

The other thing is the UIView animations. Even if you have a timer at every 60fps the attributes of the animated objects are not changed by the animation. So before you create the animation you set those properties once. And when you create the animation you set the same properties for the second time. And that's it. From now on while the animation is running if you do checks on the properties you will always get the second values.

To have a working code one option is to create the UIView animations (and perform the property checks) for every step at a certain time interval. Or use OpenGL.

中性美 2024-11-15 00:18:09

在深入讨论这个问题之前,还请确保您的 viewToRotate.frame 的大小实际上符合您的预期(请参阅我的评论)。

一旦您确定了这些属性,您可能需要检查动画对象当前 presentationLayer 上的碰撞,而不是其原始状态上的碰撞。

UIView.layer.presentationLayer
返回一个副本
包含所有属性的图层
他们正处于当前的开始
交易,与任何活跃的
应用了动画。

因此,您可以像这样调整碰撞检测:

-(void)checkCollision
{
    if(CGRectIntersectsRect(flakeView.layer.presentationLayer.frame, viewToRotate.layer.presentationLayer.frame) == 1)  
    {
        viewToRotate.alpha=0.5;
    }
}

还可以考虑使用 CoreAnimation Layer 方法 hitTest: 而不是手动碰撞检测。

hitTest:
返回最远的距离
接收者的后代
层层次结构(包括其本身)
包含指定点。

Before getting too deep into this issue, please also make sure that your viewToRotate.frame is actually sized the way you expect it (see my comment).

Once you are certain about those attributes, you might want to check the collision on the current presentationLayer of your animated objects and not on their original state.

UIView.layer.presentationLayer
Returns a copy of
the layer containing all properties as
they were at the start of the current
transaction, with any active
animations applied.

So you might adapt your collision detection like this:

-(void)checkCollision
{
    if(CGRectIntersectsRect(flakeView.layer.presentationLayer.frame, viewToRotate.layer.presentationLayer.frame) == 1)  
    {
        viewToRotate.alpha=0.5;
    }
}

Also consider using the CoreAnimation Layer method hitTest: instead of your handmade collision detection.

hitTest:
Returns the farthest
descendant of the receiver in the
layer hierarchy (including itself)
that contains a specified point.

若沐 2024-11-15 00:18:09

这些是您需要检查的以下内容。

  1. 不要使用图像初始化,使用框架初始化,然后执行
    flakeView.image = ----;因为你的图像可能足够宽
    最初 ,因此从初始化时起就发生冲突。
  2. 尝试 .center 的替代品,例如 .frame.size.x ,因为我已经
    .center 也有问题
  3. 您可能可以 NSLog 之前和之前的图像视图的边界
    减少阿尔法后

These are the following things you would want to check.

  1. Dont init with image, use init with frame and then do
    flakeView.image = ----; Because your image could be wide enough
    initially , and hence colliding from the time you initialize.
  2. Try alternatives to .center, like .frame.size.x , because I have had
    problems with .center as well
  3. You could probably NSLog the bounds of both ur imageviews before and
    after reducing alpha
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文