Ios 当我点击屏幕左侧时,炮塔以错误的方式开火
我对这一切都很陌生,所以如果这是一个非常无知的问题,我道歉。我正试图制造一个旋转的炮塔,面对水龙头,朝那个方向开火。在Ray Wenderlich的旋转炮塔教程中找到了一些代码,我将炮塔移动到屏幕的底部中心,并将炮弹的起点重新定位到同一点。这个位置更类似于老式的导弹指挥风格的游戏 不幸的是,现在当我点击屏幕右侧时,武器可以正确地发射,但当我点击左侧时,它会在屏幕外向下和向右发射,就像它不知怎么地翻转了命令一样。有人能帮我把这件事弄清楚吗?是否有另一种编码方法,这样我就不会出现左触发问题,或者我是否需要输入一些额外的内容来转换坐标,以便正确地注册抽头Ios 当我点击屏幕左侧时,炮塔以错误的方式开火,ios,cocos2d-iphone,Ios,Cocos2d Iphone,我对这一切都很陌生,所以如果这是一个非常无知的问题,我道歉。我正试图制造一个旋转的炮塔,面对水龙头,朝那个方向开火。在Ray Wenderlich的旋转炮塔教程中找到了一些代码,我将炮塔移动到屏幕的底部中心,并将炮弹的起点重新定位到同一点。这个位置更类似于老式的导弹指挥风格的游戏 不幸的是,现在当我点击屏幕右侧时,武器可以正确地发射,但当我点击左侧时,它会在屏幕外向下和向右发射,就像它不知怎么地翻转了命令一样。有人能帮我把这件事弄清楚吗?是否有另一种编码方法,这样我就不会出现左触发问题,或者我是
// Import the interfaces
#import "HelloWorldLayer.h"
#import "SimpleAudioEngine.h"
#import "GameOverLayer.h"
#import "Monster.h"
#import "LevelManager.h"
// Needed to obtain the Navigation Controller
#import "AppDelegate.h"
#pragma mark - HelloWorldLayer
// HelloWorldLayer implementation
@implementation HelloWorldLayer
// Helper class method that creates a Scene with the HelloWorldLayer as the only child.
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
- (void) addMonster {
//CCSprite * monster = [CCSprite spriteWithFile:@"monster.png"];
Monster * monster = nil;
if (arc4random() % 2 == 0) {
monster = [[[WeakAndFastMonster alloc] init] autorelease];
} else {
monster = [[[StrongAndSlowMonster alloc] init] autorelease];
}
// Determine where to spawn the monster along the Y axis
CGSize winSize = [CCDirector sharedDirector].winSize;
int minY = monster.contentSize.height / 2;
int maxY = winSize.height - monster.contentSize.height/2;
int rangeY = maxY - minY;
int actualY = (arc4random() % rangeY) + minY;
// Create the monster slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
monster.position = ccp(winSize.width + monster.contentSize.width/2, actualY);
[self addChild:monster];
// Determine speed of the monster
int minDuration = monster.minMoveDuration; //2.0;
int maxDuration = monster.maxMoveDuration; //4.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
CCMoveTo * actionMove = [CCMoveTo actionWithDuration:actualDuration position:ccp(-monster.contentSize.width/2, actualY)];
CCCallBlockN * actionMoveDone = [CCCallBlockN actionWithBlock:^(CCNode *node) {
[_monsters removeObject:node];
[node removeFromParentAndCleanup:YES];
CCScene *gameOverScene = [GameOverLayer sceneWithWon:NO];
[[CCDirector sharedDirector] replaceScene:gameOverScene];
}];
[monster runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
monster.tag = 1;
[_monsters addObject:monster];
}
-(void)gameLogic:(ccTime)dt {
[self addMonster];
}
- (id) init
{
if ((self = [super initWithColor:[LevelManager sharedInstance].curLevel.backgroundColor])) {
CGSize winSize = [CCDirector sharedDirector].winSize;
_player = [CCSprite spriteWithFile:@"player2.png"];
_player.position = ccp(winSize.width/2, 20);
[self addChild:_player];
[self schedule:@selector(gameLogic:) interval:[LevelManager sharedInstance].curLevel.secsPerSpawn];
[self setTouchEnabled:YES];
_monsters = [[NSMutableArray alloc] init];
_projectiles = [[NSMutableArray alloc] init];
[self schedule:@selector(update:)];
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"background-music-aac.caf"];
}
return self;
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (_nextProjectile != nil) return;
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [self convertTouchToNodeSpace:touch];
// Set up initial location of projectile
CGSize winSize = [[CCDirector sharedDirector] winSize];
_nextProjectile = [[CCSprite spriteWithFile:@"projectile2.png"] retain];
_nextProjectile.position = ccp(winSize.width/2, 20);
// Determine offset of location to projectile
CGPoint offset = ccpSub(location, _nextProjectile.position);
// Bail out if you are shooting down or backwards
//if (offset.x <= 0) return;
// Determine where you wish to shoot the projectile to
int realX = winSize.width + (_nextProjectile.contentSize.width/2);
float ratio = (float) offset.y / (float) offset.x;
int realY = (realX * ratio) + _nextProjectile.position.y;
CGPoint realDest = ccp(realX, realY);
// Determine the length of how far you're shooting
int offRealX = realX - _nextProjectile.position.x;
int offRealY = realY - _nextProjectile.position.y;
float length = sqrtf((offRealX*offRealX)+(offRealY*offRealY));
float velocity = 480/1; // 480pixels/1sec
float realMoveDuration = length/velocity;
// Determine angle to face
float angleRadians = atanf((float)offRealY / (float)offRealX);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
float cocosAngle = -1 * angleDegrees;
float rotateDegreesPerSecond = 180 / 0.5; // Would take 0.5 seconds to rotate 180 degrees, or half a circle
float degreesDiff = _player.rotation - cocosAngle;
float rotateDuration = fabs(degreesDiff / rotateDegreesPerSecond);
[_player runAction:
[CCSequence actions:
[CCRotateTo actionWithDuration:rotateDuration angle:cocosAngle],
[CCCallBlock actionWithBlock:^{
// OK to add now - rotation is finished!
[self addChild:_nextProjectile];
[_projectiles addObject:_nextProjectile];
// Release
[_nextProjectile release];
_nextProjectile = nil;
}],
nil]];
// Move projectile to actual endpoint
[_nextProjectile runAction:
[CCSequence actions:
[CCMoveTo actionWithDuration:realMoveDuration position:realDest],
[CCCallBlockN actionWithBlock:^(CCNode *node) {
[_projectiles removeObject:node];
[node removeFromParentAndCleanup:YES];
}],
nil]];
_nextProjectile.tag = 2;
[[SimpleAudioEngine sharedEngine] playEffect:@"pew-pew-lei.caf"];
}
- (void)update:(ccTime)dt {
NSMutableArray *projectilesToDelete = [[NSMutableArray alloc] init];
for (CCSprite *projectile in _projectiles) {
BOOL monsterHit = FALSE;
NSMutableArray *monstersToDelete = [[NSMutableArray alloc] init];
for (Monster *monster in _monsters) {
if (CGRectIntersectsRect(projectile.boundingBox, monster.boundingBox)) {
monsterHit = TRUE;
monster.hp --;
if (monster.hp <= 0) {
[monstersToDelete addObject:monster];
}
break;
}
}
for (CCSprite *monster in monstersToDelete) {
[_monsters removeObject:monster];
[self removeChild:monster cleanup:YES];
_monstersDestroyed++;
if (_monstersDestroyed > 30) {
CCScene *gameOverScene = [GameOverLayer sceneWithWon:YES];
[[CCDirector sharedDirector] replaceScene:gameOverScene];
}
}
if (monsterHit) {
[projectilesToDelete addObject:projectile];
[[SimpleAudioEngine sharedEngine] playEffect:@"explosion.caf"];
}
[monstersToDelete release];
}
for (CCSprite *projectile in projectilesToDelete) {
[_projectiles removeObject:projectile];
[self removeChild:projectile cleanup:YES];
}
[projectilesToDelete release];
}
// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
[_monsters release];
_monsters = nil;
[_projectiles release];
_projectiles = nil;
[super dealloc];
}
@end
//导入接口
#导入“HelloWorldLayer.h”
#导入“SimpleAudioEngine.h”
#导入“GameOverLayer.h”
#导入“Monster.h”
#导入“LevelManager.h”
//需要获取导航控制器
#导入“AppDelegate.h”
#pragma标记-HelloWorldLayer
//HelloWorldLayer实现
@HelloWorldLayer的实现
//帮助器类方法,用于创建将HelloWorldLayer作为唯一子对象的场景。
+(场景*)场景
{
//“场景”是一个自动释放对象。
CCScene*scene=[CCScene节点];
//“层”是一个自动释放对象。
HelloWorldLayer*层=[HelloWorldLayer节点];
//将层作为子层添加到场景中
[场景添加子对象:层];
//返回现场
返回场景;
}
-(空)怪物{
//CCSprite*monster=[CCSprite spriteWithFile:@“monster.png”];
怪物*怪物=零;
如果(arc4random()%2==0){
怪物=[[WeakAndFastMonster alloc]初始化]自动释放];
}否则{
怪物=[[StrongAndSlowMonster alloc]init]自动释放];
}
//确定沿Y轴产卵怪物的位置
CGSize winSize=[CCDirector sharedDirector].winSize;
int minY=monster.contentSize.height/2;
int maxY=winSize.height-monster.contentSize.height/2;
int rangy=maxY-minY;
int实际=(arc4random()%rangeY)+minY;
//沿右边缘在屏幕外创建怪物,
//以及沿Y轴的随机位置,如上所述
monster.position=ccp(实际为winSize.width+monster.contentSize.width/2);
[自我添加的孩子:怪物];
//确定怪物的速度
int minDuration=monster.minMoveDuration;//2.0;
int maxDuration=monster.maxMoveDuration;//4.0;
int rangeDuration=maxDuration-minDuration;
int actualDuration=(arc4random()%rangeDuration)+minDuration;
//创建操作
CCMoveTo*actionMove=[CCMoveTo actionWithDuration:actualDuration位置:ccp(-monster.contentSize.width/2,actually)];
CCCallBlockN*actionMoveDone=[CCCallBlockN actionWithBlock:^(CCNode*node){
[_怪物移除对象:节点];
[节点从父节点移除和清除:是];
CCScene*gameOverScene=[GameOverLayer scenewithon:NO];
[[CCDirector sharedDirector]replaceSecene:gameOverScene];
}];
[monster runAction:[CCSequence actions:actionMove,actionMoveDone,nil];
monster.tag=1;
[_怪物添加对象:怪物];
}
-(无效)游戏逻辑:(ccTime)dt{
[自我添加怪物];
}
-(id)init
{
if((self=[super initWithColor:[LevelManager sharedInstance].curLevel.backgroundColor])){
CGSize winSize=[CCDirector sharedDirector].winSize;
_player=[CCSprite spriteWithFile:@“player2.png”];
_player.position=ccp(winSize.width/2,20);
[self addChild:_player];
[self schedule:@selector(gameLogic:)interval:[LevelManager sharedInstance].curLevel.secsPerSpawn];
[自设置触摸启用:是];
_怪物=[[NSMutableArray alloc]init];
_射弹=[[NSMutableArray alloc]init];
[自行安排:@选择器(更新:)];
[[SimpleAudioEngine sharedEngine]播放背景音乐:@“背景音乐aac.caf”];
}
回归自我;
}
-(无效)ccTouchesEnded:(NSSet*)接触事件:(UIEvent*)事件{
如果(_nextproject!=nil)返回;
//选择要使用的触摸之一
UITouch*touch=[触摸任何对象];
CGPoint location=[self-convertTouchToNodeSpace:touch];
//设置投射物的初始位置
CGSize winSize=[[CCDirector sharedDirector]winSize];
_nextproject=[[CCSprite spriteWithFile:@“projectle2.png”]retain];
_nextproject.position=ccp(winSize.width/2,20);
//确定位置对射弹的偏移量
CGPoint offset=ccpSub(位置,下一个投影位置);
//如果你正在向下射击或向后射击,请跳伞
//如果(offset.x我想说你应该用atan2f
替换你的atanf
,即替换
float angleRadians = atanf((float)offRealY / (float)offRealX);
with(注意,atan2f
分别接受Y
和X
)
看看。你会看到从0-PI/2atanf
和atan2f
会给你同样的结果。但是,当你从PI/2到PI时,你会使用atanf
得到负角度,而atan2f
会产生正确的角度。我再次查看了你的代码,并注意到其他问题嗯,我已经改变了以下几点:
- 在下面拍摄时的“保释”条件(注意顺序的变化,否则在第一次满足保释条件后您将无法拍摄!)
- 计算
realY
和realX
-您保留了Ray教程中的代码,并将目标位置设置为始终位于右侧,而在下面的代码中,目标位置始终位于顶部
- 删除了
atan
/atan2
函数并使用ccpToAngle(ccp(offreax,offRealY))
下面
float angleRadians = atan2f((float)offRealY, (float)offRealX);
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (_nextProjectile != nil) return;
CGSize winSize = [[CCDirector sharedDirector] winSize];
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [self convertTouchToNodeSpace:touch];
CGPoint targetPosition = ccp(winSize.width / 2, 20);
// Determine offset of location to projectile
CGPoint offset = ccpSub(location, targetPosition);
// Bail out if you are shooting down or backwards
if (offset.y <= 0)
{
return;
}
// Set up initial location of projectile
_nextProjectile = [[CCSprite spriteWithFile:@"projectile2.png"] retain];
_nextProjectile.position = targetPosition;
// Determine where you wish to shoot the projectile to
int realY = winSize.height + (_nextProjectile.contentSize.height/2);
float ratio = (float) offset.x / (float) offset.y;
int realX = (realY * ratio) + _nextProjectile.position.x;
CGPoint realDest = ccp(realX, realY);
// Determine the length of how far you're shooting
int offRealX = realX - _nextProjectile.position.x;
int offRealY = realY - _nextProjectile.position.y;
float length = sqrtf((offRealX*offRealX)+(offRealY*offRealY));
float velocity = 480/1; // 480pixels/1sec
float realMoveDuration = length/velocity;
// Determine angle to face
float angleRadians = ccpToAngle(ccp(offRealX, offRealY));