当 Laser
跟 Squid
相互撞击时,
我们想要将 Squid
从场上移除。
我们需要一个 event
让我们得知发生撞击,并且需要做什麽事情。
新增一个 collision
参数,
当开始发生撞击时, start
函式会被调用,并传入当前撞击的物件。
export interface Collision {
collider: {
size: Vector;
};
collision?: {
start?<T extends GameObject & Collision>(this: T, collider: T): void;
};
}
当撞击发生时执行 start
函式,
note
我们希望 start
函式的 this
指向 GameObject
本身而非元件,
故使用 call
并传入物件作为 this
。
export function collisionDetect(instances: (Collision & Transform)[]) {
for (let i = 0; i < instances.length; i++) {
for (let j = i + 1; j < instances.length; j++) {
const A = instances[i];
const B = instances[j];
const o1 = {
x: A.position.x,
y: A.position.y,
w: A.collider.size.x,
h: A.collider.size.y,
};
const o2 = {
x: B.position.x,
y: B.position.y,
w: B.collider.size.x,
h: B.collider.size.y,
};
if (hitTest(o1, o2)) {
+ A.collision?.start?.call(A, B);
+ B.collision?.start?.call(B, A);
}
}
}
}
我们需要实作一个机制,让系统知道我们要销毁某个物件。
当 destroy
被设置成 true
时,
我们就要将该物件移除。
export interface GameObject {
destroy?: boolean;
update?(delta: number): void;
}
export default function Game(screen: Rectangle): Scene<Container> {
let instances: GameObject[] = [LaserCannon(screen), Squid()];
return {
update(delta) {
collisionDetect(instances.filter(canCollision).filter(canTransform));
instances.forEach((instance) => {
if (canControl(instance)) {
instance.handleInput(getKeyPressed());
}
if (canShoot(instance) && instance.canShoot) {
requestAnimationFrame(() => {
instances = [...instances, instance.shoot()];
});
instance.canShoot = false;
}
+ if (instance.destroy) {
+ requestAnimationFrame(() => {
+ instances = instances.filter((_instance) => _instance !== instance);
+ });
+ return;
+ }
instance.update?.(delta);
});
},
render(stage) {
instances
.filter(canRender)
.forEach((instance) => render(stage, instance));
},
};
}
当 Laser
撞到其他物件时,就将 Laser
自己跟撞击到的物件移除。
function Laser({
x,
y,
}: Vector): GameObject & Transform & Renderer & Collision {
return {
renderer: {
type: "graphics",
src: [[1], [1], [1], [1]],
},
position: { x, y },
update() {
this.position.y -= 1;
},
collider: {
size: { x: 1, y: 4 },
},
collision: {
start(other) {
other.destroy = true;
this.destroy = true;
},
},
};
}
XSS 全称为 Cross-site scripting 中文为「跨站脚本攻击」。 通常是指利用网页...
参赛动机 笔者正在转职前端工程师的路上,过去一直知道有铁人赛,也有参加的念头,但由於本人的惰性及害怕...
这是我第一次参加这种撰写文章的比赛,参加这个比赛主要是让我能保持学习并透过写文章分享自己的学习历程,...
Select vs Switch select与switch都是透过case的方式来处理,但两者却大...
前言 今天要来介绍物件型别里面的基础物件,或许会想说那除了基础物件型别以外,不是还有 TypeScr...