热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一个游戏程序的画面,Delphi5中不闪烁,Delphi6中却闪烁,为什么?

我发现一个奇怪的问题。可以这样来做一个试验:在Delphi5中建立一个工程,先放入两个Image控件,设定Image1.Width600;Image1.Height600;Im
我发现一个奇怪的问题。
可以这样来做一个试验:在Delphi5中建立一个工程,先放入两个Image控件,设定
Image1.Width = 600; Image1.Height = 600; Image2.Width = 50; Image2.Height = 50;
并确定它们的Picture属性,指定两个图片。然后添加一个button,在点击事件中写:
procedure TForm1.Button1Click(Sender: TObject);
var
  X, Y: integer;
begin
  x := Random(600);
  y := Random(600);
  image1.Canvas.CopyRect(Rect(X, Y, X + 50, Y + 50),
    image2.Canvas,
    Rect(0, 0, 50, 50));
end;
分别在Delphi5和Delphi6下面编译这两个程序,我们可以发现,当不停的点击按钮时,
在Delphi6下面,图形不断的闪烁,而在Delphi5下面根本不闪烁。
不知道是为什么?
   
btw: 我在编译鞠大龙的推箱子小游戏时发现这个问题的,大家可以试试,在网上
搜索推箱子,很容易找到源代码,用delphi6一编译,问题就出来了,屏幕不断的闪烁。
而用Delphi5编译后的exe根本不闪烁!

18 个解决方案

#1



打开双缓存模式试试

将做image容器的控件的DoubleBuffered := true;

#2


image属性设置不对,以前我也遇到过的!

#3


我也遇到过。不知道怎么解决

#4


cleverboy(小虫)可不可以详细地说一下????
多谢了!

#5


是的,比如你的IMAGE放在Panel1上面,你可以这样试试


Panel1.DoubleBuffered := true;

#6


2312(007)兄说的是正确的!谢谢!
只是小虫弟说改image的属性倒是不知如何搞。

#7


使用DoubleBuffered,

另外,这个决不比鞠大龙的那个推箱子游戏差:
http://www.tonixsoft.com/index.php?mmenu_id=3&smenu_id=0025
sokoban

#8


好久没用了,可能是属性设置有问题!

#9


大家说说这个是什么原因啊?
我也遇到过

#10


这帖子怎么还没结呀?

楼上的,答案已经个给出了

就是调整 DoubleBuffered

#11


我刚刚试了下,没有发现这样的情况啊!

#12


DoubleBuffered设置为True后,显示速度特慢。应该不是正确答案

#13


把image 放到一个载体上pannel控件上,这样就解决了image在窗体移动时刷新不及时的问题

#14


错了,这种做法再在都不能用了。要获取位图1的内存DC,然后,再将位图2的内存DC合起来再放入内存3的DC,再读出来,也就是上面的双缓冲或多缓冲,具体的做法你可以看看《VC++游戏开发》或《游戏开发概论》

#15


doublebuffer,双缓冲,D5和D6不同,在D6需要设为true

#16


呵呵,推箱子啊,我也写了一个,绝对不闪,谁要?

#17


界面:1个 400 X 400 的panel,一个speedbutton。
源码:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Buttons;

const
  XCount = 20;
  YCount = 20;
  C_SPACE = 0;
  C_WALL = 1;
  C_MAN = 2;
  C_BOX = 3;
  C_POINT = 4; 
  C_ManPoint = C_MAN + C_POINT;
  C_BoxPoint = C_BOX + C_POINT;

type
  TWallImg = class(TImage)
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

  TActImg = class(TImage)
  public
    constructor Create(AOwner: TComponent; cType: Integer); reintroduce; virtual;
    destructor Destroy; override;
  end;

  TForm1 = class(TForm)
    Panel1: TPanel;
    SpeedButton1: TSpeedButton;
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure SpeedButton1Click(Sender: TObject);
  private
    CurMap: String;
    function TurnX(X: Integer): Integer;
    function TurnY(Y: Integer): Integer;
    function TurnNum(Num, Count: Integer): Integer;
    function check(a, b: integer): boolean;
    function checkway(way: integer): boolean;
    function checkwin: BOOLEAN;
    procedure DrawWall;
    procedure DrawAct;
    procedure FreeAll;
    procedure Ini(cMap: String);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Y: array[0..XCount - 1, 0..YCount - 1] of Integer;
  ManX, ManY: Integer;

implementation

{$R *.dfm}

#18


{ TWallImg }

constructor TWallImg.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Picture.Bitmap.LoadFromFile('Wall.bmp');
  Stretch := true;
  Height := 20;
  Width := 20;
end;

destructor TWallImg.Destroy;
begin
  inherited Destroy;
end;

{ TActImg }

constructor TActImg.Create(AOwner: TComponent; cType: Integer);
begin
  inherited Create(AOwner);
  case cType of
    C_MAN, C_ManPoint: Picture.Bitmap.LoadFromFile('People.bmp');
    C_BOX: Picture.Bitmap.LoadFromFile('Box.bmp');
    C_POINT: Picture.Bitmap.LoadFromFile('Target.bmp');
    C_BoxPoint: Picture.Bitmap.LoadFromFile('Box2.bmp');
  end;
  Stretch := true;
  Height := 20;
  Width := 20;
end;

destructor TActImg.Destroy;
begin
  inherited Destroy;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case key of
    37:
      if Checkway(1) then
        begin
          DrawAct;
          manx := TurnX(manx - 1);
        end;
    39:
      if Checkway(2) then
        begin
          DrawAct;
          manx := TurnX(manx + 1);
        end;
    38:
      if Checkway(3) then
        begin
          DrawAct;
          many := TurnY(many - 1);
        end;
    40:
      if Checkway(4) then
        begin
          DrawAct;
          many := TurnY(many + 1);
        end;
  end;
  if checkwin then
    begin
      Showmessage('你赢了');
      self.OnKeyDown := nil;
    end;
end;

function TForm1.check(a, b: integer): boolean;
begin
  result := false;
  case y[TurnX(manx + a), TurnY(many + b)] of
    C_SPACE, C_POINT:
      begin
        result := true;
        y[TurnX(manx + a), TurnY(many + b)] := C_MAN + y[TurnX(manx + a), TurnY(many + b)];
        y[manx, many] := y[manx, many] - C_MAN;
      end;
    C_WALL: result := false;
    C_BOX, C_BoxPoint:
      begin
        if (y[TurnX(manx + 2 * a), TurnY(many + 2 * b)] = C_SPACE)
          or (y[TurnX(manx + 2 * a), TurnY(many + 2 * b)] = C_POINT) then
          begin
            result := true;
            y[TurnX(manx + 2 * a), TurnY(many + 2 * b)] :=
              y[TurnX(manx + 2 * a), TurnY(many + 2 * b)] + C_BOX;
            y[TurnX(manx + a), TurnY(many + b)] :=
              y[TurnX(manx + a), TurnY(many + b)] + C_MAN - C_BOX;
            y[manx, many] := y[manx, many] - C_MAN;
          end
        else
          result := false;
      end;
  end;
end;

function TForm1.checkway(way: integer): boolean;
var
  a, b: integer;
begin
  a := 0;
  b := 0;
  case way of
    1:
      begin
        a := -1;
        b := 0;
      end;
    2:
      begin
        a := 1;
        b := 0;
      end;
    3:
      begin
        a := 0;
        b := -1;
      end;
    4:
      begin
        a := 0;
        b := 1;
      end;
  end;
  result := check(a, b);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
{  CurMap := '1111111111' +
            '1111111111' +
            '1111111111' +
            '1120000111' +
            '1100301411' +
            '1100300011' +
            '1400000011' +
            '1111111111' +
            '1111111111' +
            '1111111111'; }
             
  CurMap := '00000000000000000000' +
            '00000000000000000000' +
            '00001111100000000000' +
            '00001000100000000000' +
            '00001300100000000000' +

            '00111003110000000000' +
            '00100303010000000000' +
            '11101011014001111110' +
            '10001011011111000410' +
            '10303000000000004410' +

            '11111011101211004410' +
            '00001000001111101110' +
            '00001111111000000000' +
            '00000000000000000000' +
            '00000000000000000000' +
            
            '00000000000000000000' +
            '00000000000000000000' +
            '00000000000000000000' +
            '00000000000000000000' +
            '00000000000000000000';
  Ini(CurMap);
end;

function TForm1.checkwin: BOOLEAN;
var
  i, j: Integer;
begin
  for i := 0 to XCount - 1 do
    for j := 0 to YCount - 1 do
      if Y[i, j] = C_BOX then
        begin
          Result := false;
          Exit;
        end
      else
        result := true;
end;

procedure TForm1.DrawWall;
  procedure DrawWallAtPos(X, Y: Integer);
  var
    Wall: TWallImg;
  begin
    Wall := TWallImg.Create(Panel1);
    Wall.Left := X * 20;
    Wall.Top := Y * 20;
    Wall.Parent := Panel1;
  end;

var
  i, j: Integer;  
begin
  for i := 0 to XCount - 1 do
    for j := 0 to YCount - 1 do
      if Y[i, j] = C_WALL then
        begin
          DrawWallAtPos(i, j);
        end;
end;

procedure TForm1.DrawAct;
  procedure DrawActAtPos(X, Y, cType: Integer);
  var
    Act: TActImg;
  begin
    Act := TActImg.Create(Panel1, cType);
    Act.Left := X * 20;
    Act.Top := Y * 20;
    Act.Parent := Panel1;
  end;

var
  i, j: Integer;  
begin
  for i := Panel1.ComponentCount - 1 downto 0 do
    if Panel1.Components[i] is TActImg then
      TActImg(Panel1.Components[i]).free;
  for i := 0 to XCount - 1 do
    for j := 0 to YCount - 1 do
      if (Y[i, j] <> C_SPACE) and (Y[i, j] <> C_WALL) then
        begin
          DrawActAtPos(i, j, Y[i, j]);
        end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAll;
end;

procedure TForm1.FreeAll;
var
  i: Integer;
begin
  for i := Panel1.ComponentCount - 1 downto 0 do
    if Panel1.Components[i] is TImage then
      TImage(Panel1.Components[i]).free;
end;

procedure TForm1.Ini(cMap: String);
var
  i, j: Integer;
begin
  if Length(cMap) <> XCount * YCount then
    begin
      ShowMessage('载入游戏地图失败!');
      Exit;
    end;
  FreeAll;
  for j := 0 to YCount - 1 do
    for i := 0 to XCount - 1 do
      Y[i, j] := StrToInt(cMap[j * XCount + i + 1]);
  ManX := Pos(IntToStr(C_MAN), cMap) mod XCount - 1;
  ManY := Pos(IntToStr(C_MAN), cMap) div XCount;
  DrawWall;
  DrawAct;
  self.OnKeyDown := FormKeyDown;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  Ini(CurMap);
end;

function TForm1.TurnNum(Num, Count: Integer): Integer;
begin
  Result := (Num + Count) Mod Count;
end;

function TForm1.TurnX(X: Integer): Integer;
begin
  Result := TurnNum(X, XCount);
end;

function TForm1.TurnY(Y: Integer): Integer;
begin
  Result := TurnNum(Y, YCount);
end;

end.

推荐阅读
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • 本文介绍了如何利用 `matplotlib` 库中的 `FuncAnimation` 类将 Python 中的动态图像保存为视频文件。通过详细解释 `FuncAnimation` 类的参数和方法,文章提供了多种实用技巧,帮助用户高效地生成高质量的动态图像视频。此外,还探讨了不同视频编码器的选择及其对输出文件质量的影响,为读者提供了全面的技术指导。 ... [详细]
  • Flutter 2.* 路由管理详解
    本文详细介绍了 Flutter 2.* 中的路由管理机制,包括路由的基本概念、MaterialPageRoute 的使用、Navigator 的操作方法、路由传值、命名路由及其注册、路由钩子等。 ... [详细]
  • async/await 是现代 JavaScript 中非常强大的异步编程工具,可以极大地简化异步代码的编写。本文将详细介绍 async 和 await 的用法及其背后的原理。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 原文网址:https:www.cnblogs.comysoceanp7476379.html目录1、AOP什么?2、需求3、解决办法1:使用静态代理4 ... [详细]
  • C# 实现可浮动工具栏功能
    本文介绍如何在 C# 中实现一个可浮动的工具栏,即工具栏可以从其初始位置拖出,并且可以重新拖回原位。通过创建一个新的窗口作为工具栏的容器,并利用 .NET Framework 提供的 ToolStrip 控件,可以轻松实现这一功能。 ... [详细]
  • 本地存储组件实现对IE低版本浏览器的兼容性支持 ... [详细]
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • 在《Cocos2d-x学习笔记:基础概念解析与内存管理机制深入探讨》中,详细介绍了Cocos2d-x的基础概念,并深入分析了其内存管理机制。特别是针对Boost库引入的智能指针管理方法进行了详细的讲解,例如在处理鱼的运动过程中,可以通过编写自定义函数来动态计算角度变化,利用CallFunc回调机制实现高效的游戏逻辑控制。此外,文章还探讨了如何通过智能指针优化资源管理和避免内存泄漏,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 《我的世界》Java版种子合集:探索多样世界生成
    本文介绍了《我的世界》Java版中用于生成多样化游戏世界的种子代码。这些种子是由一个或多个字符(包括正整数和负整数)组成的值,能够为玩家带来截然不同的地形和环境体验。通过使用不同的种子,玩家可以探索各种独特的地貌、生物群系和结构,从而丰富游戏的乐趣和挑战性。 ... [详细]
  • 2018 HDU 多校联合第五场 G题:Glad You Game(线段树优化解法)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356在《Glad You Game》中,Steve 面临一个复杂的区间操作问题。该题可以通过线段树进行高效优化。具体来说,线段树能够快速处理区间更新和查询操作,从而大大提高了算法的效率。本文详细介绍了线段树的构建和维护方法,并给出了具体的代码实现,帮助读者更好地理解和应用这一数据结构。 ... [详细]
author-avatar
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有