ゲームエンジン開発③ キャラクターを自作の画像にする【javascript】
前回:自作ゲームエンジンに挑戦②「さっそくゲーム作ってみる」
やっぱただの四角だと見た目につまらない。ゲームらしい画像を使わなけりゃ面白くないですよね。ってことで今回は画像を表示させてみます。
で、まず画像を用意していただきたいんですが、プレイヤー、敵、弾の3つ作成してください。大きさはプレイヤー、敵が64×64、弾が16×16です。それらをimagesフォルダに入れてください。
前回のサンプルの画像を入れ替えたのがこちらです→サンプル
では作ってきましょう(・∀・)
画像の読み込み処理
まずは使う画像をASSETSオブジェクトにまとめて入れておきます。それぞれの画像の名前とファイルの場所を入れます。ASSETSという言い方は最近のトレンドらしいんですが、まぁ使うデータのことみたいです。
var ASSETS = { 'img_player': 'images/player.png', 'img_enemy': 'images/enemy.png', 'img_bullet': 'images/bullet.png', };
で、画像の読み込みなんですが、まず画像を扱うにはImageオブジェクトを作成してそこに画像を読み込んで使います。
var image = new Image(); image.src = '画像ファイルの場所'; image.onload = function() {//読み込んだよ }
基本、上記のような感じで書きます。onloadメソッドは画像の読み込みが完了したら発生するイベントです。大きな画像だったりすると読み込むのに時間がかかったりするので必要な処理は読み込みが終わってからする必要があります。
ただ、ゲームだとたくさん画像を扱うので全部読み込んだかどうかの確認が必要です。
で、Coreクラスに以下のような処理をつけました。引数のdataはASSETSです。画像はすべてCoreクラスのassetsオブジェクトに読み込みます。
preload(data){ var length = Object.keys(data).length; var count = 0; for(let key in data) { this.assets[key] = new Image(); this.assets[key].src = data[key]; this.assets[key].onload = ()=>{ if(++count == length){//全部読み込んだ this.onload();//読み込み完了後の処理 } } } }
画像の枚数をカウントしておいて、読み込みの完了した数が画像の枚数と同じになればCoreクラスのonloadメソッドを実行します。
で、それを追加したCoreクラスがこんな感じです
class Core{//ゲーム基幹クラス constructor(){ this.canvas = document.getElementById("canvas"); this.canvas.width = SCREEN_WIDTH; this.canvas.height = SCREEN_HEIGHT; this.ctx = this.canvas.getContext("2d");//コンテキスト this.assets = [];//アセット保存用配列 this.canvas.addEventListener("mousedown", (e) => {//マウスダウン this.isMouseDown = true; player.px = e.x; player.py = e.y; }); this.canvas.addEventListener("mouseup", (e) => {//マウスアップ this.isMouseDown = false; }); this.canvas.addEventListener("mousemove", (e) => {//マウス移動 if(!this.isMouseDown)return; player.x += e.x - player.px; player.y += e.y - player.py; player.px = e.x; player.py = e.y; }); } //画像のロード preload(data){ var length = Object.keys(data).length; var count = 0; for(let key in data) { this.assets[key] = new Image(); this.assets[key].src = data[key]; this.assets[key].onload = ()=>{ if(++count == length){//全部読み込んだ this.onload();//読み込み完了後の処理 } } } } update(){//更新処理 requestAnimationFrame(()=>{this.update();});//フレーム処理のお知らせを送る this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);//画面をクリア(前の画面描画を削除) this.enterframe();//フレーム処理 this.render();//描画処理 } render(){//描画処理 enemy.render(); player.render(); bullet.render(); } enterframe(){//フレーム処理 bullet.move(); enemy.move(); var r1 = bullet.width / 2; var r2 = enemy.width / 2; if(circleCollision(bullet.x + r1, bullet.y + r1, r1, enemy.x + r2, enemy.y + r2, r2)){ enemy.y = SCREEN_HEIGHT; bullet.y = -100; } } }
読み込み完了後にゲームが始動
画像の読み込みが完了したらゲームプログラムが動き始めるようにします。
core.onloadメソッドに読み込み完了後の処理を記述します。ここで初めてrequestAnimationFrameを使います。この後は自動で更新処理が行われるようになります。
//開始 window.onload = function(){ core = new Core(); core.preload(ASSETS); core.onload = function(){ enemy = new Enemy(64, 64); player = new Player(64, 64); bullet = new Bullet(16, 16); requestAnimationFrame(()=>{core.update();});//フレーム処理のお知らせを送る } }
画像を描画する
もっとも大事な画像を描画する部分を忘れてましたね(^^;)
Charaクラスのレンダーメソッドに画像を描画するdrawImageメソッドを記述します。
class Chara{//キャラクタークラス constructor(w, h){ this.x = 0; this.y = 0; this.width = w; this.height = h; } render(){ core.ctx.drawImage(this.image, 0, 0, this.width, this.height, this.x, this.y, this.width, this.height); } }
キャラクターはすべてこのCharaクラスを継承しているのでこの一か所変更するだけでOKです。
これで画像を使ったゲームになります。
まとめ
ただの四角から画像に変わっただけでものすごく進化した気がしますね( *´艸`)
なんだかゲームエンジン作るのなんて簡単なんじゃないか?って錯覚してしまいそうですが、まぁそんなのは今だけの話ですよ。。
じゃ(‘ω’)ノ
同カテゴリー記事
記事の感想・コメント
※コメントはまだありません※