2017-10-07 109 views
1

我的2人游戏,纯文本,基于浏览器的游戏工作正常,但是没有办法让一个玩家知道对方玩家的回合是否完成,除非尝试回合他/她自。在标准的低成本GAE应用程序中可以实现传达(推送)该信息所需的结果?无插槽N玩家游戏

我已经在纯Python中消化了Joran Beasley's fine answer example,但假设套接字将增加GAE应用程序的成本。如果我关于成本的前提不正确,请纠正我,然后你能告诉我如何在GAE中添加套接字吗?但我希望有一个经济的方式来提升我的应用程序的价格低于而不需要插槽。

的Python:

class BaseHandler(webapp2.RequestHandler): 

    @webapp2.cached_property 
    def jinja2(self): 
     return jinja2.get_jinja2(app=self.app) 

    def render_template(
     self, 
     filename, 
     template_values, 
     **template_args 
     ): 
    template = JINJA_ENVIRONMENT.get_template(filename) 
     self.response.out.write(template.render(template_values)) 

class MainPage(BaseHandler): 

    def get(self): 

     global player 
     global players 
     global scores 
     global target 
     global guesses 

     player = 0 
     players = ['me','you'] 
     scores = [False , False] 
     target = random.randrange(10) 
     initguesses = ['',''] 
     guesses = initguesses 

    template_values = {'scores':scores} 
    return webapp2.redirect("/game/%s" % players[0]) 

class Game(BaseHandler): 

    def get(self,who_id): 
    who = players.index(who_id) 
    template_values = {'scores':scores,'guesses':guesses[who],'players':players,'who_id':who_id} 
     template = JINJA_ENVIRONMENT.get_template('game.html') 
     self.response.out.write(template.render(template_values)) 

    def post(self,who_id): 

    global player 
    who = players.index(who_id) 
    if who == player: 
     guess = self.request.get('guess', None) 
     guesses[player]=guess+guesses[player] 
     scores[player]=int(guess)==target 
     logging.info("target: %s" % target) 
     next_player = player 
     player = (1+player)%2 
     template_values = {'scores':scores} 
    return webapp2.redirect("/game/%s" % who_id) 

game.html

{% extends "base.html" %} 
{% block content %} 
<h1>{{who_id}}</h1> 
<br/> 
<form action="" method="post"> 
Guess an integer here <br /> 
0 ... 9: <input type="textbox" name="guess" value=></input> 
    <input type="submit" value="submit" /> 

</form> 
<p> Your previous guess(es): {{ guesses }}</p> 
<p> Got target right (yet)?: 
{% for score in scores %} 
<br /> 
{% if score %} 
<h2> 
    {% endif %} 
{{players[loop.index0] }} {{ score }} 
{% if score %} 
</h2> 
    {% endif %} 
{% endfor %} 
</p> 

{% if who_id == players[0] %} 
<p> You can start over at the beginning (<a href="/"> here.</a>) but everyone restarts. </p> 
{% endif %} 
<p>If you see no change above, it's not your turn.</p> 

{% endblock content %} 
+1

游戏预计通常需要多长时间?我想知道是否将该游戏基于Firebase的实时数据库将给您带来更好的体验?尽管你可能会遇到标准环境的挑战。 Firebase具有慷慨的免费套餐。也许是一个选择? – BrettJ

+0

用户是否可以在应用中注册启用Firebase的功能,然后他们选择支付所涉及的任何费用,但其他不想要该功能的用户不需要付费? – zerowords

+0

这听起来像是你身边的设计选择。我不认为你可以让他们直接支付你的费用。您必须为高级功能设置自己的付款。 – BrettJ

回答

1

要么你加插槽,允许用户知情权时,其对手打(压),或者你问的服务器每隔几秒(轮询)。

每个websocket,和每个服务器的投票都花钱。您投票越频繁,用户体验就越好,因为对手完成移动和用户发现之间的延迟较低。当然,更频繁的民意测验也会花费更多的钱,因为您提出的要求更多。

GAE上的Websockets并不便宜,但它可能是你想要的。

+0

你的答案可能是唯一的答案,但我想我会稍等一会,以获得更快乐的答案。我真正考虑的应用程序与失踪的第4名有关,他们可以与3位面对面的远程玩家进行比赛。也许他们可以忍受使用聊天线路或电话的无插座不便,因为时间不是这个社交游戏的关键所在。 – zerowords

+0

如果时间不重要,请使用轮询。轮询的平均额外等待时间是轮询时间的一半,所以每10秒轮询一次轮询就会增加5秒的每次轮换不必要的等待时间,这对于象棋这样的游戏来说听起来是合理的,假设没有定时器。每个轮询用户每分钟有6个请求。我不能给你一个更快乐的答案,直到gae改变定价或光速变得无限。 –

+0

伟大的答案,还有一个替代使用推送通知服务 - 请参阅我的答案。 –

2

菲利普给出了一个很好的答案。

作为替代方案,您可以考虑使用推送通知服务,例如OneSignal

当玩家进行移动时,您向OneSingla发出一个http请求,他们会处理websockets(或任何可用于客户端)发送通知。

while game.is_active: 
    client1 => AppEngine => OneSignal => client2 
    client2 => AppEngine => OneSignal => client1 

它可以免费使用OneSignal,并且有很少类似的服务。