Corona SDK: إنشاء لعبة تشبه لعبة Roll-like - Interaction
Arabic (العربية/عربي) translation by ansgaradh (you can also view the original English article)
هذا هو الجزء الثاني من برنامج تعليمي Corona SDK Rapid Roll الخاص بنا. في البرنامج التعليمي اليوم ، سنضيف واجهتنا ونبدأ بتشفير تفاعل اللعبة. واصل القراءة!
حيث توقفنا. . .
يرجى التأكد من الجزء الأول من المسلسل لفهم وإعداد هذا البرنامج التعليمي بشكل كامل.
الخطوة 1: إعلان الدالات
قم بتعريف كافة الوظائف المحلية في البداية.
local Main = {} local startButtonListeners = {} local showCredits = {} local hideCredits = {} local showGameView = {} local placeBet = {} local randomShellMove = {} local checkMovesLeft = {} local revealBall = {} local alert = {}
الخطوة 2: الانشاء
بعد ذلك ، سنقوم بإنشاء الدالة التي ستقوم بتهيئة منطق اللعبة بالكامل:
function Main() addTitleView() end
الخطوة 3: إضافة عنوان العرض
الآن نضع عنوان العرض في المرحلة ونستدعي دالة تضيف مستمعي النقر على الأزرار.
function addTitleView() bg = display.newImage('bg.png') title = display.newImage('titleBg.png') startB = display.newImage('startBtn.png') startB.x = display.contentCenterX startB.y = display.contentCenterY startB.name = 'startB' creditsB = display.newImage('creditsBtn.png') creditsB.x = display.contentCenterX creditsB.y = display.contentCenterY + 60 creditsB.name = 'creditsB' titleView = display.newGroup() titleView:insert(title) titleView:insert(startB) titleView:insert(creditsB) initialListeners('add') end
الخطوة 4: بداية مستمعو الازرار
تضيف هذه الوظيفة المستمعين الضروريين إلى أزرار TitleView .
function initialListeners(action) if(action == 'add') then startB:addEventListener('tap', gameView) creditsB:addEventListener('tap', showCredits) else startB:removeEventListener('tap', gameView) creditsB:removeEventListener('tap', showCredits) end end
الخطوة 5: إظهار الاعتمادات
تظهر شاشة الاعتمادات عندما ينقر المستخدم على زر الاعتمادات ، يتم إضافة وحدة إصغاء النقر إلى عرض الأرصدة لإزالته.
function showCredits() credits = display.newImage('creditsView.png') transition.from(credits, {time = 400, x = display.contentWidth * 2, transition = easing.outExpo}) credits:addEventListener('tap', hideCredits) startB.isVisible = false creditsB.isVisible = false end
الخطوة 6: إخفاء الاعتمادات
عندما يتم النقر على شاشة النقاط الرئيسية ، فسيتم استبعادها من المرحلة وإزالتها.
function hideCredits() startB.isVisible = true creditsB.isVisible = true transition.to(credits, {time = 600, x = display.contentWidth * 2, transition = easing.outExpo, onComplete = destroyCredits}) end function destroyCredits() credits:removeEventListener('tap', hideCredits) display.remove(credits) credits = nil end
الخطوة 7: إزالة عنوان العرض
عندما يتم النقر فوق الزر " ابدأ" ، يتم تضخيم عرض العنوان وإزالته عن طريقة عرض اللعبة.
function gameView() initialListeners('rmv') -- Remove MenuView, Start Game transition.to(titleView, {time = 500, y = -titleView.height, onComplete = function()display.remove(titleView) titleView = nil addInitialBlocks(3)end})
الخطوة 8: النتيجة والنصوص
ينشئ هذا الرمز نص النتيجة ويعيشها ويضعها في الجزء الرئيسي.
-- Score Text scoreTF = display.newText('0', 303, 22, system.nativeFont, 12) scoreTF:setTextColor(68, 68, 68) -- Lives Text livesTF = display.newText('x3', 289, 56, system.nativeFont, 12) livesTF:setTextColor(245, 249, 248) end
الخطوة 9: إضافة كتل أولية
تضيف الدالة التالية الكتل المحددة في المعلمة في موضع عشوائي ، كما ستقوم أيضًا باستدعاء الوظيفة لإضافة المشغل إلى الجزء الرئيسي.
function addInitialBlocks(n) blocks = display.newGroup() for i = 1, n do local block = display.newImage('block.png') block.x = math.floor(math.random() * (display.contentWidth - block.width)) block.y = (display.contentHeight * 0.5) + math.floor(math.random() * (display.contentHeight * 0.5)) physics.addBody(block, {density = 1, bounce = 0}) block.bodyType = 'static' blocks:insert(block) end addPlayer() end
الخطوة 10: إضافة لاعب
سيتم إضافة اللاعب عندما تكون الكتل الأولية في مرحلة. سوف يظهر في المركز X للمرحلة.
function addPlayer() player = display.newImage('player.png') player.x = (display.contentWidth * 0.5) player.y = player.height physics.addBody(player, {density = 1, friction = 0, bounce = 0}) player.isFixedRotation = true gameListeners('add') end
الخطوة 11: نقل المشغل
يستخدم مقياس التسارع لنقل المشغل عبر الشاشة ، ويتم حساب القيمة باستخدام خاصيةxGravity .
function movePlayer:accelerometer(e) -- Accelerometer Movement player.x = display.contentCenterX + (display.contentCenterX * (e.xGravity*3))
الخطوة 12: حدود الشاشة
يمنع هذا الرمز اللاعب من الذهاب إلى خارج الشاشة على الجانبين.
-- Borders if((player.x - player.width * 0.5) < 0) then player.x = player.width * 0.5 elseif((player.x + player.width * 0.5) > display.contentWidth) then player.x = display.contentWidth - player.width * 0.5 end end
الخطوة 13: إضافة "بلوك عادي"
يتم استدعاء هذه الوظيفة من قبل الموقت. سيقوم بحساب عدد عشوائي بين 1 و 4 وعندما تكون النتيجة تساوي 1 ، ستتم إضافة كتلة سيئة. إذا كانت النتيجة مختلفة عن 1 ، فسيتم إنشاء كتلة عادية. يتم إضافة الكتل إلى جدول ، وبهذه الطريقة يمكننا الوصول إليها خارج هذه الوظيفة.
function addBlock() local r = math.floor(math.random() * 4) if(r ~= 0) then local block = display.newImage('block.png') block.x = math.random() * (display.contentWidth - (block.width * 0.5)) block.y = display.contentHeight + block.height physics.addBody(block, {density = 1, bounce = 0}) block.bodyType = 'static' blocks:insert(block) else local badBlock = display.newImage('badBlock.png') badBlock.name = 'bad' physics.addBody(badBlock, {density = 1, bounce = 0}) badBlock.bodyType = 'static' badBlock.x = math.random() * (display.contentWidth - (badBlock.width * 0.5)) badBlock.y = display.contentHeight + badBlock.height blocks:insert(badBlock) end end
الخطوة 14: إضافة رسم حي
وظيفة توقيت أخرى ، سيتم إضافة رسم حي عندما يكتمل الموقت. سيكون الموقع المباشر هو آخر كتلة في الجدول - 1.
function addLive() live = display.newImage('live.png') live.name = 'live' live.x = blocks[blocks.numChildren - 1].x live.y = blocks[blocks.numChildren - 1].y - live.height physics.addBody(live, {density = 1, friction = 0, bounce = 0}) end
الخطوة 15: مستمعي اللعبة
تعمل هذه الوظيفة على إضافة المستمعين الضروريين وإزالتهم لبدء اللعبة.
function gameListeners(action) if(action == 'add') then Runtime:addEventListener('accelerometer', movePlayer) Runtime:addEventListener('enterFrame', update) blockTimer = timer.performWithDelay(800, addBlock, 0) liveTimer = timer.performWithDelay(8000, addLive, 0) player:addEventListener('collision', collisionHandler) else Runtime:removeEventListener('accelerometer', movePlayer) Runtime:removeEventListener('enterFrame', update) timer.cancel(blockTimer) timer.cancel(liveTimer) blockTimer = nil liveTimer = nil player:removeEventListener('collision', collisionHandler) end end
الخطوة 16: مراجعة الشفرة
إليك الشفرة الكاملة المكتوبة في هذا البرنامج التعليمي جنبًا إلى جنب مع التعليقات لمساعدتك في تحديد كل جزء:
-- Blocks 'Rapid Roll' like Game -- Developed by Carlos Yanez -- Hide Status Bar display.setStatusBar(display.HiddenStatusBar) -- Physics local physics = require('physics') physics.start() physics.setGravity(0, 0) -- Graphics -- [Background] local bg -- [Title View] local title local startB local creditsB -- [TitleView Group] local titleView -- [CreditsView] local credits -- [Score & Lives] local live local livesTF local lives = 3 local scoreTF local score = 0 local alertScore -- [Blocks group, Player] local blocks local player --[GameView Group] local gameView -- Variables local moveSpeed = 2 local blockTimer local liveTimer -- Functions local Main = {} local addTitleView = {} local initialListeners = {} local showCredits = {} local hideCredits = {} local destroyCredits = {} local gameView = {} local addInitialBlocks = {} local addPlayer = {} local movePlayer = {} local addBlock = {} local addLive = {} local gameListeners = {} local update = {} local collisionHandler = {} local showAlert = {} function Main() addTitleView() end function addTitleView() bg = display.newImage('bg.png') title = display.newImage('titleBg.png') startB = display.newImage('startBtn.png') startB.x = display.contentCenterX startB.y = display.contentCenterY startB.name = 'startB' creditsB = display.newImage('creditsBtn.png') creditsB.x = display.contentCenterX creditsB.y = display.contentCenterY + 60 creditsB.name = 'creditsB' titleView = display.newGroup() titleView:insert(title) titleView:insert(startB) titleView:insert(creditsB) initialListeners('add') end function initialListeners(action) if(action == 'add') then startB:addEventListener('tap', gameView) creditsB:addEventListener('tap', showCredits) else startB:removeEventListener('tap', gameView) creditsB:removeEventListener('tap', showCredits) end end function showCredits() credits = display.newImage('creditsView.png') transition.from(credits, {time = 400, x = display.contentWidth * 2, transition = easing.outExpo}) credits:addEventListener('tap', hideCredits) startB.isVisible = false creditsB.isVisible = false end function hideCredits() startB.isVisible = true creditsB.isVisible = true transition.to(credits, {time = 600, x = display.contentWidth * 2, transition = easing.outExpo, onComplete = destroyCredits}) end function destroyCredits() credits:removeEventListener('tap', hideCredits) display.remove(credits) credits = nil end function gameView() initialListeners('rmv') -- Remove MenuView, Start Game transition.to(titleView, {time = 500, y = -titleView.height, onComplete = function()display.remove(titleView) titleView = nil addInitialBlocks(3)end}) -- Score Text scoreTF = display.newText('0', 303, 22, system.nativeFont, 12) scoreTF:setTextColor(68, 68, 68) -- Lives Text livesTF = display.newText('x3', 289, 56, system.nativeFont, 12) livesTF:setTextColor(245, 249, 248) end function addInitialBlocks(n) blocks = display.newGroup() for i = 1, n do local block = display.newImage('block.png') block.x = math.floor(math.random() * (display.contentWidth - block.width)) block.y = (display.contentHeight * 0.5) + math.floor(math.random() * (display.contentHeight * 0.5)) physics.addBody(block, {density = 1, bounce = 0}) block.bodyType = 'static' blocks:insert(block) end addPlayer() end function addPlayer() player = display.newImage('player.png') player.x = (display.contentWidth * 0.5) player.y = player.height physics.addBody(player, {density = 1, friction = 0, bounce = 0}) player.isFixedRotation = true gameListeners('add') end function movePlayer:accelerometer(e) -- Accelerometer Movement player.x = display.contentCenterX + (display.contentCenterX * (e.xGravity*3)) -- Borders if((player.x - player.width * 0.5) < 0) then player.x = player.width * 0.5 elseif((player.x + player.width * 0.5) > display.contentWidth) then player.x = display.contentWidth - player.width * 0.5 end end function addBlock() local r = math.floor(math.random() * 4) if(r ~= 0) then local block = display.newImage('block.png') block.x = math.random() * (display.contentWidth - (block.width * 0.5)) block.y = display.contentHeight + block.height physics.addBody(block, {density = 1, bounce = 0}) block.bodyType = 'static' blocks:insert(block) else local badBlock = display.newImage('badBlock.png') badBlock.name = 'bad' physics.addBody(badBlock, {density = 1, bounce = 0}) badBlock.bodyType = 'static' badBlock.x = math.random() * (display.contentWidth - (badBlock.width * 0.5)) badBlock.y = display.contentHeight + badBlock.height blocks:insert(badBlock) end end function addLive() live = display.newImage('live.png') live.name = 'live' live.x = blocks[blocks.numChildren - 1].x live.y = blocks[blocks.numChildren - 1].y - live.height physics.addBody(live, {density = 1, friction = 0, bounce = 0}) end function gameListeners(action) if(action == 'add') then Runtime:addEventListener('accelerometer', movePlayer) Runtime:addEventListener('enterFrame', update) blockTimer = timer.performWithDelay(800, addBlock, 0) liveTimer = timer.performWithDelay(8000, addLive, 0) player:addEventListener('collision', collisionHandler) else Runtime:removeEventListener('accelerometer', movePlayer) Runtime:removeEventListener('enterFrame', update) timer.cancel(blockTimer) timer.cancel(liveTimer) blockTimer = nil liveTimer = nil player:removeEventListener('collision', collisionHandler) end end
في المرة القادمة...
في الجزء التالي والأخير من السلسلة ، سنعالج المجموعات وحركة اللاعبين ، والتصادمات ، والخطوات النهائية التي يجب اتخاذها قبل إصدار اختبار التطبيق ، وإنشاء شاشة بدء ، وإضافة رمز ، وأخيرًا ، تصميم التطبيق . ترقبوا الجزء الأخير!