object touch events implemented
This commit is contained in:
@@ -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 { };
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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<ScriptContext, keyof ScriptCoroutineContext>): void {
|
||||
console.log('emitting ' + event, toJS(context));
|
||||
|
||||
const coroutines = this.handlers[event]
|
||||
?.map((h) => ({
|
||||
owner: h.coroutine.thisObject.id,
|
||||
|
||||
@@ -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 extends ObjectInstance> = T & ObjectInstanceRuntimeData;
|
||||
|
||||
@@ -17,6 +17,7 @@ export type ScriptContext = ScriptCoroutineContext & {
|
||||
world: World;
|
||||
scene: Scene;
|
||||
object?: RuntimeGameObjectInstance;
|
||||
other?: RuntimeGameObjectInstance;
|
||||
}
|
||||
|
||||
export type ScriptGameEventHandler = (context: ScriptContext) => ScriptCoroutine;
|
||||
|
||||
Reference in New Issue
Block a user