创建碰撞与路径
This commit is contained in:
1 parent
f2fe653c04
commit
f27167621c
4 files changed
+783
-56
No files matched your search
+110
-2
@@ -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 },
|
||||
|
||||
Reference in new issue
Block a user