func fetchAssets(gameEngine engine.Engine, complete func()) { os.Mkdir("TestAssets", 0777) patcher := client.NewClient("TestAssets", "http://walesey.net") done := make(chan bool) go func() { patcher.SyncFiles("TestFiles") done <- true }() progressBar := ui.NewProgressBar("Downloading assets...") ui.SetProgressBar(progressBar, 0) gameEngine.AddOrtho(progressBar) progress := 0 var loader engine.Updatable loader = engine.UpdatableFunc(func(dt float64) { select { case <-patcher.Complete: progress++ ui.SetProgressBar(progressBar, 1+int((progress*20)/patcher.TotalFiles)) case <-done: gameEngine.RemoveSpatial(progressBar, true) gameEngine.RemoveUpdatable(loader) gameEngine.RequestAnimationFrame(complete) default: } }) gameEngine.AddUpdatable(loader) }
func main() { server := len(os.Args) > 1 && os.Args[1] == "server" var gameEngine engine.Engine var glRenderer *opengl.OpenglRenderer network := networking.NewNetwork() // Start server or connect to server if server { gameEngine = engine.NewHeadlessEngine() network.StartServer(serverPort) } else { glRenderer = opengl.NewOpenglRenderer("Networking example", 800, 800, false) gameEngine = engine.NewEngine(glRenderer) network.ConnectClient(fmt.Sprintf("%v:%v", serverAddr, serverPort)) } gameEngine.AddUpdatable(network) // map containing each player's entity players := make(map[string]*Player) //Networked Game events network.ClientJoinedEvent(func(clientId string) { fmt.Println("client joined, clientId: ", clientId) network.TriggerOnServerAndClients("spawn", util.SerializeArgs(clientId, startingPosition)) for _, player := range players { network.TriggerEvent("spawn", clientId, util.SerializeArgs(player.clientId, player.position)) } }) network.RegisterEvent("spawn", func(clientId string, data []byte) { buf := bytes.NewBuffer(data) playerID := util.Stringfrombytes(buf) position := util.Vector2frombytes(buf) if _, ok := players[playerID]; !ok { player := &Player{clientId: playerID} players[player.clientId] = player player.node = renderer.NewNode() player.position = position gameEngine.AddUpdatable(player) if network.IsClient() { boxGeometry := renderer.CreateBox(30, 30) boxGeometry.SetColor(color.NRGBA{254, 0, 0, 254}) player.node.Add(boxGeometry) gameEngine.AddOrtho(player.node) } } }) network.RegisterEvent("move", func(clientId string, data []byte) { buf := bytes.NewBuffer(data) playerID := util.Stringfrombytes(buf) velocity := util.Vector2frombytes(buf) if network.IsServer() && clientId != playerID { return // client is only allowed to control the player assigned to them. } if player, ok := players[playerID]; ok { player.velocity = velocity if network.IsServer() { network.BroadcastEvent("updatePlayer", util.SerializeArgs(playerID, player.position, player.velocity)) network.FlushAllWriteBuffers() } } }) network.RegisterEvent("updatePlayer", func(clientId string, data []byte) { if network.IsClient() { // This is a server to client update only buf := bytes.NewBuffer(data) playerID := util.Stringfrombytes(buf) position := util.Vector2frombytes(buf) velocity := util.Vector2frombytes(buf) if player, ok := players[playerID]; ok { player.position = position player.velocity = velocity } } }) // client setup gameEngine.Start(func() { if network.IsClient() { gameEngine.InitFpsDial() if shader, err := assets.ImportShader("shaders/build/basic.vert", "shaders/build/basic.frag"); err == nil { gameEngine.DefaultShader(shader) } glRenderer.BackGroundColor(0, 0.4, 0, 0) // input/controller manager controllerManager := glfwController.NewControllerManager(glRenderer.Window) // networked movement controls move := func(velocity mgl32.Vec2) { network.TriggerOnServerAndClients("move", util.SerializeArgs(network.ClientToken(), velocity)) } customController := controller.CreateController() controllerManager.AddController(customController.(glfwController.Controller)) customController.BindKeyAction(func() { move(mgl32.Vec2{0, -100}) }, controller.KeyW, controller.Press) customController.BindKeyAction(func() { move(mgl32.Vec2{-100, 0}) }, controller.KeyA, controller.Press) customController.BindKeyAction(func() { move(mgl32.Vec2{0, 100}) }, controller.KeyS, controller.Press) customController.BindKeyAction(func() { move(mgl32.Vec2{100, 0}) }, controller.KeyD, controller.Press) customController.BindKeyAction(func() { move(mgl32.Vec2{}) }, controller.KeyW, controller.Release) customController.BindKeyAction(func() { move(mgl32.Vec2{}) }, controller.KeyA, controller.Release) customController.BindKeyAction(func() { move(mgl32.Vec2{}) }, controller.KeyS, controller.Release) customController.BindKeyAction(func() { move(mgl32.Vec2{}) }, controller.KeyD, controller.Release) } }) }
func setupScene(gameEngine engine.Engine, shader *renderer.Shader) { camera := gameEngine.Camera() transparentNode := renderer.NewNode() gameEngine.AddSpatialTransparent(transparentNode) transparentNode.RendererParams = &renderer.RendererParams{ DepthTest: true, Unlit: true, Transparency: renderer.EMISSIVE, } // Sky cubemap skyImg, err := assets.ImportImage("TestAssets/cloudSky.jpg") if err == nil { skyImg = imaging.AdjustBrightness(skyImg, -30) skyImg = imaging.AdjustContrast(skyImg, 30) geom := renderer.CreateSkyBox() geom.Transform(mgl32.Scale3D(10000, 10000, 10000)) skyNode := renderer.NewNode() skyNode.SetOrientation(mgl32.QuatRotate(1.57, mgl32.Vec3{0, 1, 0})) skyNode.Material = renderer.NewMaterial(renderer.NewTexture("diffuseMap", skyImg, false)) skyNode.RendererParams = renderer.NewRendererParams() skyNode.RendererParams.CullBackface = false skyNode.RendererParams.Unlit = true skyNode.Add(geom) gameEngine.AddSpatial(skyNode) // create an environmentMap using the skybox texture envCubeMap := renderer.NewCubemap("environmentMap", skyImg, true) gameEngine.DefaultCubeMap(envCubeMap) } // load scene objs objs := []string{ "TestAssets/wellScene/floor.obj", "TestAssets/wellScene/frame1.obj", "TestAssets/wellScene/frame2.obj", "TestAssets/wellScene/well.obj", "TestAssets/wellScene/torches.obj", } for _, objFile := range objs { if geom, mat, err := assets.ImportObjCached(objFile); err == nil { sceneNode := renderer.NewNode() sceneNode.Add(geom) sceneNode.Material = mat sceneNode.RendererParams = renderer.NewRendererParams() sceneNode.RendererParams.CullBackface = false gameEngine.AddSpatial(sceneNode) } } for i := 0; i < 2; i++ { torchLocation := mgl32.Vec3{0.86, 1.76, 1.05} if i == 1 { torchLocation = mgl32.Vec3{0.86, 1.76, -1.05} } fire := fireParticles() spark := sparkParticles() torchParticles := effects.NewParticleGroup(camera, fire, spark) torchParticles.SetTranslation(torchLocation) transparentNode.Add(torchParticles) gameEngine.AddUpdatable(torchParticles) light := renderer.NewLight(renderer.POINT) light.SetTranslation(torchLocation.Add(mgl32.Vec3{0, 0.05, 0})) gameEngine.AddLight(light) var x float64 gameEngine.AddUpdatable(engine.UpdatableFunc(func(dt float64) { x += dt mag := float32(math.Abs(0.6*math.Sin(3*x)+0.3*math.Sin(4*x)+0.15*math.Sin(7*x)+0.1*math.Sin(15*x))) + 0.5 mag *= 0.05 light.Color = [3]float32{1 * mag, 0.6 * mag, 0.4 * mag} })) } }