Sufficiency Economy
Group Blog
 
All blogs
 

เขียนเกม บนเครื่อง Nintendo DS : ทดลองเขียนเกม Tetris


.nds และ SourceCode d/l ได้เลยครับ
จากครั้งที่แล้วได้บอกวิธี การแสดงผลแบบ Tile หรือ Text บนเครื่อง DS แล้ว ดังนั้นจึงนำหลักการดังกล่าว มาสร้างเกม Tetris กัน โดยมีข้อกำหนดว่า
มีจำนวน row= 20 และจำนวน Column = 10
มีการแสดง ตัวที่เล่นต่อไปด้วย
มี LV, จำนวน Line และ Score
หลักการคร่าวๆ ที่ใช้คือ
การวาดฺตัวฺBlock ที่หล่น จะเห็นได้ว่า Tetris 1 ตัวจะประกอบด้วย 4 blockเสมอ
ดังนั้นเราวนลูปสี่ครั้งก็ได้รูป Tetris 1 ตัว ในที่นี้คือ Function void DrawB(int color)
โดยค่าที่ต้องใช้คือค่าสี นั้นคือค่าของ Tile 1-7 นั้นเอง
ส่วน Tileที่ 0 ที่เป็นสีม่วง เรา ตั้งให้เป็นสีโปร่งแสง แต่สำหรับ Backgroud เดียวกันคือการ ลบภาพนั้นเอง

การเก็บค่า ตำแหน่ง Block เราใช้ตัวแปร int T[20][10];
ถ้าไม่มี block กำหนดให้เป็น 0 แต่ถ้ามี Block กำหนดให้เป็น9

และได้มีการ สร้าง Function การตรวจสอบว่าสามารถหมุนได้หรือไม่ ไปทางขวาได้หรือไม่ ไปทางซ้ายได้หรือไม่ คือ function chkRol chkMoveLeft chkMoveRight ตามลำดับ

มี Function ตรวจสอบว่า สามารถตกลงมาได้หรือไม่ ด้วย function chkMoveDown

ที่เหลือ ก็ลอง ไล่ code ดูนะครับ
เขียน comment ไว้ใน source ให้บ้างแล้ว
และต่อไปคงต้องหา effect มาใส่ในเกม บาง เช่น Fadein Fadeout
ในครั้งหน้าเจอกันใหม่ครับ




 

Create Date : 27 กันยายน 2551    
Last Update : 27 กันยายน 2551 22:16:07 น.
Counter : 1091 Pageviews.  

เขียนเกม บนเครื่อง Nintendo DS : การแสดงผลแบบ Tile


SourceCode+.nds กดได้เลย
ครั้งก่อนผมได้บอกวิธีการแสดงผลแบบ bitmap ไปแล้ว ต่อไปเรามาลองแสดงผลแบบ Tile บางดีกว่า
การแสดงผลแบบ bitmapจะแสดงสีได้ (R*G*B =32*32*32 =32,768 สี ) แต่แม่สีของแสง(Red-Green-Blue) มีค่า 0-31 ดังนั้น 1 จุดสี หรือเรียกว่า 1 pixel ใช้หน่วยความจำ 1+5+5+5 = 16 bit นั้นเอง bit บนสุดเป็น alpha bit มั่ง ปกติต้องมีค่า = 1 เช่นคำสั่งนี้
video_buffer_main[i] = RGB15(31,0,0) | BIT(15);

1 จอภาพมีจุดทั้งหมด 256x192= 49,152 จุด แต่จุดละ 2 bytes ดังนั้นใช้หน่วยความจำ VRAM =98,304 bytes = 0x18000 (เลขฐาน16) bytes = 96 kBytes

แต่ถ้าใช้การแสดงผลแบบ Text หรือ Tile จะใช้หน่วยความจำที่น้อยกว่า แต่ก็ต้องแลกตัวความยุ่งยากในการจัดการสี ซึ่งสีที่จะสามารถแสดงได้พร้อมกันมีเพียง 256 สี แต่ถ้าจัดการดีๆ ก็ได้ภาพที่ ok เหมือนกันครับ
ซึ่งการแสดงผลแบบนี้ จะใช้ BG0 และBG1

Tile 1 Tile มีขนาด 8x8 pixels ซึ่งเรียกว่า Tile Data ดังนั้น 1 จอภาพจึงต้องใช้ 32 x 24 Tiles = 768 Tilesมี Tile แล้วก็มีแผนที่สำหรับจัดเรียง Tile บนหน้าจอ หรือเรียกว่า Tile Map
ตำแหน่งที่เก็บข้อมูล Tile Data คือ 0x600:0000 ถึง 0x607:C000 (Base0 ถึง Base 31) หรือช่วงละ 0x4000 bytes
และตำแหน่งที่เก็บข้อมูล Tile Map คือ 0x600:0000 ถึง 0x600:F800 (Base0 ถึง Base 31) = หรือช่วงละ 0x800 bytes
ดังนั้นต้องใส่ Map ไว้ที่ 64 kBytes แรก และต้องใส่ Tile Data ไว้ที่ 256 kBytes แรก

รูปแบบของ Map Data มีสองแบบ คือแบบ 8 bit และ แบบ 16 bit เพื่อความง่ายเรามาดูเฉพาะแบบ 16 bit ก่อนละกัน
รูปแบบ


ส่วน Tile Data 1 Tile มีขนาด 64 bytes เพราะมี 256 สี ซึ่งแทนด้วย 8 bit หรือ 1 bytes

การตั้งค่า BG0_CR = BG_32x32 | BG_COLOR_256 | BG_MAP_BASE(0) | BG_TILE_BASE(1);

เนื่องจากสีมีได้เพียง 256 สี ต่อ 1 PALETTE (Palette คือจานสี) ดังนั้นต้องมีการset ค่า Palette ด้วย โดย BG_PALETTE[1] = RGB15(31,0,0); //red
BG_PALETTE[2] = RGB15(0,31,0); //green
ตำแหน่งของ Palette อยู่ที่ 0x
0500:0000-0500:01FF A-BG Palette RAM (512 Bytes) สำหรับหน้าจอหลัก
0500:0400-0500:05FF B-BG Palette RAM (512 Bytes) สำหรับหน้าจอรอง
เนื่องจากสี 1 สีใช้พื้นหน่วยความจำ 2 bytes แต่มีทั้งหมด 256 สี สรุปแล้ว Palette ต้องใช้พื้นที่ 2*256=512 = 0x200


ต่อไปเรามาดูโปรแกรมตัวอย่างกัน เป็นการแสดงผล 2 Layer
Layer ที่ 1 (BG3)เป็น Background สีเขียว และมีช่องดำๆ
ส่วน Layer ที่ 2 (BG0)จะแสดงรูปBlock

การจัดการ Memory ของ Main Screen
vramSetBankA(VRAM_A_MAIN_BG_0x06000000); // Main Screen
vramSetBankB(VRAM_B_MAIN_BG_0x06020000); // Main Screen
เราใช้ Memory Bank B เพิ่มอีก 0x20000 Bytes

มีการตั้งค่า BG0 เพิ่มขึ้น
BACKGROUND.control[0] = BG_32x32 | BG_COLOR_256 | BG_MAP_BASE(0) | BG_TILE_BASE(5)|BG_PRIORITY(0) ;
Background มี ขนาด 32x32 Tiles หรือเท่ากับ 256x256 pixels
แสดงสี 256 สีในเวลาเดียวกัน
แผนที่ของ Background (BG_MAP_BASE) เริ่มที่ตำแหน่ง 0x600:0000
ข้อมูล Tile (BG_TILE_BASE) เริ่มที่ตำแหน่ง 0x601:4000
โดยมี Priority =0 (BG_PRIORITY(0)) คือจะแสดงผลอยู่บนสุดของทุก Background

u8* tileMemory = (u8*)BG_TILE_RAM(5);
u16* mapMemory = (u16*)BG_MAP_RAM(0);

กำหนดตัวแปร tileMemory และ mapMemory เพื่อให้ง่ายต่อการอ้างถึงเวลาต้องการใส่ข้อมูล โดยค่าตำแหน่งหน่วยความจำที่กำหนดต้องสอดคล้องกับ การตั้งค่า BG0 คือเลือก Base ให้ตรงกัน

Palette
for(i=0;i<256;i++)
BG_PALETTE[i] =blockPal[i];
Copy ข้อมูลสีลงหน่วยความจำ ส่วนค่า blockPal ถูกสร้างโดยอัตโนมัติ จากข้อมูลgraphics

Tile
dmaCopyHalfWords(3, blockTiles, tileMemory, blockTilesLen);
Copy ข้อมูลรูปภาพลงหน่วยความจำ โดยข้อมูลสร้างโดยอัตโนมัติ จากข้อมูลgraphics เช่นกัน

mapMemory[32] = 1;
เป็นคำสั่งให้แสดงค่า Tile ตำแหน่ง Map 32 ดังนั้นจึงเกิด Block ที่แถวที่สอง

ส่วนฟังก์ชั่น void PlotBlock(int row, int col,int color)
เพื่อให้ง่ายต่อการแสดง Block ในช่องดำๆที่ว่างไว้

ค่าblockมีค่าได้ตั้งแต่ 0-7 เพราะรูป block เรามี 8 รูปไง


โอ้งวดนี้อธิบายเยอะมากๆๆ อาจงงๆ อยู่บาง แต่ลองไล่ Source Code ประกอบคงทำความเข้าใจได้ไม่ยาก
สุดท้าย จะมีว่ารูปที่ออกมาจะคล้ายๆ เกมส์ เกมส์หนึ่ง ..... ก็ TETRIS ไง
งั้นก็ลอง Apply ตัวอย่างนี้ กับ blog เก่าๆ เพื่อสร้างเกม Tetris อย่างง่ายดีกว่า
ใครทำได้ส่งมาให้ดูบ้างนะครับ




 

Create Date : 12 กันยายน 2551    
Last Update : 12 กันยายน 2551 18:53:45 น.
Counter : 971 Pageviews.  

เขียนเกม บนเครื่อง Nintendo DS : โปรแกรมพจนานุกรม Eng-Thai


พอดีได้ข้อมูลสนับสนุน จากคุณ real_stay เลยทดลองเขียน โปรแกรม
พจนานุกรม Eng-Thai โดยหลักการค้นหาคำนั้นได้ทดลองหลายแบบ(ที่จริง
แค่สองแบบ 55) คือ binary tree และ AVL tree คำศัพท์ประมาณ 3 หมื่น
กว่าคำ ถ้าเป็น tree แบบ balance ก็มีความลึกประมาณ 14-15 level ทำให้
การหาค่อนข้างรวดเร็ว แต่มีปัญหาตอนที่เราจะสร้าง TREE ที่การใส่ข้อมูล
จะช้ามาก binarytree ประมาณ 3 นาที ส่วน AVL tree เกือบจะชม. ได้มัง ก็
เปลี่ยนมาใช้วิธีแบบพื้นบ้าน คือ อ่านข้อมูลเข้า array แล้ว ค้นหาแบบแบ่ง
ครึ่ง (จำชื่อ algorithm ไม่ได้อ่ะ) ก็แบ่งประมาณ15 ครั้งก็เจอ เลยเลือกวิธีนี้
ในการค้นหาคำใน พจนานุกรม แต่คำศัพท์ต้องเรียกลำดับด้วยนะครับ ถึงจะ
ใช่วิธีนี้ได้ มาถึงตรงนี้ก็มาถึงบางอ้อ ว่า ที่ทำให้การใส่ข้อมูลช้า ก็คือข้อมูล
ที่เรียงกันนี้เองทำให้ข้อมูลไปหนักทางด้านขวาตลอด เพราะเรียงคำจาก a
ไปถึง z ดังนั้นถ้าเราจัดเรียงข้อมูลเข้าใหม่ให้เหมาะสม ก็คงใช้วิธีแบบ
binary tree หรือ AVL tree ได้ไม่มีปัญหา ซึ่งข้อดีอย่างหนึ่งของการใช้แบบ binary tree ก็น่าจะเป็นเรื่องหน่วยความจำที่ไม่ต้องเป็นแบบ array
ถ้าจำไม่ผิดจะเก็บไว้ที่ heap memory หรือเปล่า หว่า ?

สามารถ load มาดู code หรือ program สำเร็จรูปได้
ที่นี้ครับ




 

Create Date : 07 กันยายน 2551    
Last Update : 7 กันยายน 2551 11:53:41 น.
Counter : 989 Pageviews.  

เขียนเกม บนเครื่อง Nintendo DS : เกม Love Memory

จากกระทู้ที่แล้วได้ให้ลองเขียน เกมส์ความจำ เลยทดลองเขียนเอง
ก็ออกมาแบบนี้ ลองเล่นแล้ว น่าปวดหัวมากกว่า เอิ้กๆ ก็ลองเอาไปเล่นดูครับ ส่วน source ก็ลองไปแกะๆ ดูละกันไม่ยาก แต่เขียนมั่วๆ ไปหน่อย
แต่ถ้าจะ compile ใหม่ ต้องใส่ libary "mikmod" ลงไปด้วยนะครับ เด๋วจะ
อธิบายรายละเอียดให้ครั้งต่อไป
ตัวเกม
sourcecode




 

Create Date : 28 สิงหาคม 2551    
Last Update : 30 สิงหาคม 2551 20:40:05 น.
Counter : 793 Pageviews.  

เขียนเกม บนเครื่อง Nintendo DS : ทดลองใส่เสียงให้ ds

ตอนนี้เราจะลองใส่เสียงให้ ds กัน ปกติในเกมส์ เสียงที่ใช้จะมีสองแบบคือ
sound effect กับ เพลงบรรเลง ในครั้งนี้จะพูดถึง sound effect ก่อนครับ

sound effect จะเป็นพวกเสียงยิง ระเบิด จะใช้ format .wav (format อื่นก็ได้มัง ;-P) แล้วแปลงให้เป็น .raw ไฟล์ คือไฟล์ที่ไม่มี header ใน tutorial ส่วนใหญ่จะให้ใช้ sox แปลงไฟล์ แต่หลังๆ มันมี noise effect เลยจะขอแนะนำ audacity ให้จิ้มd/l มาใช้เลยครับ
เมื่อ ติดตั้งเสร็จให้ ตั้งค่าไฟล์เป็น raw โดยไปที่เมนู edit ->preferences เลือก tab : file format -> ไปที่กรอบ Uncompressed exported format
เลือก other จะมี dialog ขึ้นมา ให้ตั้งค่าตามรูป


วิธีแปลงก็ง่ายๆ คือ เปิด file แล้วไปเมนู File -> export as RAW
แล้วให้นำไฟล์ .raw ไปใส่ที่ folder arm9data

ต่อไปมาดูส่วนการ coding บ้าง
source code d/l มาดูก่อน


รูปแบบ folder จะเปลี่ยนแปลงนิดหน่อยเนื่องจากถ้าเป็นการประมวลผลในส่วนของ เสียงและ touch pen จะใช้ cpu arm7 แต่ถ้าเป็นgraphic จะเป็น
cpu arm9 และมีการแก้ไข makefile ลองเปรียบเทียบดูใน source ไฟล์ล่ะกัน อย่างไรก็ตามทาง libnds ได้เขียนfunction เสียงให้เรียกใช้ใน arm9 ได้เลย
ให้เปิดไฟล์ main9.c
ทำการ include ไฟล์ข้อมูลเสียง ในที่นี้จะมีสองเสียง
#include "click_raw.h"
#include "chime_raw.h"

ต่อไปเป็นการตั้งค่าเสียงและเรียกใช้งาน มีสองแบบคือ
แบบที่1
setGenericSound(11025, /* sample rate */
127, /* volume */
64, /* panning */
1 ); /* sound format*/
การเรียกใช้งาน
playGenericSound(chime_raw, chime_raw_size );
ค่า chime_raw และ chime_raw_size จะเป็นตัวแปรเก็บค่าpointerไปยังข้อมูล และตัวแปรเก็บค่าขนาดของข้อมูล
แต่เนื่องจากมี bug (มัง) ใน devkitPro ค่าของ chime_raw_size ต้องระบุเป็นตัวเลขเลย โดยดูค่าจากขนาดไฟล์ .raw นั้นๆ
ดังนั้นจึงต้องเขียนเป็น
playGenericSound(chime_raw, 20000 );
แต่จริงขนาดไฟล์ raw ของเสียง chime = 20480 แต่ผมต้องปรับเป็น 20000 เพราะอะไร ให้ทดลองเองนะครับ

แบบที่ 2
TransferSoundData click = {
click_raw, /* Sample address */
//click_raw_size, /* Sample length */
1615, /* Sample length */
11025, /* Sample rate */
127, /* Volume */
64, /* panning */
1 /* format */
};
เช่นเดียวกันครับ เสียง click ต้องปรับเป็นตัวเลข แต่คราวนี้ผมใส่ขนาดไฟล์ .raw ที่แท้จริงเลย ไม่ได้ลดขนาด ?
การเรียกใช้
playSound(&click);

สรุปการเรียกทั้งสองแบบ ก็มีข้อดีข้อเสียต่างกัน เช่นแบบที่1 set ครั้งเดียว แล้วเรียกใช้งาน แต่ความดัง(volume) ไม่สามารถปรับได้ในกรณีที่มีสองเสียง
ส่วนแบบที่2 สามารถset ค่าต่างๆ ของแต่ละเสียงตามใจเราได้เลย ไม่ว่าเป็น volume หรือ sample rate อย่างอื่นไม่ได้ลองครับ ถ้าลองแล้วได้ผลอย่างก็บอกกันด้วยครับ แต่แบบที่สองมีข้อเสียตรงต้องเขียน code อ่านข้อมูลเสียงทุกเสียงตลอด

โอ้ ได้ความรู้แค่นี้น่าจะทำเกมง่ายๆ ได้สักเก็บไหมเนีย
Project เกมส์จำเลข 1-4
กติกา เกมจะสุ่มตัวเลขมาทีละหนึ่งตัว(1-4) และแสดงผลพร้อมมีเสียงประกอบประจำตัวเลข แล้วผู้เล่นต้องกดปุ่มตัวเลขให้ถูกต้อง ต่อมาเกมก็จะ
เลือกตัวเลขขึ้นมาอีกหนึ่งตัว แต่ตอนแสดงผลจะแสดงตัวเลข ต้วแรกก่อน และตามด้วยตัวที่สอง ดังนั้นผู้เล่นต้องกดปุ่มตัวเลขให้ถูกต้อง ทั้งสองตัว ต่อจากนั้น ก็จะมีเลข 3 ตัว 4 5 6 ... ไปจนจำบ่ได้ 55 และให้คะแนะตัวเลขล่ะ1 คะแนน ที่ต้องมีเสียงประกอบเพื่อช่วยในการจำนั้นเอง การเลือกตัวเลข1-4 ก็ใช้ปุ่มทิศทางทั้ง4 ก็แล้วกันครับ
ถ้าใครทำได้ส่งมาให้ดูมังน่าคร๊าบบ




 

Create Date : 24 สิงหาคม 2551    
Last Update : 24 สิงหาคม 2551 14:00:53 น.
Counter : 752 Pageviews.  

1  2  3  4  5  6  7  8  

wink99_th
Location :
พิษณุโลก Thailand

[Profile ทั้งหมด]

ฝากข้อความหลังไมค์
Rss Feed
Smember
ผู้ติดตามบล็อก : 8 คน [?]




New Comments
Friends' blogs
[Add wink99_th's blog to your web]
Links
 

 Pantip.com | PantipMarket.com | Pantown.com | © 2004 BlogGang.com allrights reserved.