Files
lity3d/Engine/VisualScript/block_interaction.c
T
shuiyu1123 0669d102ce feat: major engine overhaul - scene demo with lighting, sphere, ground
- Scene Demo: cube + sphere + ground plane with proper lighting
- Audio: XAudio2 dynamic loading + WAV playback
- Physics: expanded collision system
- Renderer: improved pipeline with materials
- UI: extended widget system
- VisualScript: enhanced serializer + block interactions
- ASM: optimized math/memory/profiling routines
- Window: mouse input + scroll support
2026-07-12 08:21:07 +08:00

152 lines
4.8 KiB
C

// ============================================================================
// block_interaction.c - 交互系统实现
// ============================================================================
#include "block_interaction.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <Windows.h>
void interaction_init(BlockInteraction* inter) {
memset(inter, 0, sizeof(BlockInteraction));
}
void interaction_mouse_move(BlockInteraction* inter, BlockWorkspace* ws, int x, int y) {
inter->mouse_x = x;
inter->mouse_y = y;
// 拖拽积木
if (inter->dragging_block) {
float wx, wy;
workspace_screen_to_world(ws, (float)x, (float)y, &wx, &wy);
inter->dragging_block->x = wx - inter->drag_offset_x;
inter->dragging_block->y = wy - inter->drag_offset_y;
}
// 平移画布
if (inter->panning) {
float dx = (x - inter->pan_start_x) / ws->zoom;
float dy = (y - inter->pan_start_y) / ws->zoom;
ws->view_x = inter->view_start_x - dx;
ws->view_y = inter->view_start_y - dy;
}
}
void interaction_mouse_down(BlockInteraction* inter, BlockWorkspace* ws, int button) {
inter->mouse_down = 1;
inter->mouse_button = button;
float wx, wy;
workspace_screen_to_world(ws, (float)inter->mouse_x, (float)inter->mouse_y, &wx, &wy);
if (button == 0) { // 左键
// 检查是否点击槽位
BlockSlot* slot = workspace_find_slot_at(ws, wx, wy);
if (slot) {
// 开始连接
inter->connecting_from = slot;
inter->connect_start_x = wx;
inter->connect_start_y = wy;
return;
}
// 检查是否点击积木
Block* block = workspace_find_block_at(ws, wx, wy);
if (block) {
inter->dragging_block = block;
inter->drag_offset_x = wx - block->x;
inter->drag_offset_y = wy - block->y;
inter->selected_block = block;
ws->selected_block = block;
return;
}
// 点击空白区域: 取消选择
inter->selected_block = NULL;
ws->selected_block = NULL;
}
if (button == 1 || button == 2) { // 右键/中键: 平移
inter->panning = 1;
inter->pan_start_x = (float)inter->mouse_x;
inter->pan_start_y = (float)inter->mouse_y;
inter->view_start_x = ws->view_x;
inter->view_start_y = ws->view_y;
}
}
void interaction_mouse_up(BlockInteraction* inter, BlockWorkspace* ws, int button) {
inter->mouse_down = 0;
if (button == 0) {
// 结束拖拽积木
inter->dragging_block = NULL;
// 结束连接
if (inter->connecting_from) {
float wx, wy;
workspace_screen_to_world(ws, (float)inter->mouse_x, (float)inter->mouse_y, &wx, &wy);
BlockSlot* target = workspace_find_slot_at(ws, wx, wy);
if (target && target != inter->connecting_from) {
// 尝试建立连接
workspace_add_connection(ws, inter->connecting_from, target);
}
inter->connecting_from = NULL;
}
}
if (button == 1 || button == 2) {
inter->panning = 0;
}
}
void interaction_key_down(BlockInteraction* inter, BlockWorkspace* ws, int key) {
inter->key = key;
inter->key_pressed = 1;
// 删除选中的积木
if (key == 46 || key == 8) { // DELETE 或 BACKSPACE
if (inter->selected_block) {
workspace_remove_block(ws, inter->selected_block->id);
inter->selected_block = NULL;
ws->selected_block = NULL;
}
}
// 复制/粘贴 (Ctrl+C / Ctrl+V)
static Block* clipboard = NULL;
if (key == 'C' && (GetAsyncKeyState(VK_CONTROL) & 0x8000)) {
if (inter->selected_block) {
if (clipboard) block_destroy(clipboard);
clipboard = block_copy(inter->selected_block);
}
}
if (key == 'V' && (GetAsyncKeyState(VK_CONTROL) & 0x8000)) {
if (clipboard) {
Block* copy = block_copy(clipboard);
if (copy) {
copy->x += 20.0f;
copy->y += 20.0f;
copy->id = ws->next_block_id++;
workspace_add_block(ws, copy);
inter->selected_block = copy;
ws->selected_block = copy;
}
}
}
}
void interaction_mouse_wheel(BlockInteraction* inter, BlockWorkspace* ws, int delta) {
float zoom_factor = delta > 0 ? 1.1f : 0.9f;
ws->zoom *= zoom_factor;
if (ws->zoom < 0.25f) ws->zoom = 0.25f;
if (ws->zoom > 4.0f) ws->zoom = 4.0f;
}
void interaction_update(BlockInteraction* inter, BlockWorkspace* ws) {
inter->key_pressed = 0;
(void)ws;
}