找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1545|回复: 3

[教程] Ren'Py贪吃蛇

[复制链接]
发表于 2024-8-21 14:24:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Ren'Py贪吃蛇


一个Ren'Py原生实现的贪吃蛇 mini game (小游戏),可嵌入常规游戏


源码:
[RenPy] 纯文本查看 复制代码
"""renpy
python early:
"""

import pygame
from enum import Enum

renpy = renpy # type: ignore


class SnakeDirection(Enum):
    UP = 0
    DOWN = 1
    LEFT = 2
    RIGHT = 3


class Block:
    def __init__(self, limit: tuple[int, int], block_size: int = 20, color: tuple[int, int, int] = (255, 255, 255)):
        self.limit = limit
        self.block_size = block_size
        self.color = color
        self._pos: list[int, int] = self.get_random_pos()    # 左上角顶点坐标
        self.rect = (*self.pos, self.block_size, self.block_size)

    @property
    def pos(self):
        return self._pos

    @pos.setter
    def pos(self, value):
        self._pos = value
        self.rect = (*self.pos, self.block_size, self.block_size)

    def get_random_pos(self):
        x = renpy.random.choice(range(0, self.limit[0] - self.block_size, self.block_size))
        y = renpy.random.choice(range(0, self.limit[1] - self.block_size, self.block_size))
        return [x, y]


class Snake(Block):
    def __init__(self, limit: tuple[int, int], length: int = 3, block_size: int = 20, color: tuple[int, int, int] = (255, 255, 255)):
        super().__init__(limit, block_size, color)
        self.length = length
        self.pos: list[list[int, int]] = self.get_pos()
        self.direction = SnakeDirection.LEFT

    def get_pos(self):
        # 开局为水平状态
        pos = []
        xpos = [x for x in range(self.pos[0], self.pos[0] + self.block_size * self.length, self.block_size)]
        for x in xpos:
            pos.append([x, self.pos[1]])
        return pos
            

class SnakeGame(renpy.Displayable):
    
    def __init__(self, size: tuple[int, int] = (800, 800), block_size: int = 20, speed: int = 100, color: tuple[int, int, int] = (255, 255, 255), **properties):
        super().__init__(**properties)
        self.size = size
        self.block_size = block_size
        self.color = color
        self.started = True
        self.egg = Block(self.size, self.block_size, (233, 150 ,122))
        self.snake = Snake(self.size, 3, self.block_size, (0, 139, 139))
        self.score = 0
        self.fresh_time = block_size / speed

        self.started = False

    def start(self):
        self.started = True
        self.egg = Block(self.size, self.block_size, (233, 150 ,122))
        self.snake = Snake(self.size, 3, self.block_size, (0, 139, 139))
        self.score = 0
        renpy.restart_interaction()
        renpy.redraw(self, 0)

    def update(self):
        renpy.redraw(self, self.fresh_time)

        snake_head = self.snake.pos[0][:]
        if self.snake.direction == SnakeDirection.UP:
            snake_head[1] -= self.snake.block_size
        elif self.snake.direction == SnakeDirection.DOWN:
            snake_head[1] += self.snake.block_size  
        elif self.snake.direction == SnakeDirection.LEFT:
            snake_head[0] -= self.snake.block_size
        elif self.snake.direction == SnakeDirection.RIGHT:
            snake_head[0] += self.snake.block_size
        
        if (
            snake_head[0] < 0 or 
            snake_head[0] + self.snake.block_size > self.size[0] or
            snake_head[1] < 0 or
            snake_head[1] + self.snake.block_size > self.size[1] or
            snake_head in self.snake.pos
        ):
            self.started = False
            renpy.notify("你失败了!")
            return

        self.snake.pos.insert(0, snake_head)
        
        if self.snake.pos[0] == self.egg.pos:
            self.snake.length += 1
            self.score += 2
            self.egg.pos = self.egg.get_random_pos()
            renpy.restart_interaction()
        else:
            self.snake.pos.pop()

    def render(self, width, height, st, at):
        render = renpy.Render(width, height)
        canvas = render.canvas()
        # 绘制边框
        canvas.rect(self.color, (0, 0, *self.size), width=1)
        if self.started:
            # 绘制蛇
            for pos in self.snake.pos:
                canvas.rect(self.snake.color, (*pos, self.snake.block_size, self.snake.block_size))
            # 绘制蛋
            canvas.rect(self.egg.color, self.egg.rect)
            self.update()
        return render

    def event(self, ev, x, y, st):
        if ev.type == pygame.KEYDOWN:
            if ev.key == pygame.K_UP and (self.snake.direction not in (SnakeDirection.DOWN, SnakeDirection.UP)):
                self.snake.direction = SnakeDirection.UP
                self.update()
            elif ev.key == pygame.K_DOWN and (self.snake.direction not in (SnakeDirection.UP, SnakeDirection.DOWN)):
                self.snake.direction = SnakeDirection.DOWN
                self.update()
            elif ev.key == pygame.K_LEFT and (self.snake.direction not in (SnakeDirection.RIGHT, SnakeDirection.LEFT)):
                self.snake.direction = SnakeDirection.LEFT
                self.update()
            elif ev.key == pygame.K_RIGHT and (self.snake.direction not in (SnakeDirection.LEFT, SnakeDirection.RIGHT)):
                self.snake.direction = SnakeDirection.RIGHT
                self.update()



使用方式:
  • 将源码复制到游戏目录中后缀为 _ren.py py 脚本文件中
  • 或直接下载附件解压放到游戏目录中

使用示范:
[RenPy] 纯文本查看 复制代码
define snake_game = SnakeGame()


screen game():

    vbox:
        align (0.5, 0.5)
        xysize (850, 900)
        spacing 20

        hbox:
            spacing 500
            text "分数:[snake_game.score]"
            text "长度:[snake_game.snake.length]"

        add snake_game

        textbutton "开始游戏" xalign 1.0 action Function(snake_game.start)


label start:

    call screen game()

    return





使用说明:商用(嵌入游戏)需要标注 POWERED BY ZYKsslm,不可直接将源码售卖

snake_game_ren.zip

1.42 KB, 阅读权限: 10, 下载次数: 5, 下载积分: 活力 100

评分

参与人数 1干货 +3 收起 理由
烈林凤 + 3 感谢分享!

查看全部评分

发表于 2024-9-24 21:52:00 | 显示全部楼层

目前搞定了,thanks
回复 支持 0 抱歉 1

使用道具 举报

发表于 2024-9-20 11:48:33 | 显示全部楼层
大佬,我按你的方法,出来的是黑屏,连textbutton都没显示
回复 支持 抱歉

使用道具 举报

 楼主| 发表于 2024-9-23 23:15:19 | 显示全部楼层
LOVEMM 发表于 2024-9-20 11:48
大佬,我按你的方法,出来的是黑屏,连textbutton都没显示

请帖出代码
回复 支持 抱歉

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 14:03 , Processed in 0.115733 second(s), 29 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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