You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Colab中cv2_imshow图像堆叠问题及Pong游戏适配咨询

在Google Colab中解决OpenCV Pong游戏图像堆叠问题

问题描述

我在Google Colab中基于现有代码修改实现OpenCV版Pong游戏,将原代码的cv2.imshow替换为Colab专用的cv2_imshow后,发现图像会不断堆叠显示,无法在同一区域形成动态游戏画面。现咨询:

  1. 是否可在Colab中实现游戏式的同区域动态显示?若可行,请提供代码修改方案;
  2. 若不可行,是否有方法在显示新图像前清除旧图像以避免堆叠?

附上修改后的代码:

import cv2
import numpy as np
import random
from google.colab.patches import cv2_imshow

# parameters
width=1280
height=720
paddlewidth=150
paddleheight=20
paddlecolor=(75, 153, 242)
lives=3
deltax=10
deltay=-10
xpos=640
ypos=400
level=1
ball=True
ballradius=8
highscore=0
bgcolor=(30,79,24)
scorecolor=(149, 129,252)

prevval=683
myscore=0

while True:
    background=np.zeros([720,1366,3],dtype=np.uint8)
    background[:,:]=bgcolor
    val = random.randint(0, 1000)
    if val==0:
        val=prevval
    else:
        prevval=val
    cv2.rectangle(background,(1366-(val-paddlewidth//2),720-paddleheight),(1366-(val+paddlewidth//2),720),paddlecolor,-1)
    paddlerightcorner=(1366-(val-paddlewidth//2),720-paddleheight)
    paddleleftcorner=(1366-(val+paddlewidth//2),720-paddleheight)
    if ball==True:
        cv2.circle(background,(xpos,ypos),ballradius,(255,255,255),-1)
        xpos+=deltax
        ypos+=deltay
    if xpos>=1360 or xpos<=5:
        deltax=-deltax
    if ypos<=10:
        deltay=-deltay
    if xpos<=paddlerightcorner[0] and xpos>=paddleleftcorner[0]:
        if ypos>=695 and ypos<=710:
            deltay=-deltay
            myscore+=1
            if myscore%5==0 and myscore>=5:
                level+=1
                if deltax<0:
                    deltax-=2
                else:
                    deltax+=2
                if deltay<0:
                    deltay-=1
                else:
                    deltay+=1
    cv2.putText(background,'Lives: '+str(lives),(1200,35),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2)
    cv2.putText(background,'Level: '+str(level),(1200,68),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2)
    cv2.putText(background,'Score: '+str(myscore),(1200,101),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2)
    if ypos>=720:
        lives-=1
        temp=cv2.blur(background,(15,15))
        cv2.putText(temp,'You Lost a Life !',(300,360),cv2.FONT_HERSHEY_DUPLEX,3,(185,89,200),3,1)
        cv2_imshow(temp)
        cv2.waitKey(2000)
        xpos=640
        ypos=400
        if deltay>0:
            deltay=-deltay
    if lives==0:
        ball=False
        deltax=10
        deltay=-10
        level=0
        background=cv2.blur(background,(20,20))
        cv2.waitKey(1000)
        for i in range(0,720,10):
            background[i:i+10,:]=(24,34,255)
            cv2_imshow(background)
            cv2.waitKey(10)
        cv2.putText(background,'GAME OVER',(400,360),cv2.FONT_HERSHEY_DUPLEX,3,(0,255,255),2)
        cv2.putText(background,'Your Score: '+str(myscore),(420,420),cv2.FONT_HERSHEY_PLAIN,2,(0,255,35),2)
        if myscore>highscore:
            highscore=myscore
        cv2.putText(background,'HIGH SCORE: '+str(highscore),(420,480),cv2.FONT_HERSHEY_PLAIN,2,(0,255,56),2)
        cv2.putText(background,'Press q twice to exit or game restarts in 5 seconds',(300,550),cv2.FONT_HERSHEY_DUPLEX,1,(255,0,0),2)
        cv2_imshow(background)
        cv2.waitKey(5000)
        ball=True
        myscore=0
        lives=3
    if cv2.waitKey(1) & 0xff==ord('q'):
        break
    cv2_imshow(background)

问题解答

1. 可以在Colab中实现同区域动态显示

Colab支持通过IPython.display.clear_output配合cv2_imshow实现单区域动态刷新,这是适配现有代码最直接的方案。核心逻辑是每次显示新帧前,清除当前输出区域的旧内容,再加载新帧,模拟本地窗口的刷新效果。

修改要点:

  • 导入IPython.display中的clear_output工具
  • 在所有调用cv2_imshow的位置前,添加clear_output(wait=True),wait=True参数确保等待新帧内容加载后再清除旧内容,避免画面闪烁。

2. 清除旧图像的方法

上述方案本质就是清除旧图像的实现,此外也可使用matplotlib的交互式绘图模式,但clear_output方案更简洁,无需大幅改动原有游戏逻辑。

修改后的完整代码:

import cv2
import numpy as np
import random
from google.colab.patches import cv2_imshow
from IPython.display import clear_output

# parameters
width=1280
height=720
paddlewidth=150
paddleheight=20
paddlecolor=(75, 153, 242)
lives=3
deltax=10
deltay=-10
xpos=640
ypos=400
level=1
ball=True
ballradius=8
highscore=0
bgcolor=(30,79,24)
scorecolor=(149, 129,252)

prevval=683
myscore=0

while True:
    background=np.zeros([720,1366,3],dtype=np.uint8)
    background[:,:]=bgcolor
    val = random.randint(0, 1000)
    if val==0:
        val=prevval
    else:
        prevval=val
    cv2.rectangle(background,(1366-(val-paddlewidth//2),720-paddleheight),(1366-(val+paddlewidth//2),720),paddlecolor,-1)
    paddlerightcorner=(1366-(val-paddlewidth//2),720-paddleheight)
    paddleleftcorner=(1366-(val+paddlewidth//2),720-paddleheight)
    if ball==True:
        cv2.circle(background,(xpos,ypos),ballradius,(255,255,255),-1)
        xpos+=deltax
        ypos+=deltay
    if xpos>=1360 or xpos<=5:
        deltax=-deltax
    if ypos<=10:
        deltay=-deltay
    if xpos<=paddlerightcorner[0] and xpos>=paddleleftcorner[0]:
        if ypos>=695 and ypos<=710:
            deltay=-deltay
            myscore+=1
            if myscore%5==0 and myscore>=5:
                level+=1
                if deltax<0:
                    deltax-=2
                else:
                    deltax+=2
                if deltay<0:
                    deltay-=1
                else:
                    deltay+=1
    cv2.putText(background,'Lives: '+str(lives),(1200,35),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2)
    cv2.putText(background,'Level: '+str(level),(1200,68),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2)
    cv2.putText(background,'Score: '+str(myscore),(1200,101),cv2.FONT_HERSHEY_PLAIN,2,scorecolor,2)
    if ypos>=720:
        lives-=1
        temp=cv2.blur(background,(15,15))
        cv2.putText(temp,'You Lost a Life !',(300,360),cv2.FONT_HERSHEY_DUPLEX,3,(185,89,200),3,1)
        clear_output(wait=True)
        cv2_imshow(temp)
        cv2.waitKey(2000)
        xpos=640
        ypos=400
        if deltay>0:
            deltay=-deltay
    if lives==0:
        ball=False
        deltax=10
        deltay=-10
        level=0
        background=cv2.blur(background,(20,20))
        cv2.waitKey(1000)
        for i in range(0,720,10):
            background[i:i+10,:]=(24,34,255)
            clear_output(wait=True)
            cv2_imshow(background)
            cv2.waitKey(10)
        cv2.putText(background,'GAME OVER',(400,360),cv2.FONT_HERSHEY_DUPLEX,3,(0,255,255),2)
        cv2.putText(background,'Your Score: '+str(myscore),(420,420),cv2.FONT_HERSHEY_PLAIN,2,(0,255,35),2)
        if myscore>highscore:
            highscore=myscore
        cv2.putText(background,'HIGH SCORE: '+str(highscore),(420,480),cv2.FONT_HERSHEY_PLAIN,2,(0,255,56),2)
        cv2.putText(background,'Press q twice to exit or game restarts in 5 seconds',(300,550),cv2.FONT_HERSHEY_DUPLEX,1,(255,0,0),2)
        clear_output(wait=True)
        cv2_imshow(background)
        cv2.waitKey(5000)
        ball=True
        myscore=0
        lives=3
    if cv2.waitKey(1) & 0xff==ord('q'):
        break
    clear_output(wait=True)
    cv2_imshow(background)

内容的提问来源于stack exchange,提问作者Mich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 11:37:33