RenPy中文空间

 找回密码
 立即注册

QQ登录

只需一步,快速开始

12
返回列表 发新帖
楼主: 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 | 显示全部楼层
学习了~
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2022-11-1 05:13 , Processed in 0.020829 second(s), 10 queries , File On.

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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