Ios 防止玩家从地上跌落-精灵套件
我一直在尝试一个简单的精灵套件游戏,包括躲避红球。我使用的是内置的重力机制,但是我在防止玩家从地上摔下来时遇到了麻烦。我已经找到了一个解决方案(set ground.physicsBody.dynamic=NO),但玩家仍然失败。我到底需要做什么 编辑:绿色和棕色纹理是地面。现在玩家被设置为不动态,所以它是“飞行的” 以下是我在MyScene.m文件中的代码:Ios 防止玩家从地上跌落-精灵套件,ios,objective-c,sprite-kit,Ios,Objective C,Sprite Kit,我一直在尝试一个简单的精灵套件游戏,包括躲避红球。我使用的是内置的重力机制,但是我在防止玩家从地上摔下来时遇到了麻烦。我已经找到了一个解决方案(set ground.physicsBody.dynamic=NO),但玩家仍然失败。我到底需要做什么 编辑:绿色和棕色纹理是地面。现在玩家被设置为不动态,所以它是“飞行的” 以下是我在MyScene.m文件中的代码: // // MyScene.m // DodgeMan // // Created by Cormac Chester on 3
//
// MyScene.m
// DodgeMan
//
// Created by Cormac Chester on 3/8/14.
// Copyright (c) 2014 Testman Industries. All rights reserved.
//
#import "MyScene.h"
#import "EndGameScene.h"
static const uint32_t redBallCategory = 0x1 << 0;
static const uint32_t playerCategory = 0x1 << 1;
@implementation MyScene
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
/* Setup your scene here */
//Sets player location
playerLocX = 50;
playerLocY = 100;
//Sets player score
score = 0;
//Set Background
self.backgroundColor = [SKColor colorWithRed:0.53 green:0.81 blue:0.92 alpha:1.0];
//Set Ground
SKSpriteNode *ground = [SKSpriteNode spriteNodeWithImageNamed:@"ground"];
ground.position = CGPointMake(CGRectGetMidX(self.frame), 34);
ground.xScale = 0.5;
ground.yScale = 0.5;
ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ground.size];
ground.physicsBody.dynamic = NO;
//Player
self.playerSprite = [SKSpriteNode spriteNodeWithImageNamed:@"character"];
self.playerSprite.position = CGPointMake(playerLocX, playerLocY);
//Set Player Physics
self.playerSprite.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.playerSprite.size];
self.playerSprite.physicsBody.dynamic = YES;
self.playerSprite.physicsBody.categoryBitMask = playerCategory;
self.playerSprite.physicsBody.contactTestBitMask = redBallCategory;
self.playerSprite.physicsBody.collisionBitMask = 0;
self.playerSprite.physicsBody.usesPreciseCollisionDetection = YES;
//Score Label
self.scoreLabel = [SKLabelNode labelNodeWithFontNamed:@"Arial-BoldMT"];
self.scoreLabel.text = @"0";
self.scoreLabel.fontSize = 40;
self.scoreLabel.fontColor = [SKColor blackColor];
self.scoreLabel.position = CGPointMake(50, 260);
//Pause Button
self.pauseButton = [SKSpriteNode spriteNodeWithImageNamed:@"pauseButton"];
self.pauseButton.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height - 40);
self.pauseButton.name = @"pauseButton";
//Add nodes
[self addChild:ground];
[self addChild:self.playerSprite];
[self addChild:self.scoreLabel];
//[self addChild:self.pauseButton];
//Sets gravity
self.physicsWorld.gravity = CGVectorMake(0,-2);
self.physicsWorld.contactDelegate = self;
}
return self;
}
-(void)addBall
{
SKSpriteNode *redBall = [SKSpriteNode spriteNodeWithImageNamed:@"locationIndicator"];
int minY = redBall.size.height / 2;
int maxY = self.frame.size.height - redBall.size.height / 2;
int rangeY = maxY - minY;
int actualY = (arc4random() % rangeY) + minY;
NSLog(@"Actual Y: %i", actualY);
//Initiates red ball offscreen
if (actualY >= 75)
{
//Prevents balls from spawning in the ground
redBall.position = CGPointMake(self.frame.size.width + redBall.size.width/2, actualY);
[self addChild:redBall];
}
redBall.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:redBall.size.width/2];
redBall.physicsBody.dynamic = YES;
redBall.physicsBody.categoryBitMask = redBallCategory;
redBall.physicsBody.contactTestBitMask = playerCategory;
redBall.physicsBody.collisionBitMask = 0;
redBall.physicsBody.affectedByGravity = NO;
redBall.physicsBody.usesPreciseCollisionDetection = YES;
//Determine speed of red ball
int minDuration = 3.0;
int maxDuration = 5.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
SKAction *actionMove = [SKAction moveTo:CGPointMake(-redBall.size.width/2, actualY) duration:actualDuration];
SKAction *actionMoveDone = [SKAction removeFromParent];
SKAction *ballCross = [SKAction runBlock:^{
score++;
self.scoreString = [NSString stringWithFormat:@"%i", score];
self.scoreLabel.text = self.scoreString;
NSLog(@"Score was incremented. Score is now %d", score);
}];
[redBall runAction:[SKAction sequence:@[actionMove, ballCross, actionMoveDone]]];
}
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast
{
self.lastSpawnTimeInterval += timeSinceLast;
if (self.lastSpawnTimeInterval > 0.5) {
self.lastSpawnTimeInterval = 0;
[self addBall];
}
}
-(void)update:(CFTimeInterval)currentTime
{
/* Called before each frame is rendered */
// Handle time delta.
//Prevents bad stuff happening
CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
self.lastUpdateTimeInterval = currentTime;
if (timeSinceLast > 1) { // more than a second since last update
timeSinceLast = 1.0 / 120.0;
self.lastUpdateTimeInterval = currentTime;
}
[self updateWithTimeSinceLastUpdate:timeSinceLast];
}
NSDate *startTime;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
/* Called when a touch begins */
[super touchesBegan:touches withEvent:event];
//Starts Timer
startTime = [NSDate date];
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
//Pauses Scene
if ([node.name isEqualToString:@"pauseButton"])
{
NSLog(@"Pause button pressed");
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
/* Called when a touch ends */
[super touchesEnded:touches withEvent:event];
NSTimeInterval elapsedTime = [startTime timeIntervalSinceNow];
NSString *elapsedTimeString = [NSString stringWithFormat:@"Elapsed time: %f", elapsedTime];
NSLog(@"%@", elapsedTimeString);
for (UITouch *touch in touches)
{
//Gets location of touch
CGPoint location = [touch locationInNode:self];
NSLog(@"Touch Location X: %f \n Touch Location Y: %f", location.x, location.y);
//Prevents destination from being in the ground
if (location.y < 88)
{
location.y = 87.5;
}
//Moves and animates player
//int velocity = elapsedTime * -3000;
int velocity = 800.0/1.0;
NSLog(@"Velocity: %i", velocity);
float realMoveDuration = self.size.width / velocity;
SKAction *actionMove = [SKAction moveTo:location duration:realMoveDuration];
[self.playerSprite runAction:[SKAction sequence:@[actionMove]]];
}
NSLog(@"Touch ended");
}
//Collision between ball and player
- (void)redBall:(SKSpriteNode *)redBall didCollideWithPlayer:(SKSpriteNode *)playerSprite
{
NSLog(@"Player died");
[redBall removeFromParent];
[playerSprite removeFromParent];
SKTransition *reveal = [SKTransition crossFadeWithDuration:0.5];
SKScene *endGameScene = [[EndGameScene alloc] initWithSize:self.size gameEnded:YES];
[self.view presentScene:endGameScene transition: reveal];
}
- (void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
//Red ball collides with the player
if ((firstBody.categoryBitMask & redBallCategory) != 0 && (secondBody.categoryBitMask & playerCategory) != 0)
{
[self redBall:(SKSpriteNode *) firstBody.node didCollideWithPlayer:(SKSpriteNode *) secondBody.node];
}
}
@end
//
//MyScene.m
//道奇曼
//
//由Cormac Chester于2014年3月8日创作。
//版权所有(c)2014 Testman Industries。版权所有。
//
#导入“MyScene.h”
#导入“endGameSecene.h”
静态常数uint32\u t redBallCategory=0x1 0.5){
self.lastSpawnTimeInterval=0;
[自我添加球];
}
}
-(无效)更新:(CFTimeInterval)currentTime
{
/*在渲染每个帧之前调用*/
//处理时间增量。
//防止不好的事情发生
CFTimeInterval timesineclast=currentTime-self.lastUpdateTimeInterval;
self.lastUpdateTimeInterval=当前时间;
如果(timeSinceLast>1){//自上次更新后超过一秒
timeSinceLast=1.0/120.0;
self.lastUpdateTimeInterval=当前时间;
}
[self-updateWithTimeSinceLastUpdate:timeSinceLast];
}
NSDate*开始时间;
-(无效)触摸开始:(NSSet*)触摸事件:(UIEvent*)事件
{
/*当触摸开始时调用*/
[超级触摸开始:触摸事件:事件];
//启动计时器
开始时间=[NSDate date];
UITouch*touch=[触摸任何对象];
CGPoint位置=[触摸位置Innode:self];
SKNode*node=[自身节点点:位置];
//暂停场景
if([node.name isEqualToString:@“pauseButton”])
{
NSLog(@“暂停按钮按下”);
}
}
-(void)touchesend:(NSSet*)toucheevent:(UIEvent*)event
{
/*触摸结束时调用*/
[超级触控:触控事件:事件];
NSTimeInterval elapsedTime=[startTime TimeIntervalencesInnow];
NSString*elapsedTimeString=[NSString stringWithFormat:@“运行时间:%f”,elapsedTime];
NSLog(@“%@”,elapsedTimeString);
用于(UITouch*触摸屏)
{
//获取触摸的位置
CGPoint位置=[触摸位置Innode:self];
NSLog(@“触摸位置X:%f\n触摸位置Y:%f”,位置.X,位置.Y);
//防止目的地位于地面
如果(位置y<88)
{
位置y=87.5;
}
//移动和动画播放器
//int速度=延迟时间*-3000;
内速度=800.0/1.0;
NSLog(@“速度:%i”,速度);
float realMoveDuration=self.size.width/速度;
SKAction*actionMove=[SKAction moveTo:location duration:realMoveDuration];
[self.playerSprite runAction:[SKAction sequence:@[actionMove]];
}
NSLog(@“触摸结束”);
}
//球与球员的碰撞
-红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队:红球队
{
NSLog(“玩家死亡”);
[红球从父对象移除];
[PlayerPrite从父级移除];
SKTransition*reveal=[SKTransition crossFadeWithDuration:0.5];
SKScene*endGameSecene=[[endGameSecene alloc]initWithSize:self.size gameEnded:YES];
[self.view presentScene:endgame场景过渡:显示];
}
-(无效)didBeginContact:(SKPhysicsContact*)联系人
{
SKPhysicsBody*第一个Body,*第二个Body;
if(contact.bodyA.categoryBitMask
只需:
self.playerSprite.physicsBody.dynamic = NO;
应该有效。您绝对不能将其动态设置为“无兄弟”。你需要那个玩家的重力效果。(他不受物理世界的影响,所以他现在正在飞行。我们需要他倒在地上,不是吗?:) 这是一个简单的解决方案。其思想是在具有physic body的地面上创建一个“不可见的矩形块”。您需要将其“动态”设置为“否”,以防止其掉落 所以这个块显然是一个节点,它的大小:和地面一样高,和屏幕一样宽。你需要稍微调整一下位置,把它的上限放在地面上 祝你好运
我确实画了一幅画,但因为我的名声,我不能把它贴在这里:(您的问题是由于缩放而产生的。由于某些原因,在以下代码中使用“精灵工具包”缩放图像时,图像的大小不会改变。从您的图片判断,您的地面物理体矩形实际上是您想象的两倍大,并且已经吞没了播放器,这就是为什么没有碰撞检测的原因。这是从最近的一款风格非常相似的游戏经验来看。场景周围是否有一个边缘循环Physis body?碰撞标志和类别标志设置正确,以便玩家与地面碰撞?我遇到了同样的问题,我简单地解决了它 在update方法上,我放置了一个if语句:
if(player.position.y<your_closest_value_near_ground){
player.position.y == your_Closest_value_near_ground
}
if(player.position.y您的问题在于physicsBody的categoryBitMask和collisionTestBitMask。
您的按位声明:
static const uint32_t redBallCategory = 0x1 << 0;
static const uint32_t playerCategory = 0x1 << 1;
}但是玩家不会受到重力的影响。@comrod,你能为你的游戏和你站在地面上的玩家做一个屏幕截图吗?为了更好地理解我们这里有什么。所以,实际上,你的玩家只需要左/右移动。你想让玩家受到重力的影响,你想实现什么?我正计划修改控件,就像咖喱
static const uint32_t redBallCategory = 0x1 << 0;
static const uint32_t playerCategory = 0x1 << 1;
static const uint32_t groundCategory = 0x1 << 2;
@implementation MyScene
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
/* Setup your scene here */
//Sets player location
playerLocX = 50;
playerLocY = 100;
//Sets player score
score = 0;
//Set Background
self.backgroundColor = [SKColor colorWithRed:0.53 green:0.81 blue:0.92 alpha:1.0];
//Set Ground
SKSpriteNode *ground = [SKSpriteNode spriteNodeWithImageNamed:@"ground"];
ground.position = CGPointMake(CGRectGetMidX(self.frame), 34);
ground.xScale = 0.5;
ground.yScale = 0.5;
ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ground.size];
ground.physicsBody.categoryBitMask=groundCategory;
ground.physicsBody.collisionBitMask=playerCategory|redBallCategory;
ground.physicsBody.dynamic = NO;
//Player
self.playerSprite = [SKSpriteNode spriteNodeWithImageNamed:@"character"];
self.playerSprite.position = CGPointMake(playerLocX, playerLocY);
//Set Player Physics
self.playerSprite.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.playerSprite.size];
self.playerSprite.physicsBody.dynamic = YES;
self.playerSprite.physicsBody.categoryBitMask = playerCategory;
self.playerSprite.physicsBody.contactTestBitMask = redBallCategory;
self.playerSprite.physicsBody.collisionBitMask = groundCategory|redBallCategory;
self.playerSprite.physicsBody.usesPreciseCollisionDetection = YES;
//Score Label
self.scoreLabel = [SKLabelNode labelNodeWithFontNamed:@"Arial-BoldMT"];
self.scoreLabel.text = @"0";
self.scoreLabel.fontSize = 40;
self.scoreLabel.fontColor = [SKColor blackColor];
self.scoreLabel.position = CGPointMake(50, 260);
//Pause Button
self.pauseButton = [SKSpriteNode spriteNodeWithImageNamed:@"pauseButton"];
self.pauseButton.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height - 40);
self.pauseButton.name = @"pauseButton";
//Add nodes
[self addChild:ground];
[self addChild:self.playerSprite];
[self addChild:self.scoreLabel];
//[self addChild:self.pauseButton];
//Sets gravity
self.physicsWorld.gravity = CGVectorMake(0,-2);
self.physicsWorld.contactDelegate = self;
}
return self;