- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在开发一款带有 sprite 套件的简单飞行游戏。一旦 spaceship 达到最大高度和速度,它就会以恒定速度继续飞行。我注意到 spaceship 在不断的飞行过程中会随机出现断断续续的情况。我已经在这里阅读了所有关于这个问题的帖子,但没有什么能真正帮助 100% 解决它。
为了测试,我写了一个非常简单的游戏,它只包含一艘 spaceship 和一个简单的云(代码如下)。但是即使在这个非常简单的游戏中, spaceship 仍然会卡顿。 LOG 表明,即使飞船以恒定速度飞行,飞船运动也不是随机恒定的。这就是口吃的原因。
希望有人能帮我解决这个问题。感谢您的任何想法。
Sprite 套件、Objective c、Xcode 8.0、测试设备:iPhone 6 - iOS 8.3、iPhone 4s - iOS 9.3.5
CPU:最大 21%,内存:最大 8 MB,FPS:永久 60 FPS
这是我的代码(为简单起见,我将所有代码放在场景类中)
飞行场景.h
#import <SpriteKit/SpriteKit.h>
@interface FlightScene : SKScene <SKPhysicsContactDelegate>
@end
飞行场景.m
#import "FlightScene.h"
#define HERO_FLIGHT_LOG 1
//#define HERO_DEBUG_OVERLAY 1
static const CGFloat kMaxHeroVelocityY = 100.0f;
static const CGFloat kMaxHeroVelocityX = 200.0f;
@implementation FlightScene
{
SKNode *_world;
SKSpriteNode *_hero;
SKSpriteNode *_cloud;
CGPoint _heroStartPosition;
CGSize _cloudSize;
CGFloat _xAdj;
BOOL _hasBegun;
// debug
CGFloat _oldHeroX;
CGFloat _oldHeroY;
int _frame;
}
- (void)didMoveToView:(SKView *)view
{
// Setup your scene here
[super didMoveToView:view];
_hasBegun = NO;
_cloudSize = CGSizeMake(120, 80);
_xAdj = _cloudSize.width;
_heroStartPosition = CGPointMake(60, self.size.height/2);
[self addWorld];
[self addHero];
[self addCloud];
// debug
_frame = 0;
_oldHeroX = 0;
_oldHeroY = 0;
}
#pragma mark - hero
- (void)addHero
{
_hero = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship2"];
_hero.size = CGSizeMake(80.0f, 70.0f);
_hero.position = _heroStartPosition;
_hero.zPosition = 1;
_hero.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:self.size.width/2.0f];
_hero.physicsBody.affectedByGravity = NO;
_hero.physicsBody.dynamic = YES;
_hero.physicsBody.allowsRotation = NO;
_hero.physicsBody.mass = 1.0f;
_hero.physicsBody.linearDamping = 0.0f;
_hero.physicsBody.friction = 0.0f;
[_world addChild:_hero];
}
- (void)updateFlying
{
if(!_hasBegun)
return;
CGVector oldVel = _hero.physicsBody.velocity;
CGVector newVel = oldVel;
// increase the velocity
newVel.dx += (kMaxHeroVelocityX - newVel.dx) / 10.0f;
newVel.dy += (kMaxHeroVelocityY - newVel.dy) / 10.0f;
// ensure velocity doesn't exceed maximum
newVel.dx = newVel.dx > kMaxHeroVelocityX ? kMaxHeroVelocityX : newVel.dx;
newVel.dy = newVel.dy > kMaxHeroVelocityY ? kMaxHeroVelocityY : newVel.dy;
_hero.physicsBody.velocity = newVel;
}
- (void)limitHeight
{
const CGFloat maxHeight = self.size.height * 0.8f;
if(_hero.position.y > maxHeight)
_hero.position = CGPointMake(_hero.position.x, maxHeight);
}
- (void)updateFlight
{
// move hero with constant velocity
[self updateFlying];
// ensure height doesn't exceed maximum
[self limitHeight];
}
#pragma mark - game world
- (void)addWorld
{
_world = [SKNode new];
[self addChild:_world];
}
- (void)addCloud
{
_cloud = [SKSpriteNode spriteNodeWithColor:[SKColor lightGrayColor] size:_cloudSize];
_cloud.anchorPoint = CGPointMake(0, 1); // top left
_cloud.position = CGPointMake(self.size.width + _cloudSize.width, self.size.height + _cloudSize.height/2);
_cloud.zPosition = -1;
[_world addChild:_cloud];
}
#pragma mark - update world
- (void)updateCloud
{
// reposition the cloud
if(_world.position.x + _xAdj < -(_cloudSize.width + self.size.width))
{
_xAdj += _cloudSize.width + self.size.width;
CGFloat y = arc4random_uniform(_cloudSize.height - 10);
_cloud.position = CGPointMake(_xAdj + self.size.width, self.size.height + y);
}
}
- (void)updateWorld
{
// move the world
CGFloat worldX = -(_hero.position.x - _heroStartPosition.x);
_world.position = CGPointMake(worldX, _world.position.y);
[self updateCloud];
[self flightLog];
}
-(void)update:(CFTimeInterval)currentTime
{
// Called before each frame is rendered
if(!_hasBegun)
return;
_frame++;
// update hero movement
[self updateFlight];
}
- (void)didFinishUpdate
{
if(!_hasBegun)
return;
// update world movement
[self updateWorld];
}
#pragma mark - touches
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if(_hasBegun)
return;
_hasBegun = YES;
[self updateFlight];
}
#pragma mark - debug
- (void)flightLog
{
#ifdef HERO_FLIGHT_LOG
CGFloat newHeroX = _hero.position.x - _heroStartPosition.x;;
CGFloat diffX = newHeroX - _oldHeroX;
CGFloat newHeroY = _hero.position.y;
CGFloat diffY = newHeroY - _oldHeroY;
NSLog(@"oldHeroY:%f, newHeroY:%f, diffY:%f", _oldHeroY, newHeroY, diffY);
NSLog(@"oldHeroX:%f, newHeroX:%f, diffX:%f\n\n", _oldHeroX, newHeroX, diffX);
if(diffX > 3.5f)
{
//NSLog(@"\t -> frame:%d fast oldHeroY:%f, newHeroY:%f, diffY:%f", _frame, _oldHeroY, newHeroY, diffY);
NSLog(@"\t -> frame:%d fast oldHeroX:%f, newHeroX:%f, diffX:%f\n\n", _frame, _oldHeroX, newHeroX, diffX);
}
else if(diffX < 3.0f)
{
//NSLog(@"\t -> frame:%d fast oldHeroY:%f, newHeroY:%f, diffY:%f", _frame, _oldHeroY, newHeroY, diffY);
NSLog(@"\t -> frame:%d slow oldHeroX:%f, newHeroX:%f, diffX:%f\n\n", _frame, _oldHeroX, newHeroX, diffX);
}
_oldHeroX = newHeroX;
_oldHeroY = newHeroY;
#endif
}
@end
日志:
.
.
.
// no stuttering .. FPS: 60
2016-10-02 17:27:19.164 TestFlight[11009:1774440] oldHeroY:301.666534, newHeroY:301.666534, diffY:0.000000
2016-10-02 17:27:19.165 TestFlight[11009:1774440] oldHeroX:263.002899, newHeroX:266.335968, diffX:3.333069
2016-10-02 17:27:19.181 TestFlight[11009:1774440] oldHeroY:301.666534, newHeroY:301.666534, diffY:0.000000
2016-10-02 17:27:19.182 TestFlight[11009:1774440] oldHeroX:266.335968, newHeroX:269.669067, diffX:3.333099
// stuttering .. FPS: 60
2016-10-02 17:27:24.584 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:302.500031, diffY:0.833344
2016-10-02 17:27:24.585 TestFlight[11009:1774440] oldHeroX:1346.335083, newHeroX:1351.335083, diffX:5.000000
2016-10-02 17:27:24.585 TestFlight[11009:1774440] -> frame:413 fast oldHeroX:1346.335083, newHeroX:1351.335083, diffX:5.000000
2016-10-02 17:27:24.600 TestFlight[11009:1774440] oldHeroY:302.500031, newHeroY:300.833344, diffY:-1.666687
2016-10-02 17:27:24.601 TestFlight[11009:1774440] oldHeroX:1351.335083, newHeroX:1353.001709, diffX:1.666626
2016-10-02 17:27:24.601 TestFlight[11009:1774440] -> frame:414 slow oldHeroX:1351.335083, newHeroX:1353.001709, diffX:1.666626
2016-10-02 17:27:24.617 TestFlight[11009:1774440] oldHeroY:300.833344, newHeroY:301.666687, diffY:0.833344
2016-10-02 17:27:24.618 TestFlight[11009:1774440] oldHeroX:1353.001709, newHeroX:1356.335083, diffX:3.333374
2016-10-02 17:27:24.634 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.634 TestFlight[11009:1774440] oldHeroX:1356.335083, newHeroX:1359.668457, diffX:3.333374
2016-10-02 17:27:24.650 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.651 TestFlight[11009:1774440] oldHeroX:1359.668457, newHeroX:1363.001831, diffX:3.333374
2016-10-02 17:27:24.667 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:302.500031, diffY:0.833344
2016-10-02 17:27:24.668 TestFlight[11009:1774440] oldHeroX:1363.001831, newHeroX:1368.001831, diffX:5.000000
2016-10-02 17:27:24.668 TestFlight[11009:1774440] -> frame:418 fast oldHeroX:1363.001831, newHeroX:1368.001831, diffX:5.000000
2016-10-02 17:27:24.684 TestFlight[11009:1774440] oldHeroY:302.500031, newHeroY:300.833344, diffY:-1.666687
2016-10-02 17:27:24.684 TestFlight[11009:1774440] oldHeroX:1368.001831, newHeroX:1369.668457, diffX:1.666626
2016-10-02 17:27:24.685 TestFlight[11009:1774440] -> frame:419 slow oldHeroX:1368.001831, newHeroX:1369.668457, diffX:1.666626
2016-10-02 17:27:24.700 TestFlight[11009:1774440] oldHeroY:300.833344, newHeroY:301.666687, diffY:0.833344
2016-10-02 17:27:24.701 TestFlight[11009:1774440] oldHeroX:1369.668457, newHeroX:1373.001831, diffX:3.333374
2016-10-02 17:27:24.717 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:302.500031, diffY:0.833344
2016-10-02 17:27:24.718 TestFlight[11009:1774440] oldHeroX:1373.001831, newHeroX:1378.001831, diffX:5.000000
2016-10-02 17:27:24.718 TestFlight[11009:1774440] -> frame:421 fast oldHeroX:1373.001831, newHeroX:1378.001831, diffX:5.000000
2016-10-02 17:27:24.734 TestFlight[11009:1774440] oldHeroY:302.500031, newHeroY:301.666687, diffY:-0.833344
2016-10-02 17:27:24.734 TestFlight[11009:1774440] oldHeroX:1378.001831, newHeroX:1381.335205, diffX:3.333374
// no stuttering .. FPS: 60
2016-10-02 17:27:24.750 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.751 TestFlight[11009:1774440] oldHeroX:1381.335205, newHeroX:1384.668579, diffX:3.333374
2016-10-02 17:27:24.767 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.768 TestFlight[11009:1774440] oldHeroX:1384.668579, newHeroX:1388.001953, diffX:3.333374
2016-10-02 17:27:24.784 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.784 TestFlight[11009:1774440] oldHeroX:1388.001953, newHeroX:1391.335327, diffX:3.333374
2016-10-02 17:27:24.801 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.801 TestFlight[11009:1774440] oldHeroX:1391.335327, newHeroX:1394.668701, diffX:3.333374
2016-10-02 17:27:24.817 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.818 TestFlight[11009:1774440] oldHeroX:1394.668701, newHeroX:1398.002075, diffX:3.333374
2016-10-02 17:27:24.834 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.834 TestFlight[11009:1774440] oldHeroX:1398.002075, newHeroX:1401.335449, diffX:3.333374
2016-10-02 17:27:24.850 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.851 TestFlight[11009:1774440] oldHeroX:1401.335449, newHeroX:1404.668823, diffX:3.333374
2016-10-02 17:27:24.867 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.868 TestFlight[11009:1774440] oldHeroX:1404.668823, newHeroX:1408.002197, diffX:3.333374
// stuttering .. FPS: 60
2016-10-02 17:27:24.883 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:300.833344, diffY:-0.833344
2016-10-02 17:27:24.884 TestFlight[11009:1774440] oldHeroX:1408.002197, newHeroX:1409.668823, diffX:1.666626
2016-10-02 17:27:24.885 TestFlight[11009:1774440] -> frame:431 slow oldHeroX:1408.002197, newHeroX:1409.668823, diffX:1.666626
2016-10-02 17:27:24.901 TestFlight[11009:1774440] oldHeroY:300.833344, newHeroY:302.500031, diffY:1.666687
2016-10-02 17:27:24.902 TestFlight[11009:1774440] oldHeroX:1409.668823, newHeroX:1414.668823, diffX:5.000000
2016-10-02 17:27:24.902 TestFlight[11009:1774440] -> frame:432 fast oldHeroX:1409.668823, newHeroX:1414.668823, diffX:5.000000
2016-10-02 17:27:24.917 TestFlight[11009:1774440] oldHeroY:302.500031, newHeroY:300.833344, diffY:-1.666687
2016-10-02 17:27:24.918 TestFlight[11009:1774440] oldHeroX:1414.668823, newHeroX:1416.335449, diffX:1.666626
2016-10-02 17:27:24.918 TestFlight[11009:1774440] -> frame:433 slow oldHeroX:1414.668823, newHeroX:1416.335449, diffX:1.666626
2016-10-02 17:27:24.934 TestFlight[11009:1774440] oldHeroY:300.833344, newHeroY:302.500031, diffY:1.666687
2016-10-02 17:27:24.935 TestFlight[11009:1774440] oldHeroX:1416.335449, newHeroX:1421.335449, diffX:5.000000
2016-10-02 17:27:24.935 TestFlight[11009:1774440] -> frame:434 fast oldHeroX:1416.335449, newHeroX:1421.335449, diffX:5.000000
2016-10-02 17:27:24.950 TestFlight[11009:1774440] oldHeroY:302.500031, newHeroY:301.666687, diffY:-0.833344
2016-10-02 17:27:24.951 TestFlight[11009:1774440] oldHeroX:1421.335449, newHeroX:1424.668823, diffX:3.333374
// no stuttering for a while (17 seconds .. long time) .. FPS: 60
2016-10-02 17:27:24.967 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:24.968 TestFlight[11009:1774440] oldHeroX:1424.668823, newHeroX:1428.002197, diffX:3.333374
.
.
.
2016-10-02 17:27:41.559 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:41.559 TestFlight[11009:1774440] oldHeroX:4742.992188, newHeroX:4746.325684, diffX:3.333496
// stuttering .. FPS: 60
2016-10-02 17:27:41.575 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:300.833344, diffY:-0.833344
2016-10-02 17:27:41.576 TestFlight[11009:1774440] oldHeroX:4746.325684, newHeroX:4747.992188, diffX:1.666504
2016-10-02 17:27:41.576 TestFlight[11009:1774440] -> frame:1432 slow oldHeroX:4746.325684, newHeroX:4747.992188, diffX:1.666504
2016-10-02 17:27:41.592 TestFlight[11009:1774440] oldHeroY:300.833344, newHeroY:302.500031, diffY:1.666687
2016-10-02 17:27:41.593 TestFlight[11009:1774440] oldHeroX:4747.992188, newHeroX:4752.992188, diffX:5.000000
2016-10-02 17:27:41.593 TestFlight[11009:1774440] -> frame:1433 fast oldHeroX:4747.992188, newHeroX:4752.992188, diffX:5.000000
2016-10-02 17:27:41.609 TestFlight[11009:1774440] oldHeroY:302.500031, newHeroY:301.666687, diffY:-0.833344
2016-10-02 17:27:41.609 TestFlight[11009:1774440] oldHeroX:4752.992188, newHeroX:4756.325684, diffX:3.333496
2016-10-02 17:27:41.625 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:41.626 TestFlight[11009:1774440] oldHeroX:4756.325684, newHeroX:4759.659180, diffX:3.333496
2016-10-02 17:27:41.642 TestFlight[11009:1774440] oldHeroY:301.666687, newHeroY:301.666687, diffY:0.000000
2016-10-02 17:27:41.643 TestFlight[11009:1774440] oldHeroX:4759.659180, newHeroX:4762.992676, diffX:3.333496
.
.
.
// and so on ..
编辑:
我将其添加到 addHero:
方法
_hero.physicsBody.angularDamping = 0.0f;
我更改了 touchesBegan:
以便 spaceship 在不起飞的情况下立即以最大速度飞行。
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if(_hasBegun)
return;
_hasBegun = YES;
_hero.physicsBody.velocity = CGVectorMake(kMaxHeroVelocityX, kMaxHeroVelocityY);
}
我在没有 updateFlying:
方法的情况下运行代码。 spaceship 在没有起飞的情况下立即以最大速度飞行。它以恒定速度飞行,因此不需要更新速度。
我尝试了其他方法,比如将更新放入 didSimulatePhysics:
.. 打开飞行模式 .. 正如@Confused 所建议的.. 但没有任何方法可以解决这个问题。正如@crashoverride777 所说,它仍然不是 100% 完美。
如有任何其他想法,我将不胜感激。
最佳答案
这是因为 SpriteKit 的默认物理和运动/变换处理未根据增量时间进行校正。相反,只要帧速率由于系统调用或其他中断而下降,它就会卡顿。这些事情在 iOS 设备上经常发生。 iOS 系统不断地检查网络并监控各种后台事件的其他状态,并对传入的信息做出响应。
有两种处理方法。
打开飞行模式,关闭所有后台更新应用程序,并严格限制几乎所有应用程序在其设置中执行后台进程;这减少了操作系统噪音和开销。
使用增量时间滚动您自己的调整和补偿机制,使事物看起来继续以正确的速度移动到预期的目的地,即使跳过一两帧也是如此。
如果您不限于 SpriteKit,或者不需要它的物理特性,您可以包含另一个物理引擎并使用它。这最终意味着您可以使用 SceneKit、Core Animation 甚至 Metal 来进行渲染……或 SpriteKit
两个最明智的选择是 Box2D 和 Chipmunk2D。
这是将 Box2D 添加到 iOS 的教程:https://www.raywenderlich.com/2061-liquidfun-tutorial-with-metal-and-swift-part-1
这是 Chipmunk2D 的 Swift 包装器:https://github.com/jakubknejzlik/ChipmunkSwiftWrapper
关于ios - SpriteKit : Stuttering during movement with constant velocity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39819602/
所以如果我在 C++ 中有这样的东西: char A_char = 'A'; char * myPtr = &A_char; const char * myPtr = &char_A; //point
我试图在我的 Perl 脚本中将魔数(Magic Number)声明为常量,如 perlsub 中所述。但是,我收到警告: $ cat foo.perl use warnings ; use stri
我想为 data Constant a b = Constant a 这是我的直接尝试: instance Foldable (Constant a) where foldr f b (Const
我在客户端和服务器端拆分了我的文件夹,但我没有从父文件夹工作,我表现得好像它们是 2 个不同的文件夹...现在我想部署到 Heroku 但我为此需要一个主文件夹,所以我想更改我的 webpack.co
当函数不修改对象参数时,我总是让它请求一个常量引用,即使引用的对象不是真正的常量。这是错误的吗? 对于包装类,我想这样写: template class Wrapper{ private: B*
核心常量表达式的定义取决于常量表达式的概念,如要点 (2.7.1) 和 (2.9.1) 所示N4140 的。 §5.19/2: A conditional-expression e is a core
我有以下代码片段,它按预期工作。其中 x 是一个变量 var myVariable = (x === 'A' || x=== 'B') ? 'sui' : 'pai'; 但是闭包编译器正在将它转换为
我是一个国际化应用程序。其中一部分在于菜单的国际化。没关系。 通过 GWT,我可以使用 Constants 接口(interface)。 现在我必须国际化该应用程序的帮助,其中包括一些涉及菜单的文本。
在 Bjarne Stroustrup 的 A Tour of C++ 中,每章末尾都列出了一些建议。在第一章的结尾,其中一个写道: Avoid ‘‘magic constants;’’ use sy
创建常量数组的常量数组的语法是什么? 我希望函数参数是常量 char* 字符串的常量数组。 最佳答案 您可以通过将 const 放在第一个星号的右侧来实现,例如 void f(const char *
我有一本带图书馆的 Chef Recipe ,例如库.rb。它包含一个 CONSTANT: CONSTANT = 'constant' 当我为这本 Recipe 编写单元测试时,它总是给我警告: (S
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How to check for equals? (0 == i) or (i == 0) Why does
我有以下代码: constexpr unsigned long long power_function(const unsigned long long prime, const unsigned l
在一个页面上,我有几个 Angular 模块。我为每个模块定义了一个包含模块版本的常量。 var module1 = angular.module('module1').constant('versi
C++14 中的§5.19/3 定义了一个整型常量表达式和一个转换后的常量表达式: An integral constant expression is an expression of integr
如果您打开 R# 选项并转到代码编辑> C# > 命名样式,则有 2 个设置与我非常相似。本地常量和常量字段(私有(private))。一种是 lowerCaseCamel,另一种是 UpperCam
如何将恰好命名为 reverse 的以下方法重写为允许任何枚举类型的泛型方法。 public class TestX { enum Gender { male, female } pu
我和我的一位队友进行了一次有趣的谈话。 CONSTANT.equals(VARIABLE) 是否比 Java 中的 VARIABLE.equals(CONSTANT) 快? 我怀疑这是一个虚假陈述。但
我想在 c 程序中执行脚本 cmd,所以函数 SYSTEM(CONST CHAR) 可以执行它,但我想使用这个函数和 3 个不同的参数写入一次。谁能帮帮我,有没有那种功能。 最佳答案 如果我猜对了,您
VStudio 或 ReSharper 给我以下建议: constant 在这种情况下意味着什么?如果它是当前方法作用域中的一个常量,目的是什么?方法往往很小,因此与常规 var 相比,它不应该有任何
我是一名优秀的程序员,十分优秀!