Hướng dẫn tạo một game "Đập chuột" từ A đến Z trong Corona SDK.

Thảo luận trong 'Tutorials và Thủ thuật lập trình' bắt đầu bởi Khúc Vương, 16/7/14.

  1. Administrator
    Khúc Vương
    Nhân viên CoronaViet
    Tham gia ngày:
    17/1/14
    Bài viết:
    477
    Đã được thích:
    130
    Trong bài này chúng ta sẽ cùng nhau tạo ra một trò chơi “Đập chuột” có tên là Whack-a-Groundhog. Mục tiêu của trò chơi là đập vào những chú chuột trước khi chúng biến mất. Bắt đầu nào :D

    1. Intro game
    Màn hình giới thiệu sẽ cho phép người dùng thiết lập trong Options hoặc Start để chơi trò chơi.
    [​IMG]

    2. Options screen
    Màn hình Options này sẽ cho phép người chơi on/off âm nhạc và lựa chọn tốc độ xuất hiện các chú chuột.
    [​IMG]

    3. Game screen
    Màn hình game là nơi mà tất cả các hoạt động diễn ra. Các chú chuột sẽ chui lên ngẫu nhiên từ những cái hang, và người chơi cố gắng "Đập" chúng trước khi chúng thụt xuống. Người chơi cũng có thể vào được vào màn hình Options từ đây.
    [​IMG]

    4. New Project
    Mở Corona Simulator và chọn "New Project".
    [​IMG]

    Trên màn hình tiếp theo, chọn các thiết lập sau:
    [​IMG]

    Nhấn nút "Next", mở "Main.lua" trong trình soạn thảo yêu thích của bạn. Bất kỳ trình soạn thảo văn bản đơn giản nào cũng cho phép bạn viết code trên đó, nhưng mình khuyến khích sử dụng một trình soạn thảo văn bản có thể làm nổi bật các cú pháp trong code như IntelliJ IDEA Community Edition mà Corona Việt đã đề cập tới trong các bài viết trước.

    5. Project Configuration
    Trước hết chúng ta cần cấu hình cho project. Mở "Config.lua" và xóa tất cả mọi thứ. Cập nhật lại các code như sau:
    Mã (Lua):
    application = {
      content = {
        width = 320,
        height = 480,
        scale = "letterBox",
        fps = 30,
      }
    }
    6. Ẩn thanh trạng thái
    Trở lại với "Main.lua". Ta sẽ bắt đầu làm việc với nó. Chúng ta không muốn thanh trạng thái hiển thị trong game, vì vậy trong "Main.lua" ta thêm code sau:
    Mã (Lua):
    display.setStatusBar(display.HiddenStatusBar);
    7. Biến Local
    Đây là tất cả các biến chúng ta sẽ sử dụng trong trò chơi này. Đọc các ghi chú để hiểu thêm.
    Mã (Lua):
    local allGroundHogs = {} -- Bảng để chứa tất cả các chú chuột
    local groundHogXPositions = {240,410,280,145,429,80,208,366}
    local groundHogYPositions = {259,259,209,184,166,118,91,99}
    local gameScreenGroup -- group lưu giữ game screen
    local introScreenGroup -- group lưu giữ intro screen
    local optionsScreenGroup -- group lưu giữ options screen
    local isPlaying = false -- xem người chơi đã bắt đầu trò chơi hay chưa
    local groundHogTimer -- timer dùng để xuất hiện ngẫu nhiên các chú chuột
    local groundHogSpeed = 1500
    8. SetUpIntroScreen()
    Hàm setUpIntroScreen() được sử dụng để thiết lập màn hình đầu tiên hiển thị cho người chơi.
    Mã (Lua):
    function setUpIntroScreen()
    end
    9. SetUpOptionsScreen()
    Hàm setUpOptionsScreen() sẽ lo phần thiết lập màn hình Options.
    Mã (Lua):
    function setUpOptionsScreen()
    end
    10. SetUpGameScreen()
    Hàm setUpGameScreen() sẽ thiết lập màn hình game.
    Mã (Lua):
    function setUpGameScreen()
    end
    11. GetRandomGroundHog()
    Hàm getRandomGroundHog() sẽ chọn một chú chuột xuất hiện ngẫu nhiên một trong số các hang.
    Mã (Lua):
    function getRandomGroundHog()
    end
    12. GroundHogSpriteListener()
    Hàm này được sử dụng để cho biết khi nào hình ảnh animation của chú chuột đã kết thúc.
    Mã (Lua):
    function groundHogSpriteListener( event )
    end
    13. GroundHogHit()
    Hàm groundHogHit(e) sẽ cho biết khi nào người chơi đã “đập” vào một chú chuột.
    Mã (Lua):
    function groundHogHit(e)
    end
    14. SoundComplete()
    Khi nhạc kết thúc chúng ta sử dụng hàm này để bắt đầu play nó thêm một lần nữa.
    Mã (Lua):
    function soundComplete()
    end
    15. Thiết lập Game Background
    Trong bước này chúng ta sẽ bắt đầu thiết lập màn hình trò chơi. Nhập đoạn code sau vào trong hàm setUpGameScreen() mà bạn đã nhập trong các bước trên.
    Mã (Lua):
    gameScreenGroup = display.newGroup()
        local gameBackground = display.newImage("background.png", true);
        gameScreenGroup:insert(gameBackground)
    Ở dưới cùng của "Main.lua", nhập code sau:
    Mã (Lua):
    setUpGameScreen()
    16. Thiết lập các Image Sheet
    Các animation của chú chuột được tạo bằng một sprite sheet. Nhập code sau ở bên dưới dòng gameScreenGroup:insert(gameBackground) mà bạn đã nhập trong bước trên.
    Mã (Lua):
    local options = {width = 142, height = 91, numFrames = 7}
    local imageSheet = graphics.newImageSheet("groundhogsheet.png",options)
    Các biến options là một bảng chứa các tùy chọn của image sheet. Widthheight là chiều rộng và chiều cao của hình ảnh trong "groundhogsheet.png", và numFrames là số lượng hình ảnh animation của các chú chuột trong image sheet (tính thêm một ảnh trong suốt nữa là 7 nhé - công dụng của nó sẽ biết ngay sau đây :) )
    [​IMG]
    17. Sequence Data
    Chúng ta đã thiết lập imageSheet, bây giờ chúng ta thiết lập cho animations. Các dữ liệu hình ảnh animations (trình tự ảnh) được lưu giữ trong một biến sequenceData. Thêm code này vào dưới đoạn code phía trên.
    Mã (Lua):
    local sequenceData = {
        {name="show", start=2 , count = 3,time=1000,loopCount=0,loopDirection="bounce"}
    }
    Ở đây chúng ta đặt name cho trình tự là "show", và start là "frame" của imageSheet để bắt đầu từ đó và count là số lượng frame trong trình tự (nhìn lên trên nào, chúng ta có 7 frame nhưng frame đầu là hình ảnh trong suốt nên chúng ta sẽ bắt đầu bằng frame thứ 2 và kéo dài tới frame thứ 4 vì thế count của cúng ta là 3). Các loopCount là số lần bạn muốn trình tự này lập lại. 0 có nghĩa là mãi mãi, và loopDirection là cách các trình tự sẽ play.

    18. Groundhog Sprites
    Với các thiết lập imageSheetsequenceData, chúng ta có thể hiển thị các chú chuột và làm cho chúng cử động. Nhập đoạn code sau vào bên dưới sequenceData mà bạn đã nhập trong bước trên.
    Mã (Lua):
    local tempGroundHog
        for i=1, #groundHogXPositions do
            tempGroundHog = display.newSprite(imageSheet,sequenceData)
            tempGroundHog.x = groundHogXPositions[i]
            tempGroundHog.y = groundHogYPositions[i]
            tempGroundHog:setSequence("show")
            gameScreenGroup:insert(tempGroundHog)
            table.insert(allGroundHogs,tempGroundHog)
            tempGroundHog:play()
        end
    Mỗi vòng lặp chúng ta tạo ra một tempGroundHog Sprite mới, thiết lập một vị trí x và y cho nó, thiết lập trình tự là "show", chèn nó vàogameScreenGroup, và sau đó chèn nó vào bảng allGroundHogs.

    19. SetupGameScreen()
    Bây giờ, các chú chuột sẽ cử động liên tục nhưng chúng cũng không chui xuống các hang. Chúng ta cần thêm một số keys nữa để sequenceData của chúng ta sửa lỗi này. Thêm dòng sau vào trong hàm setupGameScreen():
    Mã (Lua):
    local sequenceData = {
        {name="show", start=2 , count = 3,time=800,loopCount=1,loopDirection="bounce"},
        {name = "blank",start=1,count=1},
        {name = "hit1",start=5,count=1},
        {name = "hit2", start=6,count=1},
        {name = "hit3", start=7,count=1}
    }
    Trình tự "blank" là một hình ảnh trong suốt trống và là một phần trong sprite sheet, và "hit1", "hit2", và "hit3" là trình tự của 3 trạng thái khác nhau của các chú chuột khi bị "đập". Nhìn vào hình ảnh "groundhogsheet.png" để thấy điều này. Hãy chắc chắn rằng bạn thiết lập loopCount là 1 vào trình tự "show" (vì lúc nãy mình muốn các bạn test sẽ thấy chúng cử động liên tục, nhưng bây giờ thì chỉ cần cử động 1 lần thôi :) ).

    Bây giờ ta cần thay đổi code một chút như sau:
    xóa
    Mã (Lua):
    tempGroundHog:setSequence("show")
    va thay bằng
    Mã (Lua):
    tempGroundHog:setSequence("blank")
            tempGroundHog:addEventListener('tap', groundHogHit);
    Ở đây chúng ta đã thiết lập trình tự là "blank" và add thêm một tap listener vào groundhog sprite. Tiếp theo, ta cần xóa dòng mã này:
    Mã (Lua):
    tempGroundHog:play()
    20. GroundHogHit()
    Khi một chú chuột bị tap, chúng ta sẽ xác định nó đã được chui ra khỏi hang hay chưa. Nếu như là có, chúng ta sẽ thay đổi trình tự cho một trong ba trạng thái “hit” mà chúng ta đã thêm ở bước trước. Thêm dòng sau vào bên trong hàm groundHogHit():
    Mã (Lua):
    local thisSprite = e.target
    thisSprite:removeEventListener( "sprite", groundHogSpriteListener )
        local function hide()
            thisSprite:setSequence("blank")
        end
        if(thisSprite.sequence == "show") then
            local randomIndex = math.random(3)
        thisSprite:setSequence("hit"..randomIndex)
        timer.performWithDelay(1000, hide)
        end
    Ở đây chúng ta tham chiếu đến Sprite đã được nhấp thành e.target và loại bỏ event Listener của nó. Sau đó chúng ta kiểm tra nếu trình tự của nó bằng "show". Nếu đúng như thế, chúng ta tạo ra một con số từ 1 đến 3 và thiết lập trình tự của nó tương ứng với "hit" .. randomIndex. Tất cả điều này là tạo ra các chuỗi "hit1", "hit2", hoặc "hit3". Cuối cùng, chúng ta gọi hàm ẩn sau 1000 mili giây để thiết lập các chuỗi Sprites đến frame "blank".

    21. GetRandomGroundHog()
    Hàm getRandomGroundHog() sẽ tạo ra một chú chuột ngẫu nhiên và cho phép nó bắt đầu cử động. Nhập code sau vào bên trong hàm getRandomGroundHog():
    Mã (Lua):
    local randomIndex = math.random(#allGroundHogs)

        local randomGroundHog = allGroundHogs[randomIndex]
        if(randomGroundHog.sequence ~="blank") then
            getRandomGroundHog()
        else
            randomGroundHog:addEventListener( "sprite",groundHogSpriteListener )
        randomGroundHog:setSequence("show")
        randomGroundHog:play()
        end
    Ở đây chúng ta nhận được một randomIndex từ bảng allGroundHogs. Tiếp theo, chúng ta thiết lập randomGroundHog tương ứng với index. Sau đó chúng ta kiểm tra, nếu trình tự của nó có bằng "blank" chúng ta gọi getRandomGroundHog() một lần nữa. Ngược lại, chúng ta thêm groundHogSpriteListener để thiết lập trình tự của nó là "show" và phát theo thứ tự.

    22. GroundHogSpriteListener()
    Các groundHogSpriteListener() sẽ kiểm tra trình tự "show" đã hoàn thành hay chưa. Nếu đúng như vậy, nó sẽ tự thiết lập trình tự của mình thành "blank" (sẽ trống rỗng giống như con chuột đã chui xuống hang). Nhập sau trong groundHogSpriteListener():
    Mã (Lua):
    local thisSprite = event.target --"event.target" references the sprite

        if ( event.phase == "ended" ) then
            if(thisSprite.sequence == "show") then
                thisSprite:setSequence("blank")
            end -- a half second delay
        end
    23. Animating ngẫu nhiên groundhogs
    Với tất cả các code trên, ở các vị trí chúng ta có được chú chuột ngẫu nhiên và có hiệu ứng cử động. Thêm dòng sau vào dưới cùng của hàmsetUpGameScreen ():
    Mã (Lua):
    groundHogTimer = timer.performWithDelay(groundHogSpeed, getRandomGroundHog,0)
    Nếu bạn test bạn sẽ thấy các chú chuột sẽ xuất ngẫu nhiên ra khỏi hang. Tiện tay, hãy thử “đập” vào chúng, bạn sẽ thấy một trong 3 trạng thái bị đập, và sau đó thì…trống rổng :p
    Sau khi test xong, hãy............xóa đoạn code này đi :p vì chúng ta chỉ cần nó để test thui :D

    24. SetUpIntroScreen()
    Trong bước này chúng ta sẽ bắt đầu thiết lập màn hình Intro. Nhập code sau đây vào bên trong hàm setUpIntroScreen():
    Mã (Lua):
    media.playSound("gameTrack.mp3",soundComplete)
    introScreenGroup = display.newGroup()
    local titleScreen = display.newImage("titleScreen.png")
    local playButton = display.newImage("playButton.png",100,100)
    local optionsButton = display.newImage("optionsButton.png",100,170)
    introScreenGroup:insert(titleScreen)
    introScreenGroup:insert(playButton)
    introScreenGroup:insert(optionsButton)
    Ở đây chúng ta khởi động nhạc nền, thiết lập màn hình Intro , và thêm đồ họa cho playButton và optionsButton.

    Bây giờ gọi hàm setUpIntroScreen() bên dưới nơi bạn đã gọi hàm setUpGameScreen()
    Mã (Lua):
    setUpGameScreen()
    setUpIntroScreen()
    Nếu bạn kiểm tra bạn sẽ thấy màn hình Intro . Chúng ta cần thêm event listener cho các nút và đó là những gì chúng ta sẽ làm trong các bước tiếp theo.

    25. Play Button Listener
    Nhập code sau vào bên dưới code bạn đã nhập trong bước trên:
    Mã (Lua):
    playButton:addEventListener("tap",function ()
        transition.to(introScreenGroup, {time = 300, x = -480, onComplete = function()
            groundHogTimer = timer.performWithDelay(groundHogSpeed, getRandomGroundHog,0)
        end
        })
        isPlaying = true
    end
    )
    Khi nút play được tap vào, chúng ta animate màn hình Intro ra bên trái, thiết lập groundHogTimer để tạo ra các chú chuột ngẫu nhiên, và sau đó thiết lập các biến isPlayingtrue.

    26. Options Button Listener
    Nhập code sau bên dưới code bạn đã nhập trong bước trên.
    Mã (Lua):
    optionsButton:addEventListener("tap", function()
        transition.to(optionsScreenGroup, {time = 300, y = 0, onComplete = function()
            introScreenGroup. x = -480
        end
        })
    end
    )
    Code này sẽ animates màn hình Options từ trên xuống dưới. Khi hoàn tất, nó sẽ đưa introScreenGroup ra màn hình chính từ bên trái.

    27. SetUpOptionsScreen()
    Nhập code sau vào bên trong hàm setUpOptionsScreen():
    Mã (Lua):
    optionsScreenGroup = display.newGroup()
        local optionsScreen = display.newImage("optionsScreen.png")
        local backButton = display.newImage("backButton.png",130,240)
        local soundOnText = display.newText( "Sound On/Off", 75,105, native.systemFontBold, 16 )
        local groundHogSpeedText = display.newText("Speed", 75,145,native.systemFontBold,16)
        optionsScreenGroup:insert(optionsScreen)
        optionsScreenGroup:insert(backButton)
        optionsScreenGroup:insert(soundOnText)
        optionsScreenGroup:insert(groundHogSpeedText)
        optionsScreenGroup.y = -325
    Ở đây chúng ta thiết lập các optionsScreen, thêm backButton, và thêm một vài text.

    Bây giờ gọi hàm này bên dưới nơi bạn đang gọi setUpIntroScreen:
    Mã (Lua):
    setUpIntroScreen()
    setUpOptionsScreen()
    28. SoundCheckBox
    Chúng ta sẽ sử dụng các checkbox widget để cho phép người dùng on/off âm thanh. Để có thể sử dụng các Switch và các widget khác đầu tiên chúng ta phải require "widget" module. Nhập code sau vào trên cùng của tập tin "main.lua".
    Mã (Lua):
    local widget = require( "widget" )
    Bây giờ nhập code sau bên dưới các đoạn code bạn đã nhập trong setUpOptionsScreen().
    Mã (Lua):
    local soundCheckBox = widget.newSwitch
    {
      left = 210,
      top = 98,
      style = "checkbox",
      initialSwitchState = true,
      onPress = function(e)
        local check = e.target
        if(check.isOn) then
            media.playSound("gameTrack.mp3",soundComplete)
        else
          media.stopSound()
        end
      end
    }
    optionsScreenGroup:insert(soundCheckBox)
    Điều này sẽ thiết lập checkbox Widget của chúng ta bằng cách thiết lập "style" là "checkbox". Chúng ta kiểm tra xem checkbox isOn có được chọn chưa?, và được chọn chúng ta play âm thanh "gameTrack.mp3". Nếu không, chúng ta stop âm thanh.

    Nếu bây giờ bạn kiểm tra và vào màn hình Options, bạn sẽ có thể bật/tất âm thanh.

    29. SpeedControl
    Chúng ta sử dụng một SegmentedControl để cho phép người chơi lựa chọn tốc độ xuất hiện của các chú chuột. Thêm code này vào dưới code checkbox bạn đã nhập trong bước trên:
    Mã (Lua):
    local speedControl = widget.newSegmentedControl
    {
      left = 210,
      top = 140,
      segments = { "slow", "medium", "fast"},
      segmentWidth = 50,
      defaultSegment = 1,
      onPress = function(event)
        local target = event.target
            if(target.segmentNumber == 1)then
                groundHogSpeed = 1500
            elseif (target.segmentNumber == 2)then
                groundHogSpeed = 1000
            else
                groundHogSpeed = 700
            end
      end
    }
    optionsScreenGroup:insert(speedControl)
    Ở đây chúng ta tạo ra một SegmentedControl với 3 đoạn ("slow","medium","fast"). Tùy thuộc vào người dùng đã nhấn vào đoạn nào chúng ta sẽ đặt biến groundHogSpeed cho phù hợp.

    Nếu bây giờ bạn kiểm tra bạn sẽ thấy SegmentedControl và có thể lựa chọn tốc độ , nhưng chúng ta cần phải tạo ra nút back để trở về màn hình Intro.

    30. BackButton
    Các backButton sẽ đưa chúng ta trở lại màn hình Intro. Nhập code sau đây vào bên dưới các code bước ở trên:
    Mã (Lua):
    backButton:addEventListener("tap", function()
        if(isPlaying == false)then
            introScreenGroup.x = 0
        end
        transition.to(optionsScreenGroup, {time = 300, y = -325, onComplete = function()
            if(isPlaying == true) then
            groundHogTimer =  timer.performWithDelay(groundHogSpeed, getRandomGroundHog,0)
          end
        end
        })
    end
    )
    Ở đây chúng ta kiểm tra xem trò chơi đã bắt đầu chưa vì chúng ta cũng có một nút Options trong gameplay. Nếu chưa, chúng ta đặt các introScreenGroup quay trở lại màn hình và transition màn hình Options ra ngoài. Nếu game đấu bắt đầu rồi, chúng ta thiết lập groundHogtimer tạo ra các chú chuột ngẫu nhiên để tiếp tục trò chơi.

    31. setUpGameScreen () – Thêm Options
    Chúng ta cần thêm các màn hình Options vào màn hình trò chơi chính. Thêm dòng sau vào dưới nơi bạn đã chèn các gameBackground trong gameScreenGroup().
    Mã (Lua):
    gameScreenGroup:insert(gameBackground)
    local optionsButton = display.newImage("optionsButton.png",1,270)
    gameScreenGroup:insert(optionsButton)
    Bây giờ chúng ta cần phải thêm một EventListener vào nút Options. Để làm như vậy, nhập code này dưới vòng lặp tạo ra tất cả các chú chuột (dưới cùng của function setUpGameScreen() đấy :D ).
    Mã (Lua):
    optionsButton:addEventListener("tap", function(e)
        timer.cancel(groundHogTimer)
        transition.to(optionsScreenGroup, {time = 300, y = 0, onComplete = function()
        end
        })
    end
    )
    Ở đây chúng ta cancel groundHogTimer và transition màn hình Options của chúng ta đi xuống.

    Bây giờ test xem, bạn sẽ có thể thấy được tùy chọn màn hình Options từ trong màn hình gameplay. Bạn cũng có thể thiết lập lại các tùy chọn nếu muốn.

    32. SoundComplete()
    Nếu bạn để ý bạn sẽ thấy nhạc nền đã tắt từ lâu vì nó không lập lại. Nhập code sau vào trong hàm soundComplete().
    Mã (Lua):
    media.playSound( "gameTrack.mp3", soundComplete )
    Điều này sẽ bắt đầu play soundtrack một lần nữa một khi nó play xong.

    Phù!!! Thế là chúng ta đã hoàn thành một game giải trí "đơn giản" rồi, hãy tạo thêm điểm số, những bổ sung mới mẽ khác để làm game hấp dẫn hơn. Chúc các bạn thành công.
    Last edited by a moderator: 17/7/14
  2. Member
    Bích Lệ
    Tham gia ngày:
    27/4/14
    Bài viết:
    64
    Đã được thích:
    5
    ad ơi cho e hỏi: sao phải cần 3 hit vậy, sao kg làm 1 hit cuối cùng là đủ, như vậy nếu tính điểm thì sao
  3. Administrator
    linhle
    Nhân viên CoronaViet
    Tham gia ngày:
    8/2/14
    Bài viết:
    183
    Đã được thích:
    130
    cái hit này là ngẫu nhiên đó bạn, có 3 trạng thái là để cho người chơi không nhàm chán thôi ak.
    Bích Lệ thích bài này.
  4. Member
    Bích Lệ
    Tham gia ngày:
    27/4/14
    Bài viết:
    64
    Đã được thích:
    5
    thank! a
  5. New Member
    windcloud
    Tham gia ngày:
    25/7/14
    Bài viết:
    2
    Đã được thích:
    0
    Bạn có thể share luôn sourcecode của game này không vây?
  6. Administrator
    admin
    Nhân viên CoronaViet
    Tham gia ngày:
    16/1/14
    Bài viết:
    298
    Đã được thích:
    99
    windcloud thích bài này.
  7. New Member
    windcloud
    Tham gia ngày:
    25/7/14
    Bài viết:
    2
    Đã được thích:
    0
    Thanks admin!
  8. New Member
    VanHo
    Tham gia ngày:
    17/10/14
    Bài viết:
    2
    Đã được thích:
    1
    Ad cho minh hỏi . mình làm y chang hương dẫn của Ad mà sao nó ra thế này nè. Sửa làm sao Ad
    Mình cũng mới tập làm theo thôi
    [​IMG]
  9. Administrator
    Khúc Vương
    Nhân viên CoronaViet
    Tham gia ngày:
    17/1/14
    Bài viết:
    477
    Đã được thích:
    130
    Chào bạn nếu bạn đang dung phiên bản tư 2013.2076 trở lên thì file config.lua của bạn cần phải như thế này để chạy được game:
    Mã (Lua):
    application =
    {
      content =
      {
          graphicsCompatibility = 1,  --bật V1 Compatibility mode
          width = 320,
          height = 480,
          scale = "letterbox"
      },
    }
     
  10. New Member
    VanHo
    Tham gia ngày:
    17/10/14
    Bài viết:
    2
    Đã được thích:
    1
    Thank bạn
    Khúc Vương thích bài này.
  11. New Member
    KieuOanh
    Tham gia ngày:
    10/4/15
    Bài viết:
    2
    Đã được thích:
    0
    mình đã thử như này nhưng mà mà hình vẫn không tự quay thì cài đặt ntn ak?
  12. Administrator
    Khúc Vương
    Nhân viên CoronaViet
    Tham gia ngày:
    17/1/14
    Bài viết:
    477
    Đã được thích:
    130
    bạn đã xoay ngang màn hình giả lập của corona chưa?
  13. New Member
    Thoại Nguyễn
    Tham gia ngày:
    15/2/17
    Bài viết:
    1
    Đã được thích:
    0
    sao không có tính điểm hay là số mạng được chơi với lại quay lại màng hình chính như thế nào vậy ad?
  14. New Member
    lhthe
    Tham gia ngày:
    6/10/16
    Bài viết:
    1
    Đã được thích:
    0
    Hình như phải thoát game chứ ko quay lại được bạn ạ
  15. Administrator
    Khúc Vương
    Nhân viên CoronaViet
    Tham gia ngày:
    17/1/14
    Bài viết:
    477
    Đã được thích:
    130
    Các bài viết làm game a-z chủ yếu hướng dẫn chúng ta cách thực hiện gameplay thôi, các phần chơi lại, lưu điểm số, nhiều level nó khá giống nhau và nằm ở một chủ đề khác.

Chia sẻ trang này