object touch events implemented
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
import * as Blockly from "blockly";
|
import * as Blockly from "blockly";
|
||||||
import { javascriptGenerator } from "blockly/javascript";
|
import { javascriptGenerator, Order } from "blockly/javascript";
|
||||||
|
|
||||||
Blockly.Blocks['object_touch_start_event'] = {
|
Blockly.Blocks['object_touch_start_event'] = {
|
||||||
init(this: Blockly.Block) {
|
init(this: Blockly.Block) {
|
||||||
this.appendDummyInput('NAME')
|
this.appendDummyInput()
|
||||||
.appendField('When');
|
.appendField('When');
|
||||||
this.appendValueInput('NAME')
|
this.appendValueInput('OTHER_OBJECT')
|
||||||
.setCheck('Object');
|
.setCheck('Object');
|
||||||
this.appendDummyInput('NAME')
|
this.appendDummyInput()
|
||||||
.appendField('touches me');
|
.appendField('touches me');
|
||||||
this.setStyle('event_hat');
|
this.setStyle('event_hat');
|
||||||
this.setNextStatement(true);
|
this.setNextStatement(true);
|
||||||
@@ -15,8 +15,13 @@ Blockly.Blocks['object_touch_start_event'] = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
javascriptGenerator.forBlock['object_touch_start_event'] = function (_block, _generator) {
|
javascriptGenerator.forBlock['object_touch_start_event'] = function (block, generator) {
|
||||||
return '';
|
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 { };
|
export { };
|
||||||
|
|||||||
@@ -6,13 +6,18 @@ export function generateCode(workspace: Blockly.WorkspaceSvg): string {
|
|||||||
let result = '';
|
let result = '';
|
||||||
for (const block of workspace.getTopBlocks(true)) {
|
for (const block of workspace.getTopBlocks(true)) {
|
||||||
if (block.type.endsWith('_event')) {
|
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();
|
let next = block.getNextBlock();
|
||||||
while (next) {
|
while (next) {
|
||||||
// opt_thisOnly=true prevents scrub_ from also chaining — we do it manually
|
// opt_thisOnly=true prevents scrub_ from also chaining — we do it manually
|
||||||
body += javascriptGenerator.blockToCode(next, true);
|
body += javascriptGenerator.blockToCode(next, true);
|
||||||
next = next.getNextBlock();
|
next = next.getNextBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
body = javascriptGenerator.prefixLines(body, javascriptGenerator.INDENT.repeat(2));
|
body = javascriptGenerator.prefixLines(body, javascriptGenerator.INDENT.repeat(2));
|
||||||
|
|
||||||
// const args = Array.from(block.getFields())
|
// const args = Array.from(block.getFields())
|
||||||
@@ -22,8 +27,6 @@ export function generateCode(workspace: Blockly.WorkspaceSvg): string {
|
|||||||
|
|
||||||
//TODO use args
|
//TODO use args
|
||||||
|
|
||||||
const eventName = block.type.replace(/_event$/, '');
|
|
||||||
|
|
||||||
result += `eventBus.on(
|
result += `eventBus.on(
|
||||||
'${eventName}',
|
'${eventName}',
|
||||||
function* handle_${eventName}(context) {
|
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 { useEffect, useImperativeHandle, useRef, type Ref } from "react";
|
||||||
import { Euler, Quaternion, type Group } from "three";
|
import { Euler, Quaternion, type Group } from "three";
|
||||||
import { Instance, Instances } from "@react-three/drei";
|
import { Instance, Instances } from "@react-three/drei";
|
||||||
@@ -7,6 +7,7 @@ import { ConvexHullCollider, RapierRigidBody } from "@react-three/rapier";
|
|||||||
import { SyncRigidBody } from "./SyncRigidBody";
|
import { SyncRigidBody } from "./SyncRigidBody";
|
||||||
import { reaction, runInAction } from "mobx";
|
import { reaction, runInAction } from "mobx";
|
||||||
import { v3toRapier } from "../utils";
|
import { v3toRapier } from "../utils";
|
||||||
|
import { state } from "../state";
|
||||||
|
|
||||||
export type ObjectViewInternalHandle = {
|
export type ObjectViewInternalHandle = {
|
||||||
group: Group | null;
|
group: Group | null;
|
||||||
@@ -84,6 +85,19 @@ export const ObjectViewInternal = function ({ object, objectType, ref, ...props
|
|||||||
gravityScale={object.gravityScale}
|
gravityScale={object.gravityScale}
|
||||||
position={object.position}
|
position={object.position}
|
||||||
rotation={object.rotation}
|
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) => {
|
onSync={(data) => {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
object.position = data.position;
|
object.position = data.position;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { toJS } from "mobx";
|
||||||
import type { ScriptContext, ScriptCoroutineContext, ScriptGameEventHandler } from "../types";
|
import type { ScriptContext, ScriptCoroutineContext, ScriptGameEventHandler } from "../types";
|
||||||
import type { ScriptCoroutines } from "./coroutines";
|
import type { ScriptCoroutines } from "./coroutines";
|
||||||
|
|
||||||
@@ -36,6 +37,8 @@ export class ScriptGameEventBus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
emit(event: string, context: Omit<ScriptContext, keyof ScriptCoroutineContext>): void {
|
emit(event: string, context: Omit<ScriptContext, keyof ScriptCoroutineContext>): void {
|
||||||
|
console.log('emitting ' + event, toJS(context));
|
||||||
|
|
||||||
const coroutines = this.handlers[event]
|
const coroutines = this.handlers[event]
|
||||||
?.map((h) => ({
|
?.map((h) => ({
|
||||||
owner: h.coroutine.thisObject.id,
|
owner: h.coroutine.thisObject.id,
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import type { V3 } from "../3d";
|
|||||||
import type { VoxelGroup } from "../runtime";
|
import type { VoxelGroup } from "../runtime";
|
||||||
import type { ObjectInstance } from "./object";
|
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;
|
applyImpulse(impulse: { x: number; y: number; z: number }, wakeUp: boolean): void;
|
||||||
setLinvel(vel: { 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;
|
setTranslation(translation: { x: number; y: number; z: number }, wakeUp: boolean): void;
|
||||||
@@ -18,7 +19,7 @@ export type ObjectInstanceRuntimeData = {
|
|||||||
boundingBox: { min: V3; max: V3 };
|
boundingBox: { min: V3; max: V3 };
|
||||||
updatedAt: number;
|
updatedAt: number;
|
||||||
};
|
};
|
||||||
rb: () => RigidBodyHandle | null;
|
rb: () => ObjectInstanceRigidBody | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Runtime<T extends ObjectInstance> = T & ObjectInstanceRuntimeData;
|
export type Runtime<T extends ObjectInstance> = T & ObjectInstanceRuntimeData;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export type ScriptContext = ScriptCoroutineContext & {
|
|||||||
world: World;
|
world: World;
|
||||||
scene: Scene;
|
scene: Scene;
|
||||||
object?: RuntimeGameObjectInstance;
|
object?: RuntimeGameObjectInstance;
|
||||||
|
other?: RuntimeGameObjectInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ScriptGameEventHandler = (context: ScriptContext) => ScriptCoroutine;
|
export type ScriptGameEventHandler = (context: ScriptContext) => ScriptCoroutine;
|
||||||
|
|||||||
Reference in New Issue
Block a user