PDA المساعد الشخصي الرقمي

عرض كامل الموضوع : كود لعبة إيجاد البطاقات المتشابهة [ Match & Catch ] لمرحلة واحدة



Diamond mas
10-06-2013, 12:16
السلام عليكم ورحمة الله وبركاته

بغرض فصل تعليم فلاش عن تعليم اللغة البرمجية المستخدمة فيه (ActionScript)
أقدم لكم في هذا الموضوع كود اللعبة المطروحة في من الدورة المطروحة في منتدى الدروس التعلمية في منتدى التصميم:

http://www.mexat.com/vb/attachment.php?attachmentid=1821220&stc=1&d=1360174926

الغرض من الفصل هو عدم تعقيد المتعلمين غير الراغبين في تعلم البرمجة ليس إلا،
فاللغة ActionScript مهمة جداً لتعلم برنامج فلاش وإتقانه بالشكل المناسب ولا يجب فلاش عن هذه اللغة.

لدينا في تلك اللعبة فئتان (Classes):

- الفئة SimpleGame : وتحوي الكود الرئيسي للعبة.
- الفئة Card : وتحوي الكود الخاص بالبطاقات.

الكود في الفقرتين القادمتين.

Diamond mas
10-06-2013, 12:19
/**
* Match & Catch game
*
* An open source flash game powerd by Adobe Flash Pro CS6
*
* @author Diamond mas - mexat.com ( http://www.mexat.com/vb/members/175841 )
* @copyright Copyright (c) Diamond mas, Mexat forums.
* @license http://www.gnu.org/licenses/gpl.html
* @link http://www.mexat.com/vb/threads/1070305
* @filesource
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.text.TextField;

public class SimpleGame extends MovieClip{
private const CARDS_SPACING:uint = 2;
private const CARD_WIDTH:uint = 51;
private const CARD_HEIGHT:uint = 66;
private const INIT_X:uint = 47;
private const INIT_Y:uint = 115;

private var cards:Array;
private var cardsFaceUp:Array;
private var l1_images:Array;

private var removeCardsTimer:Timer;
private var flipBackTimer:Timer;

private var points:int;
private var moves:int;
private var gameLevel:uint;
private var nom_of_cards:uint;
private var nom_of_matched_cards:uint;
private var similarCards:uint;
private var nom_of_rows:uint;
private var nom_of_cols:uint;

public function SimpleGame() {

// initialize list of images
this.l1_images = new Array();
this.l1_images.push(new img_1());
this.l1_images.push(new img_2());
this.l1_images.push(new img_3());
this.l1_images.push(new img_4());
this.l1_images.push(new img_5());
this.l1_images.push(new img_6());
}

public function Start(level:uint):void {
this.removeEventListener(MouseEvent.CLICK, start_btn_event_handler);

// initialize parameters
this.cards = new Array();
this.cardsFaceUp = new Array();

this.gameLevel = level;
this.nom_of_matched_cards = 0;
this.points = 0;
this.moves = 0;

switch(level) {
case 1:
this.nom_of_cards = 12; // total number of cards
this.similarCards = 2; // how many cards should the player match each time
this.nom_of_rows = 3; // number of rows in the board
this.nom_of_cols = 4; // number of columns in the board
break;
}

this.intializeStage(level, this.l1_images, this.CARD_WIDTH, this.CARD_HEIGHT);
}


// Assigns all cards faces (pictures)
private function intializeStage(level:uint, images:Array,
card_width:Number=51, card_height:Number=66):void {

var nom_of_picts:uint = this.nom_of_cards / this.similarCards;

var imagesArray:Array = new Array();
var random_number:uint;

// pick pictures from the first path
for (var i=0; i<nom_of_picts; i++) {
imagesArray.push({image:images[i], id:i, used:0});
}

// distribute the images randomly
for (i=0; i<this.nom_of_cards; i++) {
random_number = Math.floor(Math.random()* 100) % imagesArray.length;

this.cards.push(new Card(card_width, card_height));
this.cards[i].AddImage(imagesArray[random_number].image);
this.cards[i].PictureID = imagesArray[random_number].id;

imagesArray[random_number].used++;
if (imagesArray[random_number].used >= this.similarCards) {
imagesArray.splice(random_number, 1);
}
}

// intial (x, y) position for the cards
var current_x:uint = this.INIT_X + card_width/2;
var current_y:uint = this.INIT_Y + card_height/2;
var counter:uint = 0;

// display cards on screen
for (i=0; i < this.nom_of_rows; i++) {
for (var j=0; j < this.nom_of_cols; j++) {
this.cards[counter].x = current_x;
this.cards[counter].y = current_y;
this.cards[counter].stop();

cards[counter].addEventListener(MouseEvent.CLICK, click_Card);
cards[counter].buttonMode = true;
this.addChild(this.cards[counter]);

current_x += card_width + this.CARDS_SPACING;

counter++;
}

current_x = this.INIT_X + card_width/2;
current_y += card_height + this.CARDS_SPACING;
}
}

private function click_Card(e:MouseEvent) {

var card:Card = e.currentTarget as Card;

// if some cards are being removed, force the remove process
if (this.removeCardsTimer != null && this.removeCardsTimer.running) {
this.removeCardsTimer.dispatchEvent(new Event(TimerEvent.TIMER_COMPLETE));
}

// if some cards are being flipping back, force the flipping back process
if (this.flipBackTimer != null && this.flipBackTimer.running) {
this.flipBackTimer.dispatchEvent(new Event(TimerEvent.TIMER_COMPLETE));
}

if (this.cardsFaceUp.indexOf(card) != -1) {// same card was clicked twice
return;

} else if (this.cardsFaceUp.length < this.similarCards) {// if number of min similar cards not reached
this.cardsFaceUp.push(card);
card.Flip();
}

if (this.cardsFaceUp.length == this.similarCards) { // if number of min similar cards has been reached

var isMatch:Boolean = true;

// check match
for (var i:uint=1; i < this.cardsFaceUp.length; i++) {
if (this.cardsFaceUp[0].PictureID != this.cardsFaceUp[i].PictureID) {
isMatch = false;
break;
}
}

if (isMatch) {
this.handleMatchs();
} else {
this.points -= 5;
this.moves++;
this.pointsScreen.text = this.points.toString();
this.movesScreen.text = this.moves.toString();

this.flipBackTimer = new Timer(1000, 1);
this.flipBackTimer.addEventListener(TimerEvent.TIM ER_COMPLETE, this.flipCardsBack);
this.flipBackTimer.start();
}
}
}

private function handleMatchs() {
this.nom_of_matched_cards += this.similarCards;

this.points += 100;
this.moves++;
this.pointsScreen.text = this.points.toString();
this.movesScreen.text = this.moves.toString();

// blink the matched cards
for (var i:uint=0; i<this.cardsFaceUp.length; i++) {
this.cardsFaceUp[i].Blink();
}

this.removeCardsTimer = new Timer(500, 1);
this.removeCardsTimer.addEventListener(TimerEvent. TIMER_COMPLETE, removeCards);
this.removeCardsTimer.start();
}

// remove the cards from the screen after the timer completes
private function removeCards(e:Event):void {

for (var i:int=(this.cardsFaceUp.length - 1); i >= 0; i--) {
this.cardsFaceUp[i].removeEventListener(MouseEvent.CLICK, click_Card);

this.removeChild(this.cardsFaceUp[i]);

this.cards.splice(this.cards.indexOf(this.cardsFac eUp[i]), 1);
this.cardsFaceUp.pop();
}
this.removeCardsTimer.removeEventListener(TimerEve nt.TIMER_COMPLETE, removeCards);
this.removeCardsTimer = null;

// check for the end of the game
if (this.nom_of_matched_cards == this.nom_of_cards) {
this.endGame(null);

} else if (this.nom_of_matched_cards == this.nom_of_cards - this.similarCards) {
for(i=0; i<this.cards.length; i++) {
this.cards[i].dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
}
}

// flip back the cards after the time completes
private function flipCardsBack(e:Event): void {

if (this.flipBackTimer != null) {
this.flipBackTimer.stop();
this.flipBackTimer.removeEventListener(TimerEvent. TIMER_COMPLETE, flipCardsBack);
this.flipBackTimer = null;
}

for (var i:int=(this.cardsFaceUp.length - 1); i >= 0; i--) {
this.cardsFaceUp[i].Flip(); // flip back card
this.cardsFaceUp.pop(); // remove it from the array
}
}

private function endGame(e:MouseEvent):void {
this.removeEventListener(MouseEvent.CLICK, endGame);
this.removeEventListener(MouseEvent.CLICK, click_endLevel);

if (this.flipBackTimer != null) {
this.flipBackTimer.stop();
this.flipBackTimer.removeEventListener(TimerEvent. TIMER_COMPLETE, flipCardsBack);
this.flipBackTimer = null;
}
if (this.removeCardsTimer != null) {
this.removeCardsTimer.stop();
this.removeCardsTimer.removeEventListener(TimerEve nt.TIMER_COMPLETE, removeCards);
this.removeCardsTimer = null;
}

if (this.cards != null) {
for (var i:uint=0; i<this.cards.length; i++) {
this.cards[i].removeEventListener(MouseEvent.CLICK, click_Card);
removeChild(this.cards[i]);
}
}

this.gotoAndStop("results");
}

// display the result after game is finished
private function displayResult():void {

this.playerPoints.text = this.points.toString();
this.playerMoves.text = this.moves.toString();
}

private function start_btn_event_handler(e:MouseEvent):void {
this.gotoAndStop("start");
}

private function click_endLevel(e:MouseEvent):void {
this.endGame(null);
}

}

}


لتحميل الملف في المرفقات

Diamond mas
10-06-2013, 12:21
/**
* Match & Catch game
*
* An open source flash game powerd by Adobe Flash Pro CS6
*
* @author Diamond mas - mexat.com ( http://www.mexat.com/vb/members/175841 )
* @copyright Copyright (c) Diamond mas, Mexat forums.
* @license http://www.gnu.org/licenses/gpl.html
* @link http://www.mexat.com/vb/threads/1070305
* @filesource
*/
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.TimerEvent;
import flash.utils.Timer;

public class Card extends MovieClip {

public var pict:Sprite;
public var cover:Sprite;
private var blinkSprite:Sprite;

public var PictureID:uint;
private var flipStep:uint;
private var currentStep:uint;
private var pictureWidth:Number;
private var pictureHeight:Number;
private var isFlipping:Boolean;

private var flipTimer:Timer;
private var blinkTimer:Timer;

public function Card(cardWidth:Number=63, cardHeight:Number=62) {
this.pictureWidth = cardWidth;
this.pictureHeight = cardHeight;

this.isFlipping = false;
}

public function AddImage(img:BitmapData):void {
// adjust position and dimentions for the image
var image:Bitmap = new Bitmap(img);
image.width = this.pictureWidth;
image.height = this.pictureHeight;

this.pict = new Sprite();
this.pict.addChild(image);

this.pict.x = this.pictureWidth / -2;
this.pict.y = this.pictureHeight / -2;
this.addChild(this.pict);

// card cover
var holder:Bitmap = new Bitmap();
holder.bitmapData = new card_cover();
this.cover = new Sprite();
this.cover.addChild(holder);
this.cover.x = this.pictureWidth / -2;
this.cover.y = this.pictureHeight / -2;
this.cover.width = this.pictureWidth;
this.cover.height = this.pictureHeight;
this.addChild(this.cover);
}

public function Flip() {
if (this.flipTimer == null) {

this.flipTimer = new Timer(10);
this.flipTimer.addEventListener(TimerEvent.TIMER, doFlip);
}
if (this.flipTimer.running) {
flipStep = 10 - flipStep;
if (flipStep == 5) {
flipStep = 4;
}
} else {
flipStep = 0;
this.isFlipping = true;
this.flipTimer.start();
}
}

private function doFlip(e:TimerEvent):void {
this.currentStep = ++flipStep;
if (this.currentStep <= 5) {
this.scaleX -= 0.2;

if (this.currentStep == 5) {
this.scaleX = 0;
this.cover.visible = !this.cover.visible;
}
} else if (this.currentStep < 10) {
this.scaleX += 0.2;

} else if (this.currentStep >= 10) {
this.scaleX = 1;
this.isFlipping = false;
this.flipTimer.stop();
this.flipTimer.removeEventListener(TimerEvent.TIME R, doFlip);
this.flipTimer = null;
}
}

public function Blink():void {
this.blinkTimer = new Timer(100, 6);
this.blinkTimer.addEventListener(TimerEvent.TIMER, doBlink);
this.blinkTimer.addEventListener(TimerEvent.TIMER_ COMPLETE, clearBlink);

this.blinkSprite = new Sprite();
this.blinkSprite.graphics.beginFill(0xaebe3e, 0.5);
this.blinkSprite.graphics.drawRect(0, 0, this.pictureWidth, this.pictureHeight);
this.blinkSprite.graphics.endFill();
this.blinkSprite.x = this.pictureWidth / -2;
this.blinkSprite.y = this.pictureHeight / -2;
addChild(this.blinkSprite);

this.blinkTimer.start();
}

private function doBlink(e:TimerEvent):void {
blinkSprite.visible = ! this.blinkSprite.visible;
}

private function clearBlink(e:TimerEvent):void {
this.blinkTimer.stop();
this.blinkTimer.removeEventListener(TimerEvent.TIM ER, doBlink);
this.blinkTimer.removeEventListener(TimerEvent.TIM ER_COMPLETE, clearBlink);
this.blinkTimer = null;
removeChild(this.blinkSprite);
}
}

}



لتحميل الكود في المرفقات

Diamond mas
10-06-2013, 12:26
لتركيب الكود يجب فك ضغط الملفين SimpleGame.zip و Card.zip في نفس المجلد الذي يحوي ملف فلاش الخاص باللعبة ثم تصدير اللعبة باستخدام برنامج Adobe Flash CS6

الموضوع مفتوح لاستفساراتكم
حظاً موفقاً

بِشْر
17-06-2013, 23:21
السَلامُ عَليكُم وَ رحمَة الله ..

ما شآء الله علِيك :أوو:

بالفِعل كآن من مُدّة بودِي أعرِف طرِيقة عَمل اللعبَة حَقتَك :سعادة2:

شُكرًا لَك عَلى الأكوآد :أوو:

بجربهآ إن شآء الله عمّا قرِيب ،،

و نفكك أسرارهآ :ضحكة:

ذات الخمار
18-06-2013, 20:37
جزاك الله خيرا ..
انا خلاص طبقت اللعبة بس من باب الاستفادة اريد معرفة التعديل على الكود
لكي اغير مكان البطاقات من اليسار لليمين او للوسط مثلا

Diamond mas
19-06-2013, 12:27
السَلامُ عَليكُم وَ رحمَة الله ..

ما شآء الله علِيك :أوو:

بالفِعل كآن من مُدّة بودِي أعرِف طرِيقة عَمل اللعبَة حَقتَك :سعادة2:

شُكرًا لَك عَلى الأكوآد :أوو:

بجربهآ إن شآء الله عمّا قرِيب ،،

و نفكك أسرارهآ :ضحكة:


وعليكم السلام ورحمة الله وبركاته

تسلمي أختي ^_^
إن شاء الله تستفيدي من الموضوع، وإذا احتجتِ أي مساعدة في تفكيك الكود فسأكون في الخدمة :لعق:


جزاك الله خيرا ..
انا خلاص طبقت اللعبة بس من باب الاستفادة اريد معرفة التعديل على الكود
لكي اغير مكان البطاقات من اليسار لليمين او للوسط مثلا
الله يبارك فيكِ أختي وشكراً لانضمامك لهذا الموضوع ^_^

من ملف الكود الرئيسي (SimpleGame.as) توجهي نحو السطرين 26 و 27 ستجدينهما كالتالي:



private const INIT_X:uint = 47;
private const INIT_Y:uint = 115;
INIT_X: هي القيمة الافتراضية لموقع الزاوية العليا لأول بطاقة من الأعلى على اليسار على المحور السيني (x)
INIT_Y: هي القيمة الافتراضية لموقع الزاوية العليا لأول بطاقة من الأعلى على اليسار على المحور الصادي (y)

غيري القيم 47 و 115 لتتناسب مع الموقع الذي تريدينه للبطاقات،
يقوم الكود بإنشاء أول بطاقة في الموقع الذي تحددينه في القيمة الافتراضية ثم ينشئ البطاقات التي بعدها عن يمينها حتى يكتمل السطر ثم ينتقل إلى السطر الجديد..
بإمكانك تغيير طريقة ترتيب البطاقات كما تريدين أيضاً.. إن أردت ذلك ولم تعرفي الطريقة فما عليكِ إلا السؤال ::جيد::

ذات الخمار
20-06-2013, 08:33
بإمكانك تغيير طريقة ترتيب البطاقات كما تريدين أيضاً.. إن أردت ذلك ولم تعرفي الطريقة فما عليكِ إلا السؤال ::جيد::

جزاك الله خيرا واثابك نجحت الطريقة بعد عدة محاولات لقلة الخبرة

المثال
واذا كان وضعه مخالف فيمكنكم حذفه

لا مانع اخي من معرفة ترتيب البطاقات من باب الاستفادة
شاكرة لك جهودك وتعبك اثابك الله وجزاك عنا خيرا

Diamond mas
20-06-2013, 09:49
جزاك الله خيرا واثابك نجحت الطريقة بعد عدة محاولات لقلة الخبرة

المثال
واذا كان وضعه مخالف فيمكنكم حذفه

لا مانع اخي من معرفة ترتيب البطاقات من باب الاستفادة
شاكرة لك جهودك وتعبك اثابك الله وجزاك عنا خيرا
وإياكم ^_^
كلنا نتعلم مع التجربة ::جيد::


لا بأس إذن ;)


السطر 23 يحدد المسافة الأفقية والعامودية بين البطاقات:

private const CARDS_SPACING:uint = 2;
المسافة الحالية هي 2 بكسل.

السطرين 24 و 25 يحددان طول وعرض البطاقات:

private const CARD_WIDTH:uint = 51;
private const CARD_HEIGHT:uint = 66;
العرض 51 والطول 66 بكسل.


نأتي لعدد البطاقات، يمكنك إضافة بطاقات جديدة إلى المكتبة وتسميتها img_7 و img_8 و img_9... وهكذا بنفس الطريقة التي قمنا بتسمية البطاقات التي قبلها img_1, img_2, ... img_6
(طبعاً، مع مراعاة الحفاظ على طول وعرض موحد للبطاقات)
بعد ذلك أضيفي السطر البرمجي المسؤول عن إضافة الصور من المكتبة إلى الكود كالتالي:

- توجهي إلى السطر 54 وأضيفي سطر جديد بعده واكتب فيه ما يلي:

this.l1_images.push(new img_6());
مع مراعات استبدال img_6 بـ اسم الصورة التي تريدين إضافتها وتكرار هذه الخطوة مع جميع الصور التي تضيفينها.

- بعد ذلك توجهي إلى السطر التالي (سيكون رقم السطر 71 إذا لم تضيفي أسطر قبله، بإمكانك البحث عن هذا السطر باستخدام خاصية البحث Ctrl + F)

this.nom_of_cards = 12; // total number of cards
قومي بتغيير الرقم 12 بعدد البطاقات * 2، أي أنه إذا كان لديكِ 9 بطاقات عليك تغيير القيمة إلى 18.

لتغيير عدد الصفوف والأعمدة في ترتيب البطاقات قومي بتغيير القيم التالية (الأسطر 73 و 74 في حال لم تقومي بالتغيير على الكود، استخدمي خاصية البحث) :

this.nom_of_rows = 3; // number of rows in the board
this.nom_of_cols = 4; // number of columns in the board
الرقم 3 هو عدد الأسطر لدينا والرقم 4 هو عدد الأعمدة،
بإمكانك تغيير هذه القيم مع ملاحظة واحدة وهي أن حاصل ضرب عدد الصفوف وعدد الأعمدة يجب أن يساوي عدد البطاقات الكلي،
فإذا كان العدد الكلي 12 يمكنك تغيير عدد الصفوف والأعمدة كالتالي:
- الصفوف: 4، الأعمدة: 3
- الصفوف: 6، الأعمدة: 2
- الصفوف: 2، الأعمدة: 6

أيضاً إذا قمتِ بتغيير عدد البطاقات عندها عليك تغيير عدد الصفوف والأعمدة بما يتناسب ;)

يمكنكِ إضافة مراحل للعبة أيضاً وتغيير طريقة التقييم، هذه تغييرات طفيفة ولا تحتاج لكثير من الجهد :d

.
.
بإمكانك طرح تطبيقاتك هنا كما تشائين وسأكون سعيداً برفعها مكان التطبيق السابق ^_^
فهل تودين رفع هذا التطبيق بدل السابق؟

ذات الخمار
21-06-2013, 02:31
بإمكانك طرح تطبيقاتك هنا كما تشائين وسأكون سعيداً برفعها مكان التطبيق السابق ^_^
فهل تودين رفع هذا التطبيق بدل السابق؟

جزاك الله خيرا واثابك على تواصل جهودك وشرحك الوافي

بالنسبة للمثال الذي وضعته فهو لا يختلف كثيرا عن التطبيق السابق
فكلاهما مجرد محاولات وتجارب سواء تم رفع هذا او بقاء ذاك الامر عادي عندي

وبالنسبة للشرح ان شاء الله اعمل تطبيق له بعد التدرب عليه

قد احتاج الى عدة ايام عشان افهم الدرس

شاكرة لك جهودك

Diamond mas
22-06-2013, 10:54
جزاك الله خيرا واثابك على تواصل جهودك وشرحك الوافي

بالنسبة للمثال الذي وضعته فهو لا يختلف كثيرا عن التطبيق السابق
فكلاهما مجرد محاولات وتجارب سواء تم رفع هذا او بقاء ذاك الامر عادي عندي

وبالنسبة للشرح ان شاء الله اعمل تطبيق له بعد التدرب عليه

قد احتاج الى عدة ايام عشان افهم الدرس

شاكرة لك جهودك
بارك الله فيكِ.. وإياكم

الأمر إليكِ، فالملف المرفوع هو لكِ ولكِ الحرية باستبداله ::جيد::
خذي وقتكِ، وإذا احتجت المزيد من التوضيح فأنا في الخدمة

ذات الخمار
24-06-2013, 22:55
اخوي انا سويت تصميم من 9 بطاقات

خليت الصفوف 3 والاعمدة 6

عشان يصير المجموع 18 وعدلت على كل الاسطر المطلوبة كما في شرحك

بس يعطيني هذا الخطأ عند المعاينة

ArgumentError: Error #2109: Frame label start not found in scene Scene 1.
at flash.display::MovieClip/gotoAndStop()
at SimpleGame/start_btn_event_handler()

ذات الخمار
25-06-2013, 01:23
خلاص اخوي صححت الخطأ
كنت غلطانة في اسم المشهد والحمدالله ضبط ونحجت الطريقة
جزاك الله خيرا على الشرح الوافي استفدت منه كثيرا

وهذا التصميم

Diamond mas
26-06-2013, 08:33
خلاص اخوي صححت الخطأ
كنت غلطانة في اسم المشهد والحمدالله ضبط ونحجت الطريقة
جزاك الله خيرا على الشرح الوافي استفدت منه كثيرا

وهذا التصميم
رائعة أختي، لعبتك مميزة ::جيد::

فزت باللعبة وأحرزت النتيجة التالية:
عدد الحركات: 19
مجموع النقاط: 850
:D

ألم يضايقكِ لون الوميض عند تطابق البطاقات؟
بإمكانك تغييره عن طريق الذهاب إلى الملف Card.as وتحديداً عند السطر 113 ستجدين كود التلوين:

this.blinkSprite.graphics.beginFill(0xaebe3e, 0.5);
لاحظي اللون 0xaebe3e
اتركي الـ 0x كما هي وغيري اللون aebe3e إلى اللون الذي ترغبينه

قمتُ برفعها ()

لا تترددي بالطلب إذا احتجتِ أي شيء ;)

ذات الخمار
26-06-2013, 18:07
لم اخذ بالي من اللون لكن هذا لايمنع من التجربة للفائدة
شاكرة لك مساعدتك وتجاوبك الدائم وحسن ملاحظتك
بارك الله فيك ،،

Diamond mas
28-06-2013, 03:31
^
أكيد :d

الله يسلمك أختي، وإياكم ^_^

hoss007
07-08-2013, 11:28
شكرا على الموضوع

الف شكر