首先袜蚕,最近加入了一家做2D游戲公司(ps.我其實(shí)之前一直沒接觸過這一塊的內(nèi)容o(╯□╰)o)糟把!于是就網(wǎng)上查了一下相關(guān)資料,說實(shí)話這方面的資料很少牲剃,而且初學(xué)者可能很難接受遣疯,于是我花了半天研究了一下spriteKit!關(guān)于spriteKit的介紹我就不多廢話了凿傅,自己百度缠犀!于是把自己的一些心得寫一下!入門級小白可以過來看看聪舒,大佬們就當(dāng)看看笑話了辨液!
好的,我們廢話不多說 直接進(jìn)入正題过椎!
我們這里直接借助一個(gè)經(jīng)典案例如題吧室梅!
創(chuàng)建工程:
這里需要說明一下戏仓,SpriteKit是基于場景(Scene)來組織的疚宇,每個(gè)SKView(專門用來呈現(xiàn)SpriteKit的View)中可以渲染和管理一個(gè)SKScene,每個(gè)Scene中可以裝載多個(gè)精靈(或者其他Node赏殃,之后會詳細(xì)說明)敷待,并管理它們的行為。
打開創(chuàng)建的工程仁热,系統(tǒng)已經(jīng)默認(rèn)為我們創(chuàng)建好了GameScene場景榜揖,為了大家容易理解,我們創(chuàng)建一個(gè)自己的myScene(ps.需要繼承SKScene) 替換掉viewController的代碼抗蠢!
替換之后如下:
好了举哟,接下來就進(jìn)入正題了!
到MyScene創(chuàng)建出我們主角:
然后運(yùn)行一下迅矛。
OK妨猩!主角已經(jīng)登場!這個(gè)時(shí)候需要一些怪物秽褒!
好的壶硅,接下來我們創(chuàng)建一群小怪物威兜!
這個(gè)時(shí)候 怪物也已經(jīng)跑起來了!這里簡單說明一下Action就是用來控制精靈的行為庐椒,可以看到runAction的是一個(gè)重復(fù)類型的action椒舵,sequence這里設(shè)置了順序,也就是輸怪物創(chuàng)建出來了 然后一秒之后 繼續(xù)創(chuàng)建 然后重復(fù)约谈!
創(chuàng)建怪物的代碼在這里(注意看注釋)
- (void) addNewMonster {
SKSpriteNode *monster = [SKSpriteNode spriteNodeWithImageNamed:@"monster"];
//1 讓怪物隨機(jī)出現(xiàn)在某一個(gè)位置(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;
//這里創(chuàng)建一個(gè)行為笔宿,讓怪物跑到最左邊,并設(shè)置跑的時(shí)間
SKAction *actionMove = [SKAction moveTo:CGPointMake(-monster.size.width/2, actualY)
duration:actualDuration];
//然后 如果已經(jīng)跑到了左邊 執(zhí)行移除方法
SKAction *actionMoveDone = [SKAction runBlock:^{
[monster removeFromParent];
[self.monsters removeObject:monster];
//在這里你可以做一些邏輯 比如怪物沒被殺死 跑出屏幕 游戲結(jié)束什么的
}];
//跑起來
[monster runAction:[SKAction sequence:@[actionMove,actionMoveDone]]];
[self.monsters addObject:monster];
}
如果寫到這里你估計(jì)會想棱诱,只有怪物跑來跑去顯然差點(diǎn)東西措伐。那我們讓英雄擁有一項(xiàng)技能 那就是發(fā)射飛鏢!飛鏢怎么發(fā)射呢军俊,我們想到了touchBegan,沒錯(cuò) 點(diǎn)擊屏幕的時(shí)候 我們就發(fā)射一把飛鏢 跟當(dāng)前英雄的位置兩點(diǎn)連城一條直線侥加!就是飛鏢的飛行軌跡!然后再飛行過程中與怪物做碰撞檢測粪躬!判斷怪物是否被打死担败!
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//點(diǎn)擊屏幕 就發(fā)射飛鏢
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中提前,每一幀的渲染都會有自己的刷新回調(diào)!對泳唠,沒錯(cuò) 就是-(void)update:(CFTimeInterval)currentTime方法
下面是碰撞檢測的代碼狈网!
-(void)update:(CFTimeInterval)currentTime {
//場景的每一幀渲染時(shí)候都會走這么回調(diào)---在這里來做飛鏢和怪物的碰撞檢測吧
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];
//這里可以做一些邏輯 比如通關(guān)判定
}
if (monstersToDelete.count > 0) {
[projectilesToDelete addObject:projectile];
}
}
for (SKSpriteNode *projectile in projectilesToDelete) {
[self.projectiles removeObject:projectile];
[projectile removeFromParent];
}
}
好了,到這里基本小功能成型了笨腥!
還可以加入比如背景音樂呀拓哺,擊殺時(shí)候的音樂呀什么的!都非常方便脖母!或者豐富一下士鸥,加入一些關(guān)卡,切換場景谆级!
謝謝各位大佬閱讀烤礁!??,寫的不完善還請見諒肥照!附上demo地址:spriteKitDemo