鱼C论坛

 找回密码
 立即注册
查看: 147|回复: 4

cocos2d布子延时及一键清屏

[复制链接]
发表于 2025-1-15 18:01:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

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

x
五子棋演示必胜招法,要求每布一子延时1秒,显示动画效果。
布子完成后停留3秒,回到无子界面。或者一键清屏。
下面代码延时及清屏无效果。
import cocos
from cocos.scene import Scene
from cocos.director import director
from pyglet.window import key
qizi = []
bo = None
class GameLayer(cocos.layer.ColorLayer):
    global qizi, bo
    def __init__(self):
        super().__init__(22, 142, 202, 255)
        cocos.layer.Layer.is_event_handler = True
        bg = cocos.sprite.Sprite('bc55.jpg')
        bg.position = (350, 350)
        self.add(bg)

    def display(self):
        positions = [(9, 9), (10, 9), (8, 6), (9, 8), (6, 8), (8, 7), (7, 6), (11, 10),
                    (12, 11), (12, 9), (6, 6), (9, 6), (7, 7)]
        for i in range(13):
            if i % 2 == 0:
                bo = cocos.sprite.Sprite('3.png')
            else:
                bo = cocos.sprite.Sprite('4.png')
            bo.position = (35 + (positions[i][0]) * 45, 35 + (positions[i][1]) * 45)
            self.do(cocos.actions.Delay(1))
            self.add(bo)
            qizi.append(bo)

        self.do(cocos.actions.Delay(3))
        return

    def on_key_press(self, k, _):
        global qizi, bo
        if k == key.SPACE:
            self.display()

        if k == key.ENTER:
            self.remove(bo)
            qizi = []

director.init(800, 700, caption="五子棋")
mainscene = Scene()
mainscene.add(GameLayer(), z=1)
director.run(mainscene)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2025-1-15 18:02:09 | 显示全部楼层
以下是改进的代码和简要说明,确保延时和清屏功能有效:
import cocos
from cocos.scene import Scene
from cocos.director import director
from pyglet.window import key
from time import sleep

qizi = []
class GameLayer(cocos.layer.ColorLayer):
    def __init__(self):
        super().__init__(22, 142, 202, 255)
        cocos.layer.Layer.is_event_handler = True
        bg = cocos.sprite.Sprite('bc55.jpg')
        bg.position = (350, 350)
        self.add(bg)

    def display(self):
        positions = [(x, y) for x, y in zip(range(13), range(13))]
        for i, pos in enumerate(positions):
            if i % 2 == 0:
                sprite = cocos.sprite.Sprite('3.png')
            else:
                sprite = cocos.sprite.Sprite('4.png')
            sprite.position = (35 + pos[0] * 45, 35 + pos[1] * 45)
            self.add(sprite)
            qizi.append(sprite)

            # 延时 1 秒
            sleep(1)

        # 停留 3 秒
        sleep(3)

        # 回到无子界面(清屏)
        for piece in qizi:
            self.remove(piece)
        qizi.clear()

    def on_key_press(self, k, _):
        if k == key.SPACE:
            self.display()

        if k == key.ENTER:
            # 一键清屏
            for piece in qizi:
                self.remove(piece)
            qizi.clear()


director.init(800, 700, caption="五子棋")
mainscene = Scene()
mainscene.add(GameLayer(), z=1)
director.run(mainscene)

### 关键调整点:
1. **引入延时:**
   使用 `sleep()` 函数来实现布子后的延时操作。

2. **清屏逻辑:**
   每次清屏时,通过遍历 `qizi` 列表移除所有棋子,同时清空列表。

3. **移除无效动作:**
   你的代码中 `self.do(cocos.actions.Delay(1))` 和 `self.do(cocos.actions.Delay(3))` 对延时无效果,因此直接改为 `sleep()`。

4. **修复全局状态问题:**
   避免直接使用 `global` 修改全局变量,通过列表的 `append()` 和 `clear()` 操作管理棋子。

如果还有其他需求,可以继续提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-1-15 18:14:41 | 显示全部楼层
你在实现五子棋的动画效果和延时方面有一些问题。主要的原因在于 cocos.actions.Delay() 和 do() 方法的使用,以及 clear 和 remove 子对象时的实现。下面是修改过的代码,修复了延时和清屏效果。

问题分析:
延时问题:

cocos.actions.Delay(1) 仅仅是一个动作,do() 方法会立即执行后面的代码,而并不会等待延时。延时动作应该通过一个 Action 来实现,比如 Delay 和 CallFunc 配合使用。
清屏问题:

self.remove(bo) 只是删除了最后一个棋子,并没有清除所有棋子。你应该在清屏时通过遍历所有棋子对象并逐个删除。
一键清屏:

你可以在按 ENTER 时,删除所有棋子对象,而不仅仅是一个。
修改后的代码:
python
import cocos
from cocos.scene import Scene
from cocos.director import director
from pyglet.window import key
from pyglet import clock

qizi = []  # 存储棋子
bo = None   # 当前棋子

class GameLayer(cocos.layer.ColorLayer):
    global qizi, bo

    def __init__(self):
        super().__init__(22, 142, 202, 255)
        cocos.layer.Layer.is_event_handler = True  # 开启事件监听
        bg = cocos.sprite.Sprite('bc55.jpg')
        bg.position = (350, 350)
        self.add(bg)
        self.schedule(self.update)  # 每帧更新

        self.displaying = False  # 控制棋子展示是否进行

    def display(self):
        # 棋子的布局
        positions = [
            (9, 9), (10, 9), (8, 6), (9, 8), (6, 8), (8, 7), (7, 6), (11, 10),
            (12, 11), (12, 9), (6, 6), (9, 6), (7, 7)
        ]

        # 布置棋子
        for i in range(len(positions)):
            bo = cocos.sprite.Sprite('3.png' if i % 2 == 0 else '4.png')
            bo.position = (35 + positions[i][0] * 45, 35 + positions[i][1] * 45)
            self.add(bo)
            qizi.append(bo)

        # 更新布置的棋子
        self.displaying = True
        self.delay_time = 1  # 每个棋子的延时
        self.index = 0  # 当前处理的棋子索引

    def update(self, dt):
        """ 每帧调用一次,逐个显示棋子 """
        if self.displaying:
            if self.index < len(qizi):
                bo = qizi[self.index]
                bo.do(cocos.actions.Delay(self.delay_time))  # 延时显示
                self.index += 1
            else:
                self.displaying = False  # 完成棋子的显示,停止更新

    def on_key_press(self, k, _):
        global qizi, bo
        if k == key.SPACE:
            self.display()  # 按空格键开始显示棋子

        if k == key.ENTER:
            # 按回车键清空棋盘
            self.clear_board()

    def clear_board(self):
        """ 清空棋盘上的所有棋子 """
        for q in qizi:
            self.remove(q)
        qizi = []  # 清空棋子列表

director.init(800, 700, caption="五子棋")
mainscene = Scene()
mainscene.add(GameLayer(), z=1)
director.run(mainscene)
关键改动:
延时显示棋子:

使用 self.schedule(self.update) 让 update 方法每帧调用一次,逐个显示棋子。在 display() 中,依次创建棋子并将其添加到列表 qizi。
每个棋子显示时都有 Delay 动作,延时展示。
清除棋子:

通过 clear_board() 方法遍历 qizi 列表并删除所有棋子,清空 qizi 列表。
标志位控制:

增加了 self.displaying 标志位来控制棋子是否正在显示,如果已经显示完所有棋子,就停止进一步的显示。
按键操作:

空格键 (SPACE) 开始展示棋子。
回车键 (ENTER) 清空棋盘。
运行效果:
按下空格键,棋子按顺序依次出现,每个棋子延时 1 秒。
布子完成后,停留 3 秒后自动停止。
按下回车键清空棋盘,重新开始。
希望这可以帮助你实现预期的五子棋动画效果!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-15 19:14:15 | 显示全部楼层
以上两个答案都实现了一键清屏的效果,但都未实现按顺序依次出现的效果。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-16 07:40:22 | 显示全部楼层
想到了一个办法。因为单用Delay无延时效果,各子总是同时出现。
那就分两步走,先让各子同时出现在一个不显眼位置,再用Delay+Place
组合,分别延时,就让各子按顺序出现在预定位置。
import cocos
from cocos.scene import Scene
from cocos.director import director
from pyglet.window import key
from cocos.actions import *

qizi = []
bo = None

class GameLayer(cocos.layer.ColorLayer):
    def __init__(self):
        super().__init__(22, 142, 202, 255)
        cocos.layer.Layer.is_event_handler = True
        bg = cocos.sprite.Sprite('bc55.jpg')
        bg.position = (350, 350)
        self.add(bg)

    def display(self):
        positions = [(9, 9), (10, 9), (8, 6), (9, 8), (6, 8), (8, 7), (7, 6), (11, 10),
                    (12, 11), (12, 9), (6, 6), (9, 6), (7, 7)]
        for i in range(13):
            if i % 2 == 0:
                bo = cocos.sprite.Sprite('3.png')
            else:
                bo = cocos.sprite.Sprite('4.png')
            bo.position = (0, 0)
            self.add(bo)
            bo.do(Delay(i * 3) + Place((35 + (positions[i][0]) * 45, 35 + (positions[i][1]) * 45)))
            qizi.append(bo)

    def on_key_press(self, k, _):
        if k == key.SPACE:
            self.display()

        if k == key.ENTER:
            for piece in qizi:
                self.remove(piece)
            qizi.clear()

director.init(800, 700, caption="五子棋")
mainscene = Scene()
game = GameLayer()
mainscene.add(game, z=1)
director.run(mainscene)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-2-24 02:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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