-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy pathcell.js
More file actions
118 lines (102 loc) · 3.77 KB
/
cell.js
File metadata and controls
118 lines (102 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import {STATES} from './nonogram.js'
import {POINTER_CLICK, POINTER_ENTER, POINTER_EXIT, Pointer} from './pointer.js'
import {TWEEN} from "./tween.js"
import {RESOURCES} from './resources.js'
import {playSound} from './resources.js'
const roundedRectShape = new THREE.Shape();
const roundedRectCurveSize = 0.95;
( function roundedRect( ctx, x, y, width, height, radius ) {
ctx.moveTo( x, y + radius );
ctx.lineTo( x, y + height - radius );
ctx.quadraticCurveTo( x, y + height, x + radius, y + height );
ctx.lineTo( x + width - radius, y + height );
ctx.quadraticCurveTo( x + width, y + height, x + width, y + height - radius );
ctx.lineTo( x + width, y + radius );
ctx.quadraticCurveTo( x + width, y, x + width - radius, y );
ctx.lineTo( x + radius, y );
ctx.quadraticCurveTo( x, y, x, y + radius );
} )( roundedRectShape, 0, 0, roundedRectCurveSize, roundedRectCurveSize, 0.2 );
const tilegeo = new THREE.ExtrudeBufferGeometry(roundedRectShape, {
depth:0.1,
bevelEnabled: false
})
tilegeo.translate(-roundedRectCurveSize/2, -roundedRectCurveSize/2,0)
const cell_material_highlight = new THREE.MeshLambertMaterial({color:0xffffff})
const cell_material_normal = new THREE.MeshLambertMaterial({color:0x444444})
export const CELL_GEOMETRIES = []
export const CELL_MATERIALS = []
export const CELL_TYPE = 'cell'
export default class GridCell extends THREE.Group {
/*
grid cell has three children:
one for the tile itself
one for the front decoration
one for the back decoration
*/
constructor(nonogram, x, y) {
super()
this.cellx = x
this.celly = y
const tile = new THREE.Mesh(tilegeo,cell_material_normal)
tile.userData.type = 'tile'
this.add(tile)
let front = new THREE.Group()
front.position.z = 0.15
this.add(front)
let back = new THREE.Group()
back.position.z = -0.15
this.add(back)
function meshForState(state) {
const mesh = new THREE.Mesh(CELL_GEOMETRIES[state],CELL_MATERIALS[state])
mesh.jtype = CELL_TYPE
return mesh
}
front.add(meshForState(STATES.UNKNOWN))
back.add(meshForState(STATES.SELECTED))
this.flipping = false
this.on(tile,POINTER_ENTER,()=>{
tile.material = cell_material_highlight
playSound(RESOURCES.SOUNDS.hover)
})
this.on(tile,POINTER_EXIT,()=>{
tile.material = cell_material_normal
})
this.on(tile,POINTER_CLICK,()=>{
if(this.flipping) return
//play the sound
playSound(RESOURCES.SOUNDS.thunk)
//update the state
nonogram.rollCellState(x,y)
const r = this.rotation.x
//set a new back geometry
back.remove(back.children[0])
back.add(meshForState(nonogram.getCellState(x,y)))
//flip
this.flipping = true
TWEEN.make({
target:this.rotation,
property:'x',
from:r,
to:r+Math.PI,
duration:500,
}).onEnd(()=>{
//swap the references to front and back
const temp = front
front = back
back = temp
this.flipping = false
})
})
this.solutionMesh = new THREE.Mesh(
new THREE.BoxGeometry(1,1,1),
new THREE.MeshLambertMaterial({color:'#dddddd', flatShading:true})
)
this.solutionMesh.visible = false
this.add(this.solutionMesh)
}
on(obj, type, cb) {
if(!obj.listeners) obj.listeners = {}
if(!obj.listeners[type]) obj.listeners[type] = []
obj.listeners[type].push(cb)
}
}