前回「初めてのenchant.js 014オブジェクトの拡張[JavaScript]」までで基本的な部分はだいたい理解できたので、
今回は簡単なゲームを作ってみました。

完成サンプル


完成版のファイル一式はこちらからダウンロード
015.zip

今回JavaScriptファイルをいくつか追加してます。

js/Enemy.js
js/Shot.js

また、大幅にソースコードが変更になっているので全ソースを掲載しておきます。

index.html

<!DOCTYPE HTML>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>enchant.js example 015</title>
	<script type="text/javascript" src="js/enchant.js"></script>
	<script type="text/javascript" src="js/Player.js"></script>
	<script type="text/javascript" src="js/Shot.js"></script>
	<script type="text/javascript" src="js/Enemy.js"></script>
	<script type="text/javascript" src="js/main.js"></script>
</head>
<body>
	<h1>enchant.js example 015</h1>
	<p>
		上下左右のキーでプレイヤーを移動できます。<br />
		スペースキーで弾を発射します。<br />
		押しっぱなしにすると、素早く移動したり、弾を連射できたりします。<br />
		弾を発射しながら移動はできません。
	</p>
	<div id="enchant-stage"></div>
</body>
</<tml>

Player.js

var Player = enchant.Class.create(enchant.Sprite, {
    initialize: function(w,h){
        enchant.Sprite.call(this, w, h);
        this.image = game.assets['images/chara1.gif'];
        this.life = 5;
        this.y = game.height / 2 - this.height / 2;
        this.vx = 0;
        this.vy = 0;
        this.maxVx = 5;
        this.maxVy = 5;
        this.accel = 1;
        this.retarding = 0.98;
	},
	enterFrame:function(e){
		if(this.vx > this.maxVx) this.vx = this.maxVx;
		if(this.vx < -this.maxVx) this.vx = -this.maxVx;
		if(this.vy > this.maxVy) this.vy = this.maxVy;
		if(this.vy < -this.maxVy) this.vy = -this.maxVy;
		this.x += this.vx;
		this.y += this.vy;
		this.vx*=this.retarding;
		this.vy*=this.retarding;
		if(this.x > game.width / 2) this.x = game.width / 2;		
		if(this.x < 0) this.x = 0;		
		if(this.y > game.height - this.height) this.y = game.height - this.height;		
		if(this.y < 0) this.y = 0;		
	},
	move:function(type){
		switch(type){
			case Event.UP_BUTTON_DOWN:
				this.vy-=this.accel;
				break;		
			case Event.DOWN_BUTTON_DOWN:
				this.vy+=this.accel;
				break;		
			case Event.RIGHT_BUTTON_DOWN:
				this.vx+=this.accel;
				break;		
			case Event.LEFT_BUTTON_DOWN:
				this.vx-=this.accel;
				break;	
			default:
				error("move()に不明なイベント" + e.type + "が渡されました。");
				break;		
		}
	},
	damage:function(){
		var tgarget = this;
		tgarget.opacity = 0.5;
		setTimeout(function(){
			tgarget.opacity = 1;
		},500);
	}
});

Enemy.js

var Enemy = enchant.Class.create(enchant.Sprite, {
    initialize: function(w,h){
        enchant.Sprite.call(this, w, h);
        this.image = game.assets['images/chara1.gif'];
        this.frame = 5;
        this.scaleX = -1;
        this.x = game.width;
        this.y = (game.height - this.height) * Math.random();
        this.vx = -0 - Math.random() * 3; 
     	this.vy = -2 + Math.random() * 4;
     	this.accel = 1.02;
        this.deleted = false;
        this.score = 10;
        this.addEventListener(Event.ENTER_FRAME,this.enterFrame);
	},
	enterFrame:function(){
		this.x += this.vx;
		this.y += this.vy;
		this.vx *= this.accel;
		if(this.y < 0 || this.y > game.height - this.height){
			this.vy *= -2;
		}
	},
	remove:function(){
		this.removeEventListener(Event.ENTER_FRAME,this.enterFrame);
	}
});

Shot.js

var Shot = enchant.Class.create(enchant.Sprite, {
    initialize: function(w,h){
        enchant.Sprite.call(this, w, h);
        this.image = game.assets['images/icon0.gif'];
        this.frame = 62;
        this.vx = 5;
        this.addEventListener(Event.ENTER_FRAME,this.enterFrame);
	},
	enterFrame:function(){
		this.x += this.vx;
	},
	remove:function(){
		this.removeEventListener(Event.ENTER_FRAME,this.enterFrame);
	}
});

main.js

enchant();
window.onload = preloadAssets;

var game;
var scene;
var player;
var shots;
var enemies;
var score;
var scoreNum;
var life;
var addEnemyInterval = 1000;
var addEnemyIntervalMin = 300;


function preloadAssets(){
	game = new Game(960,320);
	game.preload(
		'images/chara1.gif',
		'images/icon0.gif',
		'sounds/jump.wav',
		'sounds/gameover.wav'
	);
	game.onload = init;
	game.start();
}


function init(){
	game.scale = 1;
	game.fps = 30;
	game.keybind(32,'space');
	scene = new Scene();
	scene.backgroundColor = "#000";
	game.pushScene(scene);

	shots = [];
	enemies = [];
	
	player = new Player(32,32);
	scene.addChild(player);
	
	score = new Label("SCORE:0");
	score.color = "#FC9";
	score.font = "normal normal 15px/1.0 monospace";
	scene.addChild(score);	
	scoreNum = 0;
	
	life = new Label("PLAYER:"+player.life);
	life.y = 17;
	life.color = "#FC9";
	life.font = "normal normal 15px/1.0 monospace";
	scene.addChild(life);
	
	main();
}


function main(){
	game.addEventListener(Event.ENTER_FRAME,entreFrame);
    game.addEventListener(Event.UP_BUTTON_DOWN,movePlayer);
    game.addEventListener(Event.DOWN_BUTTON_DOWN,movePlayer);
    game.addEventListener(Event.RIGHT_BUTTON_DOWN,movePlayer);
    game.addEventListener(Event.LEFT_BUTTON_DOWN,movePlayer);
    game.addEventListener('spacebuttondown',shoot);
    addEnemy();
}


function movePlayer(e){
	player.move(e.type);
}


function shoot(e){
	var s = new Shot(16,16);
	s.x = player.x + player.width;
	s.y = player.y + player.height / 2;
	scene.addChild(s);
	shots.push(s);
}


function entreFrame(e){
	player.enterFrame();
	var l = enemies.length;
	for(var i=0; i<l; i++){
		var deleteFlag = false;
		if(enemies[i].x + enemies[i].width < 0){
			deleteFlag = true;
		}else if(isHitShot(enemies[i])){
			deleteFlag = true;
			scoreNum += enemies[i].score;
			score.text = "SCORE:" + scoreNum;
		}else if(player.intersect(enemies[i])){	
			deleteFlag = true;
			player.life--;
			life.text = ("PLAYER:"+player.life);
			if(player.life<1){
				gameOver();
				return;
			}else{
				player.damage();
			}
		}
		if(deleteFlag){
			enemies[i].remove();
			scene.removeChild(enemies[i]);
			enemies.splice(i,1);
			i--;
			l--;
		}
	}	
}


function isHitShot(e){
	var l = shots.length;
	for(var i=0; i<l; i++){
		if(shots[i].intersect(e)){
			shots[i].remove();
			scene.removeChild(shots[i]);
			shots.splice(i,1);
			i--;
			l--;
			return true;
		}
	}
	return false;
}


function addEnemy(){
	var e = new Enemy(32,32);
	scene.addChild(e);
	enemies.push(e);
	addEnemyInterval -= 5;
	if(addEnemyInterval < addEnemyIntervalMin) addEnemyInterval = addEnemyIntervalMin;
	setTimeout(addEnemy,addEnemyInterval);
}


function gameOver(){
	game.pause();
	var label = new Label("GameOver");
	scene.addChild(label);
	label.color = "#FC9";
	label.x = game.width / 2 - 35;
	label.y = game.height / 2;
}


function error(mes){
	alert("Error:エラーが発生しました。\nメッセージ:\n" + mes);
}

まとめ

すこし長くなってしまいましたが、難しいことはしていませんので、じっくりコードを読んでいただければと思います。
また感想、変なコードだよーとかツッコミいただけると嬉しいです。

初めてのenchant.js 一覧

こちらもオススメ(別サイト)

phiさんの怒涛のTips集:なんとなくenchant.js分かってきたーって人はここのTipsを修行僧の用にストイックにこなせばennchant.jsある程度できます。と言えるようになるはず。
enchant.js 怒涛の 100 tips

こちらは、逆にうーん説明見てもよくわからんなぁーって人向け、登録は必要だけど、ビデオをみながら説明が入るのでチョー分かりやすい&enchant.js以外にも様々なレッスンビデオがやばいくらいいっぱい。しかも無料ときたもんだ。
ドットインストール:enchant.jsの基礎