blob: 76fa039a96e386cb7bf54ec7618d4d197bad3ade [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package reposition
import (
"hearts/direction"
"hearts/img/staticimg"
"hearts/logic/card"
"golang.org/x/mobile/event/touch"
"golang.org/x/mobile/exp/f32"
"golang.org/x/mobile/exp/sprite"
"golang.org/x/mobile/exp/sprite/clock"
)
const (
animSpeedScaler = .1
animRotationScaler = .15
)
// Resets the position of card c to its initial position, then realigns the suit it was in
// Takes as arguments:
// c = the card object to be reset
// cards = the total list of cards displayed on-screen
// emptySuitImgs = the list of staticImg objects showing suit icon in case of a suit becoming empty or populated
// padding = how much space there should be in between cards if the screen is wide enough to accommodate
// windowSize = an array containing the width and height of the app window
// eng = the engine running the app
func ResetCardPosition(c *card.Card, cards []*card.Card, emptySuitImgs []*staticimg.StaticImg, padding float32, windowSize []float32, eng sprite.Engine) {
newX := c.GetInitialX()
newY := c.GetInitialY()
c.Move(newX, newY, c.GetWidth(), c.GetHeight(), eng)
RealignSuit(c.GetSuit(), newY, cards, emptySuitImgs, padding, windowSize, eng)
}
// Realigns the cards in suit suitNum which are at y index oldY
// Takes as arguments:
// suitNum = the suit to be aligned
// oldY = the y-index of the suit
// cards = the total list of cards displayed on-screen
// emptySuitImgs = the list of staticImg objects showing suit icon in case of a suit becoming empty or populated
// padding = how much space there should be in between cards if the screen is wide enough to accommodate
// windowSize = an array containing the width and height of the app window
// eng = the engine running the app
func RealignSuit(suitNum card.Suit, oldY float32, cards []*card.Card, emptySuitImgs []*staticimg.StaticImg, padding float32, windowSize []float32, eng sprite.Engine) {
cardsToAlign := make([]*card.Card, 0)
for _, c := range cards {
if c.GetSuit() == suitNum && c.GetY() == oldY {
cardsToAlign = append(cardsToAlign, c)
}
}
emptySuitImg := emptySuitImgs[suitNum]
if len(cardsToAlign) == 0 {
eng.SetSubTex(emptySuitImg.GetNode(), emptySuitImg.GetImage())
} else {
eng.SetSubTex(emptySuitImg.GetNode(), emptySuitImg.GetAlt())
}
for i, c := range cardsToAlign {
width := c.GetWidth()
height := c.GetHeight()
diff := float32(len(cardsToAlign))*(padding+width) - (windowSize[0] - padding)
x := padding + float32(i)*(padding+width)
if diff > 0 && i > 0 {
x -= diff * float32(i) / float32(len(cardsToAlign)-1)
}
y := oldY
c.Move(x, y, width, height, eng)
c.SetInitialPos(x, y)
}
}
// Drags card curCard along with the mouse
func DragCard(curCard *card.Card, pixelsPerPt float32, lastMouseXY []float32, eng sprite.Engine, t touch.Event) {
newX := curCard.GetX() + (t.X-lastMouseXY[0])/pixelsPerPt
newY := curCard.GetY() + (t.Y-lastMouseXY[1])/pixelsPerPt
width := curCard.GetWidth()
height := curCard.GetHeight()
curCard.Move(newX, newY, width, height, eng)
}
// Animates a card such that it spins away in direction dir
func SpinAway(animCard *card.Card, dir direction.Direction, touch touch.Event) {
node := animCard.GetNode()
startTime := -1
node.Arranger = arrangerFunc(func(eng sprite.Engine, node *sprite.Node, t clock.Time) {
if startTime == -1 {
startTime = int(t)
}
moveSpeed := float32(int(t)-startTime) * float32(animSpeedScaler)
x := animCard.GetX()
y := animCard.GetY()
width := animCard.GetWidth()
height := animCard.GetHeight()
switch dir {
case direction.Right:
x = x + moveSpeed
case direction.Left:
x = x - moveSpeed
case direction.Across:
y = y - moveSpeed
}
animCard.SetPos(x, y, width, height)
position := f32.Affine{
{width, 0, x + width/2},
{0, height, y + height/2},
}
position.Rotate(&position, float32(t)*float32(animRotationScaler))
position.Translate(&position, -.5, -.5)
eng.SetTransform(node, position)
})
}
type arrangerFunc func(e sprite.Engine, n *sprite.Node, t clock.Time)
// Used for node.Arranger
func (a arrangerFunc) Arrange(e sprite.Engine, n *sprite.Node, t clock.Time) { a(e, n, t) }