打飞机游戏雷电是一款经典的空战游戏,利用已知的CreateJS知识就可以很容易的做出一款类似的打飞机游戏。
首先,弄一些游戏需要的资源,做这样的一个小游戏,首先需要一架玩家操控的飞机图片,然后是可以击落的敌机图片,连续的爆炸图片来组成一个爆炸的动画Sprite,开枪的声音,爆炸的声音,星空的背景,然后使用TexturePacker把这些图片合并成一张图片,并获得一个json文件,其中的数据可以用做生成SpriteSheet的参数。
而后,有了资源之后,再构想一个大概的游戏框架,从最基础的CreateJS游戏框架开始,思考游戏的流程和逻辑,逐步的添加哪些功能来实现这个游戏,我的打飞机游戏最初的框架是这样的
var stage;
function init(){
//1.导入资源,并在资源加载完成后调用处理函数handleComplete
//2.创建舞台stage
}
function handleComplete(){
buildGame();//3.创建游戏界面,星空,玩家飞机,敌机,计分版等
setContorl();//4.设置按键控制,让玩家可以左右移动并发射子弹
startGame();//5.进入游戏循环,使用tick事件实现游戏的变化,发展
}
function startGame(event){
createjs.Ticker.setFPS(60);
createjs.Ticker.addEventListener('tick',function(){
updateGame();//6.更新游戏元素的位置,更新分数等
checkGame();//7.检查游戏中的元素是否发生碰撞,敌机被击落,还是飞出屏幕等等
stage.update();
});
}
按照思路,一切顺利的话,完成这7个步骤,一个简单的打飞机游戏就产生了。那么先从导入资源和创建舞台开始吧
1.准备好所用的图片和声音,首先把所用的图片合成到一起,准备两个声音文件,发射子弹shot.mp3和爆炸的声音explosion.mp3,创建好页面的Canvas并把背景设置为黑色的
2.初始化部分,创建舞台和导入文件
function init(){
stage = new createjs.Stage('game');
sWidth = stage.canvas.width;
sHeight = stage.canvas.height;
queue = new createjs.LoadQueue(true);
createjs.Sound.registerPlugins([createjs.HTMLAudioPlugin]);
queue.installPlugin(createjs.Sound);
queue.on("complete", handleComplete);
queue.loadManifest([{id:"sprite", src:"./img/sprites.png"},
{id:"shot", src:"music/shot.mp3"},
//{id:"explosion", src:"music/explosion.mp3"}
]);
}
这里只使用PreloadJS导入了一个声音文件,爆炸的声音使用另一种方式播放,文件载入完成后,进入handleComplete函数,开始创建游戏界面/元素等工作,在handleComplete中,包含三个部分,
function handleComplete(){
buildGame();//3.创建游戏界面,包括星空,玩家飞机,敌机,计分版等
setContorl();//4.设置按键控制,让玩家可以左右移动并发射子弹
startGame();//5.进入游戏循环,使用tick事件实现游戏的变化,发展
}
先从buildGame()开始,创建界面,添加元素包含四部分
function buildGame(){
buildMsg();//计分,和 玩家剩余的飞机数
buildPlayer();//创建玩家的飞机
buildEnemy();//创建敌机
buildSpace();//星空背景,因为我没有找到星空图片
}
首先从最底层的创建背景buildSpace()开始。我打算用1px的圆来作为星星,设置alpha用透明度来表示星星的远近不同,并且远处的星星运动速度慢,而近处的速度快。
function buildSpace(){
var i, star, w, h, alpha;
for (i=0; i<200; i++){
starSky = new createjs.Container();
star = new createjs.Shape();
w = Math.floor(Math.random()*stage.canvas.width);
h = Math.floor(Math.random()*stage.canvas.height);
alpha = Math.random();
star.graphics.beginFill("#FFF").drawCircle(0,0,1);
star.x = w;
star.y = h;
star.alpha = alpha;
starSky.addChild(star);
starArr.push(star);
stage.addChild(starSky);
}
}
所有的白点先被添加到一个container中,最后添加到舞台上。好了,运行看是不是有点星空感觉,但是现在他们是不动的,打算在后面的tick中,做一个普通的动画。
接下来是创建玩家的飞机buildPlayer():
function buildPlayer(){
var data = {
images:[queue.getResult("sprite")],
frames:[
[0,0,37,42],
[37,0,42,42],
[79,0,37,42],
[116,0,42,42],
[158,0,37,42],
[0,70,64,64],
[64,70,64,64],
[128,70,64,64],
[192,70,64,64],
[256,70,64,64],
[320,70,64,64],
[384,70,64,64],
[448,70,64,64],
[512,70,64,64],
[576,70,64,64],
[640,70,64,64],
[704,70,64,64],
[768,70,64,64]
],
animations:{
ship:0,
enemy1:1,
enemy2:2,
enemy3:3,
enemy4:4,
exp:{
frames:[5,6,7,8,9,10,11,12,13,14,15,16],
speed:.5
}
}
};
spriteSheet = new createjs.SpriteSheet(data);
createjs.Sound.registerSound("./music/explosion.mp3",explosion);
player = new createjs.Sprite(spriteSheet,"ship");
player.x = sWidth/2 ;
player.y = sHeight - player.getBounds().height;
stage.addChildAt(player,0);
}
首先在这里建一个SpriteSheet,包含一个玩家飞机,四个敌机,还有一个爆炸的动画,前五个都是单帧的图片,只有爆炸是用连续图片来组成的一个动画,随后又注册了一个声音,为了测试声音文件的用法,如果没有在preload中提前载入声音文件,使用前,使用createjs.Sound.registerSound("./music/explosion.mp3",explosion);先注册一下,最后的stage.addChildAt(player,0)使用addChildAt添加元素,可以设置元素的顺序,0表示玩家的飞机永远在最上层。
有了飞机,然后定义setControl(),通过键盘操作让你的飞机动起来并且可以发射导弹,首先来定义几个常量
const ARROW_KEY_LEFT = 37;//键盘左键
const ARROW_KEY_RIGHT = 39;//键盘右键
const SPACE_KEY = 32;//键盘空格
然后是两个bool值表示左右按键的状态
var leftKeyDown = false, rightKeyDown = false;
function setControl(){
window.onkeydown = handleKeyDown;
window.onkeyup = handleKeyUp;
}
function handleKeyDown(e){
e = !e ? window.event : e;
switch(e.keyCode){
case ARROW_KEY_LEFT:
leftKeyDown = true;
break;
case ARROW_KEY_RIGHT:
rightKeyDown = true;
break;
}
}
function handleKeyUp(e){
e = !e ? window.event : e;
switch(e.keyCode){
case ARROW_KEY_LEFT:
leftKeyDown = false;
break;
case ARROW_KEY_RIGHT:
rightKeyDown = false;
break;
case SPACE_KEY:
playFire();
}
}
最后是空格键的相应函数playFire(),按下空格,发射一枚子弹
function playFire(){
if(fireAble){
var fire = new createjs.Shape();
fire.graphics.beginFill("#FF0").drawRect(0,0,2,5).endFill();
fire.x = player.x + 18;
fire.y = 658;
createjs.Sound.play("shot");
fires.push(fire);
stage.addChild(fire);}
}
fireAble是一个bool值,默认是true,当玩家飞机被摧毁后,有段时间是处于无敌状态然后把fireAble设置为false,无敌状态不能发射子弹,createjs.Sound.play("shot");可以直接调用你在preload中载入的声音,不需要像explosion.mp3一样,使用前需要注册,这样每次按键都会播放一次发射的声音,并产生一个白色的子弹,当然子弹现在也是不能动的,后面的tick相应函数中会让它动起来。
现在屏幕的最底端多了一架飞机,是不是距离成功越来越近了,现在添加信息栏buildMsg(),就是两个Text,用来显示玩家得分和剩余的战机
function buildMsg(){
livesTxt = new createjs.Text("lives:" + lives, "20px Times", "#FFF");
livesTxt.y = 5;
livesTxt.x = 10;
stage.addChild(livesTxt);
scoreTxt = new createjs.Text("score:" + score, "20px Times", "#FFF");
scoreTxt.y =5;
scoreTxt.x = sWidth - 100;
stage.addChild(scoreTxt);
}
好了,做完这些,你的游戏看起来是这样的,玩家飞机可以左右移动并发射子弹
最后是添加敌机,敌机的种类共有四种,但是你肯定不会只添加四架飞机。首先把四架飞机添加到一个数组enemyClip中,做一个敌机的集合,然后调用buildEnemis()通过循环来复制enemyClip中的每一类敌机来创建一个敌机群。
function buildEnemy() {
var i, e1, e2, e3, e4;
e1 = new createjs.Sprite(spriteSheet, "enemy1");
e2 = new createjs.Sprite(spriteSheet, "enemy2");
e3 = new createjs.Sprite(spriteSheet, "enemy3");
e4 = new createjs.Sprite(spriteSheet, "enemy4");
enemyClip.push(e1, e2, e3, e4);
buildEnemis();
}
function buildEnemis(){
var i, j=0,en,en1;
for(i=0;i<4;i++){
en = enemyClip[i].clone();
for(j=0;j<6;j++){
en1 = en.clone();
enemy.push(en1);
createjs.Tween.get(en1).wait(5000*i).to({x:300,y:800},5000,createjs.Ease.sineInOut(-2))
stage.addChild(en1);
}
}
}
到这里所有的创建工作都结束了,后面要做的就让星空、子弹动起来(通过在tick相应函数中改变y坐标,敌机使用TweenJS已经开始运动),判断子弹是否与敌机相撞,敌机是否与玩家相撞,更新得分,继续添加敌机等