1

GoogleAppEngineを使用してフラッシュゲームのウェブサイトを構築しています。私はそれに成果を載せるつもりであり、このデータをどのように正確に保存するかについて頭を悩ませています。私は(グーグル以外の)ユーザーモデルを持っています。それぞれの成果(名前、説明、写真)を保存する方法と、それらを獲得したユーザーとリンクする方法を知る必要があります。また、彼らがいつそれを獲得したか、そしてまだそれを持っていない人々のために彼らの現在の進歩を追跡する必要があります。

誰かが検出または他の達成関連のタスクについて提案をしたい場合は、遠慮なく。

編集:

Google以外のユーザーモデル:

class BeardUser(db.Model):
    email = db.StringProperty()
    username = db.StringProperty()
    password = db.StringProperty()
    settings = db.ReferenceProperty(UserSettings)
    is_admin = db.BooleanProperty()
    user_role = db.StringProperty(default="user")
    datetime = db.DateTimeProperty(auto_now_add=True)
4

2 に答える 2

3

ここでブランドンの答えに基づいて構築します。

可能であれば、Pythonファイルですべてのアチーブメントを定義する方がはるかに高速であるため、アチーブメントはメモリ内にあり、データベースをフェッチする必要はありません。これも実装が簡単です。

class StaticAchievement(object):
    """
    An achievement defined in a Python file.
    """
    by_name = {}
    by_index = []
    def __init__(self, name, description="", picture=None):        
        if picture is None: picture = "static/default_achievement.png"
        StaticAchievement.by_name[name] = self
        StaticAchievement.by_index.append(self)
        self.index = len(StaticAchievement.by_index)

# This automatically adds an entry to the StaticAchievement.by_name dict.
# It also adds an entry to to the StaticAchievement.by_index list.
StaticAchievement(
  name="tied your shoe", 
  description="You successfully tied your shoes!", 
  picture="static/shoes.png"
)

次に、各プレーヤーの実績のIDをdb.StringListPropertyに保持するだけです。プレーヤーのオブジェクトをロードした場合、アチーブメントをレンダリングするために追加のデータベースルックアップは必要ありません。すでにIDを持っているので、StaticAchievement.allでそれらをルックアップする必要があります。これは実装が簡単で、どのユーザーが特定の成果を上げているかなどを簡単に照会できます。他に何も必要ありません。

ユーザーがアチーブメントを所有していることに関連する追加データ(たとえば、アチーブメントが取得された日付)が必要な場合は、次のアプローチを選択できます。

1:同じ長さの別のListPropertyに格納します。

これにより、実装の単純さとプロパティのインデックス作成が維持されます。ただし、この種の解決策は、すべての人の好みに合うわけではありません。このデータの使用をより面倒にする必要がある場合は、次のようにプレーヤーオブジェクトにメソッドを記述します。

    def achievement_tuples(self):
        r = []
        for i in range(0, len(self.achievements)):
            r.append( (self.achievements[i], self.achievement_dates[i]) )
        return r

整数の並列ListPropertyを維持し、ユーザーが進行したときにそれらの整数をインクリメントすることで、進行状況を処理できます。

データがどのように表現されるかを理解できる限り、その表現を必要なメソッドの背後に簡単に隠すことができます。これにより、必要なインターフェイスと、必要なパフォーマンスおよびインデックス付けの特性の両方を実現できます。ただし、インデックス作成が本当に必要でなく、リストが気に入らない場合は、オプション#2を参照してください。

2:追加データをBlobPropertyに保存します。

これには、データのシリアル化と逆シリアル化が必要であり、listpropertiesの優れたクエリをあきらめますが、並列リストの概念が嫌いな場合は、おそらくもっと幸せになるでしょう。これは、App Engineの方法とは異なり、Pythonの方法で物事を実行したいときに人々が行う傾向があることです。

3:追加データをデータベースに保存します

(たとえば、Achievement IDのStringProperty、DateProperty、およびUserPropertyの両方を含むPlayersAchievementオブジェクト、およびPlayersAchievementオブジェクトへの参照でいっぱいのachivementsリストプロパティ)

プレイヤーは潜在的に多数のアチーブメントを取得することが予想されるため、このオーバーヘッドは急速に悪化します。memcache、事前にレンダリングされたHTMLのブロブやタプルのシリアル化されたリストなどの中間データの保存、タスクの設定など、それを回避するのは非常に複雑になります。これは、アチーブメントの定義が必要な場合に実行する必要がある種類の作業でもあります。それ自体を変更可能/DBに保存します。

于 2010-07-14T18:41:34.583 に答える
3

ユーザーがアチーブメントを動的に追加しない限り (ユーザーが自分のゲームをアップロードできる Kongregate など)、アチーブメント リストは静的です。つまり、(名前、説明、画像) リストをメインの python ファイルに保存したり、実績モジュールなどとして保存したりできます。このリストで指定されているように、名前または ID で動的データ内の実績を参照できます。

特定のユーザーが実績を取得したかどうかを示す簡単な方法は、プレーヤーが取得した実績を保持する ListProperty をプレーヤー モデルに追加することです。デフォルトでは、これはインデックス化されるため、どのプレイヤーがどのアチーブメントを獲得したかなどを照会できます。

ユーザーがアチーブメントを取得した日付/時刻も保存したい場合は、組み込みのプロパティがあまり理想的ではない領域に入り込んでいます。各アチーブメントに対応する日時プロパティを持つ別の ListProperty を追加することもできますが、それは厄介です: 私たちが本当に必要としているのはタプルまたは dict であり、アチーブメント ID/名前を達成された時間と一緒に保存し、簡単にすることができます。今後、各アチーブメントに関連するプロパティを追加します。

このような場合の私の通常のアプローチは、私の理想的なデータ構造を BlobProperty にダンプすることですが、これにはいくつかの欠点があり、別のアプローチを好むかもしれません。

もう 1 つのアプローチは、ユーザー モデルとは別のアチーブメント モデルと、ユーザーが取得したすべてのアチーブメントへの参照プロパティでいっぱいの ListProperty を用意することです。これには、すべてを非常に適切にインデックス化できるという利点がありますが、特に検索する実績が多数ある場合は、実行時に追加の API CPU コストが発生し、ユーザーの実績をすべて削除するなどの操作は、上記に比べて非常にコストがかかります。

于 2009-10-18T02:58:49.110 に答える