最近一直在自学objective-c,以便学习Cocos2d。
开始了一个新项目,通过经典的坠落宝石俄罗斯方块游戏自学基础知识。我采取的第一步是使用编辑 > 重构为 ARC 启用项目,并选择模板中的最后 4 个文件。
到目前为止,已经能够通过子类化 CCSprite 添加具有动态颜色精灵的单个 gem,并在它从顶部掉落的同时沿着 XCoordinates 移动它。这些宝石被赋予一个 gemPos 位置——例如 5,3——以便我稍后实现匹配方法。
在测试项目一段时间后,当一些块相互堆叠时,我会收到 EXC_BAD_ACCESS 警告。如果启用了 ARC,我对为什么会发生这种情况感到困惑。
我笨拙的代码如下(省略了 .h 文件):
默认的 helloworld 层:
-(id) init
{
if( (self=[super init]) ) {
oldGems = [[NSMutableArray alloc]init];
[self setIsTouchEnabled:YES];
[self newGem];
[self scheduleUpdate];
}
return self;
}
- (void)registerWithTouchDispatcher
{
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
oldPos = touchLocation;
return TRUE;
}
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
[self updateXCoord:(CGPoint)touchLocation];
}
- (void)updateXCoord:(CGPoint)touchLocation
{
CGPoint distance = ccpSub(touchLocation, oldPos);
float xDistance = distance.x;
if (abs(xDistance) >= 36) {
if (touchLocation.x > oldPos.x) {
[_thisGem setPosition:ccp([_thisGem position].x + 36, [_thisGem position].y)];
[_thisGem setGemPos:ccp([_thisGem gemPos].x+1,[_thisGem gemPos].y)];
NSLog(@"The gem position is %@", NSStringFromCGPoint([_thisGem gemPos]));
oldPos = touchLocation;
} else {
[_thisGem setPosition:ccp([_thisGem position].x - 36, [_thisGem position].y)];
[_thisGem setGemPos:ccp([_thisGem gemPos].x-1,[_thisGem gemPos].y)];
NSLog(@"The gem position is %@", NSStringFromCGPoint([_thisGem gemPos]));
oldPos = touchLocation;
}
}
}
- (void)newGem
{
if (_thisGem) {
PCGem *oldGem = _thisGem;
NSLog(@"Old gem position at %@", NSStringFromCGPoint([oldGem gemPos]));
[oldGems addObject:oldGem];
}
_thisGem = [[PCGem alloc] initWithGemColor];
[_thisGem setPosition:ccp(160, 450)];
[self addChild:_thisGem];
[_thisGem setGemPos:ccp(4,10)];
NSLog(@"Gem added with %@ color", [_thisGem gemColorName]);
}
- (void)update:(ccTime)dt
{
if ([_thisGem gemPos].y > 0) {
[self spaceBelowOccupied];
[_thisGem setPosition:ccp([_thisGem position].x, [_thisGem position].y-1)];
[_thisGem setGemPos:ccp([_thisGem gemPos].x, floor([_thisGem position].y / 36))];
} else {
[self newGem];
}
}
- (void)spaceBelowOccupied
{
for (PCGem *occupiedTile in oldGems) {
if (CGRectIntersectsRect(occupiedTile.boundingBox, _thisGem.boundingBox)) {
NSLog(@"Collision detected!");
[self newGem];
}
}
}
还有我笨拙的 PCGem 课:
- (id)initWithGemColor
{
if ((self = [super initWithFile:@"gemGS.png"])) {
NSArray *gemColorList = [NSArray arrayWithObjects:(NSString *)@"blue", (NSString *)@"red", (NSString *)@"green", nil];
NSInteger randColor = arc4random_uniform(3);
switch (randColor) {
case 0:
{
[self setGemColorName:[gemColorList objectAtIndex:0]];
ccColor3B gemColorRGB = {0,0,255};
[self setColor:gemColorRGB];
break;
}
case 1:
{
[self setGemColorName:[gemColorList objectAtIndex:1]];
ccColor3B gemColorRGB = {255,0,0};
[self setColor:gemColorRGB];
break;
}
case 2:
{
[self setGemColorName:[gemColorList objectAtIndex:2]];
ccColor3B gemColorRGB = {0,255,0};
[self setColor:gemColorRGB];
break;
}
}
}
return self;
}
这让我想到了另一个问题,我似乎找不到答案。在启用 ARC 的 Cocos2d 项目的示例中,我看到了使用的节点便捷方法,当然是 alloc]init]autorelease]。但是我认为您不能将 Autorelease 与 ARC 一起使用,这会导致崩溃吗?这是如何运作的?
对我的困境有什么想法吗?非常感谢澄清:)
干杯,
阿德里安