【发布时间】:2012-10-28 18:14:52
【问题描述】:
我正在尝试用 Python 创建一个回合制策略游戏(想想 Dominion)。核心游戏对象和方法是其中包含方法的 Python 类(只是典型的 OO 东西)。 UI 是一个使用 Bottle 的 HTML 客户端。我的目标是完全异步的方法。因此,唯一页面的内容是从 Python 对象生成的,我希望从页面提交以更新这些对象,而无需通过瓶子网络服务器返回页面(为此使用 jQuery AJAX)。
目前我正在开发一个基本的聊天系统,该系统检索玩家编写的消息并将它们存储为聊天对象(包含玩家和文本数据,仅此而已)。然后这些对象使用 AJAX 写入聊天窗口,每秒更新一次窗口。聊天行的 HTML 格式是 <div class="chatLine"><p>Player > </p><p>Text</p></div> 非常标准的东西。
这个基本图可能会让它更清晰一些,即使它不是真正的技术性,更概念性:
我的 BottleUI.py(这是我运行以启动服务器):
from Populate import * # Everything in Populate can now be directly called.
# NOTE: Populate allows access to "bottle" and "Main"
# This ensures the css file is available
@route('/theCSS')
def static():
return static_file('main.css', root='static')
@route('/citadel/:game/:player')
def gamePage(game, player):
if not (game.isdigit()) or not (player.isdigit()):
return "Invalid page."
game = int(game)
player = int(player)
if ((game >= 0) and (game < listOfGames.__len__())) and ((player >= 0) and (player < listOfGames[game].listOfPlayers.__len__())):
return '''
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/theCSS">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<!-- Sample AJAX script below, change as needed -->
<script type="text/javascript">
$(document).ready(function() {
$('#chatForm').submit(function(e) {
$.ajax({
type: 'POST',
url: "/AddToChat/''' + str(game) + '''/''' + str(player) + '''",
success: function() {
$('#chatInput').val("");
}
});
e.preventDefault();
});
});
setInterval("updateChat();", 1000);
$(function() {
updateChat = function() {
$('#chatText').load('/GenerateChat/''' + str(game) + '''');
};
});
</script>
<!-- Script to scroll to bottom of divs - needs to be changed into called function -->
<script type="text/javascript">
window.onload = function () {
var objDiv = document.getElementById("gameFlow");
objDiv.scrollTop = objDiv.scrollHeight;
objDiv = document.getElementById("chatText");
objDiv.scrollTop = objDiv.scrollHeight;
};
</script>
</head>
<body>
<div id="container">
<!-- Make this have background-image with the game number displaying programmatically -->
<div id="banner">
<h1>Citadel - Game ''' + str(game) + ''', Player ''' + str(player) + '''</h1>
</div>
<div id="main">
<div id="leftPanel">
<div id="playerTotals">
<h4>Player Totals:</h4>
<div id="totalsText">
<p>Money:</p>
<p>Population:</p>
<p>Troops:</p>
<p>Friend:</p>
<p>Enemy:</p>
</div>
<!-- Player totals go here (money, population/limit, troops, friend, enemy) -->
<div id="totalsNums">
</div>
<div class="clear"></div>
</div>
<div class="leftSegment">
<h4>Troop Cards:</h4>
<!-- Player's troopCards here -->
<select size=2>
</select>
</div>
<div class="leftSegment">
<h4>Territory Cards:</h4>
<!-- Player's territoryCards here -->
<select size=2>
</select>
</div>
<div class="leftSegment">
<h4>Region Cards:</h4>
<!-- Player's regionCards here -->
<select size=2>
</select>
</div>
<div class="leftSegment">
<h4>Resource Cards:</h4>
<!-- Player's resourceCards here -->
<select size=2>
</select>
</div>
<div class="leftSegment">
<h4>Diplomacy Cards:</h4>
<!-- Player's diplomacyCards here -->
<select size=2>
</select>
</div>
<div id="chatPane">
<form id="chatForm" method="POST" action="/AddToChat/''' + str(game) + '''/''' + str(player) + '''">
<textarea name="theChatText" id="chatInput"></textarea>
<input id="chatSubmit" class="button" type="submit" value="Send" />
</form>
</div>
<div class="clear"></div>
</div>
<div id="rightPanel">
<!-- Game flow goes here (shows current player/phase, attacks with results, etc) -->
<div id="gameFlow">
</div>
<!-- Player turn stuff goes here (changes depending on which phase, etc) -->
<div id="playerActions">
</div>
<!-- Chat goes here (implement last) -->
<div id="chatText">
</div>
<div class="clear"></div>
</div>
</div>
</div>
</body>
</html>
'''
else:
return "Invalid page."
run(host='localhost', port=8080)
这是我的 Populate.py(这是我的 AJAX @route 方法存储的地方):
"""
This module contains the bottle routs for AJAX population of the various parts
of the game page.
"""
from bottle import route, run, template, static_file, request
from Main import * # Everything in Main can now be directly called.
globalBegin()
@route('/AddToChat/:game/:player', method='POST')
def AddToChat(game, player):
theText = request.POST.get('theChatText', '').strip()
game = int(game)
player = int(player)
listOfGames[game].listOfPlayers[player].addChat(theText)
@route('/GenerateChat/:game')
def GenerateChat(game):
chatText = ""
game = int(game)
for line in listOfGames[game].chatList:
chatText += '<div class="chatLine"><p>'
chatText += line.player.name
chatText += ' > </p><p>'
chatText += line.text
chatText += '</p></div>'
return chatText
问题是,“chatForm”表单没有按预期工作。当我尝试提交文本时,AddToChat() 似乎认为request.POST.get('theChatText', '') 是NoneType。
所以是的,我很难理解它为什么要这样做。据我所知,'theChatText' 应该是 POST 字典中的有效键。
我还要声明我所有的核心游戏逻辑都有效(尽管很明显这不是问题所在)。
感谢任何帮助。
【问题讨论】:
-
请不要在问题标题中添加“已解决”;相反,将帮助您的答案标记为已接受;这也适用于自我回答。
-
使用string formatting 代替
'''long string ''' + str(something) + ''' more string'''将信息插入到您的输出中:'''long string {something} more string'''.format(something=something)。 -
以后会做的,谢谢你的提示:)
标签: python ajax post asynchronous bottle