diff --git a/webclient/src/blockly/events/objectTouchedMe.ts b/webclient/src/blockly/events/objectTouchedMe.ts index 125f899..2d45879 100644 --- a/webclient/src/blockly/events/objectTouchedMe.ts +++ b/webclient/src/blockly/events/objectTouchedMe.ts @@ -1,13 +1,13 @@ import * as Blockly from "blockly"; -import { javascriptGenerator } from "blockly/javascript"; +import { javascriptGenerator, Order } from "blockly/javascript"; Blockly.Blocks['object_touch_start_event'] = { init(this: Blockly.Block) { - this.appendDummyInput('NAME') + this.appendDummyInput() .appendField('When'); - this.appendValueInput('NAME') + this.appendValueInput('OTHER_OBJECT') .setCheck('Object'); - this.appendDummyInput('NAME') + this.appendDummyInput() .appendField('touches me'); this.setStyle('event_hat'); this.setNextStatement(true); @@ -15,8 +15,13 @@ Blockly.Blocks['object_touch_start_event'] = { } }; -javascriptGenerator.forBlock['object_touch_start_event'] = function (_block, _generator) { - return ''; +javascriptGenerator.forBlock['object_touch_start_event'] = function (block, generator) { + const otherObjectValue = generator.valueToCode(block, 'OTHER_OBJECT', Order.NONE) || 'undefined'; + return ` +const touchTarget = ${otherObjectValue}; +if (!context.other || !touchTarget || context.other.id !== touchTarget.id) + return; +`; }; export { }; diff --git a/webclient/src/blockly/generateCode.ts b/webclient/src/blockly/generateCode.ts index 246bd74..23de1c5 100644 --- a/webclient/src/blockly/generateCode.ts +++ b/webclient/src/blockly/generateCode.ts @@ -6,13 +6,18 @@ export function generateCode(workspace: Blockly.WorkspaceSvg): string { let result = ''; for (const block of workspace.getTopBlocks(true)) { if (block.type.endsWith('_event')) { - let body = ''; + + const eventName = block.type.replace(/_event$/, ''); + + let body = javascriptGenerator.blockToCode(block, true) as string; + let next = block.getNextBlock(); while (next) { // opt_thisOnly=true prevents scrub_ from also chaining — we do it manually body += javascriptGenerator.blockToCode(next, true); next = next.getNextBlock(); } + body = javascriptGenerator.prefixLines(body, javascriptGenerator.INDENT.repeat(2)); // const args = Array.from(block.getFields()) @@ -22,8 +27,6 @@ export function generateCode(workspace: Blockly.WorkspaceSvg): string { //TODO use args - const eventName = block.type.replace(/_event$/, ''); - result += `eventBus.on( '${eventName}', function* handle_${eventName}(context) { diff --git a/webclient/src/components/ObjectViewInternal.tsx b/webclient/src/components/ObjectViewInternal.tsx index 76f1b80..94ccdb1 100644 --- a/webclient/src/components/ObjectViewInternal.tsx +++ b/webclient/src/components/ObjectViewInternal.tsx @@ -1,4 +1,4 @@ -import type { ObjectType, RuntimeGameObjectInstance, RuntimeObjectInstance } from "../types"; +import type { ObjectType, ObjectInstanceRigidBody, RuntimeGameObjectInstance, RuntimeObjectInstance } from "../types"; import { useEffect, useImperativeHandle, useRef, type Ref } from "react"; import { Euler, Quaternion, type Group } from "three"; import { Instance, Instances } from "@react-three/drei"; @@ -7,6 +7,7 @@ import { ConvexHullCollider, RapierRigidBody } from "@react-three/rapier"; import { SyncRigidBody } from "./SyncRigidBody"; import { reaction, runInAction } from "mobx"; import { v3toRapier } from "../utils"; +import { state } from "../state"; export type ObjectViewInternalHandle = { group: Group | null; @@ -56,7 +57,7 @@ export const ObjectViewInternal = function ({ object, objectType, ref, ...props }, [object, object.id, props.isPlayer] ); - + const gameObj = object as RuntimeGameObjectInstance; useEffect( @@ -84,6 +85,19 @@ export const ObjectViewInternal = function ({ object, objectType, ref, ...props gravityScale={object.gravityScale} position={object.position} rotation={object.rotation} + onCollisionEnter={props.isEditor ? undefined : (payload) => { + const game = state.game; + if (!game) + return; + const otherHandle = payload.other.rigidBody?.handle; + if (otherHandle === undefined) + return; + const otherObj = Object.values(game.scene.objects) + .find((o) => o.rb()?.handle === otherHandle); + game.emitEvent('object_touch_start', { object: gameObj, other: otherObj }); + if (otherObj?.id === game.scene.playerObjectId) + game.emitEvent('player_touch_start', { object: gameObj, other: otherObj }); + }} onSync={(data) => { runInAction(() => { object.position = data.position; diff --git a/webclient/src/scripts/eventBus.ts b/webclient/src/scripts/eventBus.ts index 0badb88..de83a8c 100644 --- a/webclient/src/scripts/eventBus.ts +++ b/webclient/src/scripts/eventBus.ts @@ -1,3 +1,4 @@ +import { toJS } from "mobx"; import type { ScriptContext, ScriptCoroutineContext, ScriptGameEventHandler } from "../types"; import type { ScriptCoroutines } from "./coroutines"; @@ -36,6 +37,8 @@ export class ScriptGameEventBus { } emit(event: string, context: Omit): void { + console.log('emitting ' + event, toJS(context)); + const coroutines = this.handlers[event] ?.map((h) => ({ owner: h.coroutine.thisObject.id, diff --git a/webclient/src/types/model/runtime.ts b/webclient/src/types/model/runtime.ts index 6895820..cce95ef 100644 --- a/webclient/src/types/model/runtime.ts +++ b/webclient/src/types/model/runtime.ts @@ -2,7 +2,8 @@ import type { V3 } from "../3d"; import type { VoxelGroup } from "../runtime"; import type { ObjectInstance } from "./object"; -export type RigidBodyHandle = { +export type ObjectInstanceRigidBody = { + handle: number; // rapier RigidBodyHandle applyImpulse(impulse: { x: number; y: number; z: number }, wakeUp: boolean): void; setLinvel(vel: { x: number; y: number; z: number }, wakeUp: boolean): void; setTranslation(translation: { x: number; y: number; z: number }, wakeUp: boolean): void; @@ -18,7 +19,7 @@ export type ObjectInstanceRuntimeData = { boundingBox: { min: V3; max: V3 }; updatedAt: number; }; - rb: () => RigidBodyHandle | null; + rb: () => ObjectInstanceRigidBody | null; } export type Runtime = T & ObjectInstanceRuntimeData; diff --git a/webclient/src/types/scripts/eventBus.ts b/webclient/src/types/scripts/eventBus.ts index e9b93f1..d352adc 100644 --- a/webclient/src/types/scripts/eventBus.ts +++ b/webclient/src/types/scripts/eventBus.ts @@ -17,6 +17,7 @@ export type ScriptContext = ScriptCoroutineContext & { world: World; scene: Scene; object?: RuntimeGameObjectInstance; + other?: RuntimeGameObjectInstance; } export type ScriptGameEventHandler = (context: ScriptContext) => ScriptCoroutine;