TypeScriptでゲームを作りたい
あほげーに投稿してあほになりたい
ということで調べてたらたまたま作っちゃうおじさんの初心者向けページを見つけたので一気にモチベ↑
https://hothukurou.com/blog/post-2122
あと、もしかするとポートフォリオになるかも(ならないかも)
前提条件
作っちゃうおじさんの通りにやったので環境は同じ(ライブラリはpixi.js)
一回最低限のソースだけで作って確認したかったので作っちゃうおじさん製フレームワークのようなものは使わない。
使ったもの
TypeScript
jsは動的型付けなので嫌い、静的型付けなら好き
TypeScriptは静的型付けなので好き
VSCode
2021年1月現在、開発環境はやっぱりこれ一強
Webpack
複数のjs,tsファイルをひとまとめにしてくれる
pixi.js
簡単で軽いゲームの制作に向いてるらしい
作ったもの
https://github.com/Wa-taro/CollideBall
###動き
ボールが画面の縁に当たったら跳ね返る
ホットコンパイルについて
下記3つを用意
tsc -w
npx webpack-cli -w
拡張機能のLiveServerを起動
コードの説明
フォルダ構成
index.html
ブラウザが最初に認識する例のあれ
script.ts
index.htmlが最初に読み込むファイル
ball.ts
ballの速度等が含まれた型定義
node_modules
ライブラリや標準クラス等
dist
ホットコンパイル結果
index.html
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>ボールがぶつかるのを見るだけ</title>
</head>
<body>
<script src="./dist/main.js"></script>
</body>
</html>
Webpackがts
をmain.js
に変換してるのでscriptタグでは./dist/main.js
を参照している
他は(多分)一般的なhtml
script.tsについて
全体
import * as PIXI from "pixi.js";
import { Ball } from "./ball";
let gameWidth = 600;
let gameHeight = 800;
//サイズを指定してPIXI.Appricationを呼ぶ
const app = new PIXI.Application({ width: gameWidth, height: gameHeight });
// index.htmlのbody部にappを追加(append)する (app.viewはcanvasのdom要素)
document.body.appendChild(app.view);
// canvasの周りを点線枠で囲う (canvasの位置がわかりやすいので入れている)
app.renderer.view.style.border = "2px dashed black";
// canvasの背景色
app.renderer.backgroundColor = 0xa0a0a0;
// 画像"GrayBall.jpg"の読み込み
PIXI.Loader.shared.add("resources/GrayBall.png");
PIXI.Loader.shared.load((loader, resources) => {
const ball: Ball = new Ball();
ball.sprite = new PIXI.Sprite(resources["resources/GrayBall.png"].texture);
ball.xSpeed = 1;
ball.ySpeed = 1;
ball.heightSize = 100;
ball.widthSize = 100;
// ゲーム用のシーンを生成
const gameScene = new PIXI.Container();
// ゲームシーンを画面に追加
app.stage.addChild(gameScene);
gameScene.addChild(ball.sprite); // ボールをシーンに追加
function gameLoop() //フレーム毎処理
{
ball.sprite.x += ball.xSpeed;
ball.sprite.y += ball.ySpeed;
//画面縁当たり判定
if (ball.sprite.y + ball.heightSize >= gameHeight
|| ball.sprite.y <= 0) {
ball.ySpeed = -ball.ySpeed
}
if (ball.sprite.x + ball.widthSize >= gameWidth
|| ball.sprite.x <= 0) {
ball.xSpeed = -ball.xSpeed
}
}
app.ticker.add(gameLoop);
});
詳細
import * as PIXI from "pixi.js";
import { Ball } from "./ball";
let gameWidth = 600;
let gameHeight = 800;
//サイズを指定してPIXI.Appricationを呼ぶ
const app = new PIXI.Application({ width: gameWidth, height: gameHeight });
// index.htmlのbody部にappを追加(append)する (app.viewはcanvasのdom要素)
document.body.appendChild(app.view);
// canvasの周りを点線枠で囲う (canvasの位置がわかりやすいので入れている)
app.renderer.view.style.border = "2px dashed black";
// canvasの背景色
app.renderer.backgroundColor = 0xa0a0a0;
// 画像"GrayBall.jpg"の読み込み
PIXI.Loader.shared.add("resources/GrayBall.png");
書いてあるままではあるが、説明
PIXIをImport
別ファイルball.tsをImport
ゲームの幅、高さを宣言
PIXI.spplicationを使ってapplicationを生成
生成したapplicationをhtmlのbody部へ入れる
ゲーム箇所周りに点線をつける
背景を明るめのグレーにする
ballのimageを渡しておく
PIXI.Loader.shared.load((loader, resources) => {
const ball: Ball = new Ball();
ball.sprite = new PIXI.Sprite(resources["resources/GrayBall.png"].texture);
ball.xSpeed = 1;
ball.ySpeed = 1;
ball.heightSize = 100;
ball.widthSize = 100;
// ゲーム用のシーンを生成
const gameScene = new PIXI.Container();
// ゲームシーンを画面に追加
app.stage.addChild(gameScene);
gameScene.addChild(ball.sprite); // ボールをシーンに追加
PIXI.Loader.shared.load((loader, resources) =>
がPIXIで処理をするための決り文句
load後に行われる処理を記述する
ballを宣言、各プロパティ?に値を代入する
spriteに画像情報を渡す
x,y のスピードに1をセット
ballの高さ、幅に100をセット
シーン(objectのcollection)を作成
さっき作成したconst app = new PIXI.Application({ width: gameWidth, height: gameHeight });
に対してシーンをセット
シーンに対してball情報をセット
function gameLoop() //フレーム毎処理
{
ball.sprite.x += ball.xSpeed;
ball.sprite.y += ball.ySpeed;
//画面縁当たり判定
if (ball.sprite.y + ball.heightSize >= gameHeight
|| ball.sprite.y <= 0) {
ball.ySpeed = -ball.ySpeed
}
if (ball.sprite.x + ball.widthSize >= gameWidth
|| ball.sprite.x <= 0) {
ball.xSpeed = -ball.xSpeed
}
}
PIXI側で用意されているyに対して作成したball.ySpeedを足す
xも同様
画面縁当たり判定
ball.sprite.y + ball.heightSize >= gameHeight
画面下側にhitしたかチェック
ball.sprite.y <= 0
画面上部にhitしたかチェック
上記どちらかがtureならばyのエネルギーの向きを180度逆にする
※xも同様
app.ticker.add(gameLoop);
PIXIのticker(フレーム毎に繰り返す処理)にfunction gameLoop()
を追加する
ball.tsについて
全体
export class Ball {
sprite: PIXI.Sprite;
xSpeed: number;
ySpeed: number;
heightSize: number;
widthSize: number;
}
説明いるか?
一応....
sprite
PIXI.SpriteというPIXIの画像オブジェクト標準クラス
xSpeed
xに毎フレーム足していく想定で作った
yxSpeed
上と同じ
heightSize
画面下側の当たり判定をする際に位置情報に足す必要があるので
widthSize
画面右側の当たり判定をする際に位置情報に足す必要があるので