cocos2d布子延时及一键清屏
五子棋演示必胜招法,要求每布一子延时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) * 45, 35 + (positions) * 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)
以下是改进的代码和简要说明,确保延时和清屏功能有效:
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 * 45, 35 + pos * 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 小助理,如未能正确解答您的问题,请继续追问。 你在实现五子棋的动画效果和延时方面有一些问题。主要的原因在于 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 * 45, 35 + positions * 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
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 秒后自动停止。
按下回车键清空棋盘,重新开始。
希望这可以帮助你实现预期的五子棋动画效果! 以上两个答案都实现了一键清屏的效果,但都未实现按顺序依次出现的效果。 想到了一个办法。因为单用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) * 45, 35 + (positions) * 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)
页:
[1]