2017-10-07 113 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,並且有很少類似的服務。