func NewGUIMenuItem(id int, font *Font.Font, snd *Effect, x, y, delay float64, title string) *gui.GUIObject { mi := new(GUIMenuItem) mi.GUIObject.Initialize() mi.GUIObject.Id = id mi.font = font mi.snd = snd mi.delay = delay mi.title = title mi.color.SetHWColor(0xFFFFE060) mi.shadow.SetHWColor(0x30000000) mi.offset = 0.0 mi.timer = -1.0 mi.timer2 = -1.0 mi.GUIObject.Static = false mi.GUIObject.Visible = true mi.GUIObject.Enabled = true w := font.GetStringWidth(title) mi.GUIObject.Rect.Set(x-w/2, y, x+w/2, y+mi.font.GetHeight()) mi.GUIObject.Render = func() { mi.font.SetColor(mi.shadow.HWColor()) mi.font.Render(mi.GUIObject.Rect.X1+mi.offset+3, mi.GUIObject.Rect.Y1+3, Font.TEXT_LEFT, mi.title) mi.font.SetColor(mi.color.HWColor()) mi.font.Render(mi.GUIObject.Rect.X1-mi.offset, mi.GUIObject.Rect.Y1-mi.offset, Font.TEXT_LEFT, mi.title) } mi.GUIObject.Update = func(dt float64) { if mi.timer2 != -1.0 { mi.timer2 += dt if mi.timer2 >= mi.delay+0.1 { mi.color = mi.scolor2.Add(mi.dcolor2) mi.shadow = mi.sshadow.Add(mi.dshadow) mi.offset = 0.0 mi.timer2 = -1.0 } else { if mi.timer2 < mi.delay { mi.color = mi.scolor2 mi.shadow = mi.sshadow } else { mi.color = mi.scolor2.Add(mi.dcolor2.MulScalar((mi.timer2 - mi.delay) * 10)) mi.shadow = mi.sshadow.Add(mi.dshadow.MulScalar((mi.timer2 - mi.delay) * 10)) } } } else if mi.timer != -1.0 { mi.timer += dt if mi.timer >= 0.2 { mi.color = mi.scolor.Add(mi.dcolor) mi.offset = mi.soffset + mi.doffset mi.timer = -1.0 } else { mi.color = mi.scolor.Add(mi.dcolor.MulScalar(mi.timer * 5)) mi.offset = mi.soffset + mi.doffset*mi.timer*5 } } } mi.GUIObject.Enter = func() { var tcolor2 Color.ColorRGB mi.scolor2.SetHWColor(0x00FFE060) tcolor2.SetHWColor(0xFFFFE060) mi.dcolor2 = tcolor2.Sub(mi.scolor2) mi.sshadow.SetHWColor(0x00000000) tcolor2.SetHWColor(0x30000000) mi.dshadow = tcolor2.Sub(mi.sshadow) mi.timer2 = 0.0 } mi.GUIObject.Leave = func() { var tcolor2 Color.ColorRGB mi.scolor2.SetHWColor(0xFFFFE060) tcolor2.SetHWColor(0x00FFE060) mi.dcolor2 = tcolor2.Sub(mi.scolor2) mi.sshadow.SetHWColor(0x30000000) tcolor2.SetHWColor(0x00000000) mi.dshadow = tcolor2.Sub(mi.sshadow) mi.timer2 = 0.0 } mi.GUIObject.IsDone = func() bool { if mi.timer2 == -1.0 { return true } return false } mi.GUIObject.Focus = func(focused bool) { var tcolor Color.ColorRGB if focused { snd.Play() mi.scolor.SetHWColor(0xFFFFE060) tcolor.SetHWColor(0xFFFFFFFF) mi.soffset = 0 mi.doffset = 4 } else { mi.scolor.SetHWColor(0xFFFFFFFF) tcolor.SetHWColor(0xFFFFE060) mi.soffset = 4 mi.doffset = -4 } mi.dcolor = tcolor.Sub(mi.scolor) mi.timer = 0.0 } mi.GUIObject.MouseOver = func(over bool) { if over { mi.GUIObject.GUI.SetFocus(mi.GUIObject.Id) } } mi.GUIObject.MouseLButton = func(down bool) bool { if !down { mi.offset = 4 return true } snd.Play() mi.offset = 0 return false } mi.GUIObject.KeyClick = func(key Key, chr int) bool { if key == K_ENTER || key == K_SPACE { mi.GUIObject.MouseLButton(true) return mi.GUIObject.MouseLButton(false) } return false } return &mi.GUIObject }
// An example of using closures func main() { func() { const ( speed = 90.0 friction = 0.98 ) var ( spr sprite.Sprite fnt *font.Font par *particle.ParticleSystem snd *Effect x = 100.0 y = 100.0 dx = 0.0 dy = 0.0 ) hge := New() hge.SetState(LOGFILE, "tutorial03.log") hge.SetState(TITLE, "HGE Tutorial 03 - Using helper classes") hge.SetState(FPS, 100) hge.SetState(WINDOWED, true) hge.SetState(SCREENWIDTH, 800) hge.SetState(SCREENHEIGHT, 600) hge.SetState(SCREENBPP, 32) hge.SetState(FRAMEFUNC, func() int { dt := float64(Delta()) boom := func() { pan := int((x - 400) / 4) pitch := (dx*dx+dy*dy)*0.0005 + 0.2 snd.PlayEx(100, pan, pitch) } // Process keys if NewKey(K_ESCAPE).State() { return 1 } if NewKey(K_LEFT).State() { dx -= speed * dt } if NewKey(K_RIGHT).State() { dx += speed * dt } if NewKey(K_UP).State() { dy -= speed * dt } if NewKey(K_DOWN).State() { dy += speed * dt } // Do some movement calculations and collision detection dx *= friction dy *= friction x += dx y += dy if x > 784 { x = 784 - (x - 784) dx = -dx boom() } if x < 16 { x = 16 + 16 - x dx = -dx boom() } if y > 584 { y = 584 - (y - 584) dy = -dy boom() } if y < 16 { y = 16 + 16 - y dy = -dy boom() } // Update particle system par.Info.Emission = (int)(dx*dx+dy*dy) * 2 par.MoveTo(x, y) par.Update(dt) return 0 }) hge.SetState(RENDERFUNC, func() int { BeginScene() Clear(0) par.Render() spr.Render(x, y) fnt.Printf(5, 5, font.TEXT_LEFT, "dt:%.3f\nFPS:%d (constant)", Delta(), GetFPS()) EndScene() return 0 }) if err := hge.Initiate(); err == nil { defer hge.Shutdown() snd = NewEffect("menu.ogg") tex := LoadTexture("particles.png") if snd == nil || tex == nil { fmt.Printf("Error: Can't load one of the following files:\nmenu.ogg, particles.png, font1.fnt, font1.png, trail.psi\n") return } spr = sprite.New(tex, 96, 64, 32, 32) spr.SetColor(0xFFFFA000) spr.SetHotSpot(16, 16) if fnt = font.New("font1.fnt"); fnt == nil { fmt.Println("Error loading font1.fnt") return } spt := sprite.New(tex, 32, 32, 32, 32) spt.SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_NOZWRITE) spt.SetHotSpot(16, 16) par = particle.New("trail.psi", spt) if par == nil { fmt.Println("Error loading trail.psi") return } par.Fire() hge.Start() } }() for i := 0; i < 10; i++ { fmt.Println("Sleeping") time.Sleep(1 * time.Second) runtime.GC() } }
func NewGUIListBox(id int, x, y, w, h float64, fnt *font.Font, color, highlightColor, spriteHighlightColor hge.Dword) *GUIListBox { l := new(GUIListBox) l.GUIObject.Initialize() l.GUIObject.Id = id l.GUIObject.Visible = true l.GUIObject.Enabled = true l.GUIObject.Rect.Set(x, y, x+w, y+h) l.Font = fnt l.highlight = sprite.New(nil, 0, 0, w, fnt.GetHeight()) l.highlight.SetColor(highlightColor) l.color = color l.highlightColor = highlightColor l.List = list.New() l.GUIObject.Render = func() { item := l.List.Front() for i := 0; i < l.topItem; i++ { if item == nil { return } item = item.Next() } for i := 0; i < l.NumRows(); i++ { if i >= l.items { return } if l.topItem+i == l.selectedItem { l.highlight.Render(l.GUIObject.Rect.X1, l.GUIObject.Rect.Y1+float64(i)*l.Font.GetHeight()) l.Font.SetColor(l.highlightColor) } else { l.Font.SetColor(l.color) } l.Font.Render(l.GUIObject.Rect.X1+3, l.GUIObject.Rect.Y1+float64(i)*l.Font.GetHeight(), font.TEXT_LEFT, item.Value.(*guiListboxItem).text) item = item.Next() } } l.GUIObject.MouseMove = func(x, y float64) bool { l.mx, l.my = x, y return false } l.GUIObject.MouseLButton = func(down bool) bool { if down { item := l.topItem + int(l.my)/int(l.Font.GetHeight()) if item < l.Len() { l.selectedItem = item return true } } return false } l.GUIObject.MouseWheel = func(notches int) bool { l.topItem -= notches if l.topItem < 0 { l.topItem = 0 } if l.topItem > l.Len()-l.NumRows() { l.topItem = l.Len() - l.NumRows() } return true } l.GUIObject.KeyClick = func(key input.Key, chr int) bool { switch key { case input.K_DOWN: if l.selectedItem < l.Len()-1 { l.selectedItem++ if l.selectedItem > l.topItem+l.NumRows()-1 { l.topItem = l.selectedItem - l.NumRows() + 1 } return true } case input.K_UP: if l.selectedItem > 0 { l.selectedItem-- if l.selectedItem < l.topItem { l.topItem = l.selectedItem } return true } } return false } return l }