写在前面

最近一直在忙自己的维P恩的事情

公司项目也是一团乱

于是...随手找了个游戏项目改了改就上线了,就当充数了.

SpriteKit简介

SpriteKit是iOS 7之后苹果推出的2D游戏框架。它支持2D游戏中各种功能,如物理引擎,地图编辑,粒子,视频,声音精灵化,光照等。

SpriteKit中常用的类

  • SKSpriteNode 用于绘制精灵纹理
  • SKVideoNode 用于播放视频
  • SKLabelNode 用于渲染文本
  • SKShapeNode 用于渲染基于Core Graphics路径的形状
  • SKEmitterNode 用于创建和渲染粒子系统
  • SKView 对象执行动画和渲染
  • SKScene 游戏内容组织成的场景
  • SKAction 节点动画

效果

这是一个类似于FlappyBird的小游戏

集成GameCenter

分析

结构很简单

设计思路就是障碍物不断的移动.当把角色卡死时游戏结束

代码

1.预加载游戏结束时的弹出广告

2.加载背景

3.设置physicsBody

4.设置障碍物移动Action

5.设置开始面板角色及初始Action

6.加载所有内容节点

  • 初始化
- (void)initalize
{
[super initalize];
SKSpriteNode* background=[SKSpriteNode spriteNodeWithImageNamed:@"sky.png"];
background.size = self.view.frame.size;
background.position=CGPointMake(background.size.width/2, background.size.height/2);
[self addChild:background];
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
self.physicsBody.categoryBitMask = edgeCategory;
self.physicsWorld.contactDelegate = self;
self.moveWallAction = [SKAction sequence:@[[SKAction moveToX:-WALL_WIDTH duration:TIMEINTERVAL_MOVEWALL],[SKAction removeFromParent]]];
SKAction *upHeadAction = [SKAction rotateToAngle:M_PI / 6 duration:0.2f];
upHeadAction.timingMode = SKActionTimingEaseOut;
SKAction *downHeadAction = [SKAction rotateToAngle:-M_PI / 2 duration:0.8f];
downHeadAction.timingMode = SKActionTimingEaseOut;
self.moveHeadAction = [SKAction sequence:@[upHeadAction, downHeadAction,]];
[self addGroundNode];
[self addCeiling];
[self addHeroNode];
[self addResultLabelNode];
[self addInstruction];
[self runAction:[SKAction repeatActionForever:[SKAction sequence:@[
[SKAction performSelector:@selector(addFish) onTarget:self],
[SKAction waitForDuration:0.3f],
]]] withKey:ACTIONKEY_ADDFISH]; _interstitialObj = [[GDTMobInterstitial alloc]
initWithAppkey:@"1106301022"
placementId:@"2080622474511184"];
_interstitialObj.delegate = self;
//设置委托 _interstitialObj.isGpsOn = NO; //【可选】设置GPS开关
//预加载广告
[_interstitialObj loadAd]; }
  • 加载角色,设置飞行动作,触摸事件
- (void)addHeroNode
{
self.hero=[SKSpriteNode spriteNodeWithImageNamed:@"player"];
SKTexture* texture=[SKTexture textureWithImageNamed:@"player"];
_hero.physicsBody=[SKPhysicsBody bodyWithTexture:texture size:_hero.size];
_hero.anchorPoint = CGPointMake(0.5, 0.5);
_hero.position = CGPointMake(self.frame.size.width / 2, CGRectGetMidY(self.frame));
_hero.name = NODENAME_HERO;
_hero.physicsBody.categoryBitMask = heroCategory;
_hero.physicsBody.collisionBitMask = wallCategory | groundCategory|edgeCategory;
_hero.physicsBody.contactTestBitMask = holeCategory | wallCategory | groundCategory|fishCategory;
_hero.physicsBody.dynamic = YES;
_hero.physicsBody.affectedByGravity = NO;
_hero.physicsBody.allowsRotation = NO;
_hero.physicsBody.restitution = 0.4;
_hero.physicsBody.usesPreciseCollisionDetection = NO;
[self addChild:_hero];
// SKTexture* texture1=[SKTexture textureWithImageNamed:@"player"];
// SKTexture* texture2=[SKTexture textureWithImageNamed:@"player3"];
//
// SKAction *animate = [SKAction animateWithTextures:@[texture1,texture2] timePerFrame:0.1];
// [_hero runAction:[SKAction repeatActionForever:animate]];
[_hero runAction:[SKAction repeatActionForever:[self getFlyAction]]
withKey:ACTIONKEY_FLY];
} - (SKAction *)getFlyAction
{
SKAction *flyUp = [SKAction moveToY:_hero.position.y + 10 duration:0.3f];
flyUp.timingMode = SKActionTimingEaseOut;
SKAction *flyDown = [SKAction moveToY:_hero.position.y - 10 duration:0.3f];
flyDown.timingMode = SKActionTimingEaseOut;
SKAction *fly = [SKAction sequence:@[flyUp, flyDown]];
return fly;
} - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (_isGameOver) {
return;
}
if (!_isGameStart) {
[self startGame];
}
_hero.physicsBody.velocity = CGVectorMake(100, 500);
[_hero runAction:_moveHeadAction withKey:ACTIONKEY_MOVEHEAD];
}
  • 加载开始说明和结束说明
- (void)addResultLabelNode
{
self.labelNode = [SKLabelNode labelNodeWithFontNamed:@"PingFangSC-Regular"];
_labelNode.fontSize = 30.0f;
_labelNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
_labelNode.verticalAlignmentMode = SKLabelVerticalAlignmentModeTop;
_labelNode.position = CGPointMake(10, self.frame.size.height - 20);
_labelNode.fontColor = COLOR_LABEL;
_labelNode.zPosition=100;
[self addChild:_labelNode];
}
- (void)addInstruction{
self.hitSakuraToScore = [SKLabelNode labelNodeWithFontNamed:@"AmericanTypewriter"];
_hitSakuraToScore.fontSize = 20.0f;
_hitSakuraToScore.position = CGPointMake(self.frame.size.width / 2, CGRectGetMidY(self.frame)-60);
_hitSakuraToScore.fontColor = COLOR_LABEL;
_hitSakuraToScore.zPosition=100;
_hitSakuraToScore.text=@"Hit fish to Score";
// _hitSakuraToScore.text=NSLocalizedString(@"Hit Sakura to Score", nil);
[self addChild:_hitSakuraToScore];
self.tapToStart = [SKLabelNode labelNodeWithFontNamed:@"PingFangSC-Regular"];
_tapToStart.fontSize = 20.0f;
_tapToStart.position = CGPointMake(self.frame.size.width / 2, CGRectGetMidY(self.frame)-100);
_tapToStart.fontColor = COLOR_LABEL;
_tapToStart.zPosition=100;
_tapToStart.text=@"Tap to Jump";
[self addChild:_tapToStart];
}
  • 加载障碍物
- (void)addWall
{
CGFloat spaceHeigh = self.frame.size.height - GROUND_HEIGHT;
float random= arc4random() % 4;
CGFloat holeLength = HERO_SIZE.height * (2.0+random*0.1);
int holePosition = arc4random() % (int)((spaceHeigh - holeLength) / HERO_SIZE.height);
CGFloat x = self.frame.size.width;
CGFloat upHeight = holePosition * HERO_SIZE.height;
if (upHeight > 0) {
SKSpriteNode *upWall = [SKSpriteNode spriteNodeWithColor:COLOR_WALL size:CGSizeMake(WALL_WIDTH, upHeight)];
upWall.anchorPoint = CGPointMake(0, 0);
upWall.position = CGPointMake(x, self.frame.size.height - upHeight);
upWall.name = NODENAME_WALL;
upWall.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:upWall.size center:CGPointMake(upWall.size.width / 2.0f, upWall.size.height / 2.0f)];
upWall.physicsBody.categoryBitMask = wallCategory;
upWall.physicsBody.dynamic = NO;
upWall.physicsBody.friction = 0;
[upWall runAction:_moveWallAction withKey:ACTIONKEY_MOVEWALL];
[self addChild:upWall];
}
CGFloat downHeight = spaceHeigh - upHeight - holeLength;
if (downHeight > 0) {
SKSpriteNode *downWall = [SKSpriteNode spriteNodeWithColor:COLOR_WALL size:CGSizeMake(WALL_WIDTH, downHeight)];
downWall.anchorPoint = CGPointMake(0, 0);
downWall.position = CGPointMake(x, GROUND_HEIGHT);
downWall.name = NODENAME_WALL;
downWall.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:downWall.size center:CGPointMake(downWall.size.width / 2.0f, downWall.size.height / 2.0f)];
downWall.physicsBody.categoryBitMask = wallCategory;
downWall.physicsBody.dynamic = NO;
downWall.physicsBody.friction = 0;
[downWall runAction:_moveWallAction withKey:ACTIONKEY_MOVEWALL];
[self addChild:downWall];
} SKSpriteNode *hole = [SKSpriteNode spriteNodeWithColor:[UIColor clearColor] size:CGSizeMake(WALL_WIDTH, holeLength)];
hole.anchorPoint = CGPointMake(0, 0);
hole.position = CGPointMake(x, self.frame.size.height - upHeight - holeLength);
hole.name = NODENAME_HOLE;
hole.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:hole.size center:CGPointMake(hole.size.width / 2.0f, hole.size.height / 2.0f)];
hole.physicsBody.categoryBitMask = holeCategory;
hole.physicsBody.dynamic = NO;
[hole runAction:_moveWallAction withKey:ACTIONKEY_MOVEWALL];
[self addChild:hole];
}
  • 游戏开始时 不断增加障碍物
- (void)startGame
{
self.isGameStart = YES;
_hero.physicsBody.affectedByGravity = YES;
[_hero removeActionForKey:ACTIONKEY_FLY];
[_tapToStart removeFromParent];
[_hitSakuraToScore removeFromParent];
[self addResultLabelNode];
SKAction *addWall = [SKAction sequence:@[
[SKAction performSelector:@selector(addWall) onTarget:self],
[SKAction waitForDuration:TIMEINTERVAL_ADDWALL],
]];
[self runAction:[SKAction repeatActionForever:addWall] withKey:ACTIONKEY_ADDWALL];
}
  • 实时更新内容
- (void)update:(NSTimeInterval)currentTime
{
if(self.hero&&!_isGameOver){
if ( self.hero.position.x<10) {
[self gameOver];
}else if(self.hero.position.x>self.frame.size.width){
self.hero.position =CGPointMake(self.hero.position.x-20, self.hero.position.y);
}
}
__block int wallCount = 0;
[self enumerateChildNodesWithName:NODENAME_WALL usingBlock:^(SKNode *node, BOOL *stop) {
if (wallCount >= 2) {
*stop = YES;
return;
}
if (node.position.x <= -WALL_WIDTH) {
wallCount++;
[node removeFromParent];
}
}];
[self enumerateChildNodesWithName:NODENAME_HOLE usingBlock:^(SKNode *node, BOOL *stop) {
if (node.position.x <= -WALL_WIDTH) {
[node removeFromParent];
*stop = YES;
}
}];
[self enumerateChildNodesWithName:NODENAME_FISH usingBlock:^(SKNode *node, BOOL *stop) {
if (node.position.x <= -node.frame.size.width) {
[node removeFromParent];
}
}];
}
  • 设置物体碰撞效果
- (void)didBeginContact:(SKPhysicsContact *)contact
{
if (_isGameOver) {
return;
}
SKPhysicsBody *firstBody, *secondBody; if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) {
firstBody = contact.bodyA;
secondBody = contact.bodyB;
} else {
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if ((firstBody.categoryBitMask & heroCategory) && (secondBody.categoryBitMask & fishCategory)) {
if(secondBody.node.parent&&self.isGameStart){
int currentPoint = [_labelNode.text intValue];
_labelNode.text = [NSString stringWithFormat:@"%d", currentPoint + 1];
[self playSoundWithName:@"sfx_wing.caf"];
NSString *burstPath =
[[NSBundle mainBundle]
pathForResource:@"MyParticle" ofType:@"sks"];
SKEmitterNode *burstNode =
[NSKeyedUnarchiver unarchiveObjectWithFile:burstPath];
burstNode.position = secondBody.node.position;
[secondBody.node removeFromParent];
[self addChild:burstNode];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[burstNode runAction:[SKAction removeFromParent]];
});
}
}
}
- (void) didEndContact:(SKPhysicsContact *)contact{
if (_isGameOver) {
return;
}
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) {
firstBody = contact.bodyA;
secondBody = contact.bodyB;
} else {
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
return; } - (void)playSoundWithName:(NSString *)fileName
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self runAction:[SKAction playSoundFileNamed:fileName waitForCompletion:YES]];
});
}
  • 游戏结束与重新开始
- (void)gameOver
{
self.isGameOver = YES;
self.isGameStart=NO;
[_hero removeActionForKey:ACTIONKEY_MOVEHEAD];
[self removeActionForKey:ACTIONKEY_ADDWALL];
[self enumerateChildNodesWithName:NODENAME_WALL usingBlock:^(SKNode *node, BOOL *stop) {
[node removeActionForKey:ACTIONKEY_MOVEWALL];
}];
[self enumerateChildNodesWithName:NODENAME_HOLE usingBlock:^(SKNode *node, BOOL *stop) {
[node removeActionForKey:ACTIONKEY_MOVEWALL];
}];
if([_labelNode.text isEqualToString:@""])
_labelNode.text=@"0";
NSString *result=_labelNode.text;
RestartLabel *restartView = [RestartLabel getInstanceWithSize:self.size Point:result];
restartView.delegate = self;
[restartView showInScene:self];
_labelNode.text=@""; if (_interstitialObj.isReady) {
UIViewController *vc = [[[UIApplication sharedApplication] keyWindow] rootViewController];
//vc = [self navigationController];
[_interstitialObj presentFromRootViewController:vc];
} } - (void)restart
{
[self addInstruction];
self.labelNode.text = @"";
[self enumerateChildNodesWithName:NODENAME_HOLE usingBlock:^(SKNode *node, BOOL *stop) {
[node removeFromParent];
}];
[self enumerateChildNodesWithName:NODENAME_WALL usingBlock:^(SKNode *node, BOOL *stop) {
[node removeFromParent];
}];
[_hero removeFromParent];
self.hero = nil;
[self addHeroNode];
[self runAction:[SKAction repeatActionForever:[SKAction sequence:@[
[SKAction performSelector:@selector(addFish) onTarget:self],
[SKAction waitForDuration:0.3f],
]]] withKey:ACTIONKEY_ADDFISH];
self.isGameStart = NO;
self.isGameOver = NO;
} - (void)restartView:(RestartLabel *)restartView didPressRestartButton:(SKSpriteNode *)restartButton
{
[restartView dismiss];
[self restart]; }
- (void)restartView:(RestartLabel *)restartView didPressLeaderboardButton:(SKSpriteNode *)restartButton{
[self showLeaderboard];
}
  • 游戏结束可以调期GameCenter排行榜
-(void)showLeaderboard{
GKGameCenterViewController *gcViewController = [[GKGameCenterViewController alloc] init];
gcViewController.gameCenterDelegate = self;
gcViewController.viewState = GKGameCenterViewControllerStateLeaderboards;
gcViewController.leaderboardIdentifier = @"MyFirstLeaderboard";
[self.view.window.rootViewController presentViewController:gcViewController animated:YES completion:nil]; }
-(void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController
{
[gameCenterViewController dismissViewControllerAnimated:YES completion:nil];
}
  • 积分框
@interface ScoreLabel : SKSpriteNode

@property(nonatomic, copy) NSString* finalPoint;

@end

#import "ScoreLabel.h"

@implementation ScoreLabel

- (id)initWithColor:(UIColor *)color size:(CGSize)size
{
if (self = [super initWithColor:color size:size]) {
SKLabelNode* scoreLabelNode = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
scoreLabelNode.text=_finalPoint;
scoreLabelNode.fontSize = 20.0f;
scoreLabelNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
scoreLabelNode.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
scoreLabelNode.position = CGPointMake(size.width / 2.0f, size.height - 300);
scoreLabelNode.fontColor = [UIColor whiteColor];
[self addChild:scoreLabelNode]; }
return self;
} @end
  • 游戏结束节点内容
@class RestartLabel;
@protocol RestartViewDelegate <NSObject> - (void)restartView:(RestartLabel *)restartView didPressRestartButton:(SKSpriteNode *)restartButton;
- (void)restartView:(RestartLabel *)restartView didPressLeaderboardButton:(SKSpriteNode *)restartButton;
@end @interface RestartLabel : SKSpriteNode @property (weak, nonatomic) id <RestartViewDelegate> delegate;
@property (copy, nonatomic) NSString* finalPoint;
+ (RestartLabel *)getInstanceWithSize:(CGSize)size Point:(NSString *)point;
- (void)dismiss;
- (void)showInScene:(SKScene *)scene; @end #define NODENAME_BUTTON @"button"
#import "RestartLabel.h"
#import "MainViewController.h" @import GameKit;
@interface RestartLabel()
@property (strong, nonatomic) SKSpriteNode *button;
@property (strong, nonatomic) SKLabelNode *labelNode;
@property (strong, nonatomic) SKLabelNode *scoreLabelNode;
@property (strong, nonatomic) SKLabelNode *highestLabelNode;
@property (strong, nonatomic) SKSpriteNode *gameCenterNode;
@property (strong, nonatomic) SKLabelNode *gameCenterLabel;
@end @implementation RestartLabel - (id)initWithColor:(UIColor *)color size:(CGSize)size
{
if (self = [super initWithColor:color size:size]) {
self.userInteractionEnabled = YES;
self.button = [SKSpriteNode spriteNodeWithColor:[UIColor colorWithRed:0.608 green:0.349 blue:0.714 alpha:1] size:CGSizeMake(100, 50)];
_button.position = CGPointMake(size.width / 2.0f, size.height - 350);
_button.name = NODENAME_BUTTON;
[self addChild:_button];
self.labelNode = [SKLabelNode labelNodeWithFontNamed:@"PingFangSC-Regular"];
_labelNode.text = @"Restart";
_labelNode.fontSize = 20.0f;
_labelNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
_labelNode.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
_labelNode.position = CGPointMake(0, 0);
_labelNode.fontColor = [UIColor whiteColor];
[_button addChild:_labelNode];
self.gameCenterNode = [SKSpriteNode spriteNodeWithColor:[UIColor colorWithRed:0.608 green:0.349 blue:0.714 alpha:1]size:CGSizeMake(150, 50)];
_gameCenterNode.position = CGPointMake(size.width / 2.0f, size.height - 280);
[self addChild:_gameCenterNode];
self. gameCenterLabel=[SKLabelNode labelNodeWithFontNamed:@"PingFangSC-Regular"];
_gameCenterLabel.text = @"Leaderboard";
_gameCenterLabel.fontSize = 20.0f;
_gameCenterLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
_gameCenterLabel.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
_gameCenterLabel.position = CGPointMake(0, 0);
_gameCenterLabel.fontColor = [UIColor whiteColor];
[_gameCenterNode addChild:_gameCenterLabel]; }
return self;
}
-(void)addScoreLabelSize:(CGSize)size{
_scoreLabelNode = [SKLabelNode labelNodeWithFontNamed:@"PingFangSC-Regular"];
_scoreLabelNode.text=[NSString stringWithFormat:@"Your Score: \r%@",_finalPoint? _finalPoint: @"0"];
_scoreLabelNode.fontSize = 20.0f;
_scoreLabelNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
_scoreLabelNode.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
_scoreLabelNode.position = CGPointMake(size.width / 2.0f, size.height - 170);
_scoreLabelNode.fontColor = [UIColor colorWithRed:0.173 green:0.243 blue:0.314 alpha:1];
[self addChild:_scoreLabelNode];
} -(void)addHighestLabelSize:(CGSize)size{
_highestLabelNode = [SKLabelNode labelNodeWithFontNamed:@"PingFangSC-Regular"];
_highestLabelNode.fontColor = [UIColor colorWithRed:0.173 green:0.243 blue:0.314 alpha:1];
NSString* showText;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber* highestScore=[defaults objectForKey:@"HighScore"];
NSNumber* currentPoint= [NSNumber numberWithInt: [_finalPoint intValue]];
if(highestScore==nil||[currentPoint integerValue]>[highestScore integerValue]){
[defaults setObject:currentPoint forKey:@"HighScore"];
highestScore=currentPoint;
showText=@"New Record!";
_highestLabelNode.fontColor=[UIColor colorWithRed:0.753 green:0.224 blue:0.169 alpha:1];
[defaults synchronize];
}else{
showText=[NSString stringWithFormat:@"High Score: \r%lu",(long)[highestScore integerValue]];
}
if(highestScore!=nil){
[self reportScore:[highestScore integerValue]];
}
_highestLabelNode.text=showText;
_highestLabelNode.fontSize = 20.0f;
_highestLabelNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
_highestLabelNode.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
_highestLabelNode.position = CGPointMake(size.width / 2.0f, size.height - 220);
[self addChild:_highestLabelNode];
} + (RestartLabel *)getInstanceWithSize:(CGSize)size Point:(NSString *)point
{
RestartLabel *restartView = [RestartLabel spriteNodeWithColor:color(255, 255, 255, 0.6) size:size];
restartView.anchorPoint = CGPointMake(0, 0);
restartView.finalPoint=point;
[restartView addScoreLabelSize:size];
[restartView addHighestLabelSize:size];
return restartView;
} - (void)showInScene:(SKScene *)scene
{
self.alpha = 0.0f;
[scene addChild:self];
[self runAction:[SKAction fadeInWithDuration:0.3f]];
} - (void)dismiss
{
[self runAction:[SKAction fadeOutWithDuration:0.3f] completion:^{
[self removeFromParent];
}];
} - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *touchNode = [self nodeAtPoint:location];
if (touchNode == _button || touchNode == _labelNode) {
if ([_delegate respondsToSelector:@selector(restartView:didPressRestartButton:)]) {
[_delegate restartView:self didPressRestartButton:_button];
}
}else if(touchNode==_gameCenterNode || touchNode==_gameCenterLabel){
if ([_delegate respondsToSelector:@selector(restartView:didPressLeaderboardButton:)]) {
[_delegate restartView:self didPressLeaderboardButton:_button];
}
}
}
-(void)reportScore:(NSInteger)inputScore{
GKScore *score = [[GKScore alloc] initWithLeaderboardIdentifier:@"MyFirstLeaderboard"];
score.value = inputScore;
[GKScore reportScores:@[score] withCompletionHandler:^(NSError *error) {
if (error != nil) {
NSLog(@"%@", [error localizedDescription]);
}
}];
} @end

关于游戏上架Tips



蛋疼广电粽菊要求国内游戏必须备案...

我们只是想上个小游戏而已~难道还要再等个大半个月去备案么?

Apple也妥协了 在备注那里要求中国区上架游戏必须填写备案号

But!!!上有政策,下有对策嘛~

  • 填写App分类时直接选择娱乐类型上架,就不会要求填写备案号了~
  • 销售范围,不选择中国地区,这样也不会要求填写备案号,等过审了,再将销售范围改回所有地区,基本上是实时生效~

以上两种方式屡试不爽哈~对于我们个人小开发来说也算是个小福利了.

Demo地址

Github地址,欢迎Star (由于集成了广告,广点通的静态库需要单独下载下完直接扔到项目里就行)

已上架Appstore 猫爷快吃 喜欢就支持下吧~

欢迎光顾自己的小站,内容都是同步更新的~

大家低调支持下自己的 牛牛数据 Half-price~~

还没结束



快来猜猜我放的背景音乐是啥~

iOS开发实战-基于SpriteKit的FlappyBird小游戏的更多相关文章

  1. 【鸿蒙开发板试用报告】用OLED板实现FlappyBird小游戏(中)

    小伙伴们久等了,在上一篇<[开发板试用报告]用OLED板实现FlappyBird小游戏(上)>中,我们本着拿来主义的原则,成功的让小鸟在OLED屏幕上自由飞翔起来,下面我们将加入按钮交互功 ...

  2. Swift项目开发实战-基于分层架构的多版本iPhone计算器-直播公开课

    Swift项目开发实战-基于分层架构的多版本iPhone计算器-直播公开课 本课程采用Q Q群直播方式进行直播,价值99元视频课程免费直播.完整的基于Swift项目实战,手把手教你做一个Swift版i ...

  3. iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController)

    iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController)   前面我们介绍了StoryBoard这个新技术,和纯技术 ...

  4. iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController)

    iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController)   这里我们就直接上实例: 一:新建一个项目singleV ...

  5. Xamarin iOS开发实战第1章使用C#编写第一个iOS应用程序

    Xamarin iOS开发实战第1章使用C#编写第一个iOS应用程序 C#原本是用来编写Windows以及Windows Phone的应用程序.自从Xamarin问世后.C#的作用就发生了非常大的变化 ...

  6. 《iOS开发实战 从入门到上架App Store(第2版)》书籍目录

    第1章 开发准备 1.1 iOS 10新特性简述 1.1.1 新增触觉反馈编程接口 1.1.2 SiriKit框架的开放 1.1.3 引入Messages App 1.1.4 通知框架的整合与扩展 1 ...

  7. iOS开发的知名大牛博客小汇

    王巍的博客:王巍目前在日本横滨任职于LINE.工作内容主要进行Unity3D开发,8小时之外经常进行iOS/Mac开发.他的陈列柜中已有多款应用,其中番茄工作法工具非常棒.http://onevcat ...

  8. iOS开发——实战OC篇&环境搭建之StoryBoard(玩转UINavigationController与UITabBarController)

      环境搭建之StoryBoard(玩转UINavigationController与UITabBarController)   研究了这么就IOS开发,都没有所处一个像样或者自己忙一点的项目.最近自 ...

  9. iOS 开发的9个超有用小技巧

    http://www.jianshu.com/p/221507eb8590 1.如何快速的查看一段代码的执行时间. 1 2 #define TICK   NSDate *startTime = [NS ...

随机推荐

  1. win8安装sql2008及设置登陆名问题

    1. .net3.5安装        使用win8系统自带的升级功能无法成功安装.其实Windows8安装文件中已经集了.Net3.5,       (1)此时只需要使用虚拟光驱加载Windows8 ...

  2. FastReport.NET 中使用二维码

    FastReport.net 是一个比较好用的报表控件,在编辑器中编辑以后 可以直接在vs 中引用. 最近在研究fastreport 现在讲解一下 如何使用它的二维码. fastreport 没有单独 ...

  3. 基于SSE实现的极速的矩形核腐蚀和膨胀(最大值和最小值)算法。

    因未测试其他作者的算法时间和效率,本文不敢自称是最快的,但是速度也可以肯定说是相当快的,在一台I5机器上占用单核的资源处理 3000 * 2000的灰度数据用时约 20ms,并且算法和核心的大小是无关 ...

  4. if中可以使用那些作为判断条件呢?

    在所有编程语言中if是最长用的判断之一,但在js中到底哪些东西可以在if中式作为判断表达式呢? 例如如何几行,只是少了一个括号,真假就完全不同,到底表示什么含义呢 ? 1 2 3 4 5 6 7 8 ...

  5. [转] .NET领域驱动设计—看DDD是如何运用设计模式颠覆传统架构

    阅读目录: 1.开篇介绍 2.简单了解缘由(本文的前期事宜) 3.DomainModel扩展性(运用设计模式设计模型变化点) 3.1.模型扩展性 3.2.设计模式的使用(苦心专研的设计模式.设计思想可 ...

  6. LeetCode 206 单链表翻转

    https://leetcode.com/problems/reverse-linked-list/ 思路很简单,分别设置三个结点,之后依次调整结点1和结点2的指向关系. Before: pre -& ...

  7. Laravel踩坑笔记——illuminate/html被抛弃

    起因 在使用如下代码的时候发生报错 {!! Form::open() !!} 错误信息 [Symfony\Component\Debug\Exception\FatalErrorException] ...

  8. Mac, Linux中配置Latex中文字体

    对于中文的latex文档,在Linux下一般可以使用系统自带的开源字体:文泉驿(WenQuanYi)来实现,即如下的最小例子,通过xelatex命令来编译即可生成中文文档. \documentclas ...

  9. VMware中Linux系统时间与主机同步以及时区设置

    网络上有各种资料,但最简单的一种方法就是修改虚拟机的配置文件 *.vmx .修改 tools.syncTime = "FALSE" 为 tools.syncTime = " ...

  10. mysql 左连接 右连接 内链接

    一般所说的左连接,右连接是指左外连接,右外连接.做个简单的测试你看吧.先说左外连接和右外连接:[TEST1@orcl#16-12月-11] SQL>select * from t1;ID NAM ...