เอกสารประกอบการสอน - twachi.netหน า 6 การใช...

Post on 19-Jul-2020

4 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

หนา 1

เอกสารประกอบการสอน

วชา 322218 Basics of Game Programming

แบบฝกปฏบต ครงท 4 Shooting Game

โดย อ.ดร.วชราวธ ธรรมวเศษ

วตถประสงค

1. เพอเรยนรการใชงาน Arcade Physics ส าหรบสรางเกมยง

2. การรบ Input จาก Keyboard และ Mouse

3. การใช Sprite, Group, Tween และ Weapon

1. The Game Concept

เนอเรอง

Actions

o กดปมซาย ขวา เลอนยานอวกาศ

o กด Space Bar ยง

GamePlay

o ผเลนควบคมยานอวกาศ หลบ และ ยง ยานของ Alien ทลอยผานมา

o ถายงถก Alien จะหายไป และ ไดคะแนน

o ถายานอวกาศ ของผเลนถก Alien ชนจะแพ

o ถายง Alien ไดหมดจะชนะ

หนา 2

2. The Game Art Work

ออกแบบ Sprite Sheet ของ ยานอวกาศ Player, ยาน Alien และ ลกกระสน

ให น.ศ. ออกแบบใหม โดยใชโปรแกรมทถนด (แนะน า www.piskelapp.com)

ship1.png ยานของผเลน

alien.png ตว alien

bullet.png ลกกระสน

3. The Game Code

3.1. สราง Phaser Project

สรางดวย Template Basic ตงชอเปน GameLab4

3.2. แกไขไฟล assets-pack.json

เพม spritesheet ใน section level และ +spritesheet รปยาน (ship1) เอเรยน (alien) และ กระสน

(bullet) ดงตวอยาง

หนา 3

3.3. แกไข Main.js เพอก าหนดขนาดพนทของเกม

ในแบบฝกหดนจะใชขนาด 360 x 640 เพอจะท าหนาจอใหพอดกบ จอโทรศพทมอแบบแนวตง

window.onload = function() {

var game = new Phaser.Game(360, 640, Phaser.AUTO);

// Add the States your game has.

game.state.add("Boot", Boot);

game.state.add("Menu", Menu);

game.state.add("Preload", Preload);

game.state.add("Level", Level);

// Now start the Boot state.

game.state.start("Boot");

};

3.4. แกไขหนาเมน ในไฟล menu.js

เพม Sprite ยานอวกาศ และ ขอความชอผเขยนโปรแกรม

Menu.prototype.create = function() {

var sprite = this.add.sprite(this.world.centerX, this.world.centerY,

"tap-to-start");

sprite.anchor.set(0.5, 0.5);

var text = this.add.text(10, this.world.height-20, "By Wachirawut Thamviset",

{fill: 'white'}); text.scale.set(0.4);

this.ship = this.add.sprite(this.world.centerX, this.world.height-20,"ship1");

this.ship.animations.add("all").play(12,true);

this.ship.anchor.set(0.5,1);

this.ship.scale.set(3);

this.ship.smoothed = false;

this.input.onDown.active = true;

this.input.onDown.add(this.startLevel, this);

}; ค าสง this.add.text เปนการเพมขอความ ระบต าแหนง x,y, ขอความ และ style

ในสวนนให นศ. ออกแบบ Logo ชอเกม และ ตกแตงหนา Menu ดวย sprite ใหสวยงาม

หนา 4

3.5. เพม effect โดยการแสดง tween กอนจะไปฉากเลนเกม

แกไขthis.input.onDown.add(this.startLevel, this); (ใน Menu.prototype.create )

เปน this.input.onDown.add(this.startGame, this); เพอจะใหมการแสดง tween กอนไปฉากเลน

เพม function Menu.prototype.startGame โดยใหยานเคลอนทขนไปดานบนจนถงจด y=0

ในตวอยางนจะใชการเคลอนทแบบ Elastic.easeIn หลงจากทแสดงเสรจจะไปเรยก this.startLevel เพอให

ฉากเลนเกมท างาน (this.input.onDown.active = false; เพอไมใหกดซ าระหวางทรอใหยานเคลอนไหว)

Menu.prototype.startGame = function() {

this.input.onDown.active = false;

var tw = this.add.tween(this.ship);

tw.to({y:0},2000, "Elastic.easeIn",true);

tw.onComplete.addOnce(this.startLevel, this);

};

Menu.prototype.startLevel = function(){

this.game.state.start("Level");

}

ตาราง EaseMap

Power0 Power1 Power2 Power3 Power4 Quad Cubic Quart Quint Sine Expo Circ Elastic Back Bounce

Quad.easeIn Cubic.easeIn Quart.easeIn Quint.easeIn Sine.easeIn Expo.easeIn Circ.easeIn Elastic.easeIn Back.easeIn Bounce.easeIn

Quad.easeOut Cubic.easeOut Quart.easeOut Quint.easeOut Sine.easeOut Expo.easeOut Circ.easeOut Elastic.easeOut Back.easeOut Bounce.easeOut

Quad.easeInOut Cubic.easeInOut Quart.easeInOut Quint.easeInOut Sine.easeInOut Expo.easeInOut Circ.easeInOut Elastic.easeInOut Back.easeInOut Bounce.easeInOut

Linear เราสามารถใช Mouse ไปวางท String ของ tween กจะมองเหนตวอยางการเคลอนท

หนา 5

4. ฉากเลนเกม Level.js

ในฉากนจะแสดงยานท ดานลาง กลางจอ โดยใช sprite (ship1)

แสดงคะแนนทมมบนซาย

Level.prototype.create = function() {

this.game.score = 0;

this.gameover=false;

this.physics.startSystem(Phaser.Physics.ARCADE);

this.player = this.add.sprite(this.world.centerX,600,"ship1");

this.player.anchor.set(0.5,0.5);

this.player.animations.add("fly");

this.player.play("fly",12,true);

this.player.smoothed=false;

this.player.scale.set(2);

this.physics.enable(this.player, Phaser.Physics.ARCADE);

this.player.body.collideWorldBounds = true;

this.player.body.allowGravity = false;

this.player.body.maxVelocity.setTo(200,2000);

this.createAlien();

this.createWeapon();

this.scoreText = this.add.text(32, 0, ''+this.game.score, { fill: 'white' });

this.scoreText.z = 10;

this.input.keyboard.addKeyCapture([

Phaser.Keyboard.LEFT,

Phaser.Keyboard.RIGHT,

Phaser.Keyboard.SPACEBAR,

Phaser.Keyboard.X

]);

this.player.inputEnabled = true;

this.player.events.onInputDown.add(this.fireWeapon, this);

};

Level.prototype.update = function() { }

Level.prototype.createAlien = function() { }

Level.prototype.createWeapon = function() { }

Level.prototype.fireWeapon = function() { }

ค าอธบาย

this.player = this.add.sprite(this.world.centerX,600,"ship1"); เปนการสราง Sprite คณสมบตของ Sprite ทควรร x, y, position คอ ต าแหนง x,y เปนตวเลข สวน position เปน Object ทม x, y อยขางใน anchor คอ ต าแหนงของสมอ เปน Object ประกอบดวย x,y มคาระหวาง 0-1 animations เปน Animation Manager ของ sprite ใชควบคมการท า animation play( ) คอ ค าสงใหเลน animation ตาม key ทตงไว scale คอ ตวเลขแทนขนาด ถานอยกวา 1 จะเปนการยอภาพ ถามากกวา 1 จะเปนการขยาย

หนา 6

การใช Physic Arcade เบองตน Phaser จะมชดค าสงในการค านวณเกยวกบการจ าลองฟสกสในเกมสอยหลายตว เชน Arcade, P2, Ninja เปนตน ส าหรบแบบฝกหดนจะเปนฝกใช Phaser.Physics.ARCADE แบบพนฐาน หนาทของฟสกสในเกมจะใชจ าลองการเคลอนทของวตถ เกยวของกบ ความเรว ความเรง มม มวล แรงและการชน การตกกระทบ เปนตน Physics.ARCADE จะสามารถใชกบวตถทมรปทรงแบบงายๆ คอ สเหลยม และ วงกลม จงเหมาะกบเกมงายๆ ทไมตองใชการค านวณละเอยด ท าใหมความเรวในการประมวลผลสง การเรมใชงาน this.physics.startSystem(Phaser.Physics.ARCADE);

การระบวา Sprite หรอ Object ใดทจะใชงาน Physics this.physics.enable(this.player, Phaser.Physics.ARCADE);

ในตวอยางก าหนดให player ใชงาน physics

object.body เปนขอมลล าตวของวตถทอยในโลกจ าลอง ซงจะสามารถก าหนดขนาด มวล ความเรว ความเรง ได เชน ก าหนดให sprite เคลอนออกนอก world ไมได (หนาจอเกม เรยกวา World) this.player.body.collideWorldBounds = true;

ก าหนดให sprite ไรแรงดงดด ให allowGravity = false

ถามแรงดงดดยานกจะตกลงไปดานลาง แตในเกมนยานจะลอยจงก าหนดใหเปน false this.player.body.allowGravity = false;

ก าหนดคาความเรวสงสดในแนวแกน x และ y เปน pixels / sec

หมายความวา ยานจะเลอนไปตามแนวแกน x ดวยความเรวไมเกน 200 this.player.body.maxVelocity.setTo(200,2000);

5. ควบคมยานเคลอนท ซาย ขวา เราจะเขยนค าสงส าหรบควบคมยานของผเลนไวท function update

ซงฟงกชนนจะถกเรยกตลอดเวลาเกมท างาน ประมาณ 60 รอบตอวนาท

Level.prototype.update = function(){

if(this.gameover) return;

if(this.input.keyboard.isDown(Phaser.Keyboard.LEFT)){

this.player.body.acceleration.x = -600;

}else if(this.input.keyboard.isDown(Phaser.Keyboard.RIGHT)){

this.player.body.acceleration.x = 600;

}else{

this.player.body.velocity.setTo(0, 0);

this.player.body.acceleration.setTo(0, 0);

}

}

หนา 7

ค าอธบาย

เราจะใหค าสงในฟงกชนนท างานรบคาจะ keyboard เฉพาะเมอเกมยงเลนอย ถา gameover กไมตองท างานจงเขยนค าสงน if(this.gameover) return; body.acceleration คอ คาความเรงของวตถ ภายในจะม x และ y

body.acceleration.x คอ คาความเรงของวตถตามแนวแกน x

body.acceleration.y คอ คาความเรงของวตถตามแนวแกน y

ถากดปมซายใหความเรงแนวแกน x เปน -600 ยานกจะเคลอนไปทางซาย if(this.input.keyboard.isDown(Phaser.Keyboard.LEFT) this.player.body.acceleration.x = -600;

ถากดปมขวาใหความเรงแนวแกน x เปน 600 ยานกจะเคลอนไปทางขวา if(this.input.keyboard.isDown(Phaser.Keyboard.RIGHT) this.player.body.acceleration.x = 600;

ถาปลอยมอยานกจะหยด this.player.body.velocity.setTo(0, 0);

this.player.body.acceleration.setTo(0, 0);

ยานล านจะเคลอนทขนลงไมได

ถาจะใหเคลอนทขนลงดวย กสามารถเพมการควบคม body.acceleration.y

6. การสรางอาวธ อาวธของยานอวกาศในเกมนคอ การยงกระสน ในแตละเกม

อาจจะมอาวธหลากหลายชนดทมการแสดงผล และ วธการเคลอนท

แตกตางกน ซงในกรณนจะท ากระสนแบบงายๆ มการเคลอนทขนใน

แนวตงเทานน

ใน Phaser จะม plugin ชอวา Phaser.Weapon ใช

ส าหรบสรางอาวธส าหรบเกมยงโดยเฉพาะ ซงเราจะน าใชใน

แบบฝกหดน

หนา 8

Level.prototype.createWeapon = function() {

this.weapon1 = this.add.weapon(10,"bullet",1);

this.weapon1.bulletKillType = Phaser.Weapon.KILL_WORLD_BOUNDS;

this.weapon1.trackSprite(this.player,-20,-30);

this.weapon1.bulletSpeed = 500;

this.weapon1.fireAngle = 270;

this.weapon1.rate = 600;

this.weapon2 = this.add.weapon(10,"bullet",2);

this.weapon2.bulletKillType = Phaser.Weapon.KILL_WORLD_BOUNDS;

this.weapon2.trackSprite(this.player,20,-30);

this.weapon2.bulletSpeed = 500;

this.weapon2.fireAngle = 270;

this.weapon2.rate = 600;

}

ในแบบฝกหดน ยานอวกาศมปนตดทปก 2 กระบอก จงตองท า อาวธ 2 อน

ค าสง this.add.weapon(10,"bullet",3); เปนการสรางอาวธ

- ตวเลข 10 คอ จ านวนกระสนทยงไดพรอมกน ไมเกน 10 นด ก าหนดคาไดตงแต 1 ขนไป

- bullet เปนชอ spritesheet ทใชท าภาพกระสน

- ตวเลข 3 คอ หมายเลข frame (ตวอยางนม กระสน 4 แบบ 0-3)

ค าสง weapon1.bulletKillType = Phaser.Weapon.KILL_WORLD_BOUNDS;

เปนการบอกวา ลกกระสนจะลบออกไปเมอใด กรณนคอเมอออกนอกจอ (WORLD)

ค าสง weapon1.trackSprite(this.player,-20,-30);

เปนการก าหนดใหอาวธนตดอยต าแหนง ไหนของตวยาน กรณน 0,0 หมายถงจดศนยกลางยาน ปนกระบอกแรกจะใหอยปกดานซาย จงใหอยแกน x -20 (มาทางซาย 20 pixel) และ y - 30 (ขนดานบนอก 30)

ค าสง this.weapon1.bulletSpeed = 500; เปนการก าหนดความเรวของกระสน

ค าสง this.weapon1.fireAngle = 270; เปนการก าหนดมมยง

ค าสง this.weapon1.rate = 600; เปนความเรวของการยง (Phaser version 2.6)

0,0

-20,-30 20,-30

หนา 9

ค าสง this.weapon1.bulletSpeed = 500; เปนการก าหนดความเรวของกระสน

เพมค าสงยงกระสนใน fireWeapon () เมอ click ทยาน

โดยการเรยก this.weapon1.fire();

Level.prototype.fireWeapon = function(){

this.weapon1.fire(); this.weapon2.fire();

} ค าสง fireWeapon จะถกเรยกใชจาก event input ทตงไวในขอ 4

this.player.events.onInputDown.add(this.fireWeapon, this);

7. สราง aliens

เขยนในฟงกชน createAlien

Level.prototype.createAlien = function() {

this.aliens = this.add.group(this.game.world,'aliens',false,true, Phaser.Physics.ARCADE); this.aliens.z = 100;

for(i=0;i<30;i++){

a = this.aliens.create(Math.random() * 300,-Math.random() * 300,"alien");

a.animations.add("fly").play(12,true);

a.anchor.set(0.5);

a.body.velocity.y = 50;

tw = this.add.tween(a);

var nx=20+Math.random()*300;

var nt=Math.random()*500;

tw.to({x:nx},1000+nt, "Sine",true,0,Number.MAX_VALUE,true);

if(Math.random()>0.5) a.body.angularVelocity = 60

else a.body.angularVelocity = -60;

}

}

ค าสง this.aliens = this.add.group เปนการสรางกลม โดยก าหนดใหสมาชกในกลมนใช การจ าลอง

Physics แบบ Arcade

ค าสง this.aliens.z เปนการก าหนดล าดบการแสดงผลของกลมน ใหอยลาง ตวเลข score (score จะมคา z

= 10) คา z มากกวาจะอยลกกวา

ค าสง for(i=0;i<30;i++) เปนการวนลป 30 รอบ

ค าสง a = this.aliens.create เปนการสราง alien โดยการสมต าแหนง ดวย Math.random()

ค าสง a.animations.add("fly").play(12,true); เปนก าหนดคา animation

ค าสง a.body.velocity.y = 50; จะให alien เคลอนทลงมาดานลางดวยความเรว 50

ค าสง tw = this.add.tween(a); เปนการสรางการเคลอนทดวย tween ซงตวอยางนจะใหเคลอนทไปมา

ซายขวา

หนา 10

เมอรนโปรแกรมจะเหนวา Alien จะเคลอนทไปมา และ คอยๆ เลอนลงไปเรอย และหายออกไปจากจอ

เราจะเพมค าสงเพอให alien ทหายไป กลบขนไปอยดานบน ใหม

โดยจะเขยนในไวใน update ซงจะได update ใหมดงน Level.prototype.update = function(){

if(this.gameover) return;

this.aliens.forEachAlive(function(a){ if(a.y > this.world.height) a.y = -Math.random() * 300; },this);

}

ค าอธบาย this.aliens.forEachAlive(function(a){

if(a.y > this.world.height) a.y = -Math.random() * 300; },this);

เปนการสงใหวนลปประมวลผล alien ทกตวทมชวต (ยงไมถก kill) โดยเขยน code ส าหรบการประมวลผล

ไวใน function ดงตวอยาง ถา a.y หมายถง ต าแหนง y ของ alien ตวใด มากกวา ความสงของจอ ให

กลบไปดานบน โดยการสมต าแหนง

8. ตรวจสอบการชนของกระสนกบ aliens

เมอกระสนถกยงไปชนกบ alien ตวใด alien และ กระสนจะถกก าจดออกจากหนาจอ

จะเขยนดวยค าสง physics.arcade.collide และ เนองจากเรามปน 2 กระบอกดงนนจงตอง

ตรวจสอบกระสนจากปนทง 2 กระบอก ดงตวอยาง

this.physics.arcade.collide(this.aliens,this.weapon1.bullets,this.onCollide,null,this);

this.physics.arcade.collide(this.aliens,this.weapon2.bullets,this.onCollide,null,this);

ซงค าสงนจะเขยนไวใน update() ดงนน ตอนนโปรแกรมใน update จะกลายเปน

if(this.input.keyboard.isDown(Phaser.Keyboard.LEFT)){

this.player.body.acceleration.x = -600;

}else if(this.input.keyboard.isDown(Phaser.Keyboard.RIGHT)){

this.player.body.acceleration.x = 600;

}else{

this.player.body.velocity.setTo(0, 0);

this.player.body.acceleration.setTo(0, 0);

}

if(this.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)){

this.fireWeapon();

}

หนา 11

เขยน function onCollide เพมเพอท างานเมอเกดการชนกนระหวาง alien และ bullet

ใหก าจด alien และ bullet แลวเพมคะแนน

Level.prototype.onCollide = function(alien,bullet){

alien.kill();

bullet.kill();

this.game.score++;

this.scoreText.text = ''+this.game.score;

};

9. You Win

เกมนผเลนจะชนะเมอยง alien จนหมด ดงนนเราจะเพมค าสงเพอตรวจสอบวา alien หมดหรอยง และเมอ

alien หมดแลวกใหแสดงขอความวา You Win แลวกลบไป หนา Menu โดยค าสงนจะเขยนไวท update

การนบจ านวน alien ทยงอย ท าไดดวยค าสง this.aliens.countLiving() ดงนน โปรแกรมจะเขยน

ไดดงตวอยาง

if(this.aliens.countLiving()==0 ){

this.gameover=true;

win = this.add.text(this.world.centerX,this.world.centerY,"You Win",{ fill: 'Yellow'});

win.anchor.set(0.5,0.5);

win.scale.set(0.1);

var tw = this.add.tween(win.scale);

tw.to({x:2,y:2},1000, "Linear",true,0);

delay = this.add.tween(win);

delay.to({y:100},1000, "Linear",true,2000);

tw.chain(delay);

delay.onComplete.addOnce(this.quitGame, this);

}

ตวอยางนเมอ alien ตายหมด กจะสราง text “You Win” ทกลางจอ แลวใช tween ท าใหตวขยายใหญขน

แลวใช tween.chain ตอดวยเลอนขอความขนดานบน เมอแสดงจบ กเรยกใช this.quitGame กลบไป Menu

Level.prototype.quitGame = function() {

this.game.state.start("Menu");

};

Level.prototype.update = function(){

if(this.gameover) return;

if(this.input.keyboard.isDown(Phaser.Keyboard.LEFT)){

this.player.body.acceleration.x = -600;

}else if(this.input.keyboard.isDown(Phaser.Keyboard.RIGHT)){

this.player.body.acceleration.x = 600;

}else{

this.player.body.velocity.setTo(0, 0);

this.player.body.acceleration.setTo(0, 0);

}

if(this.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)){

this.fireWeapon();

}

this.aliens.forEachAlive(function(a){

if(a.y > this.world.height) a.y = -Math.random() * 300;

},this);

this.physics.arcade.collide(this.aliens,this.weapon1.bullets,this.onCollide,null,this);

this.physics.arcade.collide(this.aliens,this.weapon2.bullets,this.onCollide,null,this);

}

หนา 12

รวมแลวฟงกชน update จะม code ดงน

10. ตรวจสอบการชนของ aliens กบ player

ใหเขยนโปรแกรมเพมเตม ตรวจสอบการชนระหวาง alien กบ player

เมอชนกนใหลดพลงชวต ถาชนครบ 3 ครงใหตาย และ สรางสวนแสดง Game Over แลวกลบไปหนาเมน

เมอ Player แพ

11. ตกแตงเกม

ออกแบบเนอเรอง ตวละคร (ยาน) และ alien โดยอสระ

แกไขหนาเมน ใสชอเกม พนหลง และ อาจจะใสดนตรประกอบ(ดจากตวอยางในเวบของ phaser)

ในหนาเลนเกมใหเพม image เปนฉากหลงใหสวยงาม

Level.prototype.update = function(){

if(this.gameover) return;

if(this.input.keyboard.isDown(Phaser.Keyboard.LEFT)){

this.player.body.acceleration.x = -600;

}else if(this.input.keyboard.isDown(Phaser.Keyboard.RIGHT)){

this.player.body.acceleration.x = 600;

}else{

this.player.body.velocity.setTo(0, 0);

this.player.body.acceleration.setTo(0, 0);

}

if(this.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)){

this.fireWeapon();

}

this.aliens.forEachAlive(function(a){

if(a.y > this.world.height) a.y = -Math.random() * 300;

},this);

this.physics.arcade.collide(this.aliens,this.weapon1.bullets,this.onCollide,null,this);

this.physics.arcade.collide(this.aliens,this.weapon2.bullets,this.onCollide,null,this);

if(this.aliens.countLiving()==0 ){

this.gameover=true;

win = this.add.text(this.world.centerX,this.world.centerY,"You Win",{fill:'Yellow'});

win.anchor.set(0.5,0.5);

win.scale.set(0.1);

var tw = this.add.tween(win.scale);

tw.to({x:2,y:2},1000, "Linear",true,0);

delay = this.add.tween(win);

delay.to({y:100},1000, "Linear",true,2000);

tw.chain(delay);

delay.onComplete.addOnce(this.quitGame, this);

}

}

top related