我正在Coffeescapet中开发一个Pixi.js游戏,主要关注旋转六边形。在设置旋转动画和识别旋转的基础板状态方面,关于旋转的一切都正常工作。然而,对于棋盘上的某些精灵(并非所有),旋转它们会导致舞台上的其他精灵(并非全部)“抖动”。他们暂时移到一边,然后在旋转结束时再次移回来。我一直在努力寻找这个问题;我发现的一个结果是,有人在不同的网站上有类似的问题,但没有答案:
here
.
我不知道从哪里开始自己诊断这个bug。如果这是画布的问题,我可以在那里查看,但也可能是Pixi的问题。这是这个问题的gif图。当我单击第一个十六进制(右侧)时,许多行都会抖动。当我单击第二个十六进制(左侧)时,它们不会。
就代码而言,该项目目前规模相当大。下面是动画函数和助手方法:
## The frame count the window is on ##
@count = 0
### Moves the connector to the correct lit layer ###
@toLit = (connector) ->
try
@colorContainers[connector.color].unlit.removeChild(connector.panel)
catch
if @typeIsArray connector.color
if connector.color.length > 0
c = connector.color[0].toUpperCase()
else
c = Color.asString(Color.NONE).toUpperCase()
else
c = connector.color.toUpperCase()
if c is Color.asString(Color.NONE).toUpperCase()
@toUnlit(connector) ## Prevent lighting of color.NONE
else
@colorContainers[c.toUpperCase()].lit.addChild(connector.panel)
connector.linked = true
return
### Moves the connector to the correct unlit layer ###
@toUnlit = (connector) ->
try
@colorContainers[connector.color].lit.removeChild(connector.panel)
catch
if @typeIsArray connector.color
if connector.color.length > 0
c = connector.color[0]
else
c = Color.asString(Color.NONE)
else
c = connector.color
if connector.hex? and connector.hex instanceof Crystal
@colorContainers[Color.asString(Color.NONE).toUpperCase()].unlit.addChild(connector.panel)
else
@colorContainers[c.toUpperCase()].unlit.addChild(connector.panel)
connector.linked = false
return
### Creates a frame offset for the each color ###
@colorOffset = {}
for c in Color.values()
if not isNaN(c)
c = Color.fromString(c).toUpperCase()
else
c = c.toUpperCase()
@colorOffset[c] = Math.random() + 0.5
### Updates the pulse filter that controls lighting effects ###
@calcPulseFilter = (count) ->
for col, val of @colorContainers
pulse = val.lit.filters[0]
cont = (count + val.lit.pulseOffset)/val.lit.pulseLength
m = pulse.matrix
m[0] = Math.abs(Math.sin(cont * 2 * Math.PI)) * 0.5 + 0.5
m[5] = Math.abs(Math.sin(cont * 2 * Math.PI)) * 0.5 + 0.5
m[10] = Math.abs(Math.sin(cont * 2 * Math.PI)) * 0.5 + 0.5
m[15] = Math.abs(Math.sin(cont * 2 * Math.PI)) * 0.25 + 0.75
pulse.matrix = m
for cont in @goalContainer.children
if cont.children.length >= 2 and cont.filters.length >= 2
pulse = cont.filters[1]
correspondCont = @colorContainers[cont.children[0].color.toUpperCase()].lit
c = (count + correspondCont.pulseOffset)/correspondCont.pulseLength
m = pulse.matrix
if parseInt(cont.children[1].text.substring(0, 1)) >= parseInt(cont.children[1].text.substring(2))
m[0] = Math.abs(Math.sin(c * 2 * Math.PI)) * 0.5 + 0.5
m[5] = Math.abs(Math.sin(c * 2 * Math.PI)) * 0.5 + 0.5
m[10] = Math.abs(Math.sin(c * 2 * Math.PI)) * 0.5 + 0.5
m[15] = Math.abs(Math.sin(c * 2 * Math.PI)) * 0.25 + 0.75
else
m[0] = 1
m[5] = 1
m[10] = 1
m[15] = 1
pulse.matrix = m
return
### The animation function. Called by pixi and requests to be recalled ###
@animate = () ->
## Color animation
window.count += 1; ## Frame count
@calcPulseFilter(window.count)
rotSpeed = 1/5
tolerance = 0.000001 ## For floating point errors - difference below this is considered 'equal'
radTo60Degree = 1.04719755 ## 1 radian * this coefficient = 60 degrees
if (@BOARD?)
## Update text on goal
curLit = @BOARD.crystalLitCount()
goalContainer = @menu.children[@goalContainerIndex]
isWin = true ## True if this user has won - every goal set.
for pan in goalContainer.children
for spr in pan.children
if spr instanceof PIXI.Text and spr.color.toUpperCase() of curLit
spr.setText(curLit[spr.color.toUpperCase()] + spr.text.substring(1))
if curLit[spr.color.toUpperCase()] < parseInt(spr.text.substring(2))
isWin = false
if isWin and (not @winContainer?) and @showWinContainer
@gameOn = false
@makeWinGameContainer()
for h in @BOARD.allHexes()
##Update lighting of all hexes
if h.isLit().length > 0 and not h.backPanel.children[0].lit
h.backPanel.children[0].lit = true
if not (h instanceof Prism)
@toLit(h.backPanel.spr)
if h.isLit().length is 0 and h.backPanel.children[0].lit
h.backPanel.children[0].lit = false
if not (h instanceof Prism)
@toUnlit(h.backPanel.spr)
hLit = h.isLit()
if h instanceof Prism
## Adjust opacity of cores
for col, core of h.cores
if col.toLowerCase() not in hLit and core.alpha > 0
core.alpha = 0
else if col.toLowerCase() in hLit and core.alpha is 0
core.alpha = 0.75
nS = h.getNeighborsWithBlanks()
## Fixing lighting of connectors
for panel in h.colorPanels
col = panel.color.toLowerCase()
for connector in panel.children
for side in connector.sides
n = nS[side]
if n? and col in hLit and n.colorOfSide(n.indexLinked(h)) is col and not connector.linked
@toLit(connector)
for nPanel in n.colorPanels
for nConnector in nPanel.children
for nSide in nConnector.sides
if nSide is n.indexLinked(h) and not nConnector.linked
@toLit(nConnector)
else if connector.linked and col not in hLit
@toUnlit(connector)
if n?
for nPanel in n.colorPanels
for nConnector in nPanel.children
for nSide in nConnector.sides
if nSide is n.indexLinked(h) and not nConnector.linked
@toUnlit(nConnector)
### Rotation of a prism - finds a prism that wants to rotate and rotates it a bit. ###
### If this is the first notification that this prism wants to rotate, stops providing light. ###
### If the prism is now done rotating, starts providing light again ###
if h instanceof Prism and h.currentRotation isnt h.targetRotation
if h.canLight
h.canLight = false
h.light()
inc =
if (h.targetRotation - h.prevRotation) >= 0
rotSpeed
else
-rotSpeed
h.backPanel.rotation += inc * radTo60Degree
h.currentRotation += inc
for value in h.colorPanels
value.rotation += inc * radTo60Degree
if Math.abs(h.targetRotation - h.currentRotation) < tolerance
inc = (h.targetRotation - h.currentRotation)
h.backPanel.rotation += inc * radTo60Degree
h.currentRotation += inc
for value in h.colorPanels
value.rotation += inc * radTo60Degree
## Update side index of each sprite
for spr in value.children
newSides = []
for side in spr.sides
newSides.push((side + (h.currentRotation - h.prevRotation)) %% Hex.SIDES)
spr.sides = newSides
h.prevRotation = h.currentRotation
h.canLight = true
h.light()
### Spark and crystal color changing ###
if (h instanceof Spark or h instanceof Crystal) and h.toColor isnt ""
col = if (not isNaN(h.toColor))
Color.asString(h.toColor).toUpperCase()
else
h.toColor.toUpperCase()
h.backPanel.spr.color = col
@toLit(h.backPanel.spr)
h.toColor = ""
requestAnimFrame(animate )
@renderer.render(@stage)
return
如果您认为代码中有任何其他部分与bug相关,请告诉我,我会将这些部分放上去。任何帮助或建议都将非常棒!