Objective c 可变跳跃高度

Objective c 可变跳跃高度,objective-c,game-physics,gravity,Objective C,Game Physics,Gravity,我一直很难创建一个跳跃系统,用户可以点击跳跃按钮进行小跳跃,按住它进行更高的跳跃 我偶然发现了这个话题: 这极大地帮助我开发了以下代码: PlayerMovementTimer = [NSTimer scheduledTimerWithTimeInterval:0.005 target:self selector:@selector(movePlayer) userInfo:nil repeats:YES]; [JumpButton addTarget:self action:@select

我一直很难创建一个跳跃系统,用户可以点击跳跃按钮进行小跳跃,按住它进行更高的跳跃

我偶然发现了这个话题:

这极大地帮助我开发了以下代码:

PlayerMovementTimer = [NSTimer scheduledTimerWithTimeInterval:0.005 target:self selector:@selector(movePlayer) userInfo:nil repeats:YES];

[JumpButton addTarget:self action:@selector(jumpPlayer:) forControlEvents:UIControlEventTouchDown];
[JumpButton addTarget:self action:@selector(stopJump:) forControlEvents:UIControlEventTouchCancel | UIControlEventTouchUpInside | UIControlEventTouchDragExit];

- (void)movePlayer
{
    CGFloat playerY = Player.center.y + PlayerYV;
    if(playerY > 264) {
        PlayerYV = 0;
        playerY = 264;
    }
    if(playerY < 264) {
        PlayerYV += 0.048f - PlayerYD;
    }
    if(HoldingJump && PlayerYV < 0 && PlayerYD + 0.0018f < 0.048f) {
        PlayerYD += 0.0018f;
    }

    Player.center = CGPointMake(Player.center.x + PlayerXV, playerY);
}

- (IBAction)jumpPlayer:(id)sender
{
    if(Player.center.y == 264) {
        PlayerYD = 0;
        PlayerYV = -2.25;
        HoldingJump = true;
    }
}

- (IBAction)stopJump:(id)sender
{
    HoldingJump = false;
}
PlayerMovementTimer=[NSTimer scheduledTimerWithTimeInterval:0.005目标:自选择器:@selector(movePlayer)用户信息:无重复:是];
[JumpButton添加目标:自我操作:@selector(jumpPlayer:)forControlEvents:UIControlEventTouchDown];
[JumpButton addTarget:self action:@selector(stopJump:)for ControlEvents:UIControlEventTouchCancel | UIControlEventTouchUpInside | UIControlEventTouchDragExit];
-(无效)移动玩家
{
CGFloat playerY=Player.center.y+playerv;
如果(playerY>264){
playerv=0;
playerY=264;
}
if(playerY<264){
playerv+=0.048f-playerId;
}
如果(保持跳转和播放EV<0和播放ID+0.0018f<0.048f){
PlayerId+=0.0018f;
}
Player.center=CGPointMake(Player.center.x+PlayerXV,playerY);
}
-(iAction)jumpPlayer:(id)发送方
{
if(Player.center.y==264){
playerId=0;
playerv=-2.25;
HoldingJump=true;
}
}
-(iAction)停止跳转:(id)发送方
{
HoldingJump=false;
}
代码似乎可以工作(有些值需要微调,但我还没有来得及去做)。唯一的问题是,动作似乎有点急促(即使在真正的设备上),而且当玩家在跳跃的顶端时,他们的加速速度非常慢,我输入的任何值似乎都无法使跳跃看起来像马里奥游戏一样平滑

请看一下代码,看看我是否遗漏了一些明显的东西,或者是否有比调用void函数的NSTimer更有效的控制移动的方法。另外,将UIImageView的位置设置为浮点值是否错误


谢谢。

所以这里有很多错误。首先,是的,您不应该将ImageView或任何其他UI元素的原点设置为分数像素的坐标位置。这会导致亚像素化,从而使图像模糊。为了避免这种情况,应使用roundf()或其他类似的舍入函数将所有CGfloat舍入到最接近的整数

我看到的另一个问题是,您正在设置Player.center。为了你的缘故,我希望玩家不是一个ImageView,因为你会让你的生活变得更艰难。如上所述,当帧的原点未设置为整数CGFloat时,将获得子像素。使用“中心”属性时,很容易导致原点值错误。例如,如果我有一个11乘11的图像,并将其中心设置为(11,11),原点将设置为(5.5,5.5),并将导致子像素化。避免这种情况的简单方法是,只需进行数学运算以正确放置原点,并确保将输入的CGfloat四舍五入(或在设置它之前在帧上使用CGRectIntegral)

这里的第三个问题是计时器被称为0.005秒。让我们假设您希望此游戏以每秒60帧的速度运行。每秒60帧转换为大约0.0167秒。计时器调用该方法的频率比需要调用的频率高三倍,即使您想要60 FPS,而且,如此频繁地调用该方法可能会导致您的一些急促动作

现在,就获得“马里奥”式的跳跃而言,你真正需要做的是获得一个专用的物理引擎,因为如果你使用上面的代码,你似乎没有。物理引擎所能做的是,它将应用一个恒定的“重力”,这将有助于使玩家的跳跃看起来和动作更真实。当玩家按下按钮时,你会对玩家角色施加一种冲动。使用脉冲还可以简化您的工作,因为您可以根据按钮的按住时间等不同的方式应用脉冲。上面的代码只是试图绕过这个问题,而不是解决您没有物理引擎的真正问题


去研究一下cocos2D和Box2D作为一个可能的物理引擎,你可以使用它。cocos2D+Box2D上有丰富的资源,有一位开发人员甚至编写了一篇关于使用cocos2D创建超级马里奥克隆的教程,这将使您对物理引擎的工作原理有一些基本的了解:

谢谢!使用此信息,我能够成功地停止UIImageView上的模糊影响,并通过使用正确的计时器值使移动平滑!另外,感谢您使用物理引擎指针,但这不是必需的;我已经解决了我的问题,现在我的游戏有了一个完美的跳跃系统:)