小星圆55 2022-12-20 13:08 采纳率: 33.3%
浏览 30
已结题

Python pyglet精灵一直动

问题遇到的现象和发生背景

我想要用python+pyglet编写一个二维《Minecraft》,目前刚刚添加Steve,能动,不能操作方块

遇到的现象和发生背景,请写出第一个错误信息

当我按D的时候,Steve一直向右移动,即使松开也如此,再按A会逐渐减慢,停止。向左移动也如此。

用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%

主程序 XyCraft.py

import pyglet as pg
from random import random
from block import Block, blocks
from steve import Steve


class XyCraft:
    def __init__(self):
        self.win = pg.window.Window(
            width=768,
            height=512
        )
        self.steve = Steve()
        self.world_blocks = [  # 方块列表
            [_ for _ in range(24)],  # y=0
            [_ for _ in range(24)],  # y=1
            [_ for _ in range(24)],  # y=2
            [_ for _ in range(24)],  # y=3
            [_ for _ in range(24)],  # y=4
            [_ for _ in range(24)],  # y=5
            [_ for _ in range(24)],  # y=6
            [_ for _ in range(24)],  # y=7
            [_ for _ in range(24)],  # y=8
            [_ for _ in range(24)],  # y=9
            [_ for _ in range(24)],  # y=10
            [_ for _ in range(24)],  # y=11
            [_ for _ in range(24)],  # y=12
            [_ for _ in range(24)],  # y=13
            [_ for _ in range(24)],  # y=14
            [_ for _ in range(24)],  # y=15
        ]  # 这些奇怪的循环是占位符

        # 加载资源
        pg.resource.path = [r'.\res']
        pg.resource.reindex()
        self.sky = pg.resource.image(r"sky.png")

        self.create_world()

        @self.win.event
        def on_draw():
            self.win.clear()
            self.sky.blit(0, 0)
            for block in blocks:
                block.draw()
            self.steve.draw()


        @self.win.event
        def on_key_press(symbol, modifiers):
            self.on_key_press(symbol, modifiers)

        @self.win.event
        def on_text(text):
            self.on_text(text)

    def create_world(self):
        # 地形生成

        # 地下基层岩石生成
        for y in range(6):
            for x in range(24):
                self.world_blocks[y][x] = Block(x, y, 'stone', self.win)

        # 地表地形生成
        for y in range(6, 14):
            for x in range(24):
                if not self.create_grass(x, y):
                    self.create_stone(x, y)

    def create_grass(self, x, y):
        # 生成草块
        is_grass_probability = y / 25  # 是草块的概率随着高度增加而增加
        try:
            if self.is_air(x + 1, y):
                is_grass_probability += 1 / 15
            if self.is_air(x + 1, y):
                is_grass_probability += 1 / 15
                if self.is_air(x + 1, y):
                    is_grass_probability += 1 / 15
        except IndexError:
            ...

        if (isinstance(
                self.world_blocks[y - 1][x], type(0))):  # 如果它的下面是空气
            is_grass_probability = 0  # 概率为0
        elif (self.world_blocks[y - 1][x].name == 'grass'):  # 如果它的下面是草块
            is_grass_probability /= 10  # 则概率除以10

        if random() < is_grass_probability:
            self.world_blocks[y][x] = Block(x, y, 'grass', self.win)
            return True
        else:
            return False

    def create_stone(self, x, y):
        is_grass_probability = 10 / y  # 是除特殊情况,永远是石头:
        if (isinstance(
                self.world_blocks[y - 1][x], type(0))):  # 如果它的下面是空气
            is_grass_probability = 0  # 概率为0
        elif (self.world_blocks[y - 1][x].name == 'grass'):  # 如果它的下面是草块
            is_grass_probability = 0  # 概率为0
        if (random() < is_grass_probability):
            self.world_blocks[y][x] = Block(
                x, y, 'stone', self.win)

    def is_air(self, x, y):
        return isinstance(self.world_blocks[y][x], type(0))

    def on_key_press(self, symbol, modifiers):
        if symbol == pg.window.key.A:
            pg.clock.schedule_interval(self.steve.lmove, 1/60, )
        if symbol == pg.window.key.D:
            pg.clock.schedule_interval(self.steve.rmove, 1/60, )

    def on_text(self, text):
        ...

craft = XyCraft()
pg.app.run()

管理Steve的模块steve.py

import pyglet as pg


class Steve:
    def __init__(self, img='steve.png'):
        pg.resource.path = [r'.\res']
        pg.resource.reindex()
        self.img = pg.resource.image(img)
        self.sprite = pg.sprite.Sprite(img=self.img)

    def draw(self):
        self.sprite.draw()

    def rmove(self, dt=1/120):
        if self.sprite.x < 768-15:
            self.sprite.x += 15 * dt

    def lmove(self, dt=1/120):
        if self.sprite.x > 0:
            self.sprite.x += -15 * dt

管理方块的模块block.py


```python


import pyglet as pg


blocks = []

class Block:
    def __init__(self, x, y, name, win: pg.window.Window):
        global blocks
        blocks.append(self)
        self.x = x * 32
        self.y = y * 32
        self.name = name
        self.win = win
        pg.resource.path = [r'.\res']
        pg.resource.reindex()
        self.img = pg.resource.image(fr"{name}.png")


    def draw(self):
        self.img.blit(self.x, self.y)

    def __bool__(self):
        return True


运行结果及详细报错内容

当我按D的时候,他不是像其他游戏那样按下移动,松开停止,而是按下一直动,松开接着动,直到我按A向反方向移动,才被迫停止。

我想要达到的结果

GitHub存储库
我想按下移动,松开停止

[]([]())

  • 写回答

2条回答 默认 最新

  • 於黾 2022-12-20 13:36
    关注

    pg.clock.schedule_interval(self.steve.lmove, 1/60, )
    这是啥代码,你按下A键,就创建个clock一直往左边走吗

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 12月25日
  • 已采纳回答 12月25日
  • 创建了问题 12月20日

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?