اموزش برنامه نویسی ios بازی فلاپی برد

ساخت وبلاگ
در دو قسمت قبل آموزش ساخت بازی فلاپی برد، مراحل مختلف ساخت بازی را توضیح دادیم در قسمت اول نحوه ایجاد محیط فیزیکی، پرنده را آموختیم و در قسمت دوم نحوه حرکت دادن به پرنده و کدهای مربوط به حرکت پرنده با زدن ضربه را نوشتیم در این قسمت که قسمت سوم و آخر این مجموعه است موانعی را در بازی ایجاد می کنیم.
 آخرین عنصری که در بازی قرار می گیرد لوله می باشد که بصورت موانعی در صحنه بازی قرار دارند به نحوی که پرنده نباید با آنها برخورد کند و در صورت برخورد پرنده بازی ریستارت می شود. برای انجام اینکار دو تصویر گرافیکی pipe1.png و pipe2.png را به پروژه اضافه می کنیم. از دیدگاه گرافیکی، لوله ها در فضای بازی عناصری خاص هستند چراکه اجزایی مثل زمین، آسمان و پرنده ها در بازی ثابت و بدون تغییر هستند اما لوله ها متغیر هستند، بنابراین با تعریف دو عنصر گرافیکی pipe1  و pipe2 یک لوله از بالا صفحه نمایش را گسترش می دهد و لوله دیگر از پایین صفحه نمایش.
لوله ها با دو متد  با نام SKSprintNode S تعریف شده اند و این دو متد را در متد خالی SKNode  (بعنوان والد) قرار می دهیم.
 
[تصویر: 1--long-pipes-208x300.jpg]
تعیین فاصله بین لوله ها می تواند دلخواه باشد که ما در اینجا این فاصله را 100 انتخاب کردیم
@implementation MyScene
 
static NSInteger const kVerticalPipeGap = 100;
 
-(id)initWithSize:(CGSize)size {
لوله ها در خارج از صفحه نمایش قرار می گیرند.
یک جفت از لوله ها در قسمت بیرونی سمت راست صفحه نمایش قرار میگیرند.دستور zPosition به نحوی برای لوله ها انتخاب شده است که همیشه در پشت زمین بازی قرار گیرند.
// Create pipes
 
SKTexture* _pipeTexture1 = [SKTexture textureWithImageNamedAngry"Pipe1"];
_pipeTexture1.filteringMode = SKTextureFilteringNearest;
SKTexture* _pipeTexture2 = [SKTexture textureWithImageNamedAngry"Pipe2"];
_pipeTexture2.filteringMode = SKTextureFilteringNearest;
 
SKNode* pipePair = [SKNode node];
pipePair.position = CGPointMake( self.frame.size.width + _pipeTexture1.size.width * 2, 0 );
pipePair.zPosition = -10;
 
CGFloat y = arc4random() % (NSInteger)( self.frame.size.height / 3 );
 
SKSpriteNode* pipe1 = [SKSpriteNode spriteNodeWithTexture:_pipeTexture1];
[pipe1 setScale:2];
pipe1.position = CGPointMake( 0, y );
pipe1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:pipe1.size];
pipe1.physicsBody.dynamic = NO;
[pipePair addChild:pipe1];
 
SKSpriteNode* pipe2 = [SKSpriteNode spriteNodeWithTexture:_pipeTexture2];
[pipe2 setScale:2];
pipe2.position = CGPointMake( 0, y + pipe1.size.height + kVerticalPipeGap );
pipe2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:pipe2.size];
pipe2.physicsBody.dynamic = NO;
[pipePair addChild:pipe2];
 
SKAction* movePipes = [SKAction repeatActionForever:[SKAction moveByX:-1 y:0 duration:0.02]];
[pipePair runAction:movePipes];
 
[self addChild:pipePair];
 
پرنده با برخورد با لوله ها، با حرکت صفحه نمایش از صفحه خارج می شود.
 
[تصویر: 2-collision.gif]
میخواهیم این لوله ها بصورت منظم در صفحه نمایش داده شوند و دیگر حرکت نکنند برای انجام اینکار مجددا از SKAction استفاده می کنیم.اما به شیوه ای متفاوت :
برای تولید مجدد و منظم لوله ها در صفحه بازی باید حالت و حرکت لوله ها را ذخیره کنیم:
@interface MyScene () {
    SKSpriteNode* _bird;
    SKColor* _skyColor;
    SKTexture* _pipeTexture1;
    SKTexture* _pipeTexture2;
    SKAction* _moveAndRemovePipes;
}
@end
 
 
عملکرد _moveAndRemovePipes درست بعد از کد قبلی اضافه می شود
CGFloat distanceToMove = self.frame.size.width + 2 * _pipeTexture1.size.width;
SKAction* movePipes = [SKAction moveByX:-distanceToMove y:0 duration:0.01 * distanceToMove];
SKAction* removePipes = [SKAction removeFromParent];
_movePipesAndRemove = [SKAction sequenceAngry[movePipes, removePipes]];
 
متد spawn برای ایجاد لوله های جدید است:
-(void)spawnPipes {
    SKNode* pipePair = [SKNode node];
    pipePair.position = CGPointMake( self.frame.size.width + _pipeTexture1.size.width, 0 );
    pipePair.zPosition = -10;
     
    CGFloat y = arc4random() % (NSInteger)( self.frame.size.height / 3 );
     
    SKSpriteNode* pipe1 = [SKSpriteNode spriteNodeWithTexture:_pipeTexture1];
    [pipe1 setScale:2];
    pipe1.position = CGPointMake( 0, y );
    pipe1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:pipe1.size];
    pipe1.physicsBody.dynamic = NO;
    [pipePair addChild:pipe1];
     
    SKSpriteNode* pipe2 = [SKSpriteNode spriteNodeWithTexture:_pipeTexture2];
    [pipe2 setScale:2];
    pipe2.position = CGPointMake( 0, y + pipe1.size.height + kVerticalPipeGap );
    pipe2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:pipe2.size];
    pipe2.physicsBody.dynamic = NO;
    [pipePair addChild:pipe2];
     
    [pipePair runAction:_movePipesAndRemove];
     
    [self addChild:pipePair];
}
 
برا ی اطمینان از اینکه spawnPipesکار خود را بدرستی انجام میدهد و بصورت دائم لوله ها را تولید می کند  با استفاده از متد  SKActionکه به SKScene اینکار را انجام می دهیم:
SKAction* spawn = [SKAction performSelector:@selector(spawnPipes) onTarget:self];
SKAction* delay = [SKAction waitForDuration:2.0];
SKAction* spawnThenDelay = [SKAction sequenceAngry[spawn, delay]];
SKAction* spawnThenDelayForever = [SKAction repeatActionForever:spawnThenDelay];
[self runAction:spawnThenDelayForever];
 
این متد spawnPipes نامیده می شود که عملکرد آن به اینصورت است که حین بازی دو ثانیه متوقف می شود و سپس دوباره شروع به کار میکند.
همانطور که در تصویر زیر می بینید لوله ها بصورت مرتب  و منظم در صحنه بازی قرار می گیرند.
[تصویر: 3-repeating-pipes.gif]
تشخیص برخورد و پاسخ
حال ما نیاز داریم پس از برخورد پرنده با موانع، تغییراتی را در صحنه بازی مشاهده کنیم که برای انجام این کار از متد SKPhysicsContactDelegate استفاده می کنیم.
علاوه براین نیاز داریم، چندین مجموعه را با مدل های مختلف برای نمایش واکنش صفحه نمایش، به کدها اضافه کنیم:
@interface MyScene () {
    SKSpriteNode* _bird;
    SKColor* _skyColor;
    SKTexture* _pipeTexture1;
    SKTexture* _pipeTexture2;
    SKAction* _movePipesAndRemove;
}
@end
 
@implementation MyScene
 
static const uint32_t birdCategory = 1
static const uint32_t worldCategory = 1
static const uint32_t pipeCategory = 1
 
static NSInteger const kVerticalPipeGap = 100;
 
-(id)initWithSize:(CGSize)size {   
    if (self = [super initWithSize:size]) {
        /* Setup your scene here */
         
        self.physicsWorld.gravity = CGVectorMake( 0.0, -5.0 );
        self.physicsWorld.contactDelegate = self;
با استفاده از category می توان دسته بندی های مختلفی را تعریف کرد و تعیین کرد در صورت برخورد این اجزا با یکدیگر چه اتفاقی بیفتد .مانند آنچه در کد بالا توضیح داده شده است.
ما در اینجا برای سه عنصر لوله، جهان(که همان محیط بازی است) و پرنده، category تعریف کردیم دقت کنید که نیازی نیست برای همه عناصر کتگوری تعریف شود، فقط عناصری که برای واکنش نشان دادن حین برخورد دخالت دارند، مهم هستند.
 
برای متوقف کردن حرکت پرنده پس از برخورد، مولفه speed را برای متد SKAction تعریف می کنیم به نحوی که وقتی سرعت برابر صفر شد SKAction متوقف شود.
@interface MyScene () {
    SKSpriteNode* _bird;
    SKColor* _skyColor;
    SKTexture* _pipeTexture1;
    SKTexture* _pipeTexture2;
    SKAction* _movePipesAndRemove;
    SKNode* _moving;
}
@end
 
تمام عناصر ایجاد شده از ابتدا کدنویسی به این گره پدر متصل می شوند.
_skyColor = [SKColor colorWithRed:113.0/255.0 green:197.0/255.0 blue:207.0/255.0 alpha:1.0];
[self setBackgroundColor:_skyColor];
 
_moving = [SKNode node];
[self addChild:_moving];
 
SKTexture* birdTexture1 = [SKTexture textureWithImageNamedAngry"Bird1"];
birdTexture1.filteringMode = SKTextureFilteringNearest;
 
...
 
// Create ground
 
...
 
for( int i = 0; i
    ...
    [_moving addChild:sprite];
}
 
// Create skyline
 
...
 
for( int i = 0; i
    ...
    [_moving addChild:sprite];
-(void)spawnPipes {
    ...   
    [pipePair runAction:_movePipesAndRemove];
     
    [_moving addChild:pipePair];
}
 
حال تمامی عناصر به جز پرنده را به گره پدر متصل کردیم و بدین ترتیب هر اتفاقی برای گره پدر بیفتد بر روی فرزندان نیز اعمال می شوداز طرفی می خواهیم حرکات پرنده فقط یکبار در بازی متوقف شود که بصورت کد زیر انجام می شود.
(void)didBeginContact:(SKPhysicsContact *)contact {
    if( _moving.speed > 0 ) {
        _moving.speed = 0;
     
        // Flash background if contact is detected
        ...
    }
حتما متوجه شده اید که پرنده را به گره ی _moving متصل نکردیم اینکار برای این است که می خواهیم پرنده همچنان حرکت داشته باشد و تا زمانیکه مقدار _moving.speed>0   است کنترل تحت نظر بازیکن باشد و با ضربه به صفحه نمایش بتواند حرکات پرنده را کنترل کند.
[تصویر: 5-halt-on-collision.gif]

منبع:بلاگ سروش پرداز|برنامه نویسی ios

روید باکس...
ما را در سایت روید باکس دنبال می کنید

برچسب : نویسنده : کاوه محمدزادگان roid بازدید : 163 تاريخ : پنجشنبه 31 تير 1395 ساعت: 19:13