LoginSignup
0
0

TypeScript基礎

Last updated at Posted at 2022-12-15

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
image.png
###動き
ボールが画面の縁に当たったら跳ね返る

ホットコンパイルについて

下記3つを用意

ターミナル1
tsc -w
ターミナル2
npx webpack-cli -w

拡張機能のLiveServerを起動

コードの説明

フォルダ構成

image.png

index.html

ブラウザが最初に認識する例のあれ

script.ts

index.htmlが最初に読み込むファイル

ball.ts

ballの速度等が含まれた型定義

node_modules

ライブラリや標準クラス等

dist

ホットコンパイル結果

index.html

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がtsmain.jsに変換してるのでscriptタグでは./dist/main.jsを参照している
他は(多分)一般的なhtml

script.tsについて

全体

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について

全体

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 画面右側の当たり判定をする際に位置情報に足す必要があるので

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0