参考:https://github.com/kirualex/SprityBird
该项目基于spritekit,代码的结构很清楚,感觉用来学习spritekit非常不错。
1、项目只有一个viewController,包含:
@property (weak,nonatomic) IBOutlet SKView * gameView;@property (weak,nonatomic) IBOutlet UIView * getReadyView;@property (weak,nonatomic) IBOutlet UIView * gameOverView;@property (weak,nonatomic) IBOutlet UIImageView * medalImageView;@property (weak,nonatomic) IBOutlet UILabel * currentScore;@property (weak,nonatomic) IBOutlet UILabel * bestScoreLabel;
初始时gameOverView均不可见。
2、在viewController的viewDidLoad中加载场景:
[self.gameView presentScene:scene];
3、这里做的比较好的是,利用协议完成viewController和Scene的交互,viewController处理游戏中反馈的事件,实现对上述游戏完成、游戏开始等顶层view的操作。
@protocol SceneDelegate- (void) eventStart;- (void) eventPlay;- (void) eventWasted;@end
4、在Scene的初始化中对场景中的障碍和鸟进行绘制:
- (void) startGame{ // Reinit wasted = NO; [self removeAllChildren]; [self createBackground]; [self createFloor]; [self createScore]; [self createObstacles]; [self createBird]; // Floor needs to be in front of tubes floor.zPosition = bird.zPosition + 1; if([self.delegate respondsToSelector:@selector(eventStart)]){ [self.delegate eventStart]; }}
5、在项目里,只定义了两类node,一个是用来表述移动背景如地板、障碍、背景图等,另外一个就是绘制小鸟;
这里初始化的node对象包括鸟、障碍都会被保存在全局数据组里,在后续刷新。以障碍物的移动为例:
- (void) updateObstacles:(NSTimeInterval)currentTime{ if(!bird.physicsBody){ return; } for(int i=0;i
6、在scene中主要继承处理两个方法:
//该函数被Scene重绘每一帧调用- (void)update:(NSTimeInterval)currentTime- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
7、通过sprite的物理引擎实现碰撞操作:
bottomPipe.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:CGRectMake(0,0, WIDTH(bottomPipe) , HEIGHT(bottomPipe))]
topPipe.physicsBody.categoryBitMask = blockBitMask;topPipe.physicsBody.contactTestBitMask = birdBitMask;
- (void)didBeginContact:(SKPhysicsContact *)contact{ if(wasted){ return; } wasted = true; [Score registerScore:self.score]; if([self.delegate respondsToSelector:@selector(eventWasted)]){ [self.delegate eventWasted]; }}