웹에서의 게임 엔진 - 파트 2 - 데이터 지향 시스템
23090 단어 3dwebdevjavascripttypescript
소개
여러분, 오랜만입니다. 그러나 여기에서 다시 이 3D 웹 엔진에 대한 일련의 게시물을 계속하고 있습니다. 첫 번째 부분을 놓친 경우: 여기에서 얻으십시오: .
데이터 기반 시스템으로
마지막 부분에서는 다음과 같은 시스템 및 구성 요소를 등록했습니다.
const threeJsContext = new ThreeJSContext();
scene.registerSystem(new TransformSystem());
scene.registerSystem(new ThreeJsDynamicMeshSystem(threeJsContext));
scene.registerSystem(new UpAndDownSinSystem());
// cube
const cubeId = "cube";
scene.addEntityForSystem<Transform>(TransformSystem.TYPE, {
position: {x: 10, y: 10, z: 10,},
rotation: {x: 0, y: 0, z: 0, w: 1,}
}, cubeId);
당신이 나에게 묻는다면 정말 유연하지 않습니다. 우리는 웹에 있기 때문에 이 모든 것을 일반 인수 및 선언으로 리팩터링하여 장면의 요소를 생성할 엔진에 JSON 파일을 제공할 수 있습니다.
따라서 먼저 해당 시스템의 구현에 의존하지 않도록 각 시스템에 대한 일반 매개변수를 정의해야 합니다.
이것은 통과하는 것보다
new BoxGeometry(5, 5, 5)
하지만 오히려
{
type: "BoxGeometry",
width: 5,
height: 5,
depth: 5,
}
이것은 실제 구현에서 장면의 선언 부분을 분리하는 이점이 있습니다. 즉, 원하는 경우 물리 라이브러리를 변경하는 맞춤형 webgl 어댑터로 ThreeJ를 교체할 수 있습니다.
여기에 모든 정의를 표시하지는 않겠지만 일반적으로 다음과 같이 보입니다.
import {PackagedQuaternion} from "./Transform";
export type BodyType = "STATIC" | "DYNAMIC" | "KINEMATIC";
export interface PhysicsBase {
type: BodyType;
}
export interface PhysicsPlane extends PhysicsBase {
shape: "PLANE";
rotation: PackagedQuaternion;
}
export interface PhysicsBox extends PhysicsBase {
shape: "CUBE";
sizeInMeter: number;
massInKG: number;
}
export interface PhysicsSphere extends PhysicsBase {
shape: "SPHERE";
radiusInMeter: number;
massInKG: number;
}
export type PhysicsArgs = {
type: "PHYSIC",
arg:
| PhysicsPlane
| PhysicsBox
| PhysicsSphere
}
이제 장면 개체를 빌드하는 방법에 대한 일반적인 정의가 있습니다. (여기에서 전체 코드 참조: https://gitlab.noukakis.ch/voidbattlesengine/voidbattlesengineweb/-/tree/chapter-2/src/engine/systems/_meta )
여기서 쿼터니언에 대해 참고할 사항은 다음과 같습니다.
JS의 수치적 정밀도와 JSON에서 내보낸/빨간색 때문에 다음과 같이 오일러 각도로 내보내는 것이 더 좋습니다.
export type PackagedQuaternion = {
yaw: number,
pitch: number,
roll: number
}
파서 및 형식화된 JSON
이제 장면이 포함된 JSON을 구문 분석하고 이 JSON이 예상대로 유효한지 확인해야 합니다. 이를 위해 JSON Schema과 함께 ts-json-schema-generator을 사용하여 해당 스키마를 자동으로 생성하고 ajv을 사용하여 생성된 스키마에 대해 JSON의 유효성을 검사합니다.
다음 명령을 사용하여 스키마를 가져올 수 있습니다.
./node_modules/.bin/ts-json-schema-generator --path 'src/**/*.ts' --type 'SceneType'
지금은 스키마를 ts 파일에 저장하지만 나중에 스키마 생성 및 번들링을 자동화할 것입니다. 스키마는 다음과 같습니다.
{
"$ref": "#/definitions/SceneType",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"BodyType": {
"enum": [
"STATIC",
"DYNAMIC",
"KINEMATIC"
],
"type": "string"
...
이제 "파서"사용 사례를 작성할 준비가 되었습니다. 이 파서는 장면 JSON을 다운로드하고, 스키마에 대해 유효성을 검사하고, 장면 JSON에 설명된 엔티티로 기존 시스템을 채울 책임이 있습니다.
여기에서 사용 사례, 테스트 및 어댑터를 참조하십시오. https://gitlab.noukakis.ch/voidbattlesengine/voidbattlesengineweb/-/tree/chapter-2/src/parser
이제 시스템에 JSON 파일을 제공하고 여기에서 장면을 가져올 수 있습니다.
이제 이것은:
{
"cube": [
{
"type": "TRANSFORM",
"position": {
"x": 10,
"y": 10,
"z": 10
},
"rotation": {
"yaw": 0,
"pitch": 0,
"roll": 0
}
},
{
"type": "RENDER",
"geometry": {
"type": "BoxGeometry",
"width": 5,
"height": 5,
"depth": 5
},
"material": {
"type": "MeshBasicMaterial",
"color": 15131077
}
},
{
"type": "PHYSIC",
"arg": {
"type": "DYNAMIC",
"shape": "CUBE",
"sizeInMeter": 5,
"massInKG": 1
}
}
],
"floor": [
{
"type": "TRANSFORM",
"position": {
"x": 0,
"y": -5,
"z": 0
},
"rotation": {
"yaw": 0,
"pitch": 0,
"roll": 0
}
},
{
"type": "RENDER",
"geometry": {
"type": "BoxGeometry",
"width": 200,
"height": 1,
"depth": 200
},
"material": {
"type": "MeshBasicMaterial",
"color": 12375026
},
"corrections": [
{
"yaw": 0,
"pitch": 0,
"roll": -90
}
]
},
{
"type": "PHYSIC",
"arg": {
"type": "STATIC",
"shape": "PLANE",
"rotation": {
"yaw": 0,
"pitch": 0,
"roll": -60
}
}
}
]
}
결과는 다음과 같습니다.
Cypress와 스크린샷으로 렌더러 테스트
이제 깔끔한 부분(또한 우리가 모든 리팩터링을 만든 이유)은 cypress과 같은 테스트 자동화 도구를 사용하여 자동화된 방식으로 이 앱을 테스트할 수 있다는 것입니다.
이를 사용하여 "X축에서 45도 회전된 큐브 표시"와 같은 시나리오를 정의하고 screenshots to check for regression을 사용할 수 있습니다.
그리고 그것은 렌더러를 테스트합니다. 이제 데이터 기반 애니메이션, 셰이더 등과 같은 고급 주제를 다룰 준비가 된 것 같습니다.
다음 시간까지!
Reference
이 문제에 관하여(웹에서의 게임 엔진 - 파트 2 - 데이터 지향 시스템), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/ioannisnoukakis/game-engine-in-web-part-2-data-oriented-system-1p2n
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
마지막 부분에서는 다음과 같은 시스템 및 구성 요소를 등록했습니다.
const threeJsContext = new ThreeJSContext();
scene.registerSystem(new TransformSystem());
scene.registerSystem(new ThreeJsDynamicMeshSystem(threeJsContext));
scene.registerSystem(new UpAndDownSinSystem());
// cube
const cubeId = "cube";
scene.addEntityForSystem<Transform>(TransformSystem.TYPE, {
position: {x: 10, y: 10, z: 10,},
rotation: {x: 0, y: 0, z: 0, w: 1,}
}, cubeId);
당신이 나에게 묻는다면 정말 유연하지 않습니다. 우리는 웹에 있기 때문에 이 모든 것을 일반 인수 및 선언으로 리팩터링하여 장면의 요소를 생성할 엔진에 JSON 파일을 제공할 수 있습니다.
따라서 먼저 해당 시스템의 구현에 의존하지 않도록 각 시스템에 대한 일반 매개변수를 정의해야 합니다.
이것은 통과하는 것보다
new BoxGeometry(5, 5, 5)
하지만 오히려
{
type: "BoxGeometry",
width: 5,
height: 5,
depth: 5,
}
이것은 실제 구현에서 장면의 선언 부분을 분리하는 이점이 있습니다. 즉, 원하는 경우 물리 라이브러리를 변경하는 맞춤형 webgl 어댑터로 ThreeJ를 교체할 수 있습니다.
여기에 모든 정의를 표시하지는 않겠지만 일반적으로 다음과 같이 보입니다.
import {PackagedQuaternion} from "./Transform";
export type BodyType = "STATIC" | "DYNAMIC" | "KINEMATIC";
export interface PhysicsBase {
type: BodyType;
}
export interface PhysicsPlane extends PhysicsBase {
shape: "PLANE";
rotation: PackagedQuaternion;
}
export interface PhysicsBox extends PhysicsBase {
shape: "CUBE";
sizeInMeter: number;
massInKG: number;
}
export interface PhysicsSphere extends PhysicsBase {
shape: "SPHERE";
radiusInMeter: number;
massInKG: number;
}
export type PhysicsArgs = {
type: "PHYSIC",
arg:
| PhysicsPlane
| PhysicsBox
| PhysicsSphere
}
이제 장면 개체를 빌드하는 방법에 대한 일반적인 정의가 있습니다. (여기에서 전체 코드 참조: https://gitlab.noukakis.ch/voidbattlesengine/voidbattlesengineweb/-/tree/chapter-2/src/engine/systems/_meta )
여기서 쿼터니언에 대해 참고할 사항은 다음과 같습니다.
JS의 수치적 정밀도와 JSON에서 내보낸/빨간색 때문에 다음과 같이 오일러 각도로 내보내는 것이 더 좋습니다.
export type PackagedQuaternion = {
yaw: number,
pitch: number,
roll: number
}
파서 및 형식화된 JSON
이제 장면이 포함된 JSON을 구문 분석하고 이 JSON이 예상대로 유효한지 확인해야 합니다. 이를 위해 JSON Schema과 함께 ts-json-schema-generator을 사용하여 해당 스키마를 자동으로 생성하고 ajv을 사용하여 생성된 스키마에 대해 JSON의 유효성을 검사합니다.
다음 명령을 사용하여 스키마를 가져올 수 있습니다.
./node_modules/.bin/ts-json-schema-generator --path 'src/**/*.ts' --type 'SceneType'
지금은 스키마를 ts 파일에 저장하지만 나중에 스키마 생성 및 번들링을 자동화할 것입니다. 스키마는 다음과 같습니다.
{
"$ref": "#/definitions/SceneType",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"BodyType": {
"enum": [
"STATIC",
"DYNAMIC",
"KINEMATIC"
],
"type": "string"
...
이제 "파서"사용 사례를 작성할 준비가 되었습니다. 이 파서는 장면 JSON을 다운로드하고, 스키마에 대해 유효성을 검사하고, 장면 JSON에 설명된 엔티티로 기존 시스템을 채울 책임이 있습니다.
여기에서 사용 사례, 테스트 및 어댑터를 참조하십시오. https://gitlab.noukakis.ch/voidbattlesengine/voidbattlesengineweb/-/tree/chapter-2/src/parser
이제 시스템에 JSON 파일을 제공하고 여기에서 장면을 가져올 수 있습니다.
이제 이것은:
{
"cube": [
{
"type": "TRANSFORM",
"position": {
"x": 10,
"y": 10,
"z": 10
},
"rotation": {
"yaw": 0,
"pitch": 0,
"roll": 0
}
},
{
"type": "RENDER",
"geometry": {
"type": "BoxGeometry",
"width": 5,
"height": 5,
"depth": 5
},
"material": {
"type": "MeshBasicMaterial",
"color": 15131077
}
},
{
"type": "PHYSIC",
"arg": {
"type": "DYNAMIC",
"shape": "CUBE",
"sizeInMeter": 5,
"massInKG": 1
}
}
],
"floor": [
{
"type": "TRANSFORM",
"position": {
"x": 0,
"y": -5,
"z": 0
},
"rotation": {
"yaw": 0,
"pitch": 0,
"roll": 0
}
},
{
"type": "RENDER",
"geometry": {
"type": "BoxGeometry",
"width": 200,
"height": 1,
"depth": 200
},
"material": {
"type": "MeshBasicMaterial",
"color": 12375026
},
"corrections": [
{
"yaw": 0,
"pitch": 0,
"roll": -90
}
]
},
{
"type": "PHYSIC",
"arg": {
"type": "STATIC",
"shape": "PLANE",
"rotation": {
"yaw": 0,
"pitch": 0,
"roll": -60
}
}
}
]
}
결과는 다음과 같습니다.
Cypress와 스크린샷으로 렌더러 테스트
이제 깔끔한 부분(또한 우리가 모든 리팩터링을 만든 이유)은 cypress과 같은 테스트 자동화 도구를 사용하여 자동화된 방식으로 이 앱을 테스트할 수 있다는 것입니다.
이를 사용하여 "X축에서 45도 회전된 큐브 표시"와 같은 시나리오를 정의하고 screenshots to check for regression을 사용할 수 있습니다.
그리고 그것은 렌더러를 테스트합니다. 이제 데이터 기반 애니메이션, 셰이더 등과 같은 고급 주제를 다룰 준비가 된 것 같습니다.
다음 시간까지!
Reference
이 문제에 관하여(웹에서의 게임 엔진 - 파트 2 - 데이터 지향 시스템), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/ioannisnoukakis/game-engine-in-web-part-2-data-oriented-system-1p2n
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
./node_modules/.bin/ts-json-schema-generator --path 'src/**/*.ts' --type 'SceneType'
{
"$ref": "#/definitions/SceneType",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"BodyType": {
"enum": [
"STATIC",
"DYNAMIC",
"KINEMATIC"
],
"type": "string"
...
{
"cube": [
{
"type": "TRANSFORM",
"position": {
"x": 10,
"y": 10,
"z": 10
},
"rotation": {
"yaw": 0,
"pitch": 0,
"roll": 0
}
},
{
"type": "RENDER",
"geometry": {
"type": "BoxGeometry",
"width": 5,
"height": 5,
"depth": 5
},
"material": {
"type": "MeshBasicMaterial",
"color": 15131077
}
},
{
"type": "PHYSIC",
"arg": {
"type": "DYNAMIC",
"shape": "CUBE",
"sizeInMeter": 5,
"massInKG": 1
}
}
],
"floor": [
{
"type": "TRANSFORM",
"position": {
"x": 0,
"y": -5,
"z": 0
},
"rotation": {
"yaw": 0,
"pitch": 0,
"roll": 0
}
},
{
"type": "RENDER",
"geometry": {
"type": "BoxGeometry",
"width": 200,
"height": 1,
"depth": 200
},
"material": {
"type": "MeshBasicMaterial",
"color": 12375026
},
"corrections": [
{
"yaw": 0,
"pitch": 0,
"roll": -90
}
]
},
{
"type": "PHYSIC",
"arg": {
"type": "STATIC",
"shape": "PLANE",
"rotation": {
"yaw": 0,
"pitch": 0,
"roll": -60
}
}
}
]
}
이제 깔끔한 부분(또한 우리가 모든 리팩터링을 만든 이유)은 cypress과 같은 테스트 자동화 도구를 사용하여 자동화된 방식으로 이 앱을 테스트할 수 있다는 것입니다.
이를 사용하여 "X축에서 45도 회전된 큐브 표시"와 같은 시나리오를 정의하고 screenshots to check for regression을 사용할 수 있습니다.
그리고 그것은 렌더러를 테스트합니다. 이제 데이터 기반 애니메이션, 셰이더 등과 같은 고급 주제를 다룰 준비가 된 것 같습니다.
다음 시간까지!
Reference
이 문제에 관하여(웹에서의 게임 엔진 - 파트 2 - 데이터 지향 시스템), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ioannisnoukakis/game-engine-in-web-part-2-data-oriented-system-1p2n텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)