Cocos2d-iPhone:Retina& Cconprite位置不同非Retina屏幕

时间:2012-06-10 23:55:16

标签: iphone cocos2d-iphone

我有一个使用cocos2d-iphone构建的相当简单的应用程序,但是我一直无法解决的奇怪的定位问题。该应用程序使用精灵表,应用程序中有一个Retina和非Retina精灵表使用完全相同的艺术作品(当然除了分辨率)。用于CCSprites的应用程序中还有其他艺术品,它们都是标准的,后缀为-hd。

在应用程序中,应用程序启动时会创建一组精灵。这些最初创建的CCSprites始终在Retina&上完全相同(并且正确)定位。非Retina屏幕。

// In method called to setup sprites when app launches
// Cache & setup app sprites
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile: @"sprites.plist"];
sprites = [CCSpriteBatchNode batchNodeWithFile: @"sprites.png"];

hill = [CCSprite spriteWithSpriteFrameName: @"hill.png"];
hill.position = ccp( 160, 75 );
[sprites addChild: hill z: 1];

// ... [create more sprites in same fashion]
// NOTE: All sprites created here have correct positioning on Retina & non-Retina screens

当用户以某种方式点击屏幕时,会调用一个方法来创建另一组CCSprites(屏幕上和屏幕外),将它们全部设为动画。其中一个精灵,{{1} },始终与Retina&相同(并且正确)定位非Retina屏幕。其他人(一组云)成功创建了&动画,但他们的位置在Retina显示屏上是正确的 。在非Retina显示屏上,每个云的起始位置都不正确(handx或有时两者都不正确),动画后的结束位置也是错误的。

我在触摸方法中包含了下面的负责代码,它创建了新的精灵并将它们设置为动画。再次,它在Retina显示屏上按预期工作,但在非Retina屏幕上不正确。所使用的y在app-start中以相同的方式创建,以设置应用程序中的所有初始精灵,这些精灵始终具有正确的位置。

CCSprites

值得一提的是,在运行应用程序并在标准iPhone和iPhone(Retina)硬件选项之间切换时,我在iOS模拟器中看到了这种不正确的定位行为。我无法验证是否发生这种情况或者在实际的非Retina iPhone上没有发生,因为我没有。

然而,这是我唯一一次看到这种奇怪的定位行为(用户触摸后获得的结果不正确),并且因为我以完全相同的方式创建所有精灵(即// Elsewhere, in a method called on touch // Create clouds cloud1 = [CCSprite spriteWithSpriteFrameName: @"cloud_1.png"]; cloud1.position = ccp(-150, 320); cloud1.scale = 1.2f; cloud2 = [CCSprite spriteWithSpriteFrameName: @"cloud_2.png"]; cloud2.position = ccp(-150, 335); cloud2.scale = 1.3f; cloud3 = [CCSprite spriteWithSpriteFrameName: @"cloud_4.png"]; cloud3.position = ccp(-150, 400); cloud4 = [CCSprite spriteWithSpriteFrameName: @"cloud_5.png"]; cloud4.position = ccp(-150, 420); cloud5 = [CCSprite spriteWithSpriteFrameName: @"cloud_3.png"]; cloud5.position = ccp(400, 350); cloud6 = [CCSprite spriteWithSpriteFrameName: @"cloud_1.png"]; cloud6.position = ccp(400, 335); cloud6.scale = 1.1f; cloud7 = [CCSprite spriteWithSpriteFrameName: @"cloud_2.png"]; cloud7.flipY = YES; cloud7.flipX = YES; cloud7.position = ccp(400, 380); // Create hand hand = [CCSprite spriteWithSpriteFrameName:@"hand.png"]; hand.position = ccp(160, 650); [sprites addChild: cloud1 z: 10]; [sprites addChild: cloud2 z: 9]; [sprites addChild: cloud3 z: 8]; [sprites addChild: cloud4 z: 7]; [sprites addChild: cloud5 z: 6]; [sprites addChild: cloud6 z: 10]; [sprites addChild: cloud7 z: 8]; [sprites addChild: hand z: 10]; // ACTION!! [cloud1 runAction:[CCMoveTo actionWithDuration: 1.0f position: ccp(70, 320)]]; [cloud2 runAction:[CCMoveTo actionWithDuration: 1.0f position: ccp(60, 335)]]; [cloud3 runAction:[CCMoveTo actionWithDuration: 1.0f position: ccp(100, 400)]]; [cloud4 runAction:[CCMoveTo actionWithDuration: 1.0f position: ccp(80, 420)]]; [cloud5 runAction:[CCMoveTo actionWithDuration: 1.0f position: ccp(250, 350)]]; [cloud6 runAction:[CCMoveTo actionWithDuration: 1.0f position: ccp(250, 335)]]; [cloud7 runAction:[CCMoveTo actionWithDuration: 1.0f position: ccp(270, 380)]]; [hand runAction: handIn]; 然后设置[CCSprite spriteWithSpriteFrameName:]position),我将特别感谢任何帮助,以追踪为什么这一组精灵在非Retina屏幕上始终不正确。

修改/更新 我添加了一些额外的日志记录来调查创建的精灵正在发生的事情。以下是其中一个云的示例:

cpp()

我必须说我对此感到非常困惑。我也没有混淆这些日志。非Retina的边界框比Retina的边界框大?那些宽度/高度值甚至与它们引用的图像的大小不匹配。可能在spritesheets / texture中发生了一些奇怪的事情?我也注意到起源不匹配。也许这会影响输出?很奇怪,这只是发生在这些精灵身上,而不是其他精灵。

任何想法&建议表示赞赏。

4 个答案:

答案 0 :(得分:2)

我可以想象两个原因:

  1. SD图像的大小不是高清图像的一半
  2. plist中的图像名称不正确
  3. 确认您的高清图像的宽度和高度恰好是SD图像的两倍(反之亦然)。由于您要从HD缩小尺寸,请确保您的高清图像尺寸可以被2整除。

    plists发生常见的命名错误。通常你会有image.png和image-hd.png。然而,对于纹理图集,这略有不同。你应该有atlas.png和atlas-hd.png文件以及相关的plist文件,但是纹理图集中的图像应该引用两个版本的image.png。一个典型的错误是将image-hd.png添加到atlas-hd.png纹理图集。

    不确定这些问题是否适用。当然听起来你可能想要将记录添加到精灵位置,然后将Retina与标准分辨率位置进行比较。如果这些位置恰好偏移其他版本位置的一半或两倍,您知道您有Retina与非Retina定位错误。如果没有,您的定位或移动代码中更有可能存在错误。

答案 1 :(得分:0)

虽然问题已经消失,但没有可行的答案。

我再次将所有图像修剪为2的幂,在此过程中削减了一些额外的空间。我将纹理/ spritesheet创建工具从Zwoptex交换到TexturePacker,并使用新的.plist文件创建了两个新的精灵表作为PVR而不是PNG。

我还决定将cocos2d库升级到最新的稳定版(我之前使用的是1.0.1稳定版之前的旧版RC版)。

问题已消失,未进行任何代码更改。奇怪。

答案 2 :(得分:0)

我的猜测是替换你的spritesheets是诀窍,但你没有看到任何差异,直到模拟器完全覆盖了App的原始版本。我有问题,图像在模拟器中缓存,我不得不删除应用程序(摆动它,按X),然后神奇地出现了更新的图像。

如有疑问,请在设备上进行测试。模拟器是很多“高度陌生”的原因。不值得。

答案 3 :(得分:0)

我刚刚创建了一个测试应用并进行了测试。

对于没有视网膜的设备: ImageName.png - 适用于iPhone / iPod ImageName~ipad.png - 适用于iPad

对于具有视网膜显示的设备: ImageName@2x.png - 适用于iPhone / iPod ImageName@2x~ipad.png - 适用于iPad

如果您的iPhone高分辨率图像和iPad高分辨率图像具有相同的尺寸,您仍然可以使用@ 2x。  要加载图像,只需使用[UIImage imageNamed:@“ImageName.png”];  我刚刚在iOS模拟器上测试了iOS 5.1,5.0和4.3。  顺便说一句,为什么你应该使用@ 2x而已。

主要因为你不应该在iPhone和iPad上使用相同的图形,因为iPhone和iPad有不同的尺寸。如果您使用相同尺寸的图形,您已经为iPad视网膜显示器(如果您以前使用iPhone视网膜显示器)已经完成。如果您将使用不同尺寸的图像,那么您将为iPhone和iPad使用不同的图像名称。所以在这方面你需要添加@ 2x后缀。这就是你应该只使用@ 2x后缀的原因。 - 这些是我的想法。