我有一个使用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显示屏上,每个云的起始位置都不正确(hand
,x
或有时两者都不正确),动画后的结束位置也是错误的。
我在触摸方法中包含了下面的负责代码,它创建了新的精灵并将它们设置为动画。再次,它在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中发生了一些奇怪的事情?我也注意到起源不匹配。也许这会影响输出?很奇怪,这只是发生在这些精灵身上,而不是其他精灵。
任何想法&建议表示赞赏。
答案 0 :(得分:2)
我可以想象两个原因:
确认您的高清图像的宽度和高度恰好是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后缀的原因。 - 这些是我的想法。