مساحة اعلانية

آخر المواضيع

انشاء لعبة الدودة باستخدام برنامج cocos 2d : واجهة اللعبة.

فى هذه الدورة سنعيد لعب لعبة الاتارى الشهيرة الدودة باستخدام برنامج cocos 2d لاجهزة ios
هذا هو الدرس الثانى حيث سنتعلم طريقة انشاء واجهة اللعبة
اين توقفنا ؟؟؟

فى الدرس السابق علمتك طريقة تحميل وتنصيب وانشاء مشروع ببرنامجcocos 2d  كما شرحنا طريقة تجهيز الاصول والمجودات الخاصة بك باستخدامTexture Packer  وتحميلها على اللعبةفى درس اليوم سنشرح معلومات ادق حول واجهة المستخدم وتصميم واجهة اللعبة
الخطوة الاولى : حقل البراعم - الكائن الرئيسي باللعبةفى لعبة الدودة كان المشروم يستخدم لتحديد منطقة تحرك الدودة سنستخدم نفس الفكرة بانشاء ما اسميه البراعم.
قبل البدا فى التحدث عن الاجسام داخل اللعبة سنحتاج لشرح بعض الدوال التى تحتوى على الخصائص التى يحتاجها كل جسم هذا سيحميينا من الاكواد الزائدة فى المستقبل.انشئ ملف جديد باسم GameObject.m وفى اعلى ملف اكتب الكود التالى:
#import "cocos2d.h"
#import "GameLayer.h"
@interface GameObject : NSObject
@property(nonatomic, retain) CCSprite *sprite;
@property (nonatomic, assign) GameLayer *gameLayer;
@property(nonatomic) CGPoint position;
- (id)initWithGameLayer:(GameLayer *)layer;
- (CGRect)getBounds;
@end
هذا شرح لكل خاصية تابعوا   ساشرح معلومات اكثر عن كل الدوال عند التنفيذ
  • العفريت او الروح : كل كائن فى اللعبة يحتاج الى شئ لتمثيله بصريا  هذه ستكون صورة جسم العفريت 
  • gamelayer: مجرد اشارة الى طبقة اللعبة الرئيسية سيكون هذا مفيد للاستجابة للاصطدامات بالاضافة الى  ترك الاجسام تضيف عفاريتها الى منطقة الرسم
  • الموقع : هو مكان الجسم فى اللعبة
الان حان وقت التنفيذ اضف الكود التالى الى  GameObject.m
#import "GameObject.h"
@implementation GameObject
@synthesize sprite = _sprite;
@synthesize gameLayer = _gameLayer;
@synthesize position = _position;
- (void)dealloc {
[_sprite release];
[super dealloc];
}
- (id)initWithGameLayer:(GameLayer *)layer {
if(self = [super init]) {
self.gameLayer = layer;
}
return self;
}
// 1
- (void) setPosition:(CGPoint)position {
_position = position;
_sprite.position = position;
}
// 2
- (CGRect)getBounds {
CGSize size = [self.sprite contentSize];
return CGRectMake(self.position.x - size.width * self.sprite.anchorPoint.x,
self.position.y - size.height * self.sprite.anchorPoint.y,
size.width, size.height);
}
@end
 1. منذ ان يصبح مكان الجسم مختلف عن مكان العفريت نحتاج لكتابة واضع لخاصية الموقع للتاكد من ان العفريت يتحرك على الشاشة2. هذه الدالة ستستخدم بعد قليل عند تنفيذ دالة كشف التصادم ببساطة نحن نحدد صندوق حدود الجسم ونعيده .
الخطوة الثانية : حقل البراعم - جسم البراعم

الان لدينا فى مكانه جسم البراعم سهل الى حد ما الغرض الوحيد للبراعم هو بمثابة عقبة أمام اللاعب والدودة.
انشئ كائن جديد GameObjectيسمى البراعم كفئة فرعية
مرة اخرى نحتاج جسم جديد فى اللعبة من الفئة الفرعية للحصول على بعض الخصائص والدوال المتداولة.
أضف الكود اتالى الى Sprout.h

#import "GameObject.h" @interface Sprout : GameObject @property (nonatomic, assign) NSInteger lives; @end
الاضافة الوحيدة لجسم البرعم لGameObject هو انها تمتلك خاصية lives عندما يصيب اللاعب البرعم الذى نريده ان يصاب عددمن المرات فى هذه الحالة 3 قبل ان يختفىتنفيذ جسم البرعم سهل ايضاأضف الكود التالى الى Sprout.m.
#import "Sprout.h" #import "GameConfig.h" @implementation Sprout @synthesize lives = _lives; - (id) initWithGameLayer:(GameLayer *)layer { // 1 if(self = [super initWithGameLayer:layer]) { // 2 self.sprite = [CCSprite spriteWithSpriteFrameName:@"sprout.png"]; // 3 [self.gameLayer.spritesBatchNode addChild:self.sprite]; // 4 self.lives = kSproutLives; } return self; } // 5 - (void)setLives:(NSInteger)lives { _lives = lives; self.sprite.opacity = (_lives / 3.0) * 255; } @end
منذ كتابة الدالة initWithGameLayer نحتاج لاستدعاء نسخة من super class' ايضا هذا للتاكد ان كل شئ تم تعديله بطرية صحيحة.هذا الكود يضع العفريت الحالى للعفريت القادم من CCSpriteBatchNodeباسم  sprout.png
- يضيف العفريت الى  batch node layer لرسمه على الشاشة
- يضع عدد الحيوات للبرعم kSproutLives اعدادات الترتيب نحتاج الى اضافة بعض الخصائص عندما يصدم اللاعب البرعم ومؤشر لمعرفة كم تبقى من صحته وقد فعلت هذا بتعتيم الشاشة بنسبة الثلث عند الاصطدام تبعا للكود الرابع نحتاج الى وضع ترتيب اساسى باللعبة. لحسن الحظ اضاف البرنامج cocos 2d ملف يسمى  GameConfig.hأضف اليه الاكواد التالية:

#define kSproutLives 3
الان انشانا الجسم الرئيسي للبرعم يمكن ان نستخدمها لتوليد الحقل باكمله للعبة
الخطوة الثالثة : حقل البراعم - الاماكن العشوائيةخريطة اللعبة ستتولد بشكل عشوائئ مع عدد اقل من البراعم فى اى وقت للقيام بذلك، نحن بحاجة إلى الحفاظ على المسار من حيث اين وضعنا  البراعم. عدد البراعم على الخريطة سيكون بزيادة مستوى حيث كلما زادت البراعم كانت اللعبة اصعب اضف الخاصيتين لملف GameLayer.h أنا فقط سوف انشر الإضافات بدلاً من إعادة نشر الاكود التي كتبنا سابقا.
  #import "GameConfig.h"
@interface GameLayer : CCLayer {
// 1
BOOL _locations[kRows][kColumns];
}
// 2
@property (nonatomic, assign) NSInteger level;
@property (nonatomic, retain) NSMutableArray *sprouts
// ...Other properties...
هذه مجموعة من القيم 2dالدلالية لمعرفة مكان اجسام البراعم هذا يعنى ان تواجدت واحدة وهى خاطئة فهى غير موجودة2.هذا هو المسوى الحالى للعبةهناك احداث اخرى ستبنى على هذه الخاصية اضا الخاصية الاخرى تمتلك عدد الاجسام الحالية من البراعم داخل اللعبة تأكد من خاصصية synthesize هذه الخصائص في ملف التنفيذ، وكذلك الافراج عن مجموعة البراعم. هذه هى المرة الاخيرة التى اذكر فيها بتجميع والافراج عن الخصائصGameConfig.hشئ اخر يجب ملاحظته هو استيراد ملفGameConfig.h للوصول الى الثوابت kRows and kColumns لاتقلت بشان هذا لان سنشرحه قريباالان افتح ملف GameLayer.m.GameConfig.h واضف الواجهة الخاصة ب game layer فى الاعلىحتى نتمكن من تحديد دوال اقل التى سنستخدمها وتاكد من اضافة تقرير  حيث سنستدخمه كثيرا هنافوق خط @implementation اضف الكود التالى:
#import "Sprout.h"
@interface GameLayer(Private)
- (CGPoint)randomEmptyLocation;
- (void)placeRandomSprout;
@end
هاتان الدالتان المساعدتان لانشاء الحقل سنشرحهما وقت التنفيذ.
الان نضيف الكود التالى الى دالة

if( (self=[super init]))
_locations[i][j] = NO;
}
}
// 3
srand(time(NULL));
_sprouts = [[NSMutableArray alloc] init];
for(int i = 0; i < kStartingSproutsCount; i++) {
// 4
[self placeRandomSprout];
}

1.اللعبة تبدا بالمستوى الاول
2.بدائرة اللعب الدالة _locations تحللهم وتجعل قيمتهم لا
3.الدالةkStartingSproutsCount تضيف البراعم عشوائيا فى اللعب
أضف هذا الكود داخل ملف GameConfig.h

    #define kGridCellSize 16    #define kColumns 18    #define kRows 20    #define kStartingSproutsCount 50    #define kGameAreaStartX 24    #define kGameAreaStartY 64    #define kGameAreaHeight 353    #define kGameAreaWidth 288
الخطوة الاخيره هنا هى ان تقوم بتنفيذ الطريقتين التى عرفناهما من قبل , قم بإضافة الخصائص التالية إلى ملف الـGameLayer.m الخاص بك.

    - (void)placeRandomSprout {
// 1
Sprout *sprout = [[[Sprout alloc] initWithGameLayer:self] autorelease];
CGPoint p = [self randomEmptyLocation];

// 2
sprout.position = ccp(p.x * kGridCellSize + kGameAreaStartX,
(kGameAreaStartY - kGridCellSize + kGameAreaHeight) -
p.y * kGridCellSize - kGridCellSize/2);
// 3
[self.sprouts addObject:sprout];
}
- (CGPoint) randomEmptyLocation {
int column;
int row;
BOOL found = NO;
// 1
while(!found) {
// 2
column = (arc4random() % kColumns);
row = (arc4random() % kRows);
// 3
if(!_locations[row][column]) {
found = YES;
_locations[row][column] = YES;
}
}
// 4
return CGPointMake(column, row);
}
اضافة براعم عشوائيا1.بدانا بانشاء وتهسئة برعم جديد ووضعه فى مكان عشوائى نحتاج الى جعله داخل مكان اللعب حتى يرسم على الشاشة
2.دالة اساسية انقل البرعم من منطقة الشبكة الى منطقة اللعب بحجم منطقة اللعب وحجم الخلية
3.اخيرا يضاف البرعم الى صف البراعم الحية
المناطق الخالية العشوائية:1.هذا الدائرة لن تتم الا بعد ان نجد المكان الخالى انا اعتقد انه سيكون هناك وقت عندما لايكون هناك اماكن متاحة ستكون اللعبة فى سرعة سخيفة حينها لايستطيع اللاعب اللعب.هذا الاختبار الامثل للتاكد ان كل مساحة ليست مغطاة بالكامل اولا
2.الحصول على صف وعمود عشوائيين
3.التاكد من وجود البراعم فى اماكنها اذ لم يكن وتحديث الدالة _locations يبلغ اللعبة للتوقف
4. اخيرا نعود للنقطة الجديدة التى انشئناها
يجب ان تشبه لعبتك هذه الصورة:

الخطوة الرابعة : اللاعب
الخطوة التالية فى انشاء الواجهة هى انشاء كائن اللاعب انشاء اللاعب هو سهل للغاية بفضل مساعدة super class
انشئ ملف gameobject  جديد يسمى  player  واضف الكود التالى فى ملف player.h

 #import "GameObject.h"
@interface Player : GameObject
@property(nonatomic) NSInteger lives;
@property(nonatomic) NSInteger score;
@end
تضاف حيوات اللاعب بالاضافة الى المشتوى وتعرض فى كما فى الجزء الاخياضف الكود التالى الى ملف Player.m : #import "Player.h"
#import "GameLayer.h"
@implementation Player
@synthesize score = _score;
@synthesize lives = _lives;
- (id)initWithGameLayer:(GameLayer *)layer {
if(self = [super initWithGameLayer:layer]) {
self.sprite = [CCSprite spriteWithSpriteFrameName:@"player.png"];
[self.gameLayer.spritesBatchNode addChild:self.sprite];
}
return self;
}
@end
دالة initWithGameLayer للاعب هى نفس دالة البراعم عدا اضافة عفريت او روح مختلفة للعبة
هذا كل المتعلق باللاعب ..الخطوة الاخيرة هى تهيئة اللاعب واضافته الى اللعبة
لكن اولا يجب ان نعلن ونصرح لكائن اللاعب داخل ملف gamelayer.h. .وتاكد من استيراد ملف اللاعب هنا ايضا

@property (nonatomic, retain) Player *player;
الان اضف الكود الاتالى داخل دالة init اسفل الكود الذى كتبته فى الجزء الاخير مباشرة:
 _player = [[Player alloc] initWithGameLayer:self];
_player.lives = kPlayerStartingLives;
_player.position = ccp(kGameAreaStartX + (kGameAreaWidth / 2), 88);
_player.score = 0;
مجددا هذا يقدم الثابت الذى نريد اضافته الى gameconfig.h 
#define kPlayerStartingLives 3
الآن يجب أن اظهر اللعبة كما بالصورة:
الخطوة الخامسة : ارواح وحيوات اللاعب

يجب ان نعطى اللاعب شئ معين يعرف به كم تبقى له من الحيوات انا اخترت عرض روح اللاعب فى اعلى الجانب الايسر .فاذا امتلك اللاعب 3 حيوات فانه يظهر 3 مربعات حمراء

هناك طرق قليلة للتعامل مع هذا المطلب ..
انا اخترت هذا ليحافظ على صف ارواح اللاعب واستخدم هذا لعرض عدد حيوات اللاعب..
اضف الخاصية التالية الى GameLayer class تسمى livesSprites:

 @property(nonatomic, retain) NSMutableArray *livesSprites;
Next, add the following code to the init method:
// init live sprites
_livesSprites = [[NSMutableArray alloc] init];
// Register for lives notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateLives:)
name:kNotificationPlayerLives
object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationPlayerLives
object:nil];
لاحظ ااننى قمت باضافة الgamelayer كمراقب الى اشعار اسمه kNotificationPlayerLives.ممكن الا تكون حياة اللاعب داخل ال gamelayer , نحتاج الى اجابة سريعة عندما يحدث اصطدام . وهذه هى الطريقة الاسهل لحدوث هذا.ولاحظ ان انشر الاشعار على الفور

منذ ان اصبحت هذه الدالة مسؤلة عن رسم حيوات اللاعب.نحن نحتاج استدعاءها اثناء الدالة init لعرض حيوات اللاعب بالبداية.
وهذا باضافة دالة تسمى kNotificationPlayerLives.
تاكدمن اضافتها لملف GameConfig.h.سنقوم بعمل نفس الشئ مع نقاط اللاعب  فى لحظة لذلك اضف الكود لهذه الدالة  لكليهما :

    #define kNotificationPlayerLives @"PlayerLivesNotification"
#define kNotificationPlayerScore @"PlayerScoreNotification"
الان نحن سننفذ دالة updateLives.ستكون هذه الدالة مسؤلة عن رسم حيوات اللاعب و والتحرك الى شاشة game over عندما تنتهى حيوات اللاعب =0
اضف الدالة التالية الى ملف gamelayer.m:

- (void) updateLives:(NSNotification *) notification {
NSInteger lifeCount = self.player.lives;
// 1
[self.livesSprites enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[self.spritesBatchNode removeChild:obj cleanup:YES];
}];
[self.livesSprites removeAllObjects];
// 2
for(int i = 0; i < lifeCount; i++) {
CCSprite *sprite = [CCSprite spriteWithSpriteFrameName:@"player.png"];
sprite.position = ccp(kGameAreaStartX + (i * kGridCellSize * 2), 435);
[self.livesSprites addObject:sprite];
[self.spritesBatchNode addChild:sprite];
}
}
1. فى البداية قمنا بحذف صف دالة livesSprites وحذف جميع الارواح من المشهد.
2. ثانيا الدائرة تعتمد على حياة اللاعب التى انتهت وانشاء عفريت او روح جديدة لاضافتها للمشهد
الان اذا قمت بتشغيل اللعبة يجب ان تشاهد حياة اللاعب فى الاعلى كما بالصورة:

الخطوة السادسة : عرض نقاط اللاعبهذا سيكون مشابه جدا لعرض حيوات اللاعب فقط سنستخدم CCLabelTTF لعرض نقاط اللاعب..
تستخدم اداة CCLabelTTF فى cocos 2d لاضافة نصوص داخل الالعاب
افتح ملف GameLayer.h واضف الكود التالى :


@property(nonatomic, retain) CCLabelTTF *playerScoreLabel;
Next, go into the init method of GameLayer.m and initialize the label and notifications with the following code:
_playerScoreLabel = [[CCLabelTTF labelWithString:@"0"
dimensions:CGSizeMake(100, 25)
alignment:UITextAlignmentRight
fontName:@"Helvetica"
fontSize:18] retain];
_playerScoreLabel.position = ccp(254,435);
[self addChild:_playerScoreLabel];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateScore:)
name:kNotificationPlayerScore
object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationPlayerScore
object:nil];
هذا الكود يبدو واضح جدا لتشابهه الكير مع حيوات اللاعب. الخطوة التالية انشاء دالة updatescore للحصول على النقاط لعرضها .. افتح ملف game layer.m واضف الدالة التالية:

   - (void) updateScore:(NSNotification *) notification {
[self.playerScoreLabel setString:[NSString stringWithFormat:@"%d",self.player.score]];
}
اداة CCLabelTTF شبيهة جدا لاداة UILabel فى UIKit.
الان انت جاهز للانطلاق .الان اذا زادت النقاط باللعبة ببساطة ننشر اشعار هذا المستوى.
وستقوم الاكواد بالتحديث والتعديل تبعا لذلك.
الاصدار الاخير من اللعبة يجب ان يكون شبيها بهذا:

 فى المرة القادمة 
شرح لاكثر جزء معقد ومضحك فى اللعبة وهو الدودة
وبناء جميع اجزائها.

الكــاتــب

    • مشاركة

ليست هناك تعليقات:

جميع الحقوق محفوظة لــ الشبح للمعلوميات 2019 ©