找回密码
 立即注册

QQ登录

只需一步,快速开始

楼主: blackpineapple

[原创] 商店/物品/背包 2022最新版本教程附加代码

  [复制链接]
 楼主| 发表于 2022-7-17 10:55:01 | 显示全部楼层
显示包裹的screen,可以使用物品
[RenPy] 纯文本查看 复制代码
screen player_inventory_screen:
    modal True
    zorder 2
    default items = player_inventory.get_items(filter_empty=True)
    default num_fill = GridHelper.get_num_fill(total=len(items))
    default num_row = GridHelper.get_num_row(total=len(items))

    frame:
        yalign 0.04
        background "gui/store/title.png"
        xysize (550, 78)

        imagebutton:
            ycenter 0.4
            idle "gui/store/return.png"
            hover im.MatrixColor("gui/store/return.png", im.matrix.brightness(0.1))
            focus_mask True
            action [Play("sound", "audio/se/click.wav"),
                Hide("player_inventory_screen"), Jump('main')]

        text "物品":
            xcenter 0.5
            ycenter 0.4
            size 50
            color "f2cfcf"
            outlines [ (absolute(5), "#fbfbfb", absolute(0), absolute(0)) ]

    vbox:
        xalign 0.9
        yalign 0.05

        add "gui/store/money.png"
        text str(player.money):
            xalign 0.5
            yoffset -70
            size 30
            color "f2cfcf"
            outlines [ (absolute(5), "#fbfbfb", absolute(0), absolute(0)) ]

    frame:
        background "gui/store/store_base.png"
        xalign 0.5
        yoffset 150

        has viewport id "inventory":
            area (100, 50, 640, 380) #(xpos, ypos, width, height)
            draggable True
            mousewheel True
            child_size 1600, 2200

            grid GridHelper.NUM_COLUMN num_row:
                spacing 20

                for item in items:
                    frame:
                        background Frame("gui/store/item_base.png")
                        xysize (150, 150)

                        if player_inventory.get_num_item(item) != float('inf'):
                            text "数量:" + str(player_inventory.get_num_item(item)):
                                xalign 0.2
                                yoffset 10
                                size 12
                                color "#000"
                                outlines [ (absolute(4), "#fff", absolute(0), absolute(0)) ]

                        button:
                            background Frame("gui/store/icon_base.png")
                            hover_background Frame(im.MatrixColor("gui/store/icon_base.png", im.matrix.brightness(0.1)))
                            xysize (85, 85)
                            xalign 0.5
                            yalign 0.6
                            hovered Play("sound", "audio/se/item.mp3")


                            add item.get_icon():
                                xalign 0.5
                                yalign 0.5
                                zoom 0.1

                            action [Show("use_item_screen", item=item)]

                for i in range(num_fill):
                    frame:
                        background Frame("gui/store/item_base.png")
                        xysize (150, 150)

    vbar value YScrollValue("inventory"):
        xpos 1022
        ypos 151
        unscrollable "hide"
        xmaximum 40
        ymaximum 430
        base_bar "gui/store/bar.png"
        thumb Frame("gui/store/candy.png", xysize=(50,50))
        thumb_offset 20

    frame:
        yoffset 200
        background None
        xysize (300, 600)
        style_prefix "use_item"
        vbox:
            text "fitness: [player.fitness]"
            text "intelligence: [player.intelligence]"
            text "charisma: [player.charisma]"

screen use_item_screen(item):
    zorder 3

    style_prefix "use_item"

    frame:
        background Frame("gui/store/store_info_base.png")
        xysize (400, 400)
        xalign 0.5
        yalign 0.5

        text "是否要使用":
            xalign 0.5
            yoffset -10
            size 50
            at transform:
                linear 1.0 xzoom 0.95
                linear 1.0 xzoom 1.0
                repeat

        add item.get_icon():
            zoom 0.5

        hbox:
            yalign 0.75
            xalign 0.5
            text item.description:
                size 30

        hbox:
            spacing 100
            ypos 0.8
            xalign 0.5
            textbutton "是":
                text_style "use_item_text"
                hovered Play("sound", "audio/se/item.mp3")
                action [Hide('use_item_screen'), Call("use_item", item=item)]

            textbutton "否":
                text_style "use_item_text"
                hovered Play("sound", "audio/se/item.mp3")
                action Hide('use_item_screen')

style use_item_text:
    color "#fff"
    hover_color "#F37459"
    size 30
    outlines [ (absolute(4), "#000", absolute(2), absolute(0)) ]

label use_item(item):
    python:
        item.use(player)
        player_inventory.remove(item)

    call screen information(msg=item.description)
    return
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2022-7-17 10:55:38 | 显示全部楼层
玩家类,可以添加自己需要的属性。
[RenPy] 纯文本查看 复制代码
init -1 python:
    from collections import defaultdict

    class Player:
        def __init__(self, name):
            # 玩家的名字(string)e.g. "black pineapple"
            self.name = name

            # 智力/身材/魅力 (int) e.g. 5
            self.intelligence = 10
            self.fitness = 5
            self.charisma = 5

            # 金钱(int) e.g. 1000
            self.money = 1000

        # 增加玩家的某种属性
        # e.g. intelligence, 5 增加5点智力
        def increase_by(self, attribute, value):
            setattr(self, attribute, value + self.get(attribute))

        # 获得某个属性的数值。
        # e.g. intelligence
        def get(self, attribute):
            return getattr(self, attribute)
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2022-7-17 10:56:23 | 显示全部楼层
script.rpy

[RenPy] 纯文本查看 复制代码
# 使用规则
# 教程中的代码可以用于非商用/商用的游戏,不需要和本人联系,但是需要在发布的时候署名。
# 署名信息:
#
# Black Pineapple
# [url=mailto:blue.pepper.2019@gmail.com]blue.pepper.2019@gmail.com[/url]
#
# 禁止事项
# 非代码素材,比如美术,声音等,未经过本人许可,都禁止使用。
# 代码禁止用于非游戏的商用场合,比如在付费的教程中使用本代码,再比如加工后单纯出售代码。
#
# 程序:本人
# 背景图:自购
# UI:风华
# 立绘:自购,二改
# 物品icon:Stock Material

default player = Player(name="pineapple")
default toy_store = Shop()
default player_inventory = Inventory()

# 游戏在此开始。

label start:
    scene bg store
    call refresh_store
    jump main
    return

label main:
    menu:
        "商店界面":
            jump store
        "商店刷新":
            call refresh_store
            "商店刷新成功!"
            jump main
        "物品界面":
            jump player_inventory

    return

label refresh_store:
    python:
        renpy.random.shuffle(TOY_STORE_ITEMS)
        toy_store.refresh(TOY_STORE_ITEMS[:6])

    return

label store:
    scene bg store
    show screen store
    pause
    jump store
    return

label player_inventory:
    show screen player_inventory_screen
    pause
    jump player_inventory
    return
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2022-7-17 10:57:26 | 显示全部楼层
用来管理商店的类
[RenPy] 纯文本查看 复制代码
init -1 python:
    from collections import defaultdict
    import random
    class Shop:
        def __init__(self):
            self.inventory = Inventory()

        # 返回一个商店目前拥有的所有物品的列表。
        def get_stock(self):
            return self.inventory.get_items()

        # 卖掉商品,如果没有指定数量(count),就是卖掉一个。
        def sell(self, item, count=1):
            self.inventory.remove(item, count)

        # 购买商品,如果没有指定数量(count),就是购买一个。
        # 可以用来实现玩家卖东西给商店,可以在计算的label里面乘以一个系数,从而
        # 达到商店低价收购玩家商品的功能。
        # 商店进货也可以使用此接口。
        def buy(self, item, count=1):
            self.inventory.add(item, count)

        # 判断一个物品是不是已经卖完。
        def is_sold_out(self, item):
            n = self.inventory.get_num_item(item)
            return n == 0

        # 获得商店此物品的数量
        def get_number(self, item):
            return self.inventory.get_num_item(item)

        # 刷新商店里的物品。适用于每次商店固定输出固定数量的物品的设计。
        # 如果是那种不限制出售物品的商店,可以使用buy接口来更新商店物品。
        def refresh(self, stock):
            self.inventory = Inventory()

            for item, count in stock:
                self.buy(item, count)
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2022-7-17 10:57:59 | 显示全部楼层
商店的页面
[RenPy] 纯文本查看 复制代码
screen store:
    modal True
    zorder 2
    default items = toy_store.get_stock()
    default item_description = ""

    frame:
        yalign 0.04
        background "gui/store/title.png"
        xysize (550, 78)

        imagebutton:
            ycenter 0.4
            idle "gui/store/return.png"
            hover im.MatrixColor("gui/store/return.png", im.matrix.brightness(0.1))
            focus_mask True
            action [Play("sound", "audio/se/click.wav"), Hide("store"), Jump('main')]

        text "商店":
            xcenter 0.5
            ycenter 0.4
            size 50
            color "f2cfcf"
            outlines [ (absolute(5), "#fbfbfb", absolute(0), absolute(0)) ]

    vbox:
        xalign 0.9
        yalign 0.05

        add "gui/store/money.png"
        text str(player.money):
            xalign 0.5
            yoffset -70
            size 30
            color "f2cfcf"
            outlines [ (absolute(5), "#fbfbfb", absolute(0), absolute(0)) ]

    frame:
        background "gui/store/store_base.png"
        xalign 0.3
        yalign 0.3

        has grid 3 2:
            xcenter 0.6
            ycenter 0.65
            spacing 50


        for item in items:

            frame:
                background Frame("gui/store/item_base.png")
                xysize (150, 150)

                button:
                    xysize (30, 30)
                    xoffset 120
                    yoffset -10
                    background Frame("gui/store/question.png")
                    hover_background Frame(im.MatrixColor("gui/store/question.png", im.matrix.brightness(0.2)))

                    text "?":
                        xoffset 5
                        yoffset -10
                        size 20
                        color "f2cfcf"
                        outlines [ (absolute(5), "#fbfbfb", absolute(0), absolute(0)) ]
                    action SetScreenVariable("item_description", item.description)

                if toy_store.get_number(item) != float('inf'):
                    text "剩余:" + str(toy_store.get_number(item)):
                        xalign 0.2
                        yoffset 10
                        size 12
                        color "#000"
                        outlines [ (absolute(4), "#fff", absolute(0), absolute(0)) ]

                frame:
                    background Frame("gui/store/icon_base.png")
                    xysize (85, 85)
                    xalign 0.5
                    yalign 0.6

                    add item.get_icon():
                        xalign 0.5
                        yalign 0.5
                        zoom 0.1

                    if toy_store.is_sold_out(item):
                        text "SOLD OUT":
                            xalign 0.5
                            yoffset -10
                            size 30
                            outlines [ (absolute(3), "#000", absolute(2), absolute(1)) ]

                    else:
                        add Null()

                    text "价格:" + str(item.price):
                        size 12
                        xalign 0.5
                        yoffset 75
                        color "#000"
                        outlines [ (absolute(4), "#fff", absolute(0), absolute(0)) ]

                hbox:
                    imagebutton:
                        yoffset 140
                        idle "gui/store/buy.png"
                        hover im.MatrixColor("gui/store/buy.png", im.matrix.brightness(0.1))
                        insensitive im.Grayscale("gui/store/buy.png")
                        focus_mask True
                        sensitive not toy_store.is_sold_out(item)
                        action Call('checkout', item=item)


    add "images/character/No5.png":
        zoom 0.3
        xalign 0.9
        yalign -0.2

    frame:
        background Frame("gui/store/textbox.png")
        xysize(380, 200)
        xalign 0.95
        yalign 0.9

        text item_description:
            xalign 0.5
            yalign 0.5
            xysize (300, 160)
            outlines [ (absolute(4), "#000", absolute(2), absolute(0)) ]

screen get_item(item):
    zorder 3
    button:
        xysize (1280, 720)
        action Return()

    key "input_enter" action Return()

    frame:
        background Frame("gui/store/store_info_base.png")
        xysize (400, 400)
        xalign 0.5
        yalign 0.5

        text "购买成功":
            xalign 0.5
            yoffset -10
            size 50
            outlines [ (absolute(4), "#000", absolute(2), absolute(0)) ]
            at transform:
                linear 1.0 xzoom 0.95
                linear 1.0 xzoom 1.0
                repeat

        add item.get_icon():
            zoom 0.5

label checkout(item):
    if player.money < item.price:
        call screen information(msg="你没有足够的钱。")
        return

    python:
        player.money -= item.price
        toy_store.sell(item)
        player_inventory.add(item)
    call screen get_item(item=item)

    return
回复 支持 抱歉

使用道具 举报

发表于 2022-10-18 14:53:43 | 显示全部楼层
学习了~
回复

使用道具 举报

发表于 2023-3-10 12:15:23 | 显示全部楼层
点击物品界面后就报错了???

  1. I'm sorry, but an uncaught exception occurred.

  2. While running game code:
  3.   File "game/script.rpy", line 59, in script
  4.     pause
  5.   File "renpy/common/000statements.rpy", line 455, in execute_pause
  6.     renpy.pause()
  7.   File "game/player_inventory.rpy", line 1, in execute
  8.     screen player_inventory_screen:
  9.   File "game/player_inventory.rpy", line 1, in execute
  10.     screen player_inventory_screen:
  11.   File "game/player_inventory.rpy", line 4, in execute
  12.     default num_fill = GridHelper.get_num_fill(total=len(items))
  13.   File "game/player_inventory.rpy", line 4, in <module>
  14.     default num_fill = GridHelper.get_num_fill(total=len(items))
  15. NameError: name 'items' is not defined

  16. -- Full Traceback ------------------------------------------------------------

  17. Full traceback:
  18.   File "game/script.rpy", line 59, in script
  19.     pause
  20.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\ast.py", line 2232, in execute
  21.     self.call("execute")
  22.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\ast.py", line 2220, in call
  23.     return renpy.statements.call(method, parsed, *args, **kwargs)
  24.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\statements.py", line 281, in call
  25.     return method(parsed, *args, **kwargs)
  26.   File "renpy/common/000statements.rpy", line 455, in execute_pause
  27.     renpy.pause()
  28.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\exports.py", line 1537, in pause
  29.     rv = renpy.ui.interact(mouse='pause', type='pause', roll_forward=roll_forward, pause=delay, pause_modal=modal)
  30.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\ui.py", line 299, in interact
  31.     rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  32.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\display\core.py", line 3377, in interact
  33.     repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, pause=pause, pause_start=pause_start, pause_modal=pause_modal, **kwargs) # type: ignore
  34.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\display\core.py", line 3810, in interact_core
  35.     root_widget.visit_all(lambda i : i.per_interact())
  36.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\display\core.py", line 582, in visit_all
  37.     d.visit_all(callback, seen)
  38.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\display\core.py", line 582, in visit_all
  39.     d.visit_all(callback, seen)
  40.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\display\core.py", line 582, in visit_all
  41.     d.visit_all(callback, seen)
  42.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\display\screen.py", line 451, in visit_all
  43.     callback(self)
  44.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\display\core.py", line 3810, in <lambda>
  45.     root_widget.visit_all(lambda i : i.per_interact())
  46.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\display\screen.py", line 462, in per_interact
  47.     self.update()
  48.   File "F:\renpy-8.0.3-sdk\renpy-8.0.3-sdk\renpy\display\screen.py", line 653, in update
  49.     self.screen.function(**self.scope)
  50.   File "game/player_inventory.rpy", line 1, in execute
  51.     screen player_inventory_screen:
  52.   File "game/player_inventory.rpy", line 1, in execute
  53.     screen player_inventory_screen:
  54.   File "game/player_inventory.rpy", line 4, in execute
  55.     default num_fill = GridHelper.get_num_fill(total=len(items))
  56.   File "game/player_inventory.rpy", line 4, in <module>
  57.     default num_fill = GridHelper.get_num_fill(total=len(items))
  58. NameError: name 'items' is not defined

  59. Windows-10-10.0.19041 AMD64
  60. Ren'Py 8.0.3.22090809
  61. inventory 1.0
  62. Fri Mar 10 12:11:25 2023
复制代码

回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2023-3-11 00:09:38 | 显示全部楼层
wsx315225 发表于 2023-3-10 12:15
点击物品界面后就报错了???

说 items 没有定义,不知道你哪里写的不对。
回复 支持 抱歉

使用道具 举报

发表于 2023-3-11 11:29:39 | 显示全部楼层
我没改就是那个链接里的内容,前面两个选项没问题第三个物品界面就报错,版本的问题?
回复 支持 抱歉

使用道具 举报

发表于 2023-5-11 15:10:23 | 显示全部楼层
我这二天也给自己整了一个,含分类,使用,出售
微信截图_20230511150958.png

点评

不错不错,可以发个论坛贴经验分享一下。  发表于 2023-5-12 12:36
回复 支持 2 抱歉 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|RenPy中文空间 ( 苏ICP备17067825号|苏公网安备 32092302000068号 )

GMT+8, 2024-12-22 09:10 , Processed in 0.112155 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表