spriteKit入门,我的一些理解

首先,最近加入了一家做2D游戏公司(ps.我其实之前一直没接触过这一块的内容o(╯□╰)o)!于是就网上查了一下相关资料,说实话这方面的资料很少,而且初学者可能很难接受,于是我花了半天研究了一下spriteKit!关于spriteKit的介绍我就不多废话了,自己百度!于是把自己的一些心得写一下!入门级小白可以过来看看,大佬们就当看看笑话了!

好的,我们废话不多说 直接进入正题!

我们这里直接借助一个经典案例如题吧!

创建工程:


这里需要说明一下,SpriteKit是基于场景(Scene)来组织的,每个SKView(专门用来呈现SpriteKit的View)中可以渲染和管理一个SKScene,每个Scene中可以装载多个精灵(或者其他Node,之后会详细说明),并管理它们的行为。

打开创建的工程,系统已经默认为我们创建好了GameScene场景,为了大家容易理解,我们创建一个自己的myScene(ps.需要继承SKScene) 替换掉viewController的代码!

替换之后如下:


好了,接下来就进入正题了!

到MyScene创建出我们主角:


创建马里奥

然后运行一下。


主角登场

OK!主角已经登场!这个时候需要一些怪物!

好的,接下来我们创建一群小怪物!


创建怪物

这个时候 怪物也已经跑起来了!这里简单说明一下Action就是用来控制精灵的行为,可以看到runAction的是一个重复类型的action,sequence这里设置了顺序,也就是输怪物创建出来了 然后一秒之后 继续创建 然后重复!


创建怪物的代码在这里(注意看注释)

- (void) addNewMonster {

SKSpriteNode *monster = [SKSpriteNode spriteNodeWithImageNamed:@"monster"];

//1 让怪物随机出现在某一个位置(y)

CGSize winSize = self.size;

int minY = monster.size.height / 2;

int maxY = winSize.height - monster.size.height/2;

int rangeY = maxY - minY;

int actualY = (arc4random() % rangeY) + minY;

monster.position = CGPointMake(winSize.width + monster.size.width/2, actualY);

[self addChild:monster];

//速度

int minDuration = 2.0;

int maxDuration = 4.0;

int rangeDuration = maxDuration - minDuration;

int actualDuration = (arc4random() % rangeDuration) + minDuration;

//这里创建一个行为,让怪物跑到最左边,并设置跑的时间

SKAction *actionMove = [SKAction moveTo:CGPointMake(-monster.size.width/2, actualY)

duration:actualDuration];

//然后 如果已经跑到了左边 执行移除方法

SKAction *actionMoveDone = [SKAction runBlock:^{

[monster removeFromParent];

[self.monsters removeObject:monster];

//在这里你可以做一些逻辑 比如怪物没被杀死 跑出屏幕 游戏结束什么的

}];

//跑起来

[monster runAction:[SKAction sequence:@[actionMove,actionMoveDone]]];

[self.monsters addObject:monster];

}

如果写到这里你估计会想,只有怪物跑来跑去显然差点东西。那我们让英雄拥有一项技能 那就是发射飞镖!飞镖怎么发射呢,我们想到了touchBegan,没错 点击屏幕的时候 我们就发射一把飞镖 跟当前英雄的位置两点连城一条直线!就是飞镖的飞行轨迹!然后再飞行过程中与怪物做碰撞检测!判断怪物是否被打死!

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

//点击屏幕 就发射飞镖

for (UITouch *touch in touches) {

//

CGSize winSize = self.size;

SKSpriteNode *projectile = [SKSpriteNode spriteNodeWithImageNamed:@"projectile.png"];

projectile.position = CGPointMake(projectile.size.width/2, winSize.height/2);

//2 Get the touch location tn the scene and calculate offset

CGPoint location = [touch locationInNode:self];

CGPoint offset = CGPointMake(location.x - projectile.position.x, location.y - projectile.position.y);

// 一些基本的判断与加速度

if (offset.x <= 0) return;

[self addChild:projectile];

int realX = winSize.width + (projectile.size.width/2);

float ratio = (float) offset.y / (float) offset.x;

int realY = (realX * ratio) + projectile.position.y;

CGPoint realDest = CGPointMake(realX, realY);

int offRealX = realX - projectile.position.x;

int offRealY = realY - projectile.position.y;

float length = sqrtf((offRealX*offRealX)+(offRealY*offRealY));

float velocity = self.size.width/1; // projectile speed.

float realMoveDuration = length/velocity;

//让子弹飞吧

SKAction *moveAction = [SKAction moveTo:realDest duration:realMoveDuration];

SKAction *projectileCastAction = [SKAction group:@[moveAction]];

[projectile runAction:projectileCastAction completion:^{

[projectile removeFromParent];

[self.projectiles removeObject:projectile];

}];

[self.projectiles addObject:projectile];

}

}

接下来就是碰撞检测了!我们知道,在spriteKit中,每一帧的渲染都会有自己的刷新回调!对,没错 就是-(void)update:(CFTimeInterval)currentTime方法

下面是碰撞检测的代码!

-(void)update:(CFTimeInterval)currentTime {

//场景的每一帧渲染时候都会走这么回调---在这里来做飞镖和怪物的碰撞检测吧

NSMutableArray *projectilesToDelete = [[NSMutableArray alloc] init];

for (SKSpriteNode *projectile in self.projectiles) {

NSMutableArray *monstersToDelete = [[NSMutableArray alloc] init];

for (SKSpriteNode *monster in self.monsters) {

if (CGRectIntersectsRect(projectile.frame, monster.frame)) {

[monstersToDelete addObject:monster];

}

}

for (SKSpriteNode *monster in monstersToDelete) {

[self.monsters removeObject:monster];

[monster removeFromParent];

//这里可以做一些逻辑 比如通关判定

}

if (monstersToDelete.count > 0) {

[projectilesToDelete addObject:projectile];

}

}

for (SKSpriteNode *projectile in projectilesToDelete) {

[self.projectiles removeObject:projectile];

[projectile removeFromParent];

}

}

好了,到这里基本小功能成型了!

还可以加入比如背景音乐呀,击杀时候的音乐呀什么的!都非常方便!或者丰富一下,加入一些关卡,切换场景!



谢谢各位大佬阅读!😜,写的不完善还请见谅!附上demo地址:spriteKitDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容