创建碰撞与路径

This commit is contained in:
tianmo committed 2026-08-28 18:24:29 +08:00
1 parent f2fe653c04
commit f27167621c
4 files changed
+783 -56

No files matched your search

+110 -2
View File
@@ -1,5 +1,5 @@
import { defineStore } from 'pinia'
import { EmitterConfig, defaultConfig, ParticleState } from '../core/particleEmitter'
import { EmitterConfig, defaultConfig, ParticleState, type SceneCollider } from '../core/particleEmitter'
export interface ParticleSystem {
id: number
@@ -8,6 +8,28 @@ export interface ParticleSystem {
frames?: ParticleState[][]
}
export interface CollisionBody extends SceneCollider {
name: string
tags: string[]
selectedTag: string
followPath: boolean
}
export interface ScenePath {
id: number
name: string
enabled: boolean
x: number
y: number
rotation: number
closed: boolean
color: string
preset: '' | 'circle' | 'square' | 'polygon' | 'star'
points: Array<{ x: number; y: number; inX: number; inY: number; outX: number; outY: number }>
}
export type SceneObjectType = 'particle' | 'collision' | 'path' | 'spine'
export interface EditorState {
viewScale: number
viewX: number
@@ -46,12 +68,18 @@ export interface TimelineState {
}
let seq = 1
let colliderSeq = 1
let pathSeq = 1
export const useParticleStore = defineStore('particle', {
state: () => ({
editor: { viewScale: 1.0, viewX: 0, viewY: 0 } as EditorState,
systems: [] as ParticleSystem[],
colliders: [] as CollisionBody[],
paths: [] as ScenePath[],
activeId: 0,
activeObjectType: 'particle' as SceneObjectType,
activeObjectId: 0,
timeline: { playing: true, loop: true, frame: 0, totalFrames: 120, fps: 60, recorded: false, animation: 'animation' } as TimelineState,
settings: { tickEnabled: false, axisFontSize: 12, tickWidth: 1, showAxisLabels: true, axisColor: '#7a86ad' } as SettingsState,
}),
@@ -77,14 +105,94 @@ export const useParticleStore = defineStore('particle', {
const sys: ParticleSystem = { id: seq++, config: cfg }
this.systems.push(sys)
this.activeId = sys.id
this.activeObjectType = 'particle'
this.activeObjectId = sys.id
return sys
},
removeSystem(id: number) {
const i = this.systems.findIndex((s) => s.id === id)
if (i >= 0) this.systems.splice(i, 1)
if (this.activeId === id) this.activeId = this.systems[0]?.id ?? 0
if (this.activeObjectType === 'particle' && this.activeObjectId === id) {
const next = this.systems[0]
this.activeObjectId = next?.id ?? 0
}
},
selectSystem(id: number) {
this.activeId = id
this.activeObjectType = 'particle'
this.activeObjectId = id
},
addCollider() {
const id = colliderSeq++
const collider: CollisionBody = {
id,
name: `碰撞体 ${id}`,
tags: ['Default'],
selectedTag: 'Default',
shape: 'circle',
enabled: true,
x: 0,
y: 0,
rotation: 0,
radius: 50,
radiusX: 70,
radiusY: 45,
width: 120,
height: 80,
sides: 6,
response: 'physics',
elasticity: 0.8,
friction: 0.3,
followPath: false,
}
this.colliders.push(collider)
this.activeObjectType = 'collision'
this.activeObjectId = collider.id
return collider
},
addPath() {
const id = pathSeq++
const path: ScenePath = {
id,
name: `路径 ${id}`,
enabled: true,
x: 0,
y: 0,
rotation: 0,
closed: false,
color: '#ff933e',
preset: '',
points: [],
}
this.paths.push(path)
this.activeObjectType = 'path'
this.activeObjectId = path.id
return path
},
selectSceneObject(type: SceneObjectType, id: number) {
this.activeObjectType = type
this.activeObjectId = id
if (type === 'particle') this.activeId = id
},
removeCollider(id: number) {
const index = this.colliders.findIndex((item) => item.id === id)
if (index >= 0) this.colliders.splice(index, 1)
if (this.activeObjectType === 'collision' && this.activeObjectId === id) {
const fallback = this.systems[0]
this.activeObjectType = fallback ? 'particle' : 'collision'
this.activeObjectId = fallback?.id ?? this.colliders[0]?.id ?? 0
}
},
removePath(id: number) {
const index = this.paths.findIndex((item) => item.id === id)
if (index >= 0) this.paths.splice(index, 1)
if (this.activeObjectType === 'path' && this.activeObjectId === id) {
const fallback = this.systems[0]
this.activeObjectType = fallback ? 'particle' : 'path'
this.activeObjectId = fallback?.id ?? this.paths[0]?.id ?? 0
}
},
selectSystem(id: number) { this.activeId = id },
play() { this.timeline.playing = true },
pause() { this.timeline.playing = false },
togglePlay() { this.timeline.playing = !this.timeline.playing },