Mobile Game and Application with J2ME

1,488 views

Published on

Sprite

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,488
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
1
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Mobile Game and Application with J2ME

  1. 1. Sprite (สไปรต์) • Sprite • Sprite Frames • Frame sequence • Sprite transforms • Sprite drawing • Sprite collision
  2. 2. หลักการสร้างภาพเคลื่อนไหวบนมือ ถือ (Animation) • การสร้างภาพต่าง ๆ ที่เคลื่อนที่บนโทรศัพท์จะ ต้องแสดงภาพต่าง ๆ ด้วยความเร็วอย่างน้อย 12 เฟรม (frame) ต่อวินาที แต่ถ้าแต่ละภาพ เคลื่อนที่ด้วยความเร็ว 25 fps (frames per second) ภาพจะเคลื่อนที่ด้วยความนุ่มนวลมาก ในการพัฒนา MIDlet ต่าง ๆ ของภาพ เคลื่อนไหว จะต้องคำานึงถึงความเร็วในการ แสดงเฟรมของภาพบนโทรศัพท์มือถือ เนืองจากโทรศัพท์มือถือมีหน่วยความจำาและ ่ ความสามารถในการประมวลผลจำากัด
  3. 3. ประเภทของภาพเคลื่อนไหว ( Type of Animation) แบ่งออกเป็น 2 ประเภท คือ • ภาพเคล่ ือนไหวขึ้นอยูกับเฟรม (frame-based ่ Animation) • ภาพเคล่ ือนไหวขึ้นอยูกับการเคล่ ือนท่ส่ิงตูาง ๆ ่ ี ภายในเฟรม (Cast-based Animation
  4. 4. ร่ปแบบของภาพเคล่ ือนไหวท่เคล่ ือนท่โดยการใช้ ี ี ออปเจ็กต์ตูาง ๆ ทางกราฟฟิ กเคล่ ือนย้ายอยูาง อิสระบนพ้ืนหลัง (Background) หรือออปเจ็กต์ อ่ ืน ถือได้วาเป็ นภาพเคล่ ือนไหวของสไปรต์ท่ีนิยม ู นำ าไปใช้ในการเขียนเกมส์ สไปรต์ (Sprite) เป็นออปเจ็กต์ทางกราฟฟิกที่ สามารถเคลื่อนที่อย่างอิสระบนพื้นหลัง (Background) หรือออปเจ็กต์อื่น
  5. 5. การตรวจพบการกระทบกัน (Collision Detection) • เป็นวิธีการตรวจสอบว่า สไปรต์ (Sprite) เคลื่อนที่กระทบกับ สไปรต์ (Sprite) ตัวอื่นหรือ ไม่ มีประโยชน์มากในการนำาไปใช้กับภาพ เคลื่อนไหวของเกมส์ แต่ละสไปรต์ (Sprite) จะ มีขอบเขตเป็นสี่เหลี่ยมมุมฉาก บางส่วนของ ภาพจะโปร่งแสง เมื่อเคลื่อนที่กระทบกันจะ ทำาให้มุมของสีเหลี่ยมมุมฉากเหลื่อมลำ้ากัน ่ ทำาให้ตรวจพบได้ทันทีว่ามีการกระทบกัน
  6. 6. การสร้างภาพเคลื่อนไหวของสไปรต์ (Creating Sprite Animation) • คลาส Sprite จะให้การสนับสนุนภาพ เคลื่อนไหวของเฟรม (frame) ในลักษณะอะเรย์ ของภาพต่าง ๆ ของเฟรมและช่วยจำาแนก ประเภทภาพเคลื่อนไหว เมธอด (method) ต่าง ๆ ของคลาส Sprite ช่วยสร้างสไปรต์ การ เคลื่อนที่ของสไปรต์ ตรวจสอบการชนกันของส ไปรต์
  7. 7. คุณลักษณะต่าง ๆ ของสไปรต์ (Sprite Properties) • ตำาแหน่ง x: ใช้แทนพิกัด (coordinate) ของสไปรต์ในแนวระดับ ทีคอลัมน์ซ้ายสุดของจอภาพ ตำาแหน่ง x เป็น 0 คอลัมน์ขวาสุด ่ ของจอภาพกว้าง 100 จุด (pixel) เป็น 99 • ตำาแหน่ง y: ใช้แทนพิกัดของสไปรต์ในแนวดิ่ง แถวบนสุดของ จอภาพ ตำาแหน่ง y เป็น 0 แถวล่างสุดของจอภาพยาว 100 จุด (pixel) ตำาแหน่ง y จะเป็น 99 • ความเร็ว Vx: ใช้แทนความเร็วของสไปรต์ (ระยะที่สไปรต์ เคลื่อนที่ในแต่ละครั้ง) ในแนวระดับ นั่นคือ ทุก ๆ เฟรม (frame) สไปรต์จะเคลื่อนที่ Vx จุด (pixel) ถ้า Vx ค่าเป็นลบสไปรต์จะ เคลื่อนที่ไปทางซ้ายมือ นอกนันมันจะเคลื่อนทีไปทางขวามือ ้ ่ • ความเร็ว Vy: ใช้แทนความเร็วของสไปรต์ ในแนวดิ่ง นันคือ ทุก ่ ๆ เฟรม สไปรต์จะเคลื่อนที่ Vy จุด ถ้า Vy ค่าเป็นลบ สไปรต์จะ เคลื่อนที่ไปข้างบน นอกนั้นมันจะเคลือนที่ไปข้างล่าง และถ้า ่ ทัง Vx และ Vy เป็น 0 สไปรต์จะอยู่นง ้ ิ่ • width: ใช้แทนความกว้างของภาพกราฟฟิกของสไปรต์ เมื่อใช้ ร่วมงานกับตำาแหน่ง x มันจะกำาหนดขอบขวามือของสไปรต์บน
  8. 8. Sprite : Constructor Sprite(Image image) สร้าง single frame sprite, non-animated Sprite(Sprite sprite) สร้าง sprite จาก sprite ตัวอื่น Sprite(Image image, int frameWidth, int frameHeight) สร้าง animated-sprite จาก Image โดยสร้างเป็น frame จาก image
  9. 9. frameHeight frameWidth frame index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  10. 10. NOTE !! • Really be careful !!!! • ตอนที่เราสร้าง Sprite จาก constructor Sprite (Image image, int frameWidth, int frameHeight) • ถ้า frameWidth, frameHeight ไม่ลงตัวกับ Image ที่สร้าง Sprite จะเกิด IllegalArgumentException • เช่นถ้า Image มีขนาด 40*80 แต่เราสร้าง Sprite s = new Sprite(im,24,7) แบบนี้ ไม่ได้
  11. 11. Sprite: method boolean collidesWith(Sprite s, boolean pixelLevel) boolean collidesWIth(TiledLayer t, boolean pixelLevel) void defineCollisionRectangle(int x, int y, int w, int h) void defineReferencePixel(int x, int y) int getFrame() int getFrameSequenceLength() void nextFrame() void paint(Graphics g) void prevFrame() void setFrame(int sequenceIndex) void setFrameSequence(int[] sequence) void setTransform(int transform)
  12. 12. SpriteDemoMIDlet1.java • สร้าง GameCanvas ให้แสดง Sprite สองจุด โดยใช้ method nextFrame() และ prevFrame() ในการแสดงผล 128 pixels 192 pixels
  13. 13. class GameCanvasSprite1 extends GameCanvas implements Runnable{ Sprite hero, hero2; boolean running; protected GameCanvasSprite1() { super(true); Image im = null; try { im = Image.createImage("/sprites/c1.png"); } catch (IOException e) { } hero = new Sprite(im,32,48); //frame width = 32 hero2 = new Sprite(im,32,48); //frame height = 48 } public void start(){ running = true; Thread t = new Thread(this); t.start(); } ......
  14. 14. ................. public void run() { Graphics g = getGraphics(); int delay = 80; while(running){ drawScreen(g); hero.nextFrame(); //hero แสดง nextFrame hero2.prevFrame(); //hero2 แสดง prevFrame try {Thread.sleep(delay);} catch (InterruptedException e) { } } } void drawScreen(Graphics g){ int w = getWidth(); int h = getHeight(); g.setColor(0); g.fillRect(0, 0, w, h); hero.setPosition(w/2-50, h/2); //กำาหนดตำาแหน่ง และวาด sprite hero.paint(g); hero2.setPosition(w/2+50, h/2); hero2.paint(g); flushGraphics(); }
  15. 15. SpriteDemoMIDlet2.java • สร้าง GameCanvas ให้แสดง Sprite โดยแสดง ตำาแหนู งและทิศทาง ตาม key ท่กดคือ ี – left – right – up – down
  16. 16. IDEA • สร้าง int[] ของ direction แต่ละตัว เช่น – int[] frontDirection = {0,1,2,3}; – int[] leftDirection = {4,5,6,7}; ** ขึ้นอยู่กับรูป sprite ของเราว่าหันไปทิศทางใด ก่อน** • สร้าง thread ให้รับค่า input และ drawScreen โดยหากมีการกด key ให้เช็คว่า keyใดถูกกด เปลี่ยน direction ไปในทิศทางนั้น และใช้ method sprite.setFrameSequence(int[]) เพือเปลี่ยน frame index ของ sprite ในการ ่ แสดงผล
  17. 17. class GameCanvasSprite2 extends GameCanvas implements Runnable{ static int FRONT_DIRECTION = 0; //สร้าง static int เพือใหง่ายในการเขียน ่ code static int LEFT_DIRECTION = 1; static int RIGHT_DIRECTION = 2; static int BACK_DIRECTION = 3; Sprite hero; boolean running; int[][] sequence = { {0,1,2,3}, //front {4,5,6,7}, //left {8,9,10,11}, //right {12,13,14,15}}; //back int w, h; int cx,cy; int currentDirection = FRONT_DIRECTION; protected GameCanvasSprite2() { super(true); Image im = null; try {im = Image.createImage("/sprites/c1.png");} catch (IOException e) { } hero = new Sprite(im,32,48); w = getWidth(); h = getHeight(); cx = w/2; cy = h/2; hero.setFrameSequence(sequence[0]);
  18. 18. public void start(){ running = true; Thread t = new Thread(this); t.start(); } public void run() { Graphics g = getGraphics(); int delay = 40; while(running){ getInput(); drawScreen(g); hero.nextFrame(); try {Thread.sleep(delay);} catch (InterruptedException e) { } } } void drawScreen(Graphics g){ int w = getWidth(); int h = getHeight(); g.setColor(0); g.fillRect(0, 0, w, h); hero.setPosition(cx, cy); hero.paint(g); flushGraphics(); }
  19. 19. void getInput(){ int keyState = getKeyStates(); int cDirection = currentDirection; // เก็บทิศทางปัจจุบันไว้ เพือเช็คว่ามีการ ่ เปลี่ยนทิศทางหรือไม่ if(keyState== LEFT_PRESSED){ cx--; cx = Math.max(0, cx); currentDirection= LEFT_DIRECTION; } else if(keyState== RIGHT_PRESSED){ cx++; cx = Math.min(cx, w); currentDirection= RIGHT_DIRECTION; } else if(keyState== UP_PRESSED){ cy--; cy = Math.max(0, cy); currentDirection= BACK_DIRECTION; } else if(keyState== DOWN_PRESSED){ cy++; cy = Math.min(cy, h); currentDirection= FRONT_DIRECTION; } if(cDirection != currentDirection){ //เช็คว่ามีการเปลี่ยน direction หรือเปล่า หากเปลียนให้ ่ setFrameSequence // ใหม่เพื่อให้ได้ frame sequence ที่ตรงกับทิศทางเดิม hero.setFrameSequence(sequence[currentDirection]); }
  20. 20. END
  21. 21. Sprite & collide • SpriteCollideDemoMIDlet3.java • สร้าง GameCanvas โดยให้แสดง sprite สอง ตัว • หาก sprite ชน อีกตัว ให้หยุดเดิน
  22. 22. LayerManager
  23. 23. LayerManager methods void append(Layer l) Layer getLayerAt(int index) int getSize() void insert(Layer l, int index) void paint(Graphics g, int x, int y) void remove(Layer l) void setViewWindow(int x, int y, int w, int h) ** leyer ท่ี append กูอน จะอยูด้านบนสุด ่
  24. 24. Lab 2.11 LayerManagerDemoMIDlet1.java • สร้าง GameCanvas โดยสร้าง LayerManger เพ่ ือโหลดภาพ background และ sprite
  25. 25. class MyGameCanvas1 extends GameCanvas implements Runnable{ boolean running; int delay = 50; int cx, cy, w, h; Sprite player; Sprite background; LayerManager layerManager; protected MyGameCanvas1() { super(true); w = getWidth(); h = getHeight(); cx = w/2; cy = h/2; Image playerImage=null,bgImage=null; try { playerImage = Image.createImage("/sprites/c3.png"); bgImage = Image.createImage("/sprites/bg1.png"); } catch (IOException e) { } player = new Sprite(playerImage,32,48); background = new Sprite(bgImage); layerManager = new LayerManager(); layerManager.append(player); layerManager.append(background); }
  26. 26. public void start(){ running = true; Thread t = new Thread(this); t.start(); } public void run() { Graphics g = getGraphics(); while(running){ input(); drawScreen(g); try {Thread.sleep(delay);} catch (InterruptedException e) {} } } void input(){ ……………….. } void drawScreen(Graphics g){ g.setColor(0); g.fillRect(0, 0, w, h); player.setPosition(cx, cy); layerManager.paint(g, 0, 0); flushGraphics(); } }
  27. 27. not setting anything setViewWindow(100,0, w, h) setViewWindow(100,30,w, h);
  28. 28. LayerManager and Scrolling background • Idea ของการทำา scrolling background คือใช้ method setViewWindow(sx,sy,w,h) • โดย sx, sy คือตำาแหนู ง viewpoint บน background ท่ต้องการแสดงบน screen. ี (sx,sy)
  29. 29. Lab 2.12 LayerManagerDemoMIDlet1.java • สร้าง GameCanvas โดยให้แสดง sprite และ background เม่ ือตัว sprite ชนขอบ screen ให้ เล่ อน background ไปหน้ าถัดไป จนกวูาจะถึง ื ปลาย background
  30. 30. TiledLayer mao[] ={ 4,5,5,5,5,5,5,4,4,4, 4,5,5,5,5,5,5,5,5,4, 4,5,5,5,2,2,5,5,5,4, 4,5,5,5,2,2,5,5,5,4, 4,4,5,5,2,2,5,5,5,4, 4,4,4,5,5,2,2,2,5,4, 1,1,3,3,5,5,2,2,5,4, 3,1,3,3,3,5,5,5,5,4, 3,1,1,3,3,3,5,5,1,1, 3,3,1,1,1,1,1,1,1,3, 3,3,3,3,3,3,3,3,3,3}

×