Mobile Gameand Application withJ2ME

Preview:

DESCRIPTION

Sprite

Citation preview

Sprite (สไปรต์�)• Sprite

• Sprite Frames

• Frame sequence

• Sprite transforms

• Sprite drawing

• Sprite collision

หลักการสร�างภาพเคลั��อนไหวบนมื�อถื�อ (Animation)

• การสร�างภาพต่าง ๆ ที่��เคลื่��อนที่��บนโที่รศั�พที่�จะต่�องแสดงภาพต่าง ๆ ด�วยความเร"วอยางน�อย 12 เฟรม (frame) ต่อว$นาที่� แต่ถ้�าแต่ลื่ะภาพเคลื่��อนที่��ด�วยความเร"ว 25 fps (frames per second) ภาพจะเคลื่��อนที่��ด�วยความน&มนวลื่มาก ในการพ�ฒนา MIDlet ต่าง ๆ ของภาพเคลื่��อนไหว จะต่�องค,าน-งถ้-งความเร"วในการแสดงเฟรมของภาพบนโที่รศั�พที่�ม�อถ้�อ เน��องจากโที่รศั�พที่�ม�อถ้�อม�หนวยความจ,าแลื่ะความสามารถ้ในการประมวลื่ผลื่จ,าก�ด

ประเภทของภาพเคลั��อนไหว ( Type of Animation) แบ�งออกเป น 2 ประเภท

ค�อ •  ภาพเคลื่��อนไหวข-0นอย1ก�บเฟรม (frame-based

Animation)

•  ภาพเคลื่��อนไหวข-0นอย1ก�บการเคลื่��อนที่��ส$�งต่าง ๆ ภายในเฟรม (Cast-based Animation

 ร1ปแบบของภาพเคลื่��อนไหวที่��เคลื่��อนที่��โดยการใช้� ออปเจ"กต่�ต่าง ๆ ที่างกราฟฟ3กเคลื่��อนย�ายอยาง

อ$สระบนพ�0นหลื่�ง (Background) หร�อออปเจ"กต่� อ��น ถ้�อได�วาเป4นภาพเคลื่��อนไหวของสไปรต่�ที่��น$ยม

น,าไปใช้�ในการเข�ยนเกมส�

สไปรต์� (Sprite) เป4นออปเจ"กต่�ที่างกราฟฟ3กที่��สามารถ้เคลื่��อนที่��อยางอ$สระบนพ�0นหลื่�ง (Background) หร�อออปเจ"กต่�อ��น

การต์รวจพบการกระทบกน (Collision Detection)

• เป4นว$ธี�การต่รวจสอบวา สไปรต่� (Sprite) เคลื่��อนที่��กระที่บก�บ สไปรต่� (Sprite) ต่�วอ��นหร�อไม ม�ประโยช้น�มากในการน,าไปใช้�ก�บภาพเคลื่��อนไหวของเกมส� แต่ลื่ะสไปรต่� (Sprite) จะม�ขอบเขต่เป4นส��เหลื่��ยมม&มฉาก บางสวนของภาพจะโปรงแสง เม��อเคลื่��อนที่��กระที่บก�นจะที่,าให�ม&มของส��เหลื่��ยมม&มฉากเหลื่��อมลื่,0าก�น ที่,าให�ต่รวจพบได�ที่�นที่�วาม�การกระที่บก�น

การสร�างภาพเคลั��อนไหวของสไปรต์� (Creating Sprite Animation)

• คลัาส Sprite จะให�การสน�บสน&นภาพเคลื่��อนไหวของเฟรม (frame) ในลื่�กษณะอะเรย�ของภาพต่าง ๆ ของเฟรมแลื่ะช้วยจ,าแนกประเภที่ภาพเคลื่��อนไหว เมธีอด (method) ต่าง ๆ ของคลื่าส Sprite ช้วยสร�างสไปรต่� การเคลื่��อนที่��ของสไปรต่� ต่รวจสอบการช้นก�นของสไปรต่�

ค&ณลื่�กษณะต่าง ๆ ของสไปรต่� (Sprite Properties)

•  ต่,าแหนง x: ใช้�แที่นพ$ก�ด (coordinate) ของสไปรต่�ในแนวระด�บ ที่��คอลื่�มน�ซ้�ายส&ดของจอภาพ ต่,าแหนง x เป4น 0 คอลื่�มน�ขวาส&ดของจอภาพกว�าง 100 จ&ด (pixel) เป4น 99

•  ต่,าแหนง y: ใช้�แที่นพ$ก�ดของสไปรต่�ในแนวด$�ง แถ้วบนส&ดของจอภาพ ต่,าแหนง y เป4น 0 แถ้วลื่างส&ดของจอภาพยาว 100 จ&ด (pixel) ต่,าแหนง y จะเป4น 99

•  ความเร"ว Vx: ใช้�แที่นความเร"วของสไปรต่� (ระยะที่��สไปรต่�เคลื่��อนที่��ในแต่ลื่ะคร�0ง) ในแนวระด�บ น��นค�อ ที่&ก ๆ เฟรม (frame) สไปรต่�จะเคลื่��อนที่�� Vx จ&ด (pixel) ถ้�า Vx คาเป4นลื่บสไปรต่�จะเคลื่��อนที่��ไปที่างซ้�ายม�อ นอกน�0นม�นจะเคลื่��อนที่��ไปที่างขวาม�อ

•  ความเร"ว Vy: ใช้�แที่นความเร"วของสไปรต่� ในแนวด$�ง น��นค�อ ที่&ก ๆ เฟรม สไปรต่�จะเคลื่��อนที่�� Vy จ&ด ถ้�า Vy คาเป4นลื่บ สไปรต่�จะเคลื่��อนที่��ไปข�างบน นอกน�0นม�นจะเคลื่��อนที่��ไปข�างลื่าง แลื่ะถ้�า ที่�0ง Vx แลื่ะ Vy เป4น 0 สไปรต่�จะอย1น$�ง

•  width: ใช้�แที่นความกว�างของภาพกราฟฟ3กของสไปรต่� เม��อใช้�รวมงานก�บต่,าแหนง x ม�นจะก,าหนดขอบขวาม�อของสไปรต่�บนพ$ก�ด x

•  height: ใช้�แที่นความส1งของภาพกราฟฟ3กของสไปรต่� เม��อใช้�รวมงานก�บต่,าแหนง y ม�นจะก,าหนดขอบลื่างส&ดของสไปรต่�บนพ$ก�ด y

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 โดยสร�างเป4น frame จาก image

frameWidth

frameHeight

0 1 2 3

4 5 6 7

8 9 10 11

12 13 14 15

frame index

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) แบบน�0 ไมได�

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)

SpriteDemoMIDlet1.java

• สร�าง GameCanvas ให�แสดง Sprite สองจ&ด โดยใช้� method nextFrame() แลื่ะ prevFrame() ในการแสดงผลื่

192 pixels

128 pixels

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 = 32hero2 = new Sprite(im,32,48); //frame height = 48

}

public void start(){running = true;Thread t = new Thread(this);t.start();

}......

.................public void run() {

Graphics g = getGraphics();int delay = 80;while(running){

drawScreen(g);hero.nextFrame(); //hero แสดง nextFramehero2.prevFrame(); //hero2 แสดง prevFrametry {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();}

}

SpriteDemoMIDlet2.java

• สร�าง GameCanvas ให�แสดง Sprite โดยแสดงต่,าแหนงแลื่ะที่$ศัที่าง ต่าม key ที่��กดค�อ– left– right– up– down

IDEA

• สร�าง int[] ของ direction แต่ลื่ะต่�ว เช้น– int[] frontDirection = {0,1,2,3};– int[] leftDirection = {4,5,6,7};** ข-0นอย1ก�บร1ป sprite ของเราวาห�นไปที่$ศัที่างใดกอน**

• สร�าง thread ให�ร�บคา input แลื่ะ drawScreen โดยหากม�การกด key ให�เช้"ควา keyใดถ้1กกด เปลื่��ยน direction ไปในที่$ศัที่างน�0น แลื่ะใช้� method sprite.setFrameSequence(int[]) เพ��อเปลื่��ยน frame index ของ sprite ในการแสดงผลื่

•**ในต่�วอยางเราสร�างเป4น int[][] เพ��อเก"บ sequence เพ��อให�เข�ยน code งายข-0น **

class GameCanvasSprite2 extends GameCanvas implements Runnable{static int FRONT_DIRECTION = 0; //สร�าง static int เพ��อใหงายในการเข�ยน

codestatic 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]);

}

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();

}

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]);

}}

}

END

Sprite & collide

• SpriteCollideDemoMIDlet3.java• สร�าง GameCanvas โดยให�แสดง sprite สองต่�ว• หาก sprite ช้น อ�กต่�ว ให�หย&ดเด$น

LayerManager

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 กอน จะอย1ด�านบนส&ด

Lab 2.11 LayerManagerDemoMIDlet1.java

• สร�าง GameCanvas โดยสร�าง LayerManger เพ��อโหลื่ดภาพ background แลื่ะ sprite

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);

}

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();

}}

not setting anything setViewWindow(100,0, w, h) setViewWindow(100,30,w, h);

LayerManager and Scrolling background

• Idea ของการที่,า scrolling background ค�อใช้� method setViewWindow(sx,sy,w,h)

• โดย sx, sy ค�อต่,าแหนง viewpoint บน background ที่��ต่�องการแสดงบน screen.

(sx,sy)

Lab 2.12 LayerManagerDemoMIDlet1.java

• สร�าง GameCanvas โดยให�แสดง sprite แลื่ะbackground เม��อต่�ว sprite ช้นขอบ screen ให�

เลื่��อน background ไปหน�าถ้�ดไป จนกวาจะถ้-ง ปลื่าย background

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 }