func loadTextures(eng sprite.Engine) []sprite.SubTex { a, err := asset.Open("placeholder-sprites.png") if err != nil { log.Fatal(err) } defer a.Close() // 処理が終わったらCloseする m, _, err := image.Decode(a) if err != nil { log.Fatal(err) } t, err := eng.LoadTexture(m) if err != nil { log.Fatal(err) } const n = 128 return []sprite.SubTex{ texGopher: sprite.SubTex{t, image.Rect(1+0, 0, n-1, n)}, //splite画像の一番左の青色のテクスチャを切り出す texGround: sprite.SubTex{t, image.Rect(1+n*2, 0, n*3-1, n)}, //splite画像の左からn-1番目のテクスチャを切り出す texEarth: sprite.SubTex{t, image.Rect(1+n*5, 0, n*6-1, n)}, //splite画像の左からn-1番目のテクスチャを切り出す } }
func (g *Game) Scene(eng sprite.Engine) *sprite.Node { texs := loadTextures(eng) scene := &sprite.Node{} eng.Register(scene) eng.SetTransform(scene, f32.Affine{ {1, 0, 0}, {0, 1, 0}, }) newNode := func(fn arrangerFunc) { n := &sprite.Node{Arranger: arrangerFunc(fn)} eng.Register(n) scene.AppendChild(n) } // The gopher. newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texGopher]) eng.SetTransform(n, f32.Affine{ {tileWidth, 0, 0}, {0, tileHeight, 0}, }) }) return scene }
func loadTextures(eng sprite.Engine) []sprite.SubTex { a, err := asset.Open("sprite.png") if err != nil { log.Fatal(err) } defer a.Close() m, _, err := image.Decode(a) if err != nil { log.Fatal(err) } t, err := eng.LoadTexture(m) if err != nil { log.Fatal(err) } const n = 128 return []sprite.SubTex{ texGopherRun1: sprite.SubTex{t, image.Rect(n*0, 0, n*1, n)}, texGopherRun2: sprite.SubTex{t, image.Rect(n*1, 0, n*2, n)}, texGopherFlap1: sprite.SubTex{t, image.Rect(n*2, 0, n*3, n)}, texGopherFlap2: sprite.SubTex{t, image.Rect(n*3, 0, n*4, n)}, texGopherDead1: sprite.SubTex{t, image.Rect(n*4, 0, n*5, n)}, texGopherDead2: sprite.SubTex{t, image.Rect(n*5, 0, n*6-1, n)}, texGround1: sprite.SubTex{t, image.Rect(n*6+1, 0, n*7-1, n)}, texGround2: sprite.SubTex{t, image.Rect(n*7+1, 0, n*8-1, n)}, texGround3: sprite.SubTex{t, image.Rect(n*8+1, 0, n*9-1, n)}, texGround4: sprite.SubTex{t, image.Rect(n*9+1, 0, n*10-1, n)}, texEarth: sprite.SubTex{t, image.Rect(n*10+1, 0, n*11-1, n)}, } }
func (l *Label) newTextTexture(eng sprite.Engine) sprite.SubTex { fg, bg := image.Black, image.White draw.Draw(l.rgba, l.rgba.Bounds(), bg, image.ZP, draw.Src) d := &sfont.Drawer{ Dst: l.rgba, Src: fg, Face: truetype.NewFace(l.font, truetype.Options{ Size: l.fontSize, DPI: 72, Hinting: sfont.HintingFull, }), } spacing := 1.5 dy := int(math.Ceil(l.fontSize * spacing)) for i, s := range strings.Split(l.Text, "\n") { d.Dot = fixed.P(0, int(l.fontSize*0.8)+dy*i) d.DrawString(s) } t, err := eng.LoadTexture(l.rgba) if err != nil { log.Fatal(err) } return sprite.SubTex{t, l.rgba.Bounds()} }
func loadTextures(eng sprite.Engine) map[string]sprite.SubTex { a, err := asset.Open("tx_letters.png") if err != nil { log.Fatal(err) } defer a.Close() img, _, err := image.Decode(a) if err != nil { log.Fatal(err) } t, err := eng.LoadTexture(img) if err != nil { log.Fatal(err) } return map[string]sprite.SubTex{ ":": sprite.SubTex{t, image.Rect(0, 0, 200, 200)}, "0": sprite.SubTex{t, image.Rect(200, 0, 400, 200)}, "1": sprite.SubTex{t, image.Rect(400, 0, 600, 200)}, "2": sprite.SubTex{t, image.Rect(0, 200, 200, 400)}, "3": sprite.SubTex{t, image.Rect(200, 200, 400, 400)}, "4": sprite.SubTex{t, image.Rect(400, 200, 600, 400)}, "5": sprite.SubTex{t, image.Rect(0, 400, 200, 600)}, "6": sprite.SubTex{t, image.Rect(200, 400, 400, 600)}, "7": sprite.SubTex{t, image.Rect(400, 400, 600, 600)}, "8": sprite.SubTex{t, image.Rect(0, 600, 200, 800)}, "9": sprite.SubTex{t, image.Rect(200, 600, 400, 800)}, "GO": sprite.SubTex{t, image.Rect(0, 800, 600, 1000)}, "gooon": sprite.SubTex{t, image.Rect(0, 1000, 600, 1200)}, } }
func loadTextures(eng sprite.Engine) []sprite.SubTex { a, err := asset.Open("sprite.png") if err != nil { log.Fatal(err) } defer a.Close() m, _, err := image.Decode(a) if err != nil { log.Fatal(err) } t, err := eng.LoadTexture(m) if err != nil { log.Fatal(err) } const n = 128 // The +1's and -1's in the rectangles below are to prevent colors from // adjacent textures leaking into a given texture. // See: http://stackoverflow.com/questions/19611745/opengl-black-lines-in-between-tiles return []sprite.SubTex{ texGopherRun1: sprite.SubTex{t, image.Rect(n*0+1, 0, n*1-1, n)}, texGopherRun2: sprite.SubTex{t, image.Rect(n*1+1, 0, n*2-1, n)}, texGopherFlap1: sprite.SubTex{t, image.Rect(n*2+1, 0, n*3-1, n)}, texGopherFlap2: sprite.SubTex{t, image.Rect(n*3+1, 0, n*4-1, n)}, texGopherDead1: sprite.SubTex{t, image.Rect(n*4+1, 0, n*5-1, n)}, texGopherDead2: sprite.SubTex{t, image.Rect(n*5+1, 0, n*6-1, n)}, texGround1: sprite.SubTex{t, image.Rect(n*6+1, 0, n*7-1, n)}, texGround2: sprite.SubTex{t, image.Rect(n*7+1, 0, n*8-1, n)}, texGround3: sprite.SubTex{t, image.Rect(n*8+1, 0, n*9-1, n)}, texGround4: sprite.SubTex{t, image.Rect(n*9+1, 0, n*10-1, n)}, texEarth: sprite.SubTex{t, image.Rect(n*10+1, 0, n*11-1, n)}, } }
func (a *arrangerFunc) Arrange(e s.Engine, n *s.Node, t clock.Time) { sprite, _ := a.eng.sprites[n] frameTime := float32(t - a.eng.lastUpdate) updatePosition(sprite, frameTime) screenWidthScaler, screenHeightScaler := a.eng.GetScreenScalers() actualScaleX := screenWidthScaler * sprite.ScaleX actualScaleY := screenHeightScaler * sprite.ScaleY actualPositionX := screenWidthScaler * sprite.X actualPositionY := screenHeightScaler * sprite.Y e.SetSubTex(n, *sprite.GetCurrentFrame().Texture) r := sprite.Rotation * math.Pi / 180 matrix := f32.Affine{ {1, 0, 0}, {0, 1, 0}, } matrix.Translate(&matrix, actualPositionX, actualPositionY) //matrix.Translate(&matrix, sprite.X, sprite.Y) matrix.Rotate(&matrix, r) matrix.Scale(&matrix, actualScaleX, actualScaleY) e.SetTransform(n, matrix) a.eng.lastUpdate = t }
func loadTextures(eng sprite.Engine) []sprite.SubTex { a, err := asset.Open("assets.png") if err != nil { log.Fatal(err) } defer a.Close() m, _, err := image.Decode(a) if err != nil { log.Fatal(err) } t, err := eng.LoadTexture(m) if err != nil { log.Fatal(err) } const n = 128 // The +1's and -1's in the rectangles below are to prevent colors from // adjacent textures leaking into a given texture. // See: http://stackoverflow.com/questions/19611745/opengl-black-lines-in-between-tiles return []sprite.SubTex{ texCtrl: {T: t, R: image.Rect(0, 0, 320, 320)}, texStick: {T: t, R: image.Rect(320, 0, 440, 120)}, texBot: {T: t, R: image.Rect(0, 320, 300, 610)}, texProxSmGrey: {T: t, R: image.Rect(300, 320, 300+50, 320+15)}, texProxSmGreen: {T: t, R: image.Rect(300, 320+15, 300+50, 320+30)}, texProxSmOrange: {T: t, R: image.Rect(300, 320+30, 300+50, 320+45)}, texProxSmRed: {T: t, R: image.Rect(300, 320+45, 300+50, 320+60)}, texProxMdGrey: {T: t, R: image.Rect(300, 320+60, 300+78, 320+80)}, texProxMdOrange: {T: t, R: image.Rect(300, 320+80, 300+78, 320+100)}, texProxMdRed: {T: t, R: image.Rect(300, 320+100, 300+78, 320+120)}, texProxLgGrey: {T: t, R: image.Rect(300, 320+120, 300+110, 320+147)}, texProxLgRed: {T: t, R: image.Rect(300, 320+147, 300+110, 320+174)}, } }
// Moves s to a new position and size func (s *StaticImg) Move(newXY, newDimensions *coords.Vec, eng sprite.Engine) { eng.SetTransform(s.node, f32.Affine{ {newDimensions.X, 0, newXY.X}, {0, newDimensions.Y, newXY.Y}, }) s.current = newXY s.dimensions = newDimensions }
// Moves c to a new position and size func (c *Card) Move(newXY, newDimensions *coords.Vec, eng sprite.Engine) { eng.SetTransform(c.node, f32.Affine{ {newDimensions.X, 0, newXY.X}, {0, newDimensions.Y, newXY.Y}, }) c.current = newXY c.dimensions = newDimensions }
func (c *Card) Move(eng sprite.Engine, newX float32, newY float32) { eng.SetTransform(c.node, f32.Affine{ {c.width, 0, newX}, {0, c.height, newY}, }) c.x = newX c.y = newY }
func (t *TextTexture) Create(eng sprite.Engine, text string) (sprite.SubTex, error) { draw.Draw(t.rgba, t.rgba.Bounds(), t.bg, image.ZP, draw.Src) d := &sfont.Drawer{ Dst: t.rgba, Src: t.fg, Face: t.Face, } dy := int(math.Ceil(t.Face.Size * t.Spacing)) for i, s := range strings.Split(text, "\n") { d.Dot = fixed.P(0, int(t.Face.Size*0.8)+dy*i) d.DrawString(s) } tex, err := eng.LoadTexture(t.rgba) if err != nil { return sprite.SubTex{}, err } return sprite.SubTex{tex, t.rgba.Bounds()}, nil }
func loadScene(eng sprite.Engine, ts map[string]sprite.SubTex) *sprite.Node { root := &sprite.Node{} eng.Register(root) eng.SetTransform(root, f32.Affine{ {1, 0, 0}, {0, 1, 0}, }) n := &sprite.Node{} eng.Register(n) root.AppendChild(n) eng.SetTransform(n, f32.Affine{ {200, 0, 0}, {0, 200, 0}, }) n.Arranger = arrangerFunc(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { s := fmt.Sprintf("%02d", int(t)) eng.SetSubTex(n, ts[s[0:1]]) }) return root }
func loadTextures(eng sprite.Engine) []sprite.SubTex { a, err := asset.Open("koha1.jpg") if err != nil { log.Fatal(err) } defer a.Close() m, _, err := image.Decode(a) if err != nil { log.Fatal(err) } t, err := eng.LoadTexture(m) if err != nil { log.Fatal(err) } log.Printf("%#v", m.Bounds()) x, y := t.Bounds() return []sprite.SubTex{ texGopher: sprite.SubTex{t, image.Rect(0, 0, x, y)}, } }
func (g *Game) Scene(eng sprite.Engine) *sprite.Node { texs := loadTextures(eng) scene = &sprite.Node{} // sceneのルートノードを生成 eng.Register(scene) // Engineオブジェクトにルートノードを登録 // ルートの初期位置やスケールを設定する eng.SetTransform(scene, f32.Affine{ {1, 0, 0}, {0, 1, 0}, }) newNode := func(fn arrangerFunc) { n := &sprite.Node{Arranger: arrangerFunc(fn)} eng.Register(n) scene.AppendChild(n) } // The ground. // 地面を描画するメソッド for i := range g.groundY { i := i // 地表の描画 newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texGround]) //texGroundのテクスチャを使う eng.SetTransform(n, f32.Affine{ {tileWidth, 0, float32(i)*tileWidth - g.scroll.x}, {0, tileHeight, g.groundY[i]}, //地面を描画する }) }) // 地中の描画 newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texEarth]) eng.SetTransform(n, f32.Affine{ {tileWidth, 0, float32(i) * tileWidth}, {0, tileHeight * tilesY, g.groundY[i] + tileHeight}, }) }) } // The gopher. newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texGopher]) eng.SetTransform(n, f32.Affine{ {tileWidth, 0, tileWidth * gopherTile}, {0, tileHeight, g.gopher.y}, }) }) return scene }
// Shows the back of c func (c *Card) SetBackDisplay(eng sprite.Engine) { eng.SetSubTex(c.node, c.back) }
// Shows the front of c func (c *Card) SetFrontDisplay(eng sprite.Engine) { eng.SetSubTex(c.node, c.image) }
// Loads all images for the app func LoadTextures(eng sprite.Engine) map[string]sprite.SubTex { allTexs := make(map[string]sprite.SubTex) boundedImgs := []string{"Clubs-2.png", "Clubs-3.png", "Clubs-4.png", "Clubs-5.png", "Clubs-6.png", "Clubs-7.png", "Clubs-8.png", "Clubs-9.png", "Clubs-10.png", "Clubs-Jack.png", "Clubs-Queen.png", "Clubs-King.png", "Clubs-Ace.png", "Diamonds-2.png", "Diamonds-3.png", "Diamonds-4.png", "Diamonds-5.png", "Diamonds-6.png", "Diamonds-7.png", "Diamonds-8.png", "Diamonds-9.png", "Diamonds-10.png", "Diamonds-Jack.png", "Diamonds-Queen.png", "Diamonds-King.png", "Diamonds-Ace.png", "Spades-2.png", "Spades-3.png", "Spades-4.png", "Spades-5.png", "Spades-6.png", "Spades-7.png", "Spades-8.png", "Spades-9.png", "Spades-10.png", "Spades-Jack.png", "Spades-Queen.png", "Spades-King.png", "Spades-Ace.png", "Hearts-2.png", "Hearts-3.png", "Hearts-4.png", "Hearts-5.png", "Hearts-6.png", "Hearts-7.png", "Hearts-8.png", "Hearts-9.png", "Hearts-10.png", "Hearts-Jack.png", "Hearts-Queen.png", "Hearts-King.png", "Hearts-Ace.png", "BakuSquare.png", } unboundedImgs := []string{"Club.png", "Diamond.png", "Spade.png", "Heart.png", "gray.jpeg", "blue.png", "trickDrop.png", "trickDropBlue.png", "player0.jpeg", "player1.jpeg", "player2.jpeg", "player3.jpeg", "laptopIcon.png", "watchIcon.png", "phoneIcon.png", "tabletIcon.png", "A-Upper.png", "B-Upper.png", "C-Upper.png", "D-Upper.png", "E-Upper.png", "F-Upper.png", "G-Upper.png", "H-Upper.png", "I-Upper.png", "J-Upper.png", "K-Upper.png", "L-Upper.png", "M-Upper.png", "N-Upper.png", "O-Upper.png", "P-Upper.png", "Q-Upper.png", "R-Upper.png", "S-Upper.png", "T-Upper.png", "U-Upper.png", "V-Upper.png", "W-Upper.png", "X-Upper.png", "Y-Upper.png", "Z-Upper.png", "A-Lower.png", "B-Lower.png", "C-Lower.png", "D-Lower.png", "E-Lower.png", "F-Lower.png", "G-Lower.png", "H-Lower.png", "I-Lower.png", "J-Lower.png", "K-Lower.png", "L-Lower.png", "M-Lower.png", "N-Lower.png", "O-Lower.png", "P-Lower.png", "Q-Lower.png", "R-Lower.png", "S-Lower.png", "T-Lower.png", "U-Lower.png", "V-Lower.png", "W-Lower.png", "X-Lower.png", "Y-Lower.png", "Z-Lower.png", "Space.png", "Colon.png", "Bang.png", "Apostrophe.png", "1.png", "2.png", "3.png", "4.png", "5.png", "6.png", "7.png", "8.png", "9.png", "0.png", "1-Red.png", "2-Red.png", "3-Red.png", "4-Red.png", "5-Red.png", "6-Red.png", "7-Red.png", "8-Red.png", "9-Red.png", "0-Red.png", "1-DBlue.png", "2-DBlue.png", "3-DBlue.png", "4-DBlue.png", "5-DBlue.png", "6-DBlue.png", "7-DBlue.png", "8-DBlue.png", "9-DBlue.png", "0-DBlue.png", "A-Upper-DBlue.png", "B-Upper-DBlue.png", "C-Upper-DBlue.png", "D-Upper-DBlue.png", "E-Upper-DBlue.png", "F-Upper-DBlue.png", "G-Upper-DBlue.png", "H-Upper-DBlue.png", "I-Upper-DBlue.png", "J-Upper-DBlue.png", "K-Upper-DBlue.png", "L-Upper-DBlue.png", "M-Upper-DBlue.png", "N-Upper-DBlue.png", "O-Upper-DBlue.png", "P-Upper-DBlue.png", "Q-Upper-DBlue.png", "R-Upper-DBlue.png", "S-Upper-DBlue.png", "T-Upper-DBlue.png", "U-Upper-DBlue.png", "V-Upper-DBlue.png", "W-Upper-DBlue.png", "X-Upper-DBlue.png", "Y-Upper-DBlue.png", "Z-Upper-DBlue.png", "A-Lower-DBlue.png", "B-Lower-DBlue.png", "C-Lower-DBlue.png", "D-Lower-DBlue.png", "E-Lower-DBlue.png", "F-Lower-DBlue.png", "G-Lower-DBlue.png", "H-Lower-DBlue.png", "I-Lower-DBlue.png", "J-Lower-DBlue.png", "K-Lower-DBlue.png", "L-Lower-DBlue.png", "M-Lower-DBlue.png", "N-Lower-DBlue.png", "O-Lower-DBlue.png", "P-Lower-DBlue.png", "Q-Lower-DBlue.png", "R-Lower-DBlue.png", "S-Lower-DBlue.png", "T-Lower-DBlue.png", "U-Lower-DBlue.png", "V-Lower-DBlue.png", "W-Lower-DBlue.png", "X-Lower-DBlue.png", "Y-Lower-DBlue.png", "Z-Lower-DBlue.png", "Apostrophe-DBlue.png", "Space-DBlue.png", "A-Upper-LBlue.png", "B-Upper-LBlue.png", "C-Upper-LBlue.png", "D-Upper-LBlue.png", "E-Upper-LBlue.png", "F-Upper-LBlue.png", "G-Upper-LBlue.png", "H-Upper-LBlue.png", "I-Upper-LBlue.png", "J-Upper-LBlue.png", "K-Upper-LBlue.png", "L-Upper-LBlue.png", "M-Upper-LBlue.png", "N-Upper-LBlue.png", "O-Upper-LBlue.png", "P-Upper-LBlue.png", "Q-Upper-LBlue.png", "R-Upper-LBlue.png", "S-Upper-LBlue.png", "T-Upper-LBlue.png", "U-Upper-LBlue.png", "V-Upper-LBlue.png", "W-Upper-LBlue.png", "X-Upper-LBlue.png", "Y-Upper-LBlue.png", "Z-Upper-LBlue.png", "A-Lower-LBlue.png", "B-Lower-LBlue.png", "C-Lower-LBlue.png", "D-Lower-LBlue.png", "E-Lower-LBlue.png", "F-Lower-LBlue.png", "G-Lower-LBlue.png", "H-Lower-LBlue.png", "I-Lower-LBlue.png", "J-Lower-LBlue.png", "K-Lower-LBlue.png", "L-Lower-LBlue.png", "M-Lower-LBlue.png", "N-Lower-LBlue.png", "O-Lower-LBlue.png", "P-Lower-LBlue.png", "Q-Lower-LBlue.png", "R-Lower-LBlue.png", "S-Lower-LBlue.png", "T-Lower-LBlue.png", "U-Lower-LBlue.png", "V-Lower-LBlue.png", "W-Lower-LBlue.png", "X-Lower-LBlue.png", "Y-Lower-LBlue.png", "Z-Lower-LBlue.png", "A-Upper-Gray.png", "B-Upper-Gray.png", "C-Upper-Gray.png", "D-Upper-Gray.png", "E-Upper-Gray.png", "F-Upper-Gray.png", "G-Upper-Gray.png", "H-Upper-Gray.png", "I-Upper-Gray.png", "J-Upper-Gray.png", "K-Upper-Gray.png", "L-Upper-Gray.png", "M-Upper-Gray.png", "N-Upper-Gray.png", "O-Upper-Gray.png", "P-Upper-Gray.png", "Q-Upper-Gray.png", "R-Upper-Gray.png", "S-Upper-Gray.png", "T-Upper-Gray.png", "U-Upper-Gray.png", "V-Upper-Gray.png", "W-Upper-Gray.png", "X-Upper-Gray.png", "Y-Upper-Gray.png", "Z-Upper-Gray.png", "A-Lower-Gray.png", "B-Lower-Gray.png", "C-Lower-Gray.png", "D-Lower-Gray.png", "E-Lower-Gray.png", "F-Lower-Gray.png", "G-Lower-Gray.png", "H-Lower-Gray.png", "I-Lower-Gray.png", "J-Lower-Gray.png", "K-Lower-Gray.png", "L-Lower-Gray.png", "M-Lower-Gray.png", "N-Lower-Gray.png", "O-Lower-Gray.png", "P-Lower-Gray.png", "Q-Lower-Gray.png", "R-Lower-Gray.png", "S-Lower-Gray.png", "T-Lower-Gray.png", "U-Lower-Gray.png", "V-Lower-Gray.png", "W-Lower-Gray.png", "X-Lower-Gray.png", "Y-Lower-Gray.png", "Z-Lower-Gray.png", "Space-Gray.png", "RoundedRectangle-DBlue.png", "RoundedRectangle-LBlue.png", "RoundedRectangle-Gray.png", "Rectangle-LBlue.png", "Rectangle-DBlue.png", "HorizontalPullTab.png", "VerticalPullTab.png", "NewGamePressed.png", "NewGameUnpressed.png", "NewRoundPressed.png", "NewRoundUnpressed.png", "JoinGamePressed.png", "JoinGameUnpressed.png", "Period.png", "SitSpotPressed.png", "SitSpotUnpressed.png", "WatchSpotPressed.png", "WatchSpotUnpressed.png", "StartBlue.png", "StartGray.png", "StartBluePressed.png", "Restart.png", "Visibility.png", "VisibilityOff.png", "QuitPressed.png", "QuitUnpressed.png", "PassPressed.png", "PassUnpressed.png", "RightArrowBlue.png", "LeftArrowBlue.png", "AcrossArrowBlue.png", "RightArrowGray.png", "LeftArrowGray.png", "AcrossArrowGray.png", "TakeTrickTableUnpressed.png", "TakeTrickTablePressed.png", "TakeTrickHandPressed.png", "TakeTrickHandUnpressed.png", "android.png", "cat.png", "man.png", "woman.png", "TakeUnpressed.png", "TakePressed.png", "UnplayedBorder1.png", "UnplayedBorder2.png", "RejoinPressed.png", "RejoinUnpressed.png", } for _, f := range boundedImgs { a, err := asset.Open(f) if err != nil { log.Fatal(err) } img, _, err := image.Decode(a) if err != nil { log.Fatal(err) } t, err := eng.LoadTexture(img) if err != nil { log.Fatal(err) } imgWidth, imgHeight := t.Bounds() allTexs[f] = sprite.SubTex{t, image.Rect(0, 0, imgWidth, imgHeight)} a.Close() } for _, f := range unboundedImgs { a, err := asset.Open(f) if err != nil { log.Fatal(err) } img, _, err := image.Decode(a) if err != nil { log.Fatal(err) } t, err := eng.LoadTexture(img) if err != nil { log.Fatal(err) } imgWidth, imgHeight := t.Bounds() allTexs[f] = sprite.SubTex{t, image.Rect(1, 1, imgWidth-1, imgHeight-1)} a.Close() } return allTexs }
func (g *Game) Scene(eng sprite.Engine) *sprite.Node { texs := loadTextures(eng) scene := &sprite.Node{} eng.Register(scene) eng.SetTransform(scene, f32.Affine{ {1, 0, 0}, {0, 1, 0}, }) newNode := func(fn arrangerFunc) { n := &sprite.Node{Arranger: arrangerFunc(fn)} eng.Register(n) scene.AppendChild(n) } // The ground. for i := range g.groundY { i := i // The top of the ground. newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[g.groundTex[i]]) eng.SetTransform(n, f32.Affine{ {tileWidth, 0, float32(i)*tileWidth - g.scroll.x}, {0, tileHeight, g.groundY[i]}, }) }) // The earth beneath. newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texEarth]) eng.SetTransform(n, f32.Affine{ {tileWidth, 0, float32(i)*tileWidth - g.scroll.x}, {0, tileHeight * tilesY, g.groundY[i] + tileHeight}, }) }) } // The gopher. newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { a := f32.Affine{ {tileWidth * 2, 0, tileWidth*(gopherTile-1) + tileWidth/8}, {0, tileHeight * 2, g.gopher.y - tileHeight + tileHeight/4}, } var x int switch { case g.gopher.dead: x = frame(t, 16, texGopherDead1, texGopherDead2) animateDeadGopher(&a, t-g.gopher.deadTime) case g.gopher.v < 0: x = frame(t, 4, texGopherFlap1, texGopherFlap2) case g.gopher.atRest: x = frame(t, 4, texGopherRun1, texGopherRun2) default: x = frame(t, 8, texGopherRun1, texGopherRun2) } eng.SetSubTex(n, texs[x]) eng.SetTransform(n, a) }) return scene }
// Scene creates and returns a new app scene. func (a *App) Scene(eng sprite.Engine, sz size.Event) *sprite.Node { texs := loadTextures(eng) scene := &sprite.Node{} eng.Register(scene) eng.SetTransform(scene, f32.Affine{ {1, 0, 0}, {0, 1, 0}, }) newNode := func(fn arrangerFunc) { n := &sprite.Node{Arranger: arrangerFunc(fn)} eng.Register(n) scene.AppendChild(n) } // Controller boundaries. newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texCtrl]) eng.SetTransform(n, f32.Affine{ {ctrlSize, 0, a.ctrl.x}, {0, ctrlSize, a.ctrl.y}, }) }) // Controller stick. newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texStick]) eng.SetTransform(n, f32.Affine{ {ctrlStickSize, 0, a.stick.x}, {0, ctrlStickSize, a.stick.y}, }) }) // Bot. newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texBot]) eng.SetTransform(n, f32.Affine{ {botSize, 0, a.bot.x}, {0, botSize, a.bot.y}, }) }) // Proximity small. const ( smSizeW = 15 smSizeH = 5 ) newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texProxSmGrey+a.bot.front.sm]) eng.SetTransform(n, f32.Affine{ {smSizeW, 0, a.bot.x + botSize/2 - smSizeW/2}, {0, smSizeH, a.bot.y - 2*smSizeH}, }) }) newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texProxSmGrey+a.bot.rear.sm]) eng.SetTransform(n, f32.Affine{ {smSizeW, 0, a.bot.x + botSize/2 - smSizeW/2}, {0, -smSizeH, a.bot.y + botSize + 2*smSizeH}, }) }) // Proximity medium. const ( mdSizeW = 25 mdSizeH = 7 ) newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texProxMdGrey+a.bot.front.md]) eng.SetTransform(n, f32.Affine{ {mdSizeW, 0, a.bot.x + botSize/2 - mdSizeW/2}, {0, mdSizeH, a.bot.y - 3*mdSizeH}, }) }) newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texProxMdGrey+a.bot.rear.md]) eng.SetTransform(n, f32.Affine{ {mdSizeW, 0, a.bot.x + botSize/2 - mdSizeW/2}, {0, -mdSizeH, a.bot.y + botSize + 3*mdSizeH}, }) }) // Proximity large const ( lgSizeW = 35 lgSizeH = 10 ) newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texProxLgGrey+a.bot.front.lg]) eng.SetTransform(n, f32.Affine{ {lgSizeW, 0, a.bot.x + botSize/2 - lgSizeW/2}, {0, lgSizeH, a.bot.y - 3.2*lgSizeH}, }) }) newNode(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { eng.SetSubTex(n, texs[texProxLgGrey+a.bot.rear.lg]) eng.SetTransform(n, f32.Affine{ {lgSizeW, 0, a.bot.x + botSize/2 - lgSizeW/2}, {0, -lgSizeH, a.bot.y + botSize + 3.2*lgSizeH}, }) }) return scene }