[PYTHON] Créez des RPG 2D avec Ren'Py (3) - Boutique d'objets et d'outils

Aperçu

Bonjour, ce sont les joueurs érotiques Kanimaru vous n'êtes pas Eroge récemment, négatif, la production du jeu. Il s'agit de la troisième production de RPG 2D utilisant Ren'Py. Cette fois, nous créerons des articles et des magasins d'outils.

Dernière fois: Make 2D RPG with Ren'Py (2) -Party and Status

** Portée de cet article ** Mettre en œuvre des éléments et les activer à partir de l'écran du menu et les acheter et les vendre à la boutique d'outils

Contexte

Pourquoi avez-vous besoin d'articles pour RPG! Je pense que personne n'a ce sentiment. Si vous fabriquez un objet avant de faire une bataille, vous pourrez récupérer pendant la bataille, vous ferez donc d'abord un objet.

1. Fabriquer un article

Tout d'abord, créez un élément - je vais implémenter la pièce à utiliser à partir de l'écran de menu.

Mise en place du système

Comme la dernière fois, il ne s'agit que de Python, pas de Ren'Py, donc si vous comprenez Python, vous pouvez faire ce que vous voulez.

Commencez par créer un «inventaire» avec le type dict. Utilisez la clé comme instance de l'élément et la valeur comme le nombre d'éléments possédés. Les instances de type définies par l'utilisateur sont hachables, elles peuvent donc être utilisées comme clés de type dict. Pratique. Je ne veux pas trop utiliser de variables globales lors de l'écriture de code Python normalement, mais Ren'Py utilise des variables globales sans pitié car il y a quelques bizarreries.

inventory = {}

Ensuite, créez la classe ʻItem` qui est la base de l'élément. Définissez le prix, l'indicateur de disponibilité, etc. en tant que variables d'instance. La méthode définit un getter qui renvoie un message au moment de l'utilisation, le traitement au moment de l'acquisition / vente, etc.

class Item():
    def __init__(self, name, desc, price):
        self.name = name
        self.desc = desc
        self.price = price
        self.sell_price = int(price / 2.0)
        self.marketable_flag = True #Si faux, il ne peut pas être vendu
        self.usable_flag = True #Si False, il ne peut pas être utilisé normalement
        self.battle_flag = True #Si faux, il ne peut pas être utilisé pendant la bataille
        self.icon_image = "images/icons/medical_item.png "

    ###Omission: getter de base###

    def get_confirm_msg(self):
        return self.name + "Utilises tu?"

    def get_result_msg(self):
        return self.name + "j'ai utilisé"

    #Achat au magasin
    def buy_item(self, buy_amount = 1):
        party_money.add_value(-self.price * buy_amount)
        inventory[self] += buy_amount

    #Vente au magasin
    def sell_item(self, sell_amount = 1):
        party_money.add_value(self.sell_price * sell_amount)
        inventory[self] -= sell_amount

    #Lorsque ramassé ou reçu
    def find_item(self, find_amount = 1):
        inventory[self] += find_amount 

Créez une classe qui hérite de la classe ʻItem` pour chaque type d'élément. Articles de récupération, articles de statut supérieur, articles de matériel, articles de recette, etc. Mettez en œuvre ce dont vous avez besoin pour votre jeu. Vous trouverez ci-dessous le code de la classe d'élément de récupération à titre d'exemple.

Est nouvellement défini. Lors de l'utilisation d'un article, appelez la méthode ʻadd_current_value (diff) de l'instance de l'état cible à récupérer, et décrémentez la valeur de cet article de l''inventaire précédemment défini.

#Élément de récupération
class MedicalItem(Item):
    def __init__(self, name, desc, price, target_stat, amount):
        super(MedicalItem, self).__init__(name, desc, price)
        self.target_stat = target_stat
        self.amount = amount

    def get_target_stat(self):
        return self.target_stat

    def get_amount(self):
        return self.amount

    def get_usable_flag(self):
        if self.target_stat.get_current_value() == self.target_stat.get_max_value():
            return False
        else:
            return True

    #Augmentez le prix actuel
    def use_item(self):
        self.target_stat.add_current_value(self.amount)
        inventory[self] -= 1

Une fois que vous avez fait cela, ajoutez vos articles à l'inventaire comme suit:

medical_hp_small = MedicalItem(name = "Un petit médicament amer", desc = "Récupère une petite quantité de force physique.", price = 50, target_stat = stat_hp, amount = 40)
inventory[medical_hp_small] = 3

Vous pouvez désormais gérer vos articles.

Implémentation de l'interface utilisateur

C'est celui d'origine de Ren'Py. Le résultat de cette implémentation est d'abord montré sur la figure. SnapCrab_griseo_2020-8-1_18-12-17_No-00.png Les principales fonctions et variables utilisées sont les suivantes.

--Afficher la liste des articles sur l'écran du menu (afficher la clé dont la valeur est supérieure à 0 à partir de ʻinventory`)

Ensuite, je mettrai le code.

screens.rpy


#Paramètres de l'écran des éléments
screen inventory():

    tag menu

    use game_menu(_("article"), scroll="None"):

        style_prefix "inventory"

        hbox: #Statut côte à côte, article, liste d'articles
            spacing 40
            vbox: 
                ###Omis: écran d'état (voir la dernière fois)###
            
            viewport: #Utiliser la fenêtre pour faire défiler lorsqu'il y a de nombreux éléments
                scrollbars "vertical"
                mousewheel True
                draggable True
                pagekeys True
                xsize 350
                ysize 500
                vbox:
                    label _("article")
                    null height (2 * gui.pref_spacing)
                    for item, amount in inventory.items():
                        if amount > 0:
                            hbox:
                                $item_name = item.get_name()
                                $usable_flag = item.get_usable_flag()
                                $confirm_msg = item.get_confirm_msg()
                                $desc = item.get_desc()
                                $icon_image = item.get_icon_image()
                                add icon_image
                                if usable_flag and amount > 0: #Quand l'article est disponible
                                    textbutton _(item_name + " " + str(amount)):
                                        tooltip desc 
                                        action Confirm(confirm_msg, UseItem(item))
                                else: #Quand il ne peut pas être utilisé. Notez que l'info-bulle ne peut pas être utilisée si elle est définie sur insensible.
                                    textbutton _(item_name + " " + str(amount)):
                                        tooltip desc 
                                        action NullAction()
                                        text_style "unusable_text" #Changer de couleur
                                null height (gui.pref_spacing)

            vbox:
                xsize 350

                label _("Détails de l'article")
                $ tooltip = GetTooltip()
                if tooltip:
                    null height (4 * gui.pref_spacing)
                    text "[tooltip]"

###style omis###

style unusable_text:
    color gui.insensitive_color

Ce code affiche un écran «Confirm» qui émet un «confirm_msg» lorsqu'un élément disponible est cliqué, et appelle l'action «Utiliser l'élément» si Oui est sélectionné. ʻUse Item` est une action unique implémentée.

screens.rpy


init:
    python:
        class UseItem(Action):
            def __init__(self, item):
                self.item = item

            def predict(self):
                renpy.predict_screen("notify")

            def __call__(self):
                renpy.notify(self.item.get_result_msg())
                self.item.use_item()

Dans Ren'Py, une classe qui hérite de la classe ʻAction peut être appelée comme une Action, et quand elle est appelée, le traitement à l'intérieur call () ʻest effectué. Ici, quand ʻUseItem (item) est appelé, après avoir obtenu le result_msg de ʻitem et l'avoir affiché dans notify, la méthode ʻuse_item () de ʻitem est appelée.

Enfin, affichez l'écran ʻinventory () `créé ici dans le menu du jeu. C'est le même que le statut.

screens.rpy


screen navigation():

    ###Omission###

        if main_menu:

            ###Omission###

        else:

            textbutton _("statut") action ShowMenu("stats")

            textbutton _("article") action ShowMenu("inventory") #Ajouter cette ligne

Vous pouvez maintenant utiliser l'élément du menu du jeu.

2. Achat et vente dans un magasin d'outils

Maintenant que vous pouvez utiliser l'article, achetons-le dans la boutique d'outils. C'est là que les méthodes price et buy_item () définies dans la classe ʻItem` entrent en jeu.

Mise en place du système

Je n'ai pas grand chose à faire ici, je ne fais que définir un article dans un atelier d'outillage. Cette fois, j'en ai fait une liste, mais si vous avez le concept d'inventaire, vous pouvez le gérer en le faisant avec dict.

store.rpy


#Enregistrer un article dans la boutique d'outils
init python:
    store = [medical_hp_small, medical_hp_medium, enhancing_hp]

Implémentation de l'interface utilisateur

Le résultat de l'implémentation est également affiché ici. SnapCrab_griseo_2020-8-1_18-50-15_No-00.png C'est un peu artificiel car il est fait à partir d'images existantes (en particulier les barres de défilement), mais c'est fonctionnellement complètement un magasin d'outils. De plus, bien qu'il ne soit pas transmis dans l'image, il fait du bruit lors de l'achat ou de la vente. C'est comme un jeu!

Ci-dessous le code. La définition de classe est également publiée à la fois.

store.rpy


init 1 python:
    #Lorsque vous appuyez sur le bouton de texte de l'image de la carte d'achat
    class BuyItem(Action):
        def __init__(self, item):
            self.item = item

        def __call__(self):
            self.item.buy_item()
            renpy.restart_interaction()
            renpy.play("audio/sounds/coins.mp3")

    #Lorsque le bouton de texte sur l'image de vente est enfoncé
    class SellItem(Action):
        def __init__(self, item):
            self.item = item

        def __call__(self):
            self.item.sell_item()
            renpy.restart_interaction()
            renpy.play("audio/sounds/coins.mp3")

screen store_screen(store_instance):

    style_prefix "store"
    $current_money = party_money.get_value() #Parti variable global_money(Obtenir la valeur actuelle à partir d'une instance créée de manière appropriée de la classe monétaire)

    frame:
        background "gui/store/blank.png "
        style_group "mm"
        xalign 0
        yalign 0
    hbox:
        xalign 0.05 yalign 0.03
        add "images/icons/money.png "
        text str(current_money)

    null height (4 * gui.pref_spacing)
    hbox: #Côte à côte, achetez des images et vendez des images
        xalign 0.05
        yalign 0.4
        imagemap:
            ground "gui/store/background.png "
            label _("achat")   
            viewport:
                #yinitial yinitial
                scrollbars "vertical"
                mousewheel True
                draggable True
                pagekeys True

                side_yfill True
                vbox:
                    for item in store_instance: #Afficher l'inventaire de l'atelier d'outillage avec le montant
                        $item_name = item.get_name()
                        $item_price = item.get_price()
                        hbox:
                            if item_price > current_money: #Articles plus élevés que votre argent
                                textbutton item_name sensitive False
                                add "images/icons/money.png " yalign 1.0
                                text str(item_price)
                            else: #Articles que vous pouvez acheter
                                textbutton item_name action BuyItem(item)
                                add "images/icons/money.png " yalign 1.0
                                text str(item_price)

        null width (2 * gui.pref_spacing)
        imagemap:
            ground "gui/store/background.png "
            label _("vente")
            viewport:
                #yinitial yinitial
                scrollbars "vertical"
                mousewheel True
                draggable True
                pagekeys True

                side_yfill True

                vbox:
                    for item, amount in inventory.items(): #Afficher les articles en stock avec le prix de vente et la quantité
                        if amount > 0:
                            $item_name = item.get_name()
                            $item_sell_price = item.get_sell_price()
                            $marketable_flag = item.get_marketable_flag()
                            hbox:
                                if marketable_flag: #Articles qui se vendent
                                    textbutton item_name action SellItem(item)
                                    add "images/icons/money.png " yalign 1.0
                                    text str(item_sell_price)
                                    text "×" + str(amount)
                                else: #Articles qui ne peuvent pas être vendus
                                    textbutton item_name sensitive False

    button: #bouton retour
        xalign 0.9
        yalign 1.0
        xsize 145
        ysize 100
        text "Revenir" yalign 0.35
        background "gui/store/blank.png "
        
        action Return(True) #Revenir à l'étiquette de l'appelant

###style omis###

Je suis très heureux de pouvoir créer une boutique d'outils avec autant de code!

Conclusion et avenir

Cette fois, nous avons implémenté l'article afin qu'il puisse être utilisé à partir de l'écran de menu et acheté / vendu à la boutique d'outils. Il est presque temps de se battre, donc la prochaine fois, je créerai un système de combat.

Codes et matériaux référencés (titres omis)

Référence du code et emprunter l'interface graphique: Dragonaqua on Lemmasoft(https://lemmasoft.renai.us/forums/viewtopic.php?f=51&t=57105) Contexte: Nao Naruse Image debout: Wataokiba (https://wataokiba.net/) icône: Magasin de matériel Rosa (http://sozairosa.blog.fc2.com/)

Recommended Posts

Créez des RPG 2D avec Ren'Py (3) - Boutique d'objets et d'outils
(Mémorandum) Créer un diagramme de dispersion 3D avec matplodlib
Faisons un outil de veille de commande avec python
Essayez de créer un jeu simple avec Python 3 et iPhone
Créer un outil de formatage CSV avec Python Pandas Py Installer
Créons une application Mac avec Tkinter et py2app
Créer une visionneuse de modèle 3D avec PyQt5 et PyQtGraph
Associez Python Enum à une fonction pour la rendre appelable
Faites une loterie avec Python
Fabriquez un thermomètre BLE et obtenez la température avec Pythonista3
Faire un feu avec kdeplot
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
Créez un simple OMR (lecteur de feuille de marque) avec Python et OpenCV
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
Faire une boussole d'affichage kanji avec Raspberry Pi et Sense Hat
Générez des formes physiquement robustes avec GAN et imprimez avec une imprimante 3D
Créez une application de scraping avec Python + Django + AWS et modifiez les tâches
[4th] J'ai essayé de créer un certain outil de type Authenticator avec python
[1er] J'ai essayé de créer un certain outil de type Authenticator avec python
Faisons une interface graphique avec python.
Résoudre ABC166 A ~ D avec Python
Créer un système de recommandation avec python
Créer un filtre avec un modèle django
Faisons un graphe avec python! !!
Faisons un spacon avec xCAT
Créer un itérateur de modèle avec PySide
Faire un joli graphique avec plotly
2.Faites un arbre de décision à partir de 0 avec Python et comprenez-le (2. Bases du programme Python)
J'ai trouvé un moyen de créer un modèle 3D à partir d'une photo.
Créez un convertisseur Ethernet LAN sans fil et un routeur simple avec Raspberry Pi
Créez DNN-CRF avec Chainer et reconnaissez la progression des accords de la musique
Créez un arbre de décision à partir de 0 avec Python et comprenez-le (4. Structure des données)
Faisons un jeu de shiritori avec Python
Créer un lecteur vidéo avec PySimpleGUI + OpenCV
Créez un simulateur de gacha rare avec Flask
Créez un pipeline de notebook avec Kedro + Papermill
Fractal pour faire et jouer avec Python
Faire une figure partiellement zoomée avec matplotlib
Créez un classificateur en cascade avec Google Colaboratory
Faisons un langage simple avec PLY 1
Faire un circuit logique avec Perceptron (Perceptron multicouche)
Résoudre AtCoder ABC168 avec python (A ~ D)
Faire Oui Non Popup avec Kivy
Faire une minuterie de lavage-séchage avec Raspberry Pi
Créer une animation GIF avec surveillance des dossiers
Créez un framework Web avec Python! (1)
Faisons une IA à trois yeux avec Pylearn 2
Créez une application de bureau avec Python avec Electron
Faisons un bot Twitter avec Python!
Implémenter un modèle avec état et comportement
Créez un framework Web avec Python! (2)
Simulation physique 2D avec Box2d et wxPython
J'ai essayé de faire un processus périodique avec CentOS7, Selenium, Python et Chrome
Fabriquez un thermomètre avec Raspberry Pi et rendez-le visible sur le navigateur Partie 3
Faisons une application qui affaiblit les nerfs avec Vue.js et Django-Rest-Framework [Partie 3] ~ Implémentation de la faiblesse nerveuse ~
Créons une application qui affaiblit les nerfs avec Vue.js et Django-Rest-Framework [Partie 2] ~ Configuration de Vue ~
Faisons une application qui affaiblit les nerfs avec Vue.js et Django-Rest-Framework [Partie 1] ~ Django setup ~
Faisons une application qui affaiblit les nerfs avec Vue.js et Django-Rest-Framework [Partie 6] ~ Authentification utilisateur 2 ~
WEB grattage avec python et essayez de créer un nuage de mots à partir des critiques