Engine-இல் JavaScript
Engine-இன் script API லைஃப்சைக்கிள், coordinate traps, ஒரு object-ஐ உருவாக்கும் மூன்று வழிகள், மற்றும் சுவர்கள் வழியாக நடக்காமல் ஒன்றை நகர்த்துவது எப்படி.
ஒரே வரியில்#
ஒவ்வொரு entity-உம் ஒரு JavaScript script-ஐ சுமக்க முடியும். இது உலாவியில், உங்கள் tab-இல், live scene-க்கு எதிராக இயங்குகிறது, மேலும் இது canonical scripting API: BASIC dialect, மற்றும் editor-இல் உள்ள Python, C# மற்றும் Rust காட்சிகள் அனைத்தும் அதே surface-க்கு compile ஆகின்றன.
முழுமையான பட்டியல் API reference: 50 namespaces-இல் 538 members, ஒவ்வொன்றும் ஒரு பக்கம், ஒரு தேடலுடன். இந்தப் பக்கம், அதைப் படிப்பதற்கு முன் நீங்கள் தெரிந்துகொள்ள வேண்டியது.
Lifecycle#
function start() {} // once, when the entity starts
function update(dt) {} // every frame, dt in seconds
function fixedUpdate(dt) {} // fixed timestep, for physics
function onCollisionEnter(other) {} // first frame of contact
function onCollisionStay(other) {} // every frame while touching
function onCollisionExit(other) {} // contact just ended
function onTriggerEnter(other) {} // entered a trigger volume
function onTriggerExit(other) {}
function onMessage(msg, data, senderId) {} // entity-to-entity messaging
function onAnimationEvent(name, data) {}
function onDestroy() {}
function main() {} // console-game entry, async allowed
deltaTime, time, entityId மற்றும் entity globals;
getComponent(type), script-ஐ சொந்தமாக்கியிருக்கும் entity-இலிருந்து
ஒரு component-ஐ படிக்கிறது.
Collisions மற்றும் triggers 2D-இலும் 3D-இலும் இயங்கும், மேலும்
ஒவ்வொரு பக்கமும் அதற்கே உரிய contact normal-ஐ பெறும்:
other.contact.normal, other entity-இலிருந்து இதை நோக்கி
புள்ளிகாட்டுகிறது. "நான் அதன் மேல் இறங்கினேன்" என்பதை "அது என்
மேல் இறங்கியது" என்பதிலிருந்து ஒரு script சொல்ல அனுமதிப்பது
இதுதான், ஒரு platformer stomp other.contact.normal.y > 0.5 என்று
படிக்கிறது.
இரண்டு coordinate traps#
இரண்டும் உண்மையான debugging நேரத்தை செலவழிக்கின்றன, மேலும் இரண்டும் சத்தமாக தோல்வியடையாது.
Mouse: page vs canvas#
input.mousePosition page coordinates-இல் உள்ளது. scene.pick()
canvas coordinates-ஐ விரும்புகிறது. ஒன்றை மற்றொன்றுக்குப்
பதிலாக அனுப்புவது தவறவிடாது, அது சாளரத்தில் viewport-இன் இடத்தால்
offset செய்யப்பட்ட ஒரு புள்ளியில் தாக்குகிறது, எனவே ஒரு
click-to-move hero, நம்பத்தகுந்த ஆனால் தவறான ஒரு இடத்திற்கு
நடக்கிறார்.
argument இல்லாமல் scene.pick()-ஐ அழைக்கவும் (இது cursor-ஐ
நோக்குகிறது), அல்லது எண்கள் தேவைப்படும்போது input.mouseViewport-ஐ
பயன்படுத்தவும்.
Virtual controls canvas pixels-இல் உள்ளன#
input.addVirtualJoystick(id, x, y, size) மற்றும்
input.addVirtualButton(...), தங்கள் centres-ஐ mouseViewport
அதே இடத்தில் வைக்கின்றன. ஒரு joystick, அதன் radial dead zone-க்குப்
பிறகு ஒரு normalised X/Y-ஐ தரும்; ஒரு button held,
pressed-this-frame மற்றும் released-this-frame-ஐ தனித்தனியாக
வெளிப்படுத்தும். அவற்றின் pointer capture செய்யப்பட்டு consume
செய்யப்படுகிறது, எனவே control-இன் மேல் ஒரு தொடுதல், ஒரு raw canvas
action ஆகவும் தெரிவிக்கப்படாது.
இயல்பு joystick ஒருங்கிணைக்கப்பட்டது.
input.getJoystickX/Y(), on-screen stick, ஒரு physical gamepad, அல்லது keyboard (WASD/arrows) ஆகியவற்றில் எது வலிமையானதோ அதிலிருந்து ஒரு முழுமையான vector-ஐ எடுக்கிறது. எனவே செயலற்ற ஒரு இணைக்கப்பட்ட pad, keyboard இயக்கத்தை முடக்காது. அதன் Y axis 2D screen space-ஐ பின்பற்றுகிறது: மேல்-1.
ஒரு object-ஐ உருவாக்கும் மூன்று வழிகள், அவை ஒன்றுக்கொன்று மாற்றக்கூடியவை அல்ல#
| அது என்ன உருவாக்குகிறது | எதற்காக வாழ்கிறது | |
|---|---|---|
scene.createEntity(def) | ஒரு authored entity: இது Scene Graph-இலும் Inspector-இலும் தோன்றும் | திட்டம், இது சேமிக்கப்படும் |
game.spawn(type, pos) | ஒரு bare primitive: health இல்லை, AI இல்லை, behaviour இல்லை | play session |
game.spawnFrom(template, pos, opts) | ஒரு முழு entity-இன் நகல்: components, physics body, tags, layer, scale மற்றும் compile செய்யப்பட்ட behaviour stack | play session |
game.spawn debris மற்றும் prototypes-க்கு சரியானது, மேலும்
enemies-க்கு பயனற்றது: அதனால் ஊட்டப்படும் ஒரு spawner,
செயலற்ற பந்துகளை உருவாக்கும். spawnFrom நகலெடுக்கும் template,
நீங்கள் editor-இல் compose செய்து hierarchy-இன் eye-ஆல் அணைக்கும்
ஒரு சாதாரண entity: தனி வடிவம் இல்லை, இரண்டாவது editor இல்லை, எனவே
நீங்கள் பார்ப்பதுதான் தோன்றுவது.
// Once, at start: a missing template should say so, not fail every wave silently
if (!game.hasTemplate('Skeleton')) console.warn('no Skeleton template');
const mob = game.spawnFrom('Skeleton', { x, y, z }, { tag: 'Enemy' });
template, ஒரு id, ஒரு பெயர் அல்லது ஒரு tag-ஐ ஏற்கும். play-இன்
போது செய்யப்படும் நகல்கள் play-scoped, எனவே stop() அவற்றை
அகற்றும், மேலும் edit scene ஒருபோதும் அசுத்தமாகாது.
ஒரு entity-ஐ அணைப்பது என்றால் மறைந்ததும் AND அமைதியானதும்: node disabled, script நிறுத்தப்பட்டது, physics body இனி பதிலளிக்காது. மறைப்பது மட்டும் ஒரு கண்ணுக்குத் தெரியாத எதிரி இன்னும் உங்களைத் தாக்கும்படி விட்டுவிடும்.
game.setEnabled(id, on)ஒரு script-இலிருந்து இதை இயக்குகிறது, eye icon hierarchy-இலிருந்து இதை இயக்குகிறது.
ஏதேனும் ஒன்றை நகர்த்துதல்: ஒரு body-ஐ push செய்யுங்கள், teleport செய்யாதீர்கள்#
ஒவ்வொரு frame-உம் transform.position-ஐ எழுதுவது சுவர்கள்
வழியாகவும், மற்ற monsters வழியாகவும், தரை வழியாகவும் நடக்கிறது.
அதற்குப் பதிலாக velocity-ஐ இயக்குங்கள், ஆனால் இயக்க ஏதேனும்
இருக்கும்போது மட்டும்:
if (physics.hasBody) {
const v = physics.getVelocity();
physics.setVelocity({ x: vx, y: v.y, z: vz }); // pushes a real body
} else {
transform.position.x += vx * dt; // legitimate for a flyer
}
ஒரு body இல்லாமல் physics.setVelocity, யாரும் integrate செய்யாத
ஒரு field-ஐ நிரப்புகிறது, மேலும் entity நின்றுவிடும். இதனால்தான்
physics.hasBody இருக்கிறது, மேலும் இதனால்தான் catalogue-இல் உள்ள
ஒவ்வொரு moving behaviour-உம், ஒரு பதிலை எடுத்துக்கொள்ளாமல்
கேள்வியைக் கேட்கிறது. நிறுத்துவது என்றால் velocity-ஐ ரத்து
செய்வது: எதுவும் செய்யாமல் இருப்பது body-ஐ coast செய்யவே விடும்.
ஒரு position-ஐ எழுதுவது இப்போது ஒரு physics body-ஐ நகர்த்தும். Havok transform-ஐ இயக்குகிறது, ஒருபோதும் நேர்மாறாக இல்லை, எனவே ஒரு dynamic body-இல்
transform.position-ஐ assign செய்வது முன்பு அடுத்த step-இல் overwrite செய்யப்படும்: ஒரு physical entity-இல் ஒவ்வொரு teleport-உம் அமைதியாக தோல்வியடையும். position proxy body-ஐ மீண்டும் sync செய்கிறது, rotation proxy எப்போதும் செய்தது போலவே.
Pathfinding ஒரு snapshot#
pathfinding.createGrid(), அது அழைக்கப்பட்ட இடத்தில்
மையப்படுத்தப்பட்ட ஒரு கிரிட்டை ஒருமுறை raycast செய்கிறது. அந்த
box-ஐ விட்டு வெளியேறுவது null-ஐ தரும், மேலும் பெரும்பாலான
callers பிறகு ஒரு வார்த்தையும் இல்லாமல், சுவர்கள் வழியாக, ஒரு
நேர்கோட்டிற்குத் திரும்புகின்றன.
கிரிட் இயல்பாகவே கோரப்பட்ட பயணத்தில் மீண்டும் மையப்படுத்தப்படும்.
ஒரு நிலையான உலகில், மீண்டும் கட்டமைப்பது வீணாக ஒரு raycast pass-ஐ
செலவழிக்கும் இடத்தில், setAutoRecenter(false) இதைத் தவிர்க்கிறது.
console.log log செய்யும். Print வரையும்.#
console என்பது console.log / warn / error, மற்ற எங்கும்
போலவே. BASIC Print திரையில் வரைகிறது, மேலும் ஒவ்வொரு
frame-உம் அழைக்கப்படுகிறது, இரண்டும் வேண்டுமென்றே தனித்தனி
commands, மேலும் அவற்றைக் குழப்புவதுதான்
ஒரு console-ஐ ஒரு frame loop-உடன் நிரப்புகிறது.
Script எங்கு இயங்குகிறது#
editor-இலும் ஒரு web build-இலும், scripts உலாவியில் இயங்குகின்றன. ஒரு native desktop அல்லது mobile build-இல், அவை ஒரு embedded QuickJS runtime-இல், மாறாமல், அதே source-ஆக, ஒரு port அல்லாமல் இயங்குகின்றன.
நீங்கள் எடிட் செய்யும்போது Scripts உலாவியின் சொந்த database-இல் சேமிக்கப்படுகின்றன, எனவே சேமிக்கப்படாத ஒரு buffer ஒரு reload-ஐ தாண்டி நிலைத்திருக்கும்; அவை மற்ற எல்லாவற்றுடனும் திட்டத்திற்குள் சேமிக்கப்படுகின்றன.
வரம்புகளும் பொதுவான சிக்கல்களும்#
- ஒரு argument-உடன்
scene.pick()canvas coordinates-ஐ விரும்புகிறது. மேலே பார்க்கவும்; இதுவே மிகவும் பொதுவான தவறான-இட பிழை. game.spawnஒரு primitive-ஐ உருவாக்குகிறது, ஒரு character-ஐ அல்ல.spawnFrom-ஐ பயன்படுத்தவும்.- விளையாட்டின் நடுவில் பிறக்கும் entities-க்கு ஒரு body உருவாக்கப்படுகிறது. Physics முன்பு Play-இல் மட்டுமே கட்டமைக்கப்படும், எனவே பின்னர் spawn செய்யப்பட்ட எதுவும் அதன் கையால் வைக்கப்பட்ட அண்டைவீட்டார் சரியாக நடந்துகொள்ளும்போது, அமைதியாக உலகின் வழியாக விழுந்துவிடும்.
- எட்டு படிகள் AI teammate-இன் உச்சவரம்பு, உங்களுடையது அல்ல.
ஒரு script loop-க்கு அப்படி எந்த வரம்பும் இல்லை; ஒரு
கட்டுப்பாடற்ற
while, மற்ற எங்கும் போலவே frame-ஐ hang செய்யும். - மற்ற நான்கு மொழி காட்சிகளும் இதிலிருந்து transpile செய்யப்படுகின்றன. ஒரு Python அல்லது Rust காட்சியை எடிட் செய்து திரும்ப மாறுவது, சேமிக்கப்பட்ட JavaScript வழியாகச் செல்கிறது, ஏன் என்று BASIC பக்கம் பார்க்கவும்.