Hướng dẫn tạo Module lưu điểm trong game

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

  1. Administrator
    Khúc Vương
    Nhân viên CoronaViet
    Tham gia ngày:
    17/1/14
    Bài viết:
    492
    Đã được thích:
    130
    [​IMG]
    Một câu hỏi thường xuyên được hỏi trong các diễn đàn, đặc biệt là từ các dev mới là"Làm thế nào để lưu điểm trong game?". Hôm nay mình sẽ hướng dẫn các bạn về việc này qua 3 bước:

    1. Thiết lập một biến để lưu điểm.

    2. Hiển thị điểm.

    3. Save số điểm để có thể dùng sau này.

    Score Module
    Corona không xây dựng cho bạn 1 score module, vì vậy bạn hãy tự tạo cho app của bạn, bắt đầu với một hàm "khởi tạo" cơ bản:
    Mã (Lua):
    local M = {}  --create the local module table (this will hold our functions and data)

    M.score = 0  --set the initial score to 0
    function M.init( options )
      local customOptions = options or {}
      local opt = {}
      opt.fontSize = customOptions.fontSize or 24
      opt.font = customOptions.font or native.systemFontBold
      opt.x = customOptions.x or display.contentCenterX
      opt.y = customOptions.y or opt.fontSize*0.5
      opt.maxDigits = customOptions.maxDigits or 6
      opt.leadingZeros = customOptions.leadingZeros or false
      M.filename = customOptions.filename or "scorefile.txt"
      local prefix = ""
      if ( opt.leadingZeros ) then
          prefix = "0"
      end
      M.format = "%" .. prefix .. opt.maxDigits .. "d"
      M.scoreText = display.newText( string.format(M.format, 0), opt.x, opt.y, opt.font, opt.fontSize )
      return M.scoreText
    end
    Như bạn thấy, các tùy chọn hỗ trợ là:

    · fontSize — Kích thước của văn bản hiển thị điểm.

    · font — Phông chữ.

    · x — vị trí x để hiển thị bảng điểm.

    · y — vị trí y để hiển thị bảng điểm.

    · maxDigits — Có bao nhiêu số trong điểm số.

    · leadingZeros true hoặc false: bạn có muốn để số 0 phía trước điểm số?

    · filename — tên file save.

    Hầu hết các biến ở đây khá đơn giản, nhưng chúng ta có thể mở rộng để có các đặc tính liên kết và các thiết lập khác.Ví dụ, chúng ta có thể thêm các tùy chọn để kiểm soát các điểm neo bên trái hoặc phải bảng điểm.

    Mặc định sẽ là:
    font size=24
    font=Helvetica

    maxDigits=6
    filename=scorefile.txt



    Thiết lập
    Chúng ta hãy viết một hàm để setting, getting, và adding điểm số:

    Mã (Lua):
    function M.set( value )

      M.score = value
      M.scoreText.text = string.format( M.format, M.score )
    end
    function M.get()
      return M.score
    end
    function M.add( amount )
      M.score = M.score + amount
      M.scoreText.text = string.format( M.format, M.score )
    end


    Saving and Loading điểm số
    Phần cuối cùng trong module của chúng ta cần là khả năng save và load điểm lên một tập tin.
    Mã (Lua):
    function M.save()

      local path = system.pathForFile( M.filename, system.DocumentsDirectory )
      local file = io.open(path, "w")
      if ( file ) then
          local contents = tostring( M.score )
          file:write( contents )
          io.close( file )
          return true
      else
          print( "Error: could not read ", M.filename, "." )
          return false
      end
    end
    function M.load()
      local path = system.pathForFile( M.filename, system.DocumentsDirectory )
      local contents = ""
      local file = io.open( path, "r" )
      if ( file ) then
          -- read all contents of file into a string
          local contents = file:read( "*a" )
          local score = tonumber(contents);
          io.close( file )
          return score
      else
          print( "Error: could not read scores from ", M.filename, "." )
      end
      return nil
    end
    return M
    Như đã thấy ở đoạn code trên, tập tin lưu điểm tồn tại trong system.DocumentsDirectory. Chúng ta không thể ghi nó vào system.ResourceDirectory vì các tập tin trong thư mục này là chỉ đọc, và cả system.TemporaryDirectory system.CachesDirectory vì 2 thư mục này dễ dàng bị dọn dẹp tự động bởi hệ thống. Vì vậy, chúng ta tạo file này trong documents directory.


    Đưa vào sử dụng
    Khi chúng ta tạo ra các module chúng ta có thể sử dụng nó như sau:
    Mã (Lua):
    local score = require( "score" )

    local scoreText = score.init({
      fontSize = 20,
      font = "Helvetica",
      x = display.contentCenterX,
      y = 20,
      maxDigits = 7,
      leadingZeros = true,
      filename = "scorefile.txt",
    })


    Để sử dụng, bạn có thể làm như sau:

    · score.set( value ) — đặt giá trị.

    · local myscore = score.get() — lấy giá trị hiện tại.

    · score.add( value ) — thêm giá trị vào điểm hiện tại.

    · score.save() — save điểm.

    · local highscore = score.load() — load số điểm trước đó.

    Chúc bạn thành công!

    Update: bạn có thế download toàn bộ code để nghiên cứu thêm. Khi một đối tượng được touch, điểm số sẽ tăng và các đối tượng được remove khỏi màn hình. Để đa dạng, mỗi đối tượng có một giá trị thiết lập cho nó: 50 điểm cho một cái thùng nhỏ, 100 điểm cho một cái thùng lớn, và 500 điểm cho một container màu xanh lá cây. Click vào từng đối tượng và xem sự gia tăng điểm số. Hai nút đã được thêm vào để hiễn thị hàm save() và load(). Để kiểm tra nó, lưu điểm số, rétart ứng dụng (Control-R hoặc Cmd-R), và sau đó load các điểm đã được lưu lại.
    Last edited: 25/6/15
    Lanh thích bài này.
  2. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
    anh cho em hỏi tẹo, em mới học về corona SDK, có 1 bài tập là làm 1 game đánh bóng nhỏ, mỗi lần di chuyển cái vợt đánh trúng quả bóng sẽ có 1 điểm, số điểm này cộng dần lên, rồi khoi đánh trượt sẽ lưu lại điểm cao nhất, em đã làm xong phần chuyển động, đánh bóng, còn phần tính điểm và cộng điểm em ko biết làm, anh hướng dẫn kỹ hơn cho em được không ạ, em cảm ơn nhiều ạ
  3. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
    anh nhắn tin lại cho em, để em hỏi này chút được ko ạ 0973.281.113
  4. Administrator
    admin
    Nhân viên CoronaViet
    Tham gia ngày:
    16/1/14
    Bài viết:
    303
    Đã được thích:
    100
    Bạn hỏi chung chung quá! Cái này là thuật toán bạn lưu điểm thôi, bạn muốn lưu điểm ơ đâu và khi nào cộng điểm là yêu cầu game của bạn chứ sao mình hướng dẫn bạn được.
  5. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
    em mới học được 2 ngày, tự học nên cũng chưa hiểu rõ lắm, mỗi lần cái vợt đánh trúng quả bóng sẽ được cộng 1 điểm, lần thứ 2 lại cộng lên, cho tới khi đánh trượt, quả bóng rới xuống ấy ạ, sau đó tính tổng điểm, và lưu lại điểm cao nhất
    đây là code của em ạ

    --> add physics
    local physics = require("physics")
    physics.start( )
    --
    physics.setGravity(0, 9.8 )

    --> add wall
    local wall = display.newImage("wall.png")

    --> add bong1
    local bong = display.newImage("tron.png")
    bong.x = display.contentWidth/2
    physics.addBody(bong, { bounce = 1.0,})



    --> add kinh 1
    local kinh = display.newImage("kinh.png")
    kinh.y = display.contentCenterY
    physics.addBody(kinh, "static", {bounce = 0.5})


    --> add kinh 2
    local kinh1 = display.newImage("kinh.png")
    kinh1.x = kinh.x + 320
    physics.addBody(kinh1, "static", {bounce = 0.5})



    display.setStatusBar( display.HiddenStatusBar )

    --> add vot
    local vot = display.newImage("vot.png")
    vot.y = display.contentHeight - vot.stageHeight/2
    vot.x = display.contentCenterX
    vot.rotation = 1
    physics.addBody(vot, "kinematic", { friction = 0.5, bounce = 1,0})

    local function startDrag( event )
    local t = event.target
    local phase = event.phase
    --Bắt đầu khi chạm vào đối tượng
    if "began" == phase then
    display.getCurrentStage():setFocus( t )
    t.isFocus = true
    t.x0 = event.x - t.x
    t.y0 = event.y - t.y
    event.target.bodyType = "kinematic"
    event.target.angularVelocity = 0
    elseif t.isFocus then
    --Di chuyển đối tượng
    if "moved" == phase then
    t.x = event.x - t.x0
    t.y = event.y - t.y0
    elseif "ended" == phase or "cancelled" == phase then
    display.getCurrentStage():setFocus( nil )
    t.isFocus = false
    if ( not event.target.isPlatform ) then
    event.target.bodyType = "static"
    end
    end
    end
    return true
    end
    --------------------------------------------------------------------------------
    --Gọi hàm startDrag để gắn vào đối tượng image
    vot:addEventListener( "touch", startDrag )
  6. Administrator
    Khúc Vương
    Nhân viên CoronaViet
    Tham gia ngày:
    17/1/14
    Bài viết:
    492
    Đã được thích:
    130
    Ý của bạn mà muốn tụi mình chỉ cho bạn code để cộng điểm khi đánh trúng và lưu lại đúng ko ạ?
  7. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
    dạ, em mới học qua thôi nên không biết, anh chỉ cho em với được không ạ, nếu code ngắn và dễ hiểu thì chỉ cho em với ạ, em cảm ơn, đây là bải tập nhỏ, em đang tự làm thôi ạ
  8. Administrator
    linhle
    Nhân viên CoronaViet
    Tham gia ngày:
    8/2/14
    Bài viết:
    190
    Đã được thích:
    133
    trước tiên bạn phải xác định được ở đâu là sự kiện đánh trúng và ở đâu là sự kiện đánh trượt nhé.
    Bạn cần khai báo 1 biến để lưu điểm đó.
    nếu đánh trúng bạn chỉ cần cho biến đó cộng 1, cụ thể là
    score = score + 1
    còn nếu đánh trượt thì bạn so sánh biến lưu điểm đó với điểm cao nhất mà bạn đã lưu lại ở đâu đó, nếu nó lớn hơn thì bạn chỉ cần cập nhật biến điểm cao nhất đó thôi
  9. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
    code của nó có dài không, a code mẫu hộ em phần tính điểm thôi, phần lưu điểm em sẽ tìm hiểu, chứ nói thế này em cũng không hiểu rõ lắm, em tìm tài liệu toàn tài liệu Corona tiếng anh, nên khó đọc với lại khó hiểu quá, em cảm ơn anh nhé
  10. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
    khai báo biến thế nào, các hàm ra sao em còn chưa được rõ, tự mò mẫm thế này khó quá, hjx
  11. Administrator
    linhle
    Nhân viên CoronaViet
    Tham gia ngày:
    8/2/14
    Bài viết:
    190
    Đã được thích:
    133
    trong game của bạn khi cái vợt đánh trúng trái bóng là tính điểm hay trái bóng phải trúng vào một vật nào đó mới tính điểm hay sao bạn.
  12. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
    quả bóng rơi tự do anh ak, cứ di chuyển cái vợt, đỡ được trái bóng cho nó ko rơi xuống dưới là được tính điểm, nó nảy lên rồi lại rơi xuống, cứ đỡ như thế, nghĩa là quả bóng chạm vào cái vợt là được điểm ạ
  13. Administrator
    linhle
    Nhân viên CoronaViet
    Tham gia ngày:
    8/2/14
    Bài viết:
    190
    Đã được thích:
    133
    Ak vậy thì bạn cần tạo một sự kiện chạm cho quả bóng hoặc cái vợt,
    --Tạo biến lưu trữ điểm
    local score = 0
    local function eventCollision(self, event)
    if event.phase == "began" then
    if event.other.name == "bong" then
    score = score + 1
    end
    elseif event.phase == "ended" then

    end
    end
    vot.collision = eventCollision
    vot:addEventListener("collision", vot)

    --Lưu ý bạn phải đặt tên cho trái bóng của bạn thông qua thuộc tính name, ví dụ
    bong.name = "bong"
    Last edited: 21/5/14
  14. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
    ok anh, thank anh nhiều lắm nhé :), giờ còn vấn đề lưu điểm với lại, sau 1 time chơi, đạt đến tầm 10d thì sẽ tăng thêm 1 quả bóng nữa thôi, cứ như thế, tăng dẫn, 50 điểm sẽ có 6 quả bóng rơi liên tiếp trên màn hình thôi, có khó khăn gì em sẽ hỏi anh nhé, em cảm ơn
  15. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
    anh ơi, giúp em thì giúp cho chót với, mỗi lần chạm nó hiển thị điểm lên cho người chơi biết, đến 1 mức nào đấy rồi thì có thêm 1 quảng bóng nữa, 10d chẳng hạn, rồi 20d lại thêm quả nữa, cứ như thế cho tới khi chết thì thôi, rồi lưu điểm cao nhất lại, có màn hình chơi với lại thêm 1 màn hình overgame để hiện luôn ra điểm cao nhất thôi anh ạ, anh giúp em nốt lần này với, cho em làm xong cái bài tập này, tối mai em phải nộp rồi ạ, hu hu
    Last edited: 21/5/14
  16. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
  17. New Member
    FPT_113
    Tham gia ngày:
    21/5/14
    Bài viết:
    11
    Đã được thích:
    0
    anh ơi, giúp em thì giúp cho chót đi anh, hộ em với, hjx
  18. Administrator
    linhle
    Nhân viên CoronaViet
    Tham gia ngày:
    8/2/14
    Bài viết:
    190
    Đã được thích:
    133
    bạn cứ làm đi không hiểu phần nào thì trao đổi với mọi người chứ yêu cầu của bạn hầu như là làm một cái game hoàn chỉnh luôn rồi.
  19. New Member
    ulolo24
    Tham gia ngày:
    23/12/14
    Bài viết:
    82
    Đã được thích:
    2
    cho mình hỏi phần lưu ký tên người chơi thì làm thế nào?
  20. Administrator
    linhle
    Nhân viên CoronaViet
    Tham gia ngày:
    8/2/14
    Bài viết:
    190
    Đã được thích:
    133
    Lưu ký tên là lưu cái gì vậy bạn? Bạn có thể nói rõ là muốn lưu cái gì được không ak!
    ulolo24 thích bài này.

Chia sẻ trang này