双缓冲

改进版——使用了双缓冲技术

你离开我真会死。 提交于 2020-01-15 02:29:36
import java.awt.*; import java.awt.event.*; public class DrawTurtle { private int x, y; public static void main(String[] args) { new DrawTurtle(); } public DrawTurtle() { x = 100; y = 10; Frame frame = new Frame("DrawTurtle"); DrawLittleTurtle turtle = new DrawLittleTurtle(); frame.add(turtle); frame.setSize(500, 500); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); turtle.requestFocus(); turtle.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP) { y -

WinForm之GDI手动双缓冲技术

北慕城南 提交于 2020-01-15 00:18:52
private void button1_Click( object sender, EventArgs e) { Bitmap bmp = new Bitmap(this.picturebox.Width, this.picturebox.Height); //在内存中创建一个bmp图,bmp的大小和窗口中picturebox的大小相同 Graphics g = Graphics.FromImage(bmp); //通过内存中的bmp图像创建一个在内存中的画布g,那么在画布上的任何操作就都是在内存中操作了 Brush b = new SolidBrush(Color.Green); //创建一个绿色的笔刷 Rectangle r = new Rectangle(10, 10, this.picturebox.Width, this.picturebox.Height); //创建一个长方形 g.FillRectangle(b,r); //在内存中的画布中画我们要画的图形 b.Dispose(); //释放画笔 g.Dispose(); //释放画布 this.picturebox.CreateGraphics().DrawImage(bmp, 0, 0); //最后就是我们手动双缓冲技术的 最后一步了,就是将内存中的bmp的图像一次性的展示到窗口中的picturebox中 }

VC GDI双缓冲机制绘图防屏幕闪烁实现步骤

≡放荡痞女 提交于 2020-01-15 00:01:17
在OnDraw(CDC* pDC) 中添加如下代码 CDC MemDC; //首先定义一个显示设备对象   CBitmap MemBitmap;//定义一个位图对象   //随后建立与屏幕显示兼容的内存显示设备   MemDC.CreateCompatibleDC(NULL);   //这时还不能绘图,因为没有地方画 ^_^   //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小,也可以自己定义(如:有滚动条时就要大于当前窗口的大小,在BitBlt时决定拷贝内存的哪部分到屏幕上)   MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);   //将位图选入到内存显示设备中   //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上   CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);   //先用背景色将位图清除干净,这里我用的是白色作为背景   //你也可以用自己应该用的颜色   MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));   //绘图   MemDC.MoveTo(……);   MemDC.LineTo(……);   //将内存中的图拷贝到屏幕上进行显示   pDC-

Java双缓冲技术

我是研究僧i 提交于 2020-01-07 17:42:26
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 双缓冲技术是为了解决Java在游戏编程的过程中由于页面刷新频率太快,而引起的页面闪烁问题。 它的执行过程是这样的:repaint() 到update()再到paint(),而我们的双缓冲代码就写在update()里, 下面是一段代码: Image offScreenImage=null; public void update(Graphics g) { //双缓冲技术 if(offScreenImage==null){ offScreenImage=this.createImage(GAME_WIDTH,GAME_HEIGHT); } Graphics goffScreen=offScreenImage.getGraphics(); Color c=goffScreen.getColor(); goffScreen.setColor(Color.GREEN); goffScreen.fillRect(0, 0, GAME_WIDTH,GAME_HEIGHT); goffScreen.setColor(c); paint(goffScreen); g.drawImage(offScreenImage, 0, 0,null); } ... } 这就是它的核心代码。 来源: oschina 链接: https:/

MFC 画图CDC双缓冲

一曲冷凌霜 提交于 2020-01-01 01:33:17
void CPCBGUIView::OnDraw(CDC* pDC) { //CPCBGUIDoc* pDoc = GetDocument(); //ASSERT_VALID(pDoc); //if (!pDoc) // return; CDC m_pMemDC; CBitmap m_pBitmap; CRect rect; GetClientRect(rect); int x=rect.Width(); int y=rect.Height(); m_pMemDC.CreateCompatibleDC(pDC); m_pBitmap.CreateCompatibleBitmap(pDC,x,y); m_pMemDC.SelectObject(m_pBitmap); pDC->SetMapMode(MM_ANISOTROPIC);//自定义方式 x向右增加 y向上增加 pDC->SetWindowExt(x,y); pDC->SetViewportExt(x,-y); pDC->SetWindowOrg(0,y); m_pMemDC.SetMapMode(MM_ANISOTROPIC); m_pMemDC.SetWindowExt(x,y); m_pMemDC.SetViewportExt(x,-y); m_pMemDC.SetWindowOrg(0,y); m_pMemDC

Win32双缓冲绘图和位图的绘制

最后都变了- 提交于 2019-12-10 15:01:10
前言: 为什么需要使用双缓冲技术?可能很多朋友会问,不知道你们有没有发现,当屏幕刷新的时候会有闪烁,这样让人的体验感极差。原因是绘图与显示器刷新不同步,有时间差,为解决这一问题,这就需要用到双缓冲技术来绘图了。双缓冲技术是相对单缓冲而言的,单缓冲就是直接在设备DC上绘图;而双缓冲就是先在一个与设备DC相兼容的内存缓冲区里进行绘图,然后再一次性复制到设备DC上。一次性在屏幕上显示就不会出现闪烁的现象。 这里需要注意的是:我们创建的兼容DC,不能直接在上面绘图,这里还需要一块画布,那我们创建的兼容DC就相当于画板,有了画板、画布,将画布选放在画板兼容DC上就可以进行绘图了。然后一次性贴在设备DC上就搞定了。如下: HDC mdc = CreateComatibleDC ( hdc ) ; // 创建兼容DC 画板 HBITMAP bmp = CreatrCompatibleBitnap ( hdc , 600 , 600 ) ; // 创建画布 SelectObject ( mdc , bmp ) ; // 将画布选入画板 一、双缓冲技术的使用 双缓冲绘图步骤: 在内存中创建兼容DC缓冲区(依次包括创建兼容DCCreateComatibleDC、创建画布CreatrCompatibleBitnap、将画布选入SelectObject)。 在缓冲区进行画图操作(可以画图形、也可以贴位图)

实现一个双缓冲队列

五迷三道 提交于 2019-12-07 21:33:11
在生产者-消费者模式中,我们常常会使用到队列,这个队列在多个线程共享访问时存在互斥和竞争操作, 意味着每次访问都要加锁。如何更好的如何减少锁竞争次数呢 ?今天要介绍的双缓冲队列就是个不错的选择。 双缓冲队列就是冲着同步/互斥的开销来的。我们知道,在多个线程并发访问同一个资源的时候,需要特别注意线程的同步问题。稍稍不注意,噢货,程序结果不正确了。 原理 直接上图: 锁 在双缓冲队列中,锁除了起到保护数据安全的作用来,还要承担线程调度的任务。 双队列交换位置和任务入队列都需要对当前队列进行操作,因此,他们是互斥的操作。 消费操作放在单独的线程中,在没有任务进来时,需要将线程置为等待状态。 使用两个信号量,来调度入列队和交换队列的操作。同时,我们还需要一个信号量,在没有任务入队列时,阻塞整个消费线程。 主要使用 AutoResetEvent,ManualResetEvent,它们的具体使用可以看一下园子里的文章: http://www.cnblogs.com/springyangwc/archive/2011/10/12/2208991.html AutoResetEvent.WaitOne()每次只允许一个线程进入,当某个线程得到信号后,AutoResetEvent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只有继续等待

游戏中的双缓冲模式试验

大憨熊 提交于 2019-12-04 13:43:29
我们假设一个游戏,舞台上有三个演员(A,B,C),每个演员有一个自己面对的演员且成一个环(A面对B,B面对C,C面对A)。我们可以扇一个演员的耳光,这个演员不管谁扇的他,他都会去扇他面对的演员(所以我们只要任意扇一个人,他们就会一直成环的扇下去)。 首先写好演员的类: public class Actor { private string m_sName; //名字 private bool m_bIsSlapped; //是否被扇 private Actor m_facedActor; //面对的演员 public string Name { set { m_sName = value; } get { return m_sName; } } public Actor(string name) { m_sName = name; Reset(); //构造时设为未被扇 } public void Face(Actor actor) //设置面对演员 { m_facedActor = actor; } public void Reset() //重置状态 { m_bIsSlapped = false; } public void Slap() //被扇 { m_bIsSlapped = true; } public bool WasSlapped() //是否被扇 { return

双缓冲(Double Buffer)原理和使用

孤街浪徒 提交于 2019-12-01 16:03:48
一、双缓冲作用 双缓冲甚至是多缓冲,在许多情况下都很有用。一般需要使用双缓冲区的地方都是由于“生产者”和“消费者”供需不一致所造成的。这样的情况在很多地方后可能会发生,使用多缓冲可以很好的解决。我举几个常见的例子: 例 1. 在网络传输过程中数据的接收,有时可能数据来的太快来不及接收导致数据丢失。这是由于“发送者”和“接收者”速度不一致所致,在他们之间安排一个或多个缓冲区来存放来不及接收的数据,让速度较慢的“接收者”可以慢慢地取完数据不至于丢失。 例2. 再如,计算机中的三级缓存结构:外存(硬盘)、内存、高速缓存(介于CPU和内存之间,可能由多级)。从左到右他们的存储容量不断减小,但速度不断提升,当然价格也是越来越贵。作为“生产者”的 CPU 处理速度很快,而内存存取速度相对CPU较慢,如果直接在内存中存取数据,他们的速度不一致会导致 CPU 能力下降。因此在他们之间又增加的高速缓存来作为缓冲区平衡二者速度上的差异。 例3. 在图形图像显示过程中,计算机从显示缓冲区取数据然后显示,很多图形的操作都很复杂需要大量的计算,很难访问一次显示缓冲区就能写入待显示的完整图形数据,通常需要多次访问显示缓冲区,每次访问时写入最新计算的图形数据。而这样造成的后果是一个需要复杂计算的图形,你看到的效果可能是一部分一部分地显示出来的,造成很大的闪烁不连贯。而使用双缓冲

C# - 双缓冲绘图技术

断了今生、忘了曾经 提交于 2019-12-01 12:01:21
双缓冲绘图,是指先在内存中进行各种绘图操作,在将内存中绘制好的图形取出显示在控件上,这样可以避免窗口闪烁的现象。 根据上述原理,我们可以自行实现双缓冲绘图,示例代码如下: private void Paint() { // tempImage -> 临时位图 // tempGraphics -> 临时位图的绘图对象 // viewGraphics -> 显示控件的绘图对象 using (Bitmap tempImage = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height)) using (Graphics tempGraphics = Graphics.FromImage(tempImage)) using (Graphics viewGraphics = pictureBox1.CreateGraphics()) { // 步骤一:在临时位图上绘图 tempGraphics.Clear(Color.Black); // 使用黑色填充 if (MainImage != null) tempGraphics.DrawImage(MainImage, 0, 0, pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height); //