• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

System monet w grze przeglądarkowej dla wielu kont

0 głosów
130 wizyt
pytanie zadane 19 sierpnia 2020 w Python przez Dzango111 Użytkownik (600 p.)

Tworzę grę przeglądarkową, w której, jak można się domyślić, każdy gracz będzie miał monety – z możliwością ich zarabiania, bądź wydawania. Stworzyłem osobną apkę (monety), a w pliku models ("monety/models.py") znajduje się poniższy kod

class Waluta(models.Model):
    def dodaj(x):
        global ilosc
        ilosc += x

    def odejmij(y):
        global ilosc
        ilosc -= y

    nazwa = models.CharField(default="Kaktus Coin", max_length=50)
    ilosc = models.IntegerField(default=5)

    def __str__(self):
        return self.nazwa

Jednakże, po namyśle dochodzę do wniosku, że w praktyce stworzenie jednej Waluty z nazwą "Kaktus Coin" oznaczać będzie, że każde konto będzie miało tyle samo monet co inni gracze: dodanie/odjęcie na jednym koncie, spowoduje zmianę na innych. Nie planuje wdrożyć quasikomunizmu do mojej aplikacji, więc naturalnie jest do zachowanie niepożądane. I tutaj clue pytania: jak to dobrze zrobić, aby każdy gracz miał swoje monety, niezależne od innych? Myślałem nad tym, żeby przy tworzeniu konta, każdy gracz tworzył nową Walutę, aby wszystkie były poindeksowane tzn. gracz nr. 63 miałby walutę nr. 63 i wszelkie działania na jego koncie wpływały by tylko na wartość tejże waluty ponumerowanej. Tylko że to rozwiązanie wydaje mi się mocno zagmatwane w praktyce, wymagałoby dużego zautomatyzowania i mam obawy, że na moim poziomie (ledwo jedną stronę w django wcześniej napisałem) byłoby to zbyt skomplikowane.

Czy da się to zrobić prościej? Z góry dziękuję za odpowiedź i zaangażowanie.

1 odpowiedź

0 głosów
odpowiedź 19 sierpnia 2020 przez Nelson89 Dyskutant (7,500 p.)
wybrane 2 września 2020 przez Dzango111
 
Najlepsza

Cześć,

Tej koncepcji nie rozumiem.

Myślałem nad tym, żeby przy tworzeniu konta, każdy gracz tworzył nową Walutę, aby wszystkie były poindeksowane tzn. gracz nr. 63 miałby walutę nr. 63

Chcesz, żeby każdy gracz miał swoją walutę? Przelicznik walut byłby inny w stosunku do waluty jednego gracza do waluty innego gracza? Czy może masz na myśli to, że każdy gracz będzie tworzyć obiekt klasy Waluta?

Jeżeli ma być jedna obowiązująca waluta dla wszystkich graczy, to rozwiązaniem byłoby dodanie atrybutu przechowującego aktualny stan konta do klasy modelu użytkownika. I wtedy każdy użytkownik będzie mieć niezależne miejsce, gdzie będzie zapisana informacja o stanie jego portfela.

Możesz utworzyć też osobną klasę np. o nazwie Portfel, w której znajdowałby się atrybut z nazwą użytkownika (z wykorzystaniem relacji one to one) i z zawartości portfela.

Pozdrawiam,

Nelson

komentarz 20 sierpnia 2020 przez Dzango111 Użytkownik (600 p.)

Hej,

" Czy może masz na myśli to, że każdy gracz będzie tworzyć obiekt klasy Waluta?" Tak, dokładnie to miałem na myśli, ale jak już zdążyłem powiedzieć, byłoby to zbyt skomplikowane.

"Jeżeli ma być jedna obowiązująca waluta dla wszystkich graczy, to rozwiązaniem byłoby dodanie atrybutu przechowującego aktualny stan konta do klasy modelu użytkownika" Właśnie coś takiego jest mi potrzebne. Poszukam w dokumentacji, ale jakbyś wiedział może, jaki to byłby atrybut, byłbym bardzo wdzięczny.

komentarz 20 sierpnia 2020 przez Nelson89 Dyskutant (7,500 p.)

Cześć,

Tutaj masz dwa przykłady:

1. Masz osobny model na porfel

from django.db import models
from django.contrib.auth.models import User 

class Gracz(models.Model):
    uzytkownik = models.OneToOneField(
        User, 
        on_delete=models.CASCADE
    )


class Portfel(models.Model):
        place = models.OneToOneField(
            Gracz,
            on_delete=models.CASCADE,
            primary_key=True,
        )
        saldo = models.IntegerField(default=100)

 

2. Masz saldo użytkownika zapisane w jego modelu.

from django.db import models
from django.contrib.auth.models import User 

class Gracz(models.Model):
    uzytkownik = models.OneToOneField(
        User, 
        on_delete=models.CASCADE
    )
    saldo = models.IntegerField(default=100)

W obu wariantach używasz klasy django.db.modelsIntegerField (jest także django.db.modelsFloatField)do przechowania zawartości portfela. Wartość default określi początkową zawartość portfela (domyślnie to 0).

Pozdrawiam,

Nelson

komentarz 26 sierpnia 2020 przez Dzango111 Użytkownik (600 p.)

Hej,

Mam problem z tymi rozwiązaniami, ponieważ nie posiadałem nigdzie modelu z użytkownikiem (w tym przypadku Gracz), by go edytować[1]. Gdy w podstronie administratora (home/admin) próbuję dodać Portfel, wtedy 'place' nie pokazuje nic do wyboru (a jest to konieczne, do wyboru jest tylko długa kreska). Do rejestracji wykorzystuję RegisterForm

from django.shortcuts import render, redirect
from .forms import RegisterForm

def rejestracja(response):
    if response.method == "POST":
        form = RegisterForm(response.POST)
        if form.is_valid():
            form.save()
            return redirect('/ogrod')
    else:
        form = RegisterForm()

    return render(response, "rejestracja.html", {"form":form})

Plik forms.py wygląda następująco 

from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth.models import User

class RegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ["username", "email", "password1", "password2"]

[1] A po stworzeniu modelu użytkownika (Gracz) to ewidentnie nie odwołuje się on do istniejących użytkowników (choćby komenda Gracz.objects.all() nie pokazuje żadnych użytkowników, mimo, że jest ich trochę).

Nie wiem czy to mój sposób rejestracji jest wadliwy, w każdym razie nie wiem jak w obecnej sytuacji, bez aktywnego modelu Gracz, dodać do User pole z saldem. Jeśli się nieprecyzyjnie wysłowiłem, postaram się poprawić, najwyżej spróbuję innej metody rejestracji, bo z tą nawet dobrze nie wiem jak z sql wywołać userów.

komentarz 26 sierpnia 2020 przez Dzango111 Użytkownik (600 p.)
edycja 26 sierpnia 2020 przez Dzango111

Utworzyłem w 'admin.py' komendę: 'admin.site.register(Gracz)'. Co ciekawe, po ustawieniu w panelu administratora (Monety › Graczs) jednego z graczy i zapisaniu, jestem zdolny do wyboru w fieldzie 'place' tegoż gracza – wtedy cały system monet działa dla wszystkich graczy i właśnie badam, czy każdy ma osobne saldo.

1
komentarz 27 sierpnia 2020 przez Nelson89 Dyskutant (7,500 p.)

Myślę, że mógłbyś wykorzystać widok formularza rejestracji użytkownika, aby przypisać graczowi portfel przy rejestracji.

Tutaj masz fragment kodu dla drugiego wariantu - z klasą Gracz, która ma atrybut saldo z domyślną wartością.

from .models import Gracz

...

def rejestracja(response):
    if response.method == "POST":
        form = RegisterForm(response.POST)
        if form.is_valid():
            form.save()
            user = User.objects.all().filter(username=username)[0]
            gracz = Gracz(uzytkownik=user)
            gracz.save()
            return redirect('/ogrod')

 

W tym widoku, po udanej rejestracji (wysłaniu zwalidowanego formularza) zostanie utworzony obiekt Gracz, który zostanie powiązany z użytkownikiem, który się zarejestrował.

Jak użyłeś relacji OneToOne w modelu, to każdy gracz powinien mieć osobne pieniądze.

Pozdrawiam,

Nelson

komentarz 30 sierpnia 2020 przez Dzango111 Użytkownik (600 p.)

Ta koncepcja bardzo mi się podoba, jednakże, czy linijka 10 musi zawierać dane 'username'? Z tym wychodzi błąd "NameError: name 'username' is not defined", a próbując wielu importów

(np. "from django import forms",
"from django.contrib.auth.forms import UserCreationForm")

nie ma żadnej zmiany i strona wciąż nie może znaleźć tegoż 'username'.

Pozdrawiam serdecznie i dziękuję za cierpliwość
 

komentarz 31 sierpnia 2020 przez Dzango111 Użytkownik (600 p.)

Wygląda to tak:

 

>>> User.objects.get(username="bob") 
<User: bob>
>>> User.objects.all().filter(username="bob")
<QuerySet [<User: bob>]>
>>> User.objects.all().filter(username="bob")[0]
<User: bob>
>>> User.objects.all().filter(username=username)[0]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
NameError: name 'username' is not defined

 

1
komentarz 1 września 2020 przez Nelson89 Dyskutant (7,500 p.)

Ahh, bo widzisz, w tym kodzie, który Ci podałem wkradł się błąd... zmienną username, musisz najpierw stworzyć i przypisać jej wartość. Przed linijką w której następuje wyszukanie nazwy gracza, musisz określić kogo szukasz. Pobierasz to z formy:

...
username = form.data['username']

I dopiero potem następuje część:

user = User.objects.all().filter(username=username)[0]
...

Pozdrawiam,

Nelson

 

komentarz 2 września 2020 przez Dzango111 Użytkownik (600 p.)
Teraz wszystko działa jak należy!

Gorące podziękowania wysyłam.
komentarz 2 września 2020 przez Nelson89 Dyskutant (7,500 p.)
Fajnie, że wszystko dobrze gra

powodzenia przy dalszej pracy!

pozdrawiam,

Nelson

Podobne pytania

0 głosów
0 odpowiedzi 148 wizyt
0 głosów
0 odpowiedzi 61 wizyt
pytanie zadane 3 marca 2020 w PHP przez auaauaaua Początkujący (370 p.)
0 głosów
1 odpowiedź 88 wizyt

88,325 zapytań

136,919 odpowiedzi

305,555 komentarzy

58,598 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...