// Testing full image adjustment after screen resizing (assumes adjustImgs is scaling dimensions) func TestThree(test *testing.T) { u = uistate.MakeUIState() u.Scene = &sprite.Node{} u.Eng = glsprite.Engine(nil) u.Eng.Register(u.Scene) u.Eng.SetTransform(u.Scene, f32.Affine{ {1, 0, 0}, {0, 1, 0}, }) imgPos := coords.MakeVec(5, 20) imgDimensions := coords.MakeVec(10, 10) newButton := texture.MakeImgWithoutAlt(subtex, imgPos, imgDimensions, u) u.Buttons["1"] = newButton oldWindow := u.WindowSize.DividedBy(2) resize.AdjustImgs(oldWindow, u) newPos := u.Buttons["1"].GetCurrent() newDimensions := u.Buttons["1"].GetDimensions() dimExpect := imgDimensions.Times(2) posExpect := imgPos.Times(2) if newDimensions.X != dimExpect.X { test.Errorf("Expected width %f, got %f", dimExpect.X, newDimensions.X) } if newDimensions.Y != dimExpect.Y { test.Errorf("Expected height %f, got %f", dimExpect.Y, newDimensions.Y) } if newPos.X != posExpect.X { test.Errorf("Expected x %f, got %f", posExpect.X, newPos.X) } if newPos.Y != posExpect.Y { test.Errorf("Expected y %f, got %f", posExpect.Y, newPos.Y) } }
// Returns a vec containing a card's position after being passed to the player with index playerIndex func DetermineTablePassPosition(c *card.Card, cardNum, playerIndex int, u *uistate.UIState) *coords.Vec { cardDim := u.TableCardDim dropTargetXY := u.DropTargets[playerIndex].GetCurrent() dropTargetDim := u.DropTargets[playerIndex].GetDimensions() targetCenter := dropTargetXY.PlusVec(dropTargetDim.DividedBy(2)) xPlayerBlockSize := 2*u.PlayerIconDim.X + u.Padding yPlayerBlockSize := u.TopPadding + u.TableCardDim.Y + 3*u.Padding + u.PlayerIconDim.Y blockEdge := targetCenter.MinusVec(cardDim.Times(1.5).Plus(u.Padding)) var destination *coords.Vec switch playerIndex { case 0: destination = coords.MakeVec( blockEdge.X+float32(cardNum)*(u.Padding+cardDim.X), u.WindowSize.Y-yPlayerBlockSize-u.TableCardDim.Y) case 1: destination = coords.MakeVec( xPlayerBlockSize, blockEdge.Y+float32(cardNum)*(u.Padding+cardDim.Y)) case 2: destination = coords.MakeVec( blockEdge.X+float32(cardNum)*(u.Padding+cardDim.X), yPlayerBlockSize+u.Padding) case 3: destination = coords.MakeVec( u.WindowSize.X-xPlayerBlockSize-u.TableCardDim.X, blockEdge.Y+float32(cardNum)*(u.Padding+cardDim.Y)) } return destination }
// Testing NewImgWithAlt func TestFive(test *testing.T) { scene := &sprite.Node{} eng := glsprite.Engine(nil) u.Eng = eng u.Scene = scene pos := coords.MakeVec(5, 10) dimensions := coords.MakeVec(20, 10) i := texture.MakeImgWithAlt(subtex, subtex, pos, dimensions, true, u) if i.GetCurrent().X != pos.X { test.Errorf("Expected x %f, got %f", pos.X, i.GetCurrent().X) } if i.GetCurrent().Y != pos.Y { test.Errorf("Expected y %f, got %f", pos.Y, i.GetCurrent().Y) } if i.GetInitial().X != pos.X { test.Errorf("Expected inital x %f, got %f", pos.X, i.GetInitial().X) } if i.GetInitial().Y != pos.Y { test.Errorf("Expected initial y %f, got %f", pos.Y, i.GetInitial().Y) } if i.GetDimensions().X != dimensions.X { test.Errorf("Expected width %f, got %f", dimensions.X, i.GetDimensions().X) } if i.GetDimensions().Y != dimensions.Y { test.Errorf("Expected height %f, got %f", dimensions.Y, i.GetDimensions().Y) } }
func MakeStringImgLeftAlign(input, color, altColor string, displayColor bool, start *coords.Vec, scaler, maxWidth float32, u *uistate.UIState) []*staticimg.StaticImg { textures := getStringImgs(input, color, u.Texs) var altTexs []sprite.SubTex if color != altColor { altTexs = getStringImgs(input, altColor, u.Texs) } // adjust scaler if string is too long totalWidth := float32(0) for _, img := range textures { totalWidth += float32(img.R.Max.X) / scaler } if totalWidth > maxWidth { scaler = totalWidth * scaler / maxWidth } allImgs := make([]*staticimg.StaticImg, 0) for i, img := range textures { subTexDims := coords.MakeVec(float32(img.R.Max.X), float32(img.R.Max.Y)) dims := subTexDims.DividedBy(scaler) var textImg *staticimg.StaticImg if len(altTexs) == 0 { textImg = MakeImgWithoutAlt(img, start, dims, u) } else { textImg = MakeImgWithAlt(img, altTexs[i], start, dims, displayColor, u) } allImgs = append(allImgs, textImg) start = coords.MakeVec(start.X+dims.X, start.Y) } return allImgs }
// Testing resetting card position func TestSix(test *testing.T) { u = uistate.MakeUIState() u.Scene = &sprite.Node{} u.Eng = glsprite.Engine(nil) u.Eng.Register(u.Scene) u.Eng.SetTransform(u.Scene, f32.Affine{ {1, 0, 0}, {0, 1, 0}, }) u.EmptySuitImgs = []*staticimg.StaticImg{staticimg.MakeStaticImg(), staticimg.MakeStaticImg(), staticimg.MakeStaticImg(), staticimg.MakeStaticImg()} u.WindowSize = windowSize n := texture.MakeNode(u) for _, e := range u.EmptySuitImgs { e.SetImage(subtex) e.SetAlt(subtex) e.SetNode(n) } c := card.NewCard(card.Two, card.Heart) c2 := card.NewCard(card.Four, card.Heart) n = texture.MakeNode(u) n2 := texture.MakeNode(u) initialXY := coords.MakeVec(10, 10) curXY := coords.MakeVec(100, 30) dimensions := coords.MakeVec(5, 5) c.SetNode(n) c2.SetNode(n2) c.SetInitial(initialXY) c2.SetInitial(initialXY) c.Move(curXY, dimensions, u.Eng) c2.Move(curXY, dimensions, u.Eng) u.Cards = append(u.Cards, c) u.Cards = append(u.Cards, c2) if c.GetCurrent().X != curXY.X { test.Errorf("Expected x %f, got %f", curXY.X, c.GetCurrent().X) } if c.GetCurrent().Y != curXY.Y { test.Errorf("Expected y %f, got %f", curXY.Y, c.GetCurrent().Y) } reposition.ResetCardPosition(c, u.Eng) reposition.ResetCardPosition(c2, u.Eng) reposition.RealignSuit(c.GetSuit(), c.GetInitial().Y, u) if c.GetCurrent().X != u.Padding { test.Errorf("Expected x %f, got %f", initialXY.X, c.GetCurrent().X) } if c.GetCurrent().Y != initialXY.Y { test.Errorf("Expected y %f, got %f", initialXY.Y, c.GetCurrent().Y) } if c2.GetCurrent().X != u.Padding+dimensions.X+u.Padding { test.Errorf("Expected x %f, got %f", u.Padding+dimensions.X+u.Padding, c2.GetCurrent().X) } if c2.GetCurrent().Y != initialXY.Y { test.Errorf("Expected y %f, got %f", initialXY.Y, c2.GetCurrent().Y) } }
func determineDestination(animCard *card.Card, dir direction.Direction, windowSize *coords.Vec) *coords.Vec { switch dir { case direction.Right: return coords.MakeVec(animCard.GetCurrent().X+windowSize.X, animCard.GetCurrent().Y) case direction.Left: return coords.MakeVec(animCard.GetCurrent().X-windowSize.X, animCard.GetCurrent().Y) case direction.Across: return coords.MakeVec(animCard.GetCurrent().X, animCard.GetCurrent().Y-windowSize.Y) case direction.Down: return coords.MakeVec(animCard.GetCurrent().X, animCard.GetCurrent().Y+windowSize.Y) // Should not occur default: return coords.MakeVec(-1, -1) } }
// Realigns the cards in suit suitNum which are at y index oldY func RealignSuit(suitNum card.Suit, oldY float32, u *uistate.UIState) { cardsToAlign := make([]*card.Card, 0) for _, c := range u.Cards { if c.GetSuit() == suitNum && c.GetCurrent().Y == oldY { cardsToAlign = append(cardsToAlign, c) } } emptySuitImg := u.EmptySuitImgs[suitNum] if len(cardsToAlign) == 0 { u.Eng.SetSubTex(emptySuitImg.GetNode(), emptySuitImg.GetImage()) } else { u.Eng.SetSubTex(emptySuitImg.GetNode(), emptySuitImg.GetAlt()) } for i, c := range cardsToAlign { dimVec := c.GetDimensions() diff := float32(len(cardsToAlign))*(u.Padding+dimVec.X) - (u.WindowSize.X - u.Padding) x := u.Padding + float32(i)*(u.Padding+dimVec.X) if diff > 0 && i > 0 { x -= diff * float32(i) / float32(len(cardsToAlign)-1) } curVec := coords.MakeVec(x, oldY) c.Move(curVec, dimVec, u.Eng) c.SetInitial(curVec) } }
// Animate playing of a card in the split view // Should not be called when the player whose hand is being displayed is the player of the card func AnimateSplitCardPlay(c *card.Card, player int, quit chan bool, u *uistate.UIState) { dropTarget := u.DropTargets[(player-u.CurPlayerIndex+u.NumPlayers)%u.NumPlayers] toPos := dropTarget.GetCurrent() toDim := dropTarget.GetDimensions() texture.PopulateCardImage(c, u) switch player { case (u.CurPlayerIndex + 1) % u.NumPlayers: c.Move(coords.MakeVec(-toDim.X, 0), toDim, u.Eng) case (u.CurPlayerIndex + 2) % u.NumPlayers: c.Move(coords.MakeVec((u.WindowSize.X-toDim.X)/2, -toDim.Y), toDim, u.Eng) case (u.CurPlayerIndex + 3) % u.NumPlayers: c.Move(coords.MakeVec(u.WindowSize.X, 0), toDim, u.Eng) } ch := make(chan bool) animateCardMovement(ch, c, toPos, toDim, u) SwitchOnChan(ch, quit, func() {}, u) }
// Animation to bring in the play slot when app is in the hand view and it is the player's turn func AnimateInPlay(u *uistate.UIState) { imgs := append(u.DropTargets, u.BackgroundImgs[0]) for _, i := range imgs { dims := i.GetDimensions() to := coords.MakeVec(i.GetCurrent().X, i.GetCurrent().Y+u.WindowSize.Y/3+u.TopPadding) AnimateImageNoChannel(i, to, dims, u) } }
// Animation to bring in the pass slot func AnimateInPass(u *uistate.UIState) { imgs := append(u.Other, u.DropTargets...) imgs = append(imgs, u.Buttons["pass"]) for _, i := range imgs { dims := i.GetDimensions() to := coords.MakeVec(i.GetCurrent().X, i.GetCurrent().Y+u.WindowSize.Y) AnimateImageNoChannel(i, to, dims, u) } }
func UpdateImgPositions(sz size.Event, u *uistate.UIState) { // must copy u.WindowSize instead of creating a pointer to it oldWindowSize := coords.MakeVec(u.WindowSize.X, u.WindowSize.Y) updateWindowSize(sz, u) if windowExists(oldWindowSize) && windowExists(u.WindowSize) { u.Padding = scaleVar(u.Padding, oldWindowSize, u.WindowSize) AdjustImgs(oldWindowSize, u) } }
// Animation for the 'take' action, when app is in the hand view func AnimateHandCardTake(ch chan bool, animImages []*staticimg.StaticImg, u *uistate.UIState) { for i, image := range animImages { destination := coords.MakeVec(image.GetCurrent().X, image.GetCurrent().Y-u.WindowSize.Y) if i < len(animImages)-1 { AnimateImageNoChannel(image, destination, image.GetDimensions(), u) } else { animateImageMovement(ch, image, destination, image.GetDimensions(), u) } } }
// Animation for the 'pass' action, when app is in the hand view func AnimateHandCardPass(ch chan bool, animImages []*staticimg.StaticImg, u *uistate.UIState) { for counter, i := range animImages { dims := i.GetDimensions() to := coords.MakeVec(i.GetCurrent().X, i.GetCurrent().Y-u.WindowSize.Y) if counter < len(animImages)-1 { AnimateImageNoChannel(i, to, dims, u) } else { animateImageMovement(ch, i, to, dims, u) } } }
// Drags all input cards and images together with the mouse func DragImgs(t touch.Event, cards []*card.Card, imgs []*staticimg.StaticImg, u *uistate.UIState) { tVec := coords.MakeVec(t.X, t.Y) for _, i := range imgs { newVec := i.GetCurrent().PlusVec(tVec.MinusVec(u.LastMouseXY).DividedBy(u.PixelsPerPt)) i.Move(newVec, i.GetDimensions(), u.Eng) } for _, c := range cards { newVec := c.GetCurrent().PlusVec(tVec.MinusVec(u.LastMouseXY).DividedBy(u.PixelsPerPt)) c.Move(newVec, c.GetDimensions(), u.Eng) } }
// Given a card object, populates it with its positioning values and sets its position on-screen for the player hand view func SetCardPositionHand(c *card.Card, indexInSuit int, suitCounts []int, u *uistate.UIState) { suitCount := float32(suitCounts[c.GetSuit()]) heightScaler := float32(4 - c.GetSuit()) diff := suitCount*(u.Padding+u.CardDim.X) - (u.WindowSize.X - u.Padding) x := u.Padding + float32(indexInSuit)*(u.Padding+u.CardDim.X) if diff > 0 && indexInSuit > 0 { x -= diff * float32(indexInSuit) / (suitCount - 1) } y := u.WindowSize.Y - heightScaler*(u.CardDim.Y+u.Padding) - u.BottomPadding pos := coords.MakeVec(x, y) c.SetInitial(pos) c.Move(pos, u.CardDim, u.Eng) }
// Testing AdjustKeepDimensions func TestTwo(test *testing.T) { imgPos := coords.MakeVec(5, 20) imgDimensions := coords.MakeVec(10, 10) oldWindow := coords.MakeVec(30, 60) newPos, _, newDimensions := resize.AdjustKeepDimensions(imgPos, imgPos, imgDimensions, oldWindow, windowSize) widthExpect := imgDimensions.X heightExpect := imgDimensions.Y xExpect := float32(25) yExpect := float32(32.5) if newDimensions.X != widthExpect { test.Errorf("Expected width %f, got %f", widthExpect, newDimensions.X) } if newDimensions.Y != heightExpect { test.Errorf("Expected height %f, got %f", heightExpect, newDimensions.Y) } if newPos.X != xExpect { test.Errorf("Expected x %f, got %f", xExpect, newPos.X) } if newPos.Y != yExpect { test.Errorf("Expected y %f, got %f", yExpect, newPos.Y) } }
func MakeStringImgRightAlign(input, color, altColor string, displayColor bool, end *coords.Vec, scaler, maxWidth float32, u *uistate.UIState) []*staticimg.StaticImg { textures := getStringImgs(input, color, u.Texs) var altTexs []sprite.SubTex if color != altColor { altTexs = getStringImgs(input, altColor, u.Texs) } // adjust scaler if string is too long totalWidth := float32(0) for _, img := range textures { totalWidth += float32(img.R.Max.X) / scaler } if totalWidth > maxWidth { scaler = totalWidth * scaler / maxWidth } // reverse textures for i, j := 0, len(textures)-1; i < j; i, j = i+1, j-1 { textures[i], textures[j] = textures[j], textures[i] } allImgs := make([]*staticimg.StaticImg, 0) for i, img := range textures { subTexDims := coords.MakeVec(float32(img.R.Max.X), float32(img.R.Max.Y)) dims := subTexDims.DividedBy(scaler) end = coords.MakeVec(end.X-dims.X, end.Y) var textImg *staticimg.StaticImg if len(altTexs) == 0 { textImg = MakeImgWithoutAlt(img, end, dims, u) } else { textImg = MakeImgWithAlt(img, altTexs[i], end, dims, displayColor, u) } allImgs = append(allImgs, textImg) } return allImgs }
func AnimateHandCardTakeTrick(ch chan bool, cards []*card.Card, u *uistate.UIState) { imgs := append(u.DropTargets, u.BackgroundImgs[0]) for _, i := range imgs { dims := i.GetDimensions() to := coords.MakeVec(i.GetCurrent().X, i.GetCurrent().Y-u.WindowSize.Y/3-u.TopPadding) AnimateImageNoChannel(i, to, dims, u) } for i, c := range cards { destination := c.GetDimensions().Times(-1) if i < len(cards)-1 { animateCardNoChannel(c, destination, c.GetDimensions(), u) } else { animateCardMovement(ch, c, destination, c.GetDimensions(), u) } } }
func CardPositionTable(playerIndex int, cardIndex *coords.Vec, u *uistate.UIState) *coords.Vec { var x float32 var y float32 switch playerIndex { case 0: x = horizontalPlayerCardX(u.WindowSize, cardIndex, u.TableCardDim, u.BottomPadding, u.Overlap.X) y = u.WindowSize.Y - u.TableCardDim.Y - u.BottomPadding case 1: x = u.BottomPadding y = verticalPlayerCardY(u.WindowSize, cardIndex, u.TableCardDim, u.PlayerIconDim, u.BottomPadding, u.Overlap.Y, u.CardScaler) case 2: x = horizontalPlayerCardX(u.WindowSize, cardIndex, u.TableCardDim, u.BottomPadding, u.Overlap.X) y = u.TopPadding case 3: x = u.WindowSize.X - u.BottomPadding - u.TableCardDim.X y = verticalPlayerCardY(u.WindowSize, cardIndex, u.TableCardDim, u.PlayerIconDim, u.BottomPadding, u.Overlap.Y, u.CardScaler) } return coords.MakeVec(x, y) }
// Animation for the 'play' action, when app is in the hand view func AnimateHandCardPlay(ch chan bool, animCard *card.Card, u *uistate.UIState) { for _, o := range u.Other { BringNodeToFront(o.GetNode(), u) } for _, img := range u.Buttons { BringNodeToFront(img.GetNode(), u) } for _, img := range u.ModText { BringNodeToFront(img.GetNode(), u) } imgs := []*staticimg.StaticImg{u.BackgroundImgs[0], u.DropTargets[0]} for counter, i := range imgs { dims := i.GetDimensions() to := coords.MakeVec(i.GetCurrent().X, i.GetCurrent().Y-u.WindowSize.Y) if counter < len(imgs)-1 { AnimateImageNoChannel(i, to, dims, u) } else { animateImageMovement(ch, i, to, dims, u) } } }
func MakeStringImgCenterAlign(input, color, altColor string, displayColor bool, center *coords.Vec, scaler, maxWidth float32, u *uistate.UIState) []*staticimg.StaticImg { textures := getStringImgs(input, color, u.Texs) totalWidth := float32(0) newScaler := scaler for _, img := range textures { totalWidth += float32(img.R.Max.X) / scaler } if totalWidth > maxWidth { newScaler = totalWidth * scaler / maxWidth totalWidth = maxWidth } startX := center.X - totalWidth/2 startY := center.Y if len(textures) > 0 { startY = center.Y + (float32(textures[0].R.Max.Y)/scaler-float32(textures[0].R.Max.Y)/newScaler)/2 } start := coords.MakeVec(startX, startY) return MakeStringImgLeftAlign(input, color, altColor, displayColor, start, newScaler, maxWidth, u) }
func AnimateOutSplit(ch chan bool, u *uistate.UIState) { ResetAnims(u) topOfBanner := u.WindowSize.Y - 4*u.CardDim.Y - 5*u.Padding - u.BottomPadding - 40 tableImgs := make([]*staticimg.StaticImg, 0) bannerImgs := make([]*staticimg.StaticImg, 0) bannerImgs = append(bannerImgs, u.Other...) bannerImgs = append(bannerImgs, u.Buttons["takeTrick"]) bannerImgs = append(bannerImgs, u.Buttons["toggleSplit"]) tableImgs = append(tableImgs, u.DropTargets...) tableImgs = append(tableImgs, u.BackgroundImgs[:u.NumPlayers+1]...) for _, img := range tableImgs { from := img.GetCurrent() to := coords.MakeVec(from.X, from.Y-topOfBanner) AnimateImageNoChannel(img, to, img.GetDimensions(), u) } for _, img := range u.ModText { from := img.GetCurrent() var to *coords.Vec if from.Y < topOfBanner { to = coords.MakeVec(from.X, from.Y-topOfBanner) } else { to = coords.MakeVec(from.X, from.Y-topOfBanner+10) } AnimateImageNoChannel(img, to, img.GetDimensions(), u) } for i, img := range bannerImgs { from := img.GetCurrent() to := coords.MakeVec(from.X, from.Y-topOfBanner+10) if i == 0 && i < len(bannerImgs)-1 { oldDim := img.GetDimensions() newDim := coords.MakeVec(oldDim.X, oldDim.Y+10) newTo := coords.MakeVec(to.X, to.Y-10) AnimateImageNoChannel(img, newTo, newDim, u) } else if i < len(bannerImgs)-1 { AnimateImageNoChannel(img, to, img.GetDimensions(), u) } else { animateImageMovement(ch, img, to, img.GetDimensions(), u) } } }
func MakeUIState() *UIState { return &UIState{ StartTime: time.Now(), Cards: make([]*card.Card, 0), TableCards: make([]*card.Card, 0), BackgroundImgs: make([]*staticimg.StaticImg, 0), EmptySuitImgs: make([]*staticimg.StaticImg, 0), DropTargets: make([]*staticimg.StaticImg, 0), Buttons: make(map[string]*staticimg.StaticImg), Other: make([]*staticimg.StaticImg, 0), ModText: make([]*staticimg.StaticImg, 0), RoundScores: make([]int, numPlayers), LastMouseXY: coords.MakeVec(-1, -1), NumPlayers: numPlayers, NumSuits: numSuits, CardSize: cardSize, CardScaler: cardScaler, TopPadding: topPadding, BottomPadding: bottomPadding, WindowSize: coords.MakeVec(-1, -1), CardDim: coords.MakeVec(cardSize, cardSize), TableCardDim: coords.MakeVec(cardSize*cardScaler, cardSize*cardScaler), PlayerIconDim: coords.MakeVec(2*cardSize/3, 2*cardSize/3), Overlap: coords.MakeVec(3*cardSize*cardScaler/4, 3*cardSize*cardScaler/4), Padding: float32(5), CurView: None, Done: false, Debug: false, SequentialPhases: true, SwitchingViews: false, UserData: make(map[int]map[string]interface{}), PlayerData: make(map[int]int), AnimChans: make([]chan bool, 0), DiscGroups: make(map[string]*DiscStruct), CurPlayerIndex: -1, Audio: makePlayerStruct([]string{"whooshIn.wav", "whooshOut.wav"}), LatestTimestamp: 0, } }
// Drags card curCard along with the mouse func DragCard(t touch.Event, u *uistate.UIState) { tVec := coords.MakeVec(t.X, t.Y) newVec := u.CurCard.GetCurrent().PlusVec(tVec.MinusVec(u.LastMouseXY).DividedBy(u.PixelsPerPt)) u.CurCard.Move(newVec, u.CurCard.GetDimensions(), u.Eng) }
"golang.org/x/mobile/exp/f32" "golang.org/x/mobile/exp/sprite" "golang.org/x/mobile/exp/sprite/glsprite" "hearts/img/coords" "hearts/img/reposition" "hearts/img/resize" "hearts/img/staticimg" "hearts/img/texture" "hearts/img/uistate" "hearts/logic/card" "testing" ) var ( subtex sprite.SubTex windowSize = coords.MakeVec(90, 90) u *uistate.UIState ) // Testing AdjustScaleDimensions func TestOne(test *testing.T) { imgPos := coords.MakeVec(5, 20) imgDimensions := coords.MakeVec(10, 10) oldWindow := coords.MakeVec(30, 60) newPos, _, newDimensions := resize.AdjustScaleDimensions(imgPos, imgPos, imgDimensions, oldWindow, windowSize) widthExpect := imgDimensions.X * 3 heightExpect := imgDimensions.Y * 3 / 2 xExpect := float32(15) yExpect := float32(30) if newDimensions.X != widthExpect { test.Errorf("Expected width %f, got %f", widthExpect, newDimensions.X)