Flappy Bird สำหรับ Android เขียนด้วย C ขนาดต่ำกว่า 100KB
(github.com/VadimBoev)- โปรเจกต์นี้มีเป้าหมายสร้าง Flappy Bird โคลนสำหรับ Android ด้วย C พร้อมลดขนาด APK ให้ ต่ำกว่า 100KB
- หลังจากได้รู้จัก rawdrawandroid ในปี 2021 ผู้พัฒนาต้องการสร้างเกมที่มี APK ขนาดเล็ก และการได้เห็น C# Flappy Bird ใน Raylib Discord เมื่อเดือนกันยายน 2024 ก็เป็นจุดเริ่มต้นให้ลองทำเวอร์ชัน C
- วิธีการพัฒนาคือแพ็กเกจไลบรารีเนทีฟที่เขียนด้วย C ลงใน APK และผสานการทำงานของ OpenGL ES 2, เชดเดอร์ และ Android Native Activity
- เสียงถูก บีบอัดเป็น MP3 และเล่นผ่าน OpenSLES ส่วนการถอดรหัส PNG ใช้ upng
- รองรับการบิลด์ด้วย Visual Studio Code บน Windows และ Makefile บน Linux/macOS พร้อมระบุว่าสิทธิ์ในเกมและทรัพยากรเป็นของ DotGEARS
เป้าหมายและที่มาของโปรเจกต์
- Flappy Bird in C คือโปรเจกต์ที่ต้องการเขียน Flappy Bird โคลนที่ทำงานบน Android ด้วย C และคงขนาด APK ให้ ต่ำกว่า 100KB
- จุดเริ่มต้นมาจาก rawdrawandroid ที่ได้รู้จักในปี 2021 โดยเป้าหมายคือทำเกมที่ทั้งเข้าใจได้และน่าสนใจ พร้อมลดขนาด APK ให้เล็กที่สุด
- Flappy Bird มีตัวอย่างการพอร์ตไปหลายภาษาอยู่แล้ว จึงถูกเลือกเป็นเป้าหมายในการทำโคลนอย่างเป็นธรรมชาติ
ความพยายามก่อนหน้าและปัญหา
- ในปี 2021 ผู้พัฒนาได้ศึกษา Raylib และความพยายามครั้งแรกในการสร้างเกมด้วย C++ โดยใช้ ImGui ก็ล้มเหลว
- ปัญหาในตอนนั้นมีหลายอย่าง
- ขนาด APK อยู่ที่ประมาณ 1MB
- เกมเกิดการแครช
- ภายใน APK มีเพียงไลบรารี armeabi-v7a
- ตามข้อกำหนดของ Google ในปี 2022 จำเป็นต้องมีไลบรารี arm64-v8a ด้วย
แรงจูงใจในการลองใหม่ปี 2024
- หลังจากเห็น C# Flappy Bird ในช่อง Raylib Discord เมื่อเดือนกันยายน 2024 ผู้พัฒนาจึงเริ่มลองสร้าง Flappy Bird สำหรับ Android ด้วย C และทำให้ APK มีขนาดต่ำกว่า 100KB
- แม้เป้าหมายจะดูไม่สมจริง แต่ความท้าทายเชิงแข่งขันก็กลายเป็นแรงผลักดันในการลงมือทำ
วิธีการพัฒนา
- จุดเริ่มต้นคือการคอมไพล์ Hello World ที่เขียนด้วย C และแพ็กเกจไลบรารีนั้นลงใน APK
- เสียงถูกบีบอัดเป็น ไฟล์ MP3 และเล่นด้วย OpenSLES
- สำหรับการถอดรหัสไฟล์ PNG เลือกใช้ upng
- งานกราฟิกและการเชื่อมต่อกับ Android ใช้ OpenGL ES 2, เชดเดอร์ และ Android Native Activity ร่วมกัน
วิธีบิลด์
- บน Windows ใช้สภาพแวดล้อม Visual Studio Code เป็นหลัก
- สร้าง
.envจาก.env.example - รัน
build.bat
- สร้าง
- บน Linux และ macOS สามารถบิลด์ได้ด้วย Makefile ที่ให้มา
- จำเป็นต้องติดตั้ง Android command-line tools
- ตั้งค่าตัวแปรสภาพแวดล้อมในไฟล์
.envที่รากโปรเจกต์ - เข้า
cd FlappyBirdแล้วรันmake
- ขั้นตอนการบิลด์แบบละเอียดเพิ่มเติมให้ดูที่
BUILDING.md - APK ที่เซ็นแล้วจะถูกสร้างไว้ที่
FlappyBird/app/build/outputs/apk/FlappyBird-signed.apk
ลิขสิทธิ์และโปรเจกต์อ้างอิง
- ผู้เขียนโปรเจกต์ระบุว่าไม่ได้อ้างสิทธิ์ลิขสิทธิ์ และสิทธิ์ในตัวเกมกับทรัพยากรเป็นของ DotGEARS
- โปรเจกต์ที่เป็นแรงบันดาลใจมีดังนี้
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
อยากให้ App Store มีตัวกรอง ดูเฉพาะแอปต่ำกว่า 10MB
แอปที่เร็วที่สุดและมีโฆษณา/ไมโครทรานแซกชันน้อย มักจะเป็นแอปขนาดเล็ก
มีโอกาสสูงมากที่จะพอใจกับแอปเทอร์โมมิเตอร์ขนาด 3MB มากกว่าแอปเทอร์โมมิเตอร์ขนาด 150MB
แอปพวกนั้นเล็กจริง ๆ ถึงขั้นทั้งหมดต่ำกว่า 200KB
นายหน้าจัดหางานมักเรียกร้องผลงานให้โชว์ราวกับเป็นพอร์ตโฟลิโองานศิลป์ แม้กับแอปที่ไม่มีอยู่แล้วหรือเซิร์ฟเวอร์โปรดักชันปิดไปแล้วก็ตาม
เกณฑ์ที่ยิ่งตามอำเภอใจไปกว่านั้นคือการตรวจว่าเคยทำ แอปใหญ่ ไหม และถ้าคุณใช้เทคนิคปรับแต่งประสิทธิภาพดูมีฝีมือจำนวนมากจนทำเป็นแพ็กเกจ 8–12MB ได้ มันกลับถูกมองเหมือนเป็นสัญญาณว่าแอป/บริการ/ฐานผู้ใช้มีขนาดเล็ก
ในความเป็นจริง ต่อให้มียอดดาวน์โหลดและผู้ใช้นับร้อยล้านก็ไม่เกี่ยวอะไรกับเกณฑ์นั้นเลย และวงการนี้มีแรงจูงใจมหาศาลให้สร้าง แอปที่บวมเทอะทะ
เช่น ต้องค้นหาไปตั้ง 9 รอบรวมโฆษณาด้วย กว่าจะเจอแอปเทอร์โมมิเตอร์ที่เกิน 7MB
เคยทำงานบนทั้งสองแพลตฟอร์มมาหลายปี แต่ก็ไม่แน่ใจเหตุผลที่แท้จริง เดาว่าอาจเป็นเพราะ Android มีธรรมเนียมใช้ เวกเตอร์อาร์ต แข็งแรงกว่าบิตแมปมาก และไลบรารี Swift เคยต้องคอมไพล์รวมไปกับแอปอยู่หลายปี ก่อนจะใช้การลิงก์แบบไดนามิกฝั่งระบบปฏิบัติการได้ด้วยความเสถียรของ ABI
อยากให้กรองหาแอปที่เป็นแบบเสียเงิน ไม่มีโฆษณา และบางทีก็ไม่มีการซื้อในแอปได้
ออกนอกเรื่องนิดหน่อย แต่เมื่อก่อนเคยเขียน การทบทวนวรรณกรรม ว่าทำไมผู้คนถึงเล่น Flappy Bird
ตอนนั้นเป็นนักศึกษาปริญญาโทด้านเกมศึกษา และสุดท้ายไม่ได้ไปสายวิชาการ แต่เอามาแชร์สนุก ๆ
สำหรับคนที่สนใจ อยู่ที่นี่ [1]
[1] http://www.fdg2015.org/papers/fdg2015_paper_60.pdf
ในอีกด้านหนึ่ง ตัวเกมเองไม่มีความคืบหน้าจริง ๆ หรือการเพิ่มระดับความยากเลย ไม่ว่าคะแนนปัจจุบันจะเป็น 0, 10 หรือ 100 ความยากก็เหมือนเดิม
แต่ทุกครั้งที่ทำสถิติใหม่ มันจะกลายเป็นยอดเขาลูกใหม่ที่ผู้เล่นต้องข้ามให้ได้ ยอดแรก และอาจเป็นยอดที่น่าหงุดหงิดที่สุด คือการทำให้ได้ 1 คะแนน และการไปถึงคะแนนสองหลักนั้นโดยพื้นฐานแล้วต้องเชี่ยวชาญการควบคุมหลัก ๆ รวมถึงฟิสิกส์และจังหวะที่แม่นยำ และต้องเรียนรู้วิธีรับมือกับหลายสถานการณ์
อุปสรรคที่จะไปถึงสามหลักขึ้นไปดูแทบจะเหมือนเป็นสิ่งที่สร้างขึ้นเอง และความกลัวกับความตึงเครียดเมื่อเข้าใกล้สถิติส่วนตัวมักเป็นอุปสรรคใหญ่ที่สุดที่ขวางการทำสถิติใหม่
พอข้ามสถิตินั้นได้สักครั้ง ครั้งต่อไปที่เข้าใกล้จุดนั้น อาการมือสั่นจะหายไปอย่างมหัศจรรย์ แต่เมื่อเข้าใกล้สถิติใหม่ มันก็กลับมาอีก
แนวคิดเกมเพลย์พื้นฐานนั้นเรียบง่ายจนน่าหลอกตา แต่สำหรับคนที่อยากมองลึกลงไป มีหลายชั้นให้แกะออกมา
https://www.foddy.net/Athletics.html
มี ไม่ถึง 4,000 บรรทัด
457 android_native_app_glue.c
360 audio.c
802 game.c
201 init.c
93 main.c
39 mouse.c
38 shaders.c
229 texture.c
1377 upng.c
27 utils.c
3623 total
มันไม่ได้เป็นโปรแกรมที่ซับซ้อนขนาดนั้น พูดตรง ๆ ผมว่า 4,000 บรรทัด ยังเยอะเกินไปด้วยซ้ำ
ในปี 2020 ผมเคยทำของคล้าย ๆ กันด้วย Nim แล้วปล่อยสาธารณะ แต่กราฟิกสวยน้อยกว่า
ความต่างคือผมลงลึกกว่านั้น ถึงขั้นเขียน แอสเซมเบลอร์สำหรับ Dalvik bytecode และไฟล์ .apk จริง ๆ
https://www.youtube.com/watch?v=wr9X5NCwPlI&list=PLxLdEZg8DR...
น่าเสียดายที่โค้ดในรีโพพังไปตามกาลเวลา และบางครั้งก็คิดว่าสักวันจะลองกู้มันกลับมา
บางทีก็นึกถึงแอปที่ถ้ามันถูกขัดเกลาอีกนิดคงทำขึ้นมาได้ง่าย ๆ
เจ๋งมากจริง ๆ
ดีที่ได้เห็น แอป Android ต่ำกว่า 1MB รันได้ทุกที่ แม้แต่บน HTC รุ่นเก่า
ผมเคยคิดว่าการสร้าง Android APK จำเป็นต้องมีโค้ดเชื่อมต่อฝั่ง Java พอเห็นโปรเจกต์นี้แล้วรู้สึกดีมาก
ไม่มีไฟล์ Java เลยสักไฟล์ ถือว่ายอดเยี่ยม
โปรเจกต์ rawandroid ที่คนอื่นพูดถึงก็น่าดูเช่นกัน
https://github.com/cnlohr/rawdrawandroid/tree/master
ไม่ว่าจะทำอะไรก็ตาม หากจะรันได้ก็ต้องมีอินสแตนซ์ของ Activity และถึงจะสร้างใน C ได้ แต่ก็ต้องใช้โค้ด boilerplate จำนวนมากที่ใน Java ส่วนใหญ่จัดการได้ด้วยการสืบทอดคลาส
ใน C ล้วน ๆ จะทำแบบนี้: https://github.com/VadimBoev/FlappyBird/blob/master/FlappyBi... https://github.com/VadimBoev/FlappyBird/blob/master/FlappyBi...
Super Mario Bros มีขนาดเพียง 40KB เท่านั้น
https://news.ycombinator.com/item?id=21213421
ส่วนโคลน Flappy Bird ตัวนี้รันได้บน อุปกรณ์นับไม่ถ้วน ที่มีการจัดวางฮาร์ดแวร์และซอฟต์แวร์แตกต่างกันไป
พลาดโอกาสตั้งชื่อว่า Floppy Bird ไปแล้ว เพราะมันใส่ลงในฟลอปปีดิสก์ 3.5 นิ้วได้
ตัวที่เด่นที่สุดเป็นแค่เวอร์ชันเปลี่ยนสกินง่าย ๆ ที่ใช้ไอคอนฟลอปปีดิสก์แทนนก
แน่นอนว่า ‘angry birds’ ก็เป็น ‘ongry beards’
เทคนิคการสร้างแอป C สำหรับ Android ด้วย rawdrawandroid แบบนี้ จะนำไปใช้กับเฟรมเวิร์ก C อื่น ๆ อย่าง raylib ได้ไหม?
แล้วจะใช้ระบบพัฒนานี้ผ่าน Termux เพื่อสร้างสภาพแวดล้อมพัฒนา C สำหรับ Android บน Android เองได้ไหม?
ผมมีสคริปต์ build ที่ยังไม่สมบูรณ์นักซึ่งใช้กับโปรเจกต์ raylib ของผม
แน่นอนว่าควรจัดการเรื่องการเซ็นให้ดีกว่านี้ และอาจอยาก build สำหรับเป้าหมายอื่นนอกจาก aarch64 ด้วย อีกทั้ง SDK ของคุณก็อาจไม่ได้ติดตั้งอยู่ที่ /home/denis
นอกจากนี้ยังไม่แน่ใจว่าการเพิ่มไฟล์ .so เข้าไปใน apk ด้วยวิธีนี้เป็นแนวทางที่ Android สมัยใหม่ชอบหรือไม่ แต่ตอนนี้ยังใช้งานได้
https://gist.github.com/deniska/f1ee73e18e1444eb724c01f933b6...
ถ้าบอกว่า “สำหรับ Android” ก็แปลว่าใช้ Java ได้ และ bytecode อาจมีความหนาแน่นมาก จึงน่าจะทำให้เล็กกว่านี้ได้อีก
ไม่ได้ตั้งใจจะลดคุณค่าโปรเจกต์บน Android นี้นะ เพราะเขาก็ไม่ได้อ้างว่าสร้างโคลน Flappy Bird ที่เล็กที่สุด
[0] https://laroldsjubilantjunkyard.itch.io/flappy-bird-gameboy/...
[1] https://laroldsjubilantjunkyard.itch.io/flappy-bird-gameboy
[2] https://www.youtube.com/watch?v=m839Vg_qXzM
ในหัวผมรู้สึกว่าน่าจะลดลงไปได้มากกว่านี้อีก และ 10KB ก็ฟังดูพอเป็นจริงได้แบบลาง ๆ