123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- package global
- import "math"
- import al "gitlab.com/beoran/al5go/al"
- import "gitlab.com/beoran/ebsgo/engine/tile"
- import "gitlab.com/beoran/ebsgo/engine/physics"
- import "gitlab.com/beoran/ebsgo/monolog"
- type FPS struct {
- FPS float64
- Now float64
- Time float64
- Show bool
- }
- type State struct {
- Display * al.Display
- Fullscreen bool
- W int
- H int
- HaveAudio bool
- HaveTouch bool
- HaveJoystick bool
- Done bool
- DefaultFont * al.Font
- TTF * al.Font
- Colors map[string](al.Color)
- Queue * al.EventQueue
- FPS
- Frames int
- LastUpdate float64
- Joysticks [] * al.Joystick
- Map * tile.Map
- // MapID store.ID
- // area.Area
- Camera physics.Camera
- // Sprites sprite.List
- // ScriptEngine raku.Runtime
- // zori.Console
- // zori.State
- // Actor area.Thing
- }
- func (ms * State) Hf() float32 {
- return float32(ms.H)
- }
- func (ms * State) Wf() float32 {
- return float32(ms.W)
- }
- func (ms * State) LogIfFail(ok bool, text string) bool {
- if !ok {
- monolog.Error("%s", text)
- }
- return ok
- }
- func (ms * State) LoadMap(name string) {
- tm, err := tile.LoadMapFifi(name)
- if err != nil {
- monolog.Error("Could not load tile map: %s", err)
- } else {
- ms.Map = tm
- }
- }
- func (ms * State) SetupJoysticks() {
- if (!ms.HaveJoystick) {
- return
- }
-
- ms.Joysticks = make([]*al.Joystick, 0)
-
- num := al.GetNumJoysticks()
-
-
- monolog.Printf("Found %d joysticks.\n", num)
-
- for i:= 0; i < num; i ++ {
- joy := al.GetJoystick(i)
- ms.Joysticks = append(ms.Joysticks, joy)
- monolog.Printf("Joystick nr %d, name %s", i, joy.GetName())
- snum := joy.GetNumSticks()
- bnum := joy.GetNumButtons()
- monolog.Printf("%d sticks and %d buttons", snum, bnum)
- }
-
- ms.Queue.RegisterEventSource(al.JoystickEventSource())
- }
- func (ms * State) InstallAllegro() bool {
-
- res := ms.LogIfFail(al.InstallSystem(), "Could not install Allegro")
- res = res && ms.LogIfFail(al.InstallKeyboard(), "Could not install Keyboard")
- res = res && ms.LogIfFail(al.InstallMouse(), "Could not install mouse")
- al.InitFontAddon()
- res = res && ms.LogIfFail(al.InitTTFAddon(), "Could not init TTF addon")
- res = res && ms.LogIfFail(al.InitPrimitivesAddon(), "Could not init primitives addon")
- res = res && ms.LogIfFail(al.InitImageAddon(), "Could not init image addon")
- if res {
- ms.HaveTouch = al.InstallTouchInput()
- ms.HaveJoystick = al.InstallJoystick()
- ms.HaveAudio = al.InstallAudio()
- ms.HaveAudio = ms.HaveAudio && al.InitAcodecAddon()
- }
- ms.Queue = al.CreateEventQueue()
-
- ms.SetupJoysticks()
-
- return res
- }
- func (ms * State) OpenDisplay(w, h int, title string, fullscreen bool) * al.Display {
- ms.Fullscreen = fullscreen
- ms.W = w
- ms.H = h
- flags := 0
- // Use full screen mode if needed.
- if fullscreen {
- flags = al.FULLSCREEN // | GENERATE_EXPOSE_EVENTS
- } else {
- al.SetNewDisplayFlags(flags)
- }
- // Create a window to display things on: 640x480 pixels.
- display := al.CreateDisplay(w, h)
- display.Resize(w, h)
- if !(fullscreen) {
- display.SetWindowTitle(title)
- }
- ms.Display = display
-
- ms.Queue.RegisterEventSource(al.GetKeyboardEventSource())
- ms.Queue.RegisterEventSource(al.GetMouseEventSource())
- ms.DefaultFont = al.CreateBuiltinFont()
-
- ms.FPS.Time = al.Time()
-
- ms.Camera.W = ms.Display.Widthf()
- ms.Camera.H = ms.Display.Heightf()
-
- return display
- }
- func (ms * State) ScaleDisplay() {
- real_w := ms.Display.Width()
- real_h := ms.Display.Height()
- scale_x := real_w / ms.W
- scale_y := real_h / ms.H
- scale := scale_y
-
- if scale_x < scale_y {
- scale = scale_x
- }
- offset_x := (real_w - (ms.W * scale)) / 2
- offset_y := (real_h - (ms.H * scale)) / 2
-
- trans := al.CreateIdentityTransform()
- /* Draw black bars to cover the usused areas. */
- black := al.MapRGB(0,0,0)
-
- if (offset_y > 0) {
- al.DrawFilledRectangleInt(-offset_x , -offset_y, real_w, 0, black)
- al.DrawFilledRectangleInt(-offset_x , ms.H, real_w, ms.H +offset_y, black)
- }
- if (offset_x > 0) {
- al.DrawFilledRectangleInt(-offset_x , -offset_y, 0, real_h, black)
- al.DrawFilledRectangleInt(ms.W , -offset_y, ms.W + offset_x, real_h, black)
- }
-
- trans.ScaleInt(scale, scale).TranslateInt(offset_x, offset_y).Use()
- /* al.SetClippingRectangle(offset_x, offset_y, ms.W, ms.H); */
- }
- func (ms * State) DrawFPS() {
- white := al.MapRGB(255,255,255)
- black := al.MapRGB(0,0,255)
- al.DrawFilledRectangleInt(10, 10, 100, 10 + ms.DefaultFont.LineHeight(),black)
- ms.DefaultFont.DrawTextf(white, 10.0, 10.0, al.ALIGN_LEFT, "FPS: %d", int(ms.FPS.FPS))
- }
- func (ms * State) Update() {
- ms.Frames++
- now := al.Time()
- delta := now - ms.LastUpdate
- ms.LastUpdate = now
- if ms.Map != nil {
- ms.Map.Update(delta)
- }
-
- if (now - ms.FPS.Time) >= 1.0 {
- realfps := float64(ms.Frames) / (now - ms.FPS.Time)
- /* Display and use a rounded value for FPS, the number after the comma is normally due to jitter anyway. */
- ms.FPS.FPS = math.Floor(realfps + 0.5)
- /* A little trick, to prevent jerkiness, keep half the frames; and half the time */
- ms.Frames = ms.Frames / 2
- ms.FPS.Time = now - 0.5
- }
- }
- func (ms * State) Draw() {
- if ms.Map != nil {
- ms.Map.Draw(&ms.Camera)
- }
- yellow := al.MapRGB(255, 255, 0)
- al.DrawFilledCircle(30.0, 40.0, 15.0, yellow)
- ms.DrawFPS()
- al.FlipDisplay()
- }
- func (ms * State) Load() {
- ms.LoadMap("map/map_0001_tiled11.tmx")
- }
- func (ms * State) Run() {
- ms.Load()
-
- for !ms.Done {
- ms.Draw()
- ms.HandleEvents()
- ms.Update()
- }
- }
- func (ms * State) HandleEvents() {
- for event, ok := ms.Queue.GetNextEvent() ; ok ; event, ok = ms.Queue.GetNextEvent() {
- ms.HandleEvent(event.Event())
- }
- }
- func (ms * State) HandleEvent(event al.Event) {
- switch uevent := event.(type) {
- case *al.KeyboardEvent: ms.HandleKeyboardEvent(uevent)
- default: break
- }
- }
- func (ms * State) HandleKeyboardEvent(event * al.KeyboardEvent ) {
- switch (event.Keycode()) {
- case al.KEY_ESCAPE: ms.Done = true
- case al.KEY_UP: ms.Camera.Y-= 10
- case al.KEY_DOWN: ms.Camera.Y+= 10
- case al.KEY_LEFT: ms.Camera.X-= 10
- case al.KEY_RIGHT: ms.Camera.X+= 10
- }
- }
|