From 05013370fddf6d4aeedf840de5a462ffa19f0772 Mon Sep 17 00:00:00 2001 From: Marvin Blum Date: Tue, 3 May 2016 21:03:00 +0200 Subject: [PATCH] Basic system and window creation. --- README.md | 11 ++++++- actor.go | 28 +++++++++++++++++ game.go | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ system.go | 68 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 actor.go create mode 100644 game.go create mode 100644 system.go diff --git a/README.md b/README.md index 4f6c351..82af253 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,11 @@ -# go-game +# go-game (package "goga") + Game engine written in Go using OpenGL and GLFW. +**Under heavy development, do not use yet!** + +## Dependencies + +* https://github.com/go-gl/gl + - 4.5-core +* https://github.com/go-gl/glfw + - 3.1 diff --git a/actor.go b/actor.go new file mode 100644 index 0000000..fd73d14 --- /dev/null +++ b/actor.go @@ -0,0 +1,28 @@ +package goga + +import () + +// An actor ID is a unique integer, +// which can be used to reference an actor. +type ActorId uint64 + +// A basic actor, having a unique ID. +// Use NewActor() to create new actors. +type Actor struct { + id ActorId +} + +var ( + actorIdGen = ActorId(0) +) + +// Creates a new basic actor with unique ID. +func NewActor() *Actor { + actorIdGen++ + return &Actor{actorIdGen} +} + +// Returns the ID of actor. +func (a *Actor) GetId() ActorId { + return a.id +} diff --git a/game.go b/game.go new file mode 100644 index 0000000..ff87417 --- /dev/null +++ b/game.go @@ -0,0 +1,89 @@ +package goga + +import ( + "github.com/go-gl/glfw/v3.1/glfw" + "math" + "time" +) + +const ( + default_width = uint32(600) + default_height = uint32(400) + default_title = "Game" + default_exit_on_close = true +) + +// Run options allow to set some parameters on startup. +type RunOptions struct { + Title string + Width uint32 + Height uint32 + ExitOnClose bool +} + +// Main game object. +type Game interface { +} + +var ( + running = true +) + +// Creates a new window with given options and starts the game. +// The game struct must implement the Game interface. +// If options is nil, the default options will be used. +// This function will panic on error. +func Run(game Game, options *RunOptions) { + // init glfw + if err := glfw.Init(); err != nil { + panic("Error initializing GLFW: " + err.Error()) + } + + defer glfw.Terminate() + + // create window + width := default_width + height := default_height + title := default_title + exitOnClose := default_exit_on_close + + if options != nil { + width = options.Width + height = options.Height + title = options.Title + exitOnClose = options.ExitOnClose + } + + wnd, err := glfw.CreateWindow(int(width), int(height), title, nil, nil) + + if err != nil { + panic("Error creating GLFW window: " + err.Error()) + } + + // start and loop + wnd.MakeContextCurrent() + delta := time.Duration(0) + var deltaSec float64 + + for running { + if exitOnClose && wnd.ShouldClose() { + return + } + + start := time.Now() + + if !math.IsInf(deltaSec, 0) && !math.IsInf(deltaSec, -1) { + updateSystems(deltaSec) + } + + delta = time.Since(start) + deltaSec = delta.Seconds() + wnd.SwapBuffers() + glfw.PollEvents() + } +} + +// Stops the game and closes the window. +func Stop() { + running = false +} diff --git a/system.go b/system.go new file mode 100644 index 0000000..6bb8728 --- /dev/null +++ b/system.go @@ -0,0 +1,68 @@ +package goga + +import () + +// A system provides logic for actors satisfying required components. +// They are automatically updated on each frame. +type System interface { + Update(float64) + Add(actor *Actor) bool + Remove(actor *Actor) bool + RemoveById(id ActorId) bool + RemoveAll() + Len() int + GetName() string +} + +var ( + systems []System +) + +// Adds a system to the game. +// Returns false if the system exists already. +func AddSystem(system System) bool { + for _, sys := range systems { + if sys == system { + return false + } + } + + systems = append(systems, system) + + return true +} + +// Removes the given system. +// Returns false if it could not be found. +func RemoveSystem(system System) bool { + for i, sys := range systems { + if sys == system { + systems = append(systems[:i], systems[i+1:]...) + return true + } + } + + return false +} + +// Removes all systems. +func RemoveAllSystems() { + systems = make([]System, 0) +} + +// Finds and returns a system by name, or nil if not found. +func GetSystemByName(name string) System { + for _, system := range systems { + if system.GetName() == name { + return system + } + } + + return nil +} + +func updateSystems(delta float64) { + for _, system := range systems { + system.Update(delta) + } +}