0Pricing
Lua Academy · บทเรียน

การเคลื่อนที่และการชน

สร้างฉากที่เล่นได้

การเคลื่อนที่และการชน เป็นบทเรียน Lua Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Lua Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

ตำแหน่งและความเร็ว

การเคลื่อนที่ใน LÖVE หมายถึงการเปลี่ยนตำแหน่งของวัตถุตามเวลา ให้จัดเก็บ x และ y จากนั้นบวกค่าความเร็วใน love.update โดยปรับตาม dt

การเก็บความเร็วเป็น dx และ dy ต่อวินาทีช่วยให้การเคลื่อนที่แนวทแยงและฟิสิกส์เป็นระเบียบ และไม่ขึ้นกับอัตราเฟรม

function love.update(dt)
  player.x = player.x + player.dx * dt
  player.y = player.y + player.dy * dt
end

การเคลื่อนที่ที่ขับเคลื่อนด้วยข้อมูลนำเข้า

ผสานการตรวจสอบสถานะเข้ากับความเร็วเพื่อบังคับทิศทางของวัตถุ อ่านปุ่มทิศทางใน love.update แล้วใช้ความเร็วคูณด้วย dt

เนื่องจากมีการตรวจสอบ love.keyboard.isDown ในทุกเฟรม ผู้เล่นจึงเคลื่อนที่อย่างราบรื่นขณะกดปุ่มค้างไว้

function love.update(dt)
  if love.keyboard.isDown('left') then player.x = player.x - player.speed*dt end
  if love.keyboard.isDown('right') then player.x = player.x + player.speed*dt end
end

การปรับความเร็วแนวทแยงให้เป็นมาตรฐาน

การกดปุ่มทิศทางสองปุ่มพร้อมกันทำให้การเคลื่อนที่แนวทแยงเร็วขึ้น เนื่องจากทั้งสองแกนเพิ่มความเร็วเต็มที่ วิธีแก้คือทำให้เวกเตอร์การเคลื่อนที่เป็นเวกเตอร์หน่วย

หารทิศทางด้วยความยาวของมันเพื่อให้ขนาดมีค่าเป็น 1 จากนั้นคูณด้วยความเร็ว เท่านี้ระยะทางแนวทแยงจะเท่ากับการเคลื่อนที่เป็นเส้นตรง

local dx, dy = ix, iy
local len = math.sqrt(dx*dx + dy*dy)
if len > 0 then
  player.x = player.x + (dx/len) * player.speed * dt
end

การรักษาตำแหน่งให้อยู่ภายในหน้าจอ

จำกัดค่าตำแหน่งเพื่อให้วัตถุอยู่ภายในหน้าจอ อ่านขนาดหน้าต่างด้วย love.graphics.getWidth และ getHeight จากนั้นจำกัดพิกัดให้อยู่ในขอบเขต

math.max และ math.min เมื่อใช้ร่วมกันจะจำกัดค่าให้อยู่ระหว่างค่าต่ำสุดและค่าสูงสุดได้อย่างเรียบร้อย

local w = love.graphics.getWidth()
player.x = math.max(0, math.min(player.x, w - player.size))

กล่องขอบเขตที่จัดแนวตามแกน

การชนที่ง่ายที่สุดใช้สี่เหลี่ยม ซึ่งเรียกว่า AABB หรือกล่องขอบเขตที่จัดแนวตามแกน แต่ละวัตถุจะมี x, y, ความกว้าง และความสูง

กล่องสองกล่องทับซ้อนกันเมื่อกล่องทั้งสองตัดกันทั้งบนแกนนอนและแกนตั้งในเวลาเดียวกัน การตรวจสอบนี้ทำได้รวดเร็วและเพียงพอสำหรับเกมสองมิติส่วนใหญ่

-- box: { x, y, w, h }

การทดสอบการทับซ้อนของ AABB

สี่เหลี่ยมสองรูปจะทับซ้อนกันเมื่อไม่มีแกนใดที่ขอบของรูปหนึ่งเลยขอบตรงข้ามของอีกรูป การทดสอบแบบคลาสสิกใช้การเปรียบเทียบสี่ครั้งร่วมกัน

หากการเปรียบเทียบทั้งสี่เป็นจริง กล่องจะตัดกัน เงื่อนไขเดียวนี้เป็นกลไกหลักของการตรวจจับการชนในเกมสองมิติ

function overlaps(a, b)
  return a.x < b.x + b.w and
         b.x < a.x + a.w and
         a.y < b.y + b.h and
         b.y < a.y + a.h
end

การตอบสนองต่อการชน

เมื่อ overlaps คืนค่า true แล้ว ให้ตัดสินใจว่าจะเกิดอะไรขึ้น เช่น เก็บเหรียญ รับความเสียหาย หรือหยุดการเคลื่อนที่ ตรวจสอบการชนใน love.update หลังจากเคลื่อนที่แล้ว

สำหรับไอเท็มที่เก็บได้ เพียงลบไอเท็มนั้นหรือเพิ่มคะแนน สำหรับกำแพงทึบ ให้ดันผู้เล่นกลับออกมา

function love.update(dt)
  movePlayer(dt)
  if overlaps(player, coin) then
    score = score + 1
    coin.dead = true
  end
end

การชนของวงกลม

สำหรับวัตถุทรงกลม การชนที่อาศัยระยะทางจะแม่นยำกว่า วงกลมสองวงจะชนกันเมื่อระยะห่างระหว่างจุดศูนย์กลางน้อยกว่าผลรวมของรัศมี

การเปรียบเทียบระยะทางยกกำลังสองช่วยหลีกเลี่ยงการคำนวณรากที่สองซึ่งมีค่าใช้จ่ายสูง และเป็นการปรับปรุงประสิทธิภาพที่ใช้กันทั่วไปเมื่อตรวจสอบวัตถุจำนวนมาก

function circlesHit(a, b)
  local dx, dy = a.x - b.x, a.y - b.y
  local rsum = a.r + b.r
  return dx*dx + dy*dy < rsum*rsum
end

การแก้ไขการชนกับกำแพง

หากต้องการหยุดผู้เล่นที่กำแพง วิธีง่าย ๆ คือเคลื่อนที่แยกแต่ละแกน แล้วเลิกทำขั้นตอนที่ทำให้เกิดการทับซ้อน

เคลื่อนที่ตามแกน x แล้วตรวจสอบ หากชนให้ย้อนค่า x กลับ ทำซ้ำกับแกน y การแก้ไขการชนแบบแยกแกนนี้ช่วยป้องกันการติดค้างที่มุม

player.x = player.x + vx * dt
if overlaps(player, wall) then player.x = player.x - vx * dt end
player.y = player.y + vy * dt
if overlaps(player, wall) then player.y = player.y - vy * dt end

การใช้แรงโน้มถ่วง

เกมแนวแพลตฟอร์มจะเพิ่มความเร่งลงด้านล่างอย่างคงที่ เพิ่มความเร็วแนวตั้งด้วยค่าแรงโน้มถ่วงคูณ dt ในแต่ละเฟรม จากนั้นใช้ความเร็วปรับตำแหน่ง

เมื่อผู้เล่นลงถึงพื้น ให้ตั้งความเร็วแนวตั้งเป็นศูนย์เพื่อหยุดการตก การกระโดดจะกำหนดความเร็วแนวตั้งเป็นค่าลบ

function love.update(dt)
  player.dy = player.dy + GRAVITY * dt
  player.y = player.y + player.dy * dt
end

การลบวัตถุที่หมดสภาพ

หลังจากการชน คุณมักต้องลบวัตถุออก ให้วนซ้ำรายการจากด้านหลังและเรียกใช้ table.remove เพื่อให้ดัชนียังคงถูกต้องขณะลบ

การวนซ้ำจากด้านหลังเป็นรูปแบบมาตรฐานของ Lua ที่ปลอดภัยสำหรับการลบรายการระหว่างวนซ้ำ และช่วยหลีกเลี่ยงรายการที่ถูกข้ามเมื่อวนซ้ำจากด้านหน้า

for i = #coins, 1, -1 do
  if coins[i].dead then
    table.remove(coins, i)
  end
end

ตรวจสอบความเข้าใจ

ทดสอบความเข้าใจเกี่ยวกับการเคลื่อนที่และการชนใน LÖVE

สรุป

การเคลื่อนที่ประกอบด้วยตำแหน่ง ความเร็ว และ dt โดยทำให้ความเร็วแนวทแยงเป็นมาตรฐานเพื่อความยุติธรรม และจำกัดค่าเพื่อให้วัตถุอยู่บนหน้าจอ การชนเริ่มจากการทดสอบการทับซ้อนของ AABB และใช้การตรวจสอบระยะทางของวงกลมกับวัตถุทรงกลม

แก้ไขการชนกับกำแพงด้วยการย้อนการเคลื่อนที่แยกตามแกน เพิ่มแรงโน้มถ่วงสำหรับเกมแนวแพลตฟอร์ม และลบวัตถุที่หมดสภาพด้วยการวนซ้ำจากด้านหลังร่วมกับ table.remove

คำถามที่พบบ่อย

บทเรียน “การเคลื่อนที่และการชน” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเคลื่อนที่และการชน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Lua Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเคลื่อนที่และการชน”

สร้างฉากที่เล่นได้ คุณปฏิบัติ Lua Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Lua Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Lua Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การเคลื่อนที่และการชน” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Lua Academy นี้ได้ไหม

ได้ บทเรียน Lua Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ลูปเกมของ LOVE
  2. วาดรูปร่างและภาพ
  3. จัดการข้อมูลนำเข้า
  4. การเคลื่อนที่และการชน
← กลับไปที่ Lua Academy