2012-12-08 46 views
1

我现在只开始修改Go了大约一个星期了,我对它印象颇深。但是,我仍然遇到一些问题,但仍然无法解决问题。golang - 网络游戏的主循环

现在的主要问题是,虽然我有连接处理代码工作,但我想添加一个独立于连接循环的主游戏循环。如何做到这一点?

package main 

import (
    "fmt" 
    "net" 
    "strconv" 
    "time" 
    "galaxy" 
) 

const PORT = 5555 

func main() { 
    playerFactory := galaxy.NewPlayerFactory() 

    server, err := net.Listen("tcp", ":" + strconv.Itoa(PORT)) 
    if server == nil { 
    panic("listen failed: " + err.Error() + "\n") 
    } else { 
    defer server.Close() 
    } 

    // main loop 
    go func() { 
    for { 
     // entity updates 
     playerFactory.Update() 
    } 
    }() // adding this just blocks everything after the goroutine 

    // connection handling 
    for { 
    conn, err := server.Accept() 
    if err != nil { 
     fmt.Printf("client error: %s\n", err.Error()) 
    } else { 
     playerFactory.CreatePlayer(conn) 
    } 
    } 

} 

有了它目前正在写的主循环运行(这是我想补充的部分)的方式,但处理代码的连接被忽略。这是在哪里使用渠道来传递控制权?我相信这个解决方案对于一个更加老练的Go程序员来说是显而易见的,我期待着您的回答。

回答

4

如果playerFactory.Update()从来没有(通过阻断对资源为例)释放CPU,也不能保证其他够程运行

你可以试着改变GOMAXPROCS,但是这将取决于你的CPU的数量和问题会在其他非阻塞的例程后重新出现。

而我看不到任何游戏循环没有中断运行的原因。最常见的情况是,你必须定期做一些事情。

在这种情况下,你的代码将

// main loop 
    go func() { 
    timer := time.Tick(100 * time.Millisecond) 
    for now := range timer { 
     // entity updates (you could use now for physic engine calculs) 
     // this is called every 100 millisecondes 
     playerFactory.Update() 
    } 
    }() 
+0

我去掉了时间计算,以保持示例简单。现在,playerFactory.Update()只会打印一条消息(假设客户端已连接)。 再次,此循环运行,但代码似乎永远不会到达连接处理循环,这是令我困惑的部分。 – bojo

+0

我刚刚测试了我给你的代码:它后面的行被执行。你确定你连接正确吗?你确定你正确地使用了计时器吗?(例如,我曾经这样做过)?这不是关于时间计算,而是关于阻塞直到发生滴答(每100毫秒)。 –

+0

我不完全确定自己做错了什么,但是我将计时器代码更改为您的计时器代码,现在一切正常,正如我期待的那样。谢谢您的帮助! (好吧,你编辑的评论解释它,现在得到它)。 – bojo