工欲善其事,必先利其器。
此节会先准备现代开发中不可或缺的一些工具,
卡比将会使用 Vite, 作为打包工具喔。
首先 建立新的专案
yarn create @vitejs/app [专案名称] --template vanilla-ts
例如.
yarn create @vitejs/app space-invaders --template vanilla-ts
进入那个专案,并开启 Dev Server
yarn 会下载这个专案有用到的所有第三方套件
cd space-invaders
yarn
接着 yarn dev 会开启 dev server
yarn dev
打开浏览器 localhost:3000
,此时画面应为
打开你的 Editor,开始出发拉!
首先要先在页面上生成 <canvas />
以方便卡比绘图,
卡比将采用 pixi.js
作为绘图引擎,
yarn add pixi.js
note. 请注意卡比此时的版本为 "pixi.js": "^6.0.4"
接着在 src/main.ts
导入,
import { Application } from "pixi.js";
接着卡比将底下预设的程序码换成
const app = new Application();
document.querySelector("#app")?.append(app.view);
此时画面应该如下,
程序码如下,
-- src/main.ts
import { Application } from "pixi.js";
const app = new Application();
document.querySelector("#app")?.append(app.view);
那个年代并没有绘图软件,图片都是由工程师透过程序绘成,
所以卡比首先要思考如何用程序绘制点阵图形。
卡比试着画出,这个游戏的代表外星人 Crab
。
可以简单看出 Crab
由高度 8 pixels 跟宽度 11 pixels 的点阵图构成,且只有一个颜色。
像这样的图形可以透过 2维阵列
来记录整张图片点阵资料,
简单的方式来记录每个格子里面有没有颜色即可,
例如 1 - 有颜色, 0 - 没有颜色。
故可以用以下表示这张图片,
const image = [
[0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0],
];
然後试着用上面的资料绘制点阵图。
接者卡比要用 pixi.js
中的 Graphics
API 进行点阵图绘制,
- import { Application } from "pixi.js";
+ import { Application, Graphics } from "pixi.js";
生成物件
const graphics = new Graphics();
遍历 image
阵列,透过资料来绘制图形,
if (image[y][x] === 0) continue;
0 的话就不画颜色,直接跳过。
beginFill(0xffffff)
是指先选好要上的颜色,0xffffff
就是白色的 16 进位色码。
drawRect(x, y, w, h)
是指在某个位置画一个特定宽高的矩形。
endFill()
画完形状并涂上颜色。
for (let y = 0; y < image.length; y++) {
for (let x = 0; x < image[y].length; x++) {
if (image[y][x] === 0) continue;
graphics.beginFill(0xffffff);
graphics.drawRect(x, y, 1, 1);
graphics.endFill();
}
}
最後将这个图形放到画面上即可
app.stage.addChild(graphics);
此时画面应该如下
似乎有点小,将画面的比例调整一下,
宽度 11 px, 高度 8 px, 放大 10 倍 来看看
- const app = new Application();
+ const app = new Application({
+ width: 11,
+ height: 8,
+ resolution: 10,
+ });
就这样卡比画出 Crab
了。
程序码如下,
-- src/main.ts
import { Application, Graphics } from "pixi.js";
const app = new Application({
width: 11,
height: 8,
resolution: 10,
});
document.querySelector("#app")?.append(app.view);
const image = [
[0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0],
];
const graphics = new Graphics();
for (let y = 0; y < image.length; y++) {
for (let x = 0; x < image[y].length; x++) {
if (image[y][x] === 0) continue;
graphics.beginFill(0xffffff);
graphics.drawRect(x, y, 1, 1);
graphics.endFill();
}
}
app.stage.addChild(graphics);
接下来卡比要将这段Crab
的程序码整理到一个地方放,
方便以後卡比要再画出Crab
时可以直接使用,而不需要重新走过上面的思考流程。
首先,卡比在 src
底下建立 characters
的资料夹,并建立一只新的档案叫 Crab.ts
。
并把画出 Crab
的相关程序码搬到那个地方。
-- src/characters/Crab.ts
import { Graphics } from "pixi.js";
const image = [
[0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0],
];
export default function Crab() {
const graphics = new Graphics();
for (let y = 0; y < image.length; y++) {
for (let x = 0; x < image[y].length; x++) {
if (image[y][x] === 0) continue;
graphics.beginFill(0xffffff);
graphics.drawRect(x, y, 1, 1);
graphics.endFill();
}
}
return graphics;
}
之後来测试一下 Crab
函式。
-- src/main.ts
import "./style.css";
import { Application } from "pixi.js";
import Crab from "./characters/Crab";
const app = new Application({
width: 11,
height: 8,
resolution: 10,
});
document.querySelector("#app")?.append(app.view);
app.stage.addChild(Crab());
这样卡比成功重构了Crab
。
因为接下来的角色作法跟上面的 Crab
差不多,
卡比直接提供其他角色的资料以供大家做练习。
以下练习可以自行调整 Application
的画布大小喔。
const laserCannon = [
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
const octopus = [
[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0],
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
];
const squid = [
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 0],
[1, 1, 0, 1, 1, 0, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 1, 0, 0, 1, 0, 0],
[0, 1, 0, 1, 1, 0, 1, 0],
[1, 0, 1, 0, 0, 1, 0, 1],
];
Crab
,LaserCannon
,Octopus
,Squid
,要怎麽做呢?
<<: Day03 - 使用 Google Compute Engine 建立 VM
>>: 建立 Google App Script 专案(2)
Hashicorp Nomad: Docker driver image behavior 在Has...
前言 今天来加入更多的Dependencies,以及聊天开发的准备 Cocoapods 那麽我们先来...
使用tablatout串fragment xml程序码 <?xml version="...
今日目标 实作SAT碰撞侦测 SAT的作法 回顾一下,AABB的作法是不管是甚麽形状,都把物件包进矩...
前言 今天会分享我的阅读api心得 并做简易的操作来使用今天研读後的成果 前几日会以阅读文件跟熟悉永...