136 lines
3.1 KiB
Go
136 lines
3.1 KiB
Go
package internal
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"math/rand"
|
|
|
|
"git.wisellama.rocks/Project-Ely/project-ely/internal/animation"
|
|
"git.wisellama.rocks/Project-Ely/project-ely/internal/channels"
|
|
"git.wisellama.rocks/Project-Ely/project-ely/internal/entity"
|
|
"git.wisellama.rocks/Project-Ely/project-ely/internal/player"
|
|
"git.wisellama.rocks/Project-Ely/project-ely/internal/sprite"
|
|
"git.wisellama.rocks/Wisellama/gosimpleconf"
|
|
rl "github.com/gen2brain/raylib-go/raylib"
|
|
)
|
|
|
|
// Drawables can be rendered with OpenGL. See the 'entity' and 'animation' packages.
|
|
type Drawable interface {
|
|
Draw() error
|
|
}
|
|
|
|
// Objects can have physical interactions. See the 'entity' and 'physics' packages.
|
|
type Object interface {
|
|
Update() error
|
|
}
|
|
|
|
// Run is the main function to start the game.
|
|
func Run(ctx context.Context, configMap gosimpleconf.ConfigMap) error {
|
|
var err error
|
|
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
defer cancel()
|
|
|
|
framerate64 := gosimpleconf.Int64(configMap["game.framerate"])
|
|
framerate := int32(framerate64)
|
|
|
|
// Initialize the RayLib window
|
|
channels.RL.Do(func() {
|
|
rl.InitWindow(800, 600, configMap["game.title"])
|
|
rl.SetTargetFPS(framerate)
|
|
})
|
|
defer func() {
|
|
channels.RL.Do(func() {
|
|
rl.CloseWindow()
|
|
})
|
|
}()
|
|
|
|
// Initialize our sprites and animations
|
|
sprite.InitSpriteCache()
|
|
animation.DefineAnimations()
|
|
|
|
drawables := make([]Drawable, 0)
|
|
objects := make([]Object, 0)
|
|
|
|
center := rl.Vector2{X: float32(rl.GetScreenWidth()) / 2, Y: float32(rl.GetScreenHeight()) / 2 * -1}
|
|
player1 := player.NewPlayer(ctx)
|
|
player1Penguin := entity.NewPenguin()
|
|
player1Penguin.SetColor(rl.Gold)
|
|
player1Penguin.GetObject().SetPosition(center)
|
|
player1.SetControlledObject(player1Penguin.GetObject())
|
|
drawables = append(drawables, player1Penguin)
|
|
objects = append(objects, player1Penguin)
|
|
|
|
for i := 0; i < 10; i++ {
|
|
p := entity.NewPenguin()
|
|
p.GetObject().SetPosition(rl.Vector2{
|
|
X: rand.Float32() * float32(rl.GetScreenWidth()),
|
|
Y: rand.Float32() * float32(rl.GetScreenHeight()*-1),
|
|
})
|
|
p.GetAnimationTracker().SetAnimation(animation.RandomPenguinAnimation())
|
|
p.ToggleStaticAnimation()
|
|
|
|
drawables = append(drawables, p)
|
|
objects = append(objects, p)
|
|
}
|
|
|
|
// And now starting the main loop
|
|
running := true
|
|
for running {
|
|
channels.RL.Do(func() {
|
|
if rl.WindowShouldClose() {
|
|
cancel()
|
|
}
|
|
})
|
|
|
|
// Allow us to exit early if the context is done
|
|
select {
|
|
case <-ctx.Done():
|
|
running = false
|
|
default:
|
|
// Keep running
|
|
}
|
|
if !running {
|
|
break
|
|
}
|
|
|
|
player1.Update()
|
|
|
|
// Update physics
|
|
// TODO probably move out to something else to handle collisions.
|
|
for _, o := range objects {
|
|
err = o.Update()
|
|
if err != nil {
|
|
log.Printf("error updating physics: %v", err)
|
|
}
|
|
}
|
|
|
|
channels.RL.Do(func() {
|
|
rl.BeginDrawing()
|
|
})
|
|
|
|
// Draw stuff
|
|
for _, d := range drawables {
|
|
err = d.Draw()
|
|
if err != nil {
|
|
log.Printf("error drawing: %v", err)
|
|
}
|
|
}
|
|
|
|
channels.RL.Do(func() {
|
|
rl.ClearBackground(rl.Black)
|
|
rl.DrawText("Some Text!", 190, 200, 20, rl.Blue)
|
|
rl.DrawText(fmt.Sprintf("%v FPS", rl.GetFPS()), 190, 250, 20, rl.Blue)
|
|
})
|
|
|
|
channels.RL.Do(func() {
|
|
rl.EndDrawing()
|
|
})
|
|
}
|
|
|
|
sprite.CleanupSpriteCache()
|
|
|
|
return nil
|
|
}
|