게임을 만들다가 생긴 문제..

leonid의 이미지


C#으로 게임을 만들고 있는데

그래픽에 이것저것 넣다보니 게임이 느려지면서 뚝뚝 끊겨버립니다.

GDI만 쓰고 있습니다.

그리는 속도를 향상시키려면 어떻게 해야 할까요?

다이렉트X나 오픈GL을 쓰는 방법밖에 없을까요?

bootmeta의 이미지

dobule buffering이 가능하도록 보이지 않는 버퍼 drawing을 지원했던 기억이 납니다.
혹시 C#에서도 double buffering이 가능하지 않을까요?
특별히 계산량이 많이 않다면 double buffering만으로도 만족할만한 결과가 나옵니다.

leonid의 이미지

form에서 기본적으로 제공하고 있더군요..

게임이기 때문에 당연히 true로 체크 했습니다.

주요 계산량으로는.. 밑의 함수를 한 화면에서 약 20~40번을 호출합니다.

화면의 배경으로 이미지파일도 하나 그려줍니다.

한번 그릴 때마다 1 밀리초씩 쉬었습니다.
(Thread.sleep(0)으로 하니 메모리를 100% 차지하더군요 --; 노트북 사용자분들이 싫어할것 같아서)

        public void Draw(Graphics g, PointF pos, float size, float lightOffset)
        {
            PointF trans = new PointF(pos.X + 0.5f * size, pos.Y + (-slideCellCount + slideCell + slideRate + 0.5f) * size);
            float scale = size * (1 - shrinkRate);
            if (scale == 0) return;
 
            float thickness = OptionManager.BoxThickness;
 
            int cosine = (int)(255 * Math.Cos((light + lightOffset) * Math.PI / 180));
            int sine = (int)(255 * Math.Sin((light + lightOffset) * Math.PI / 180));
            SolidBrush[] brushTable = new SolidBrush[4];
            brushTable[0] = new SolidBrush(Color.FromArgb(Math.Abs(cosine), cosine >= 0 ? Color.White : Color.Black));
            brushTable[2] = new SolidBrush(Color.FromArgb(Math.Abs(cosine), cosine >= 0 ? Color.Black : Color.White));
            brushTable[1] = new SolidBrush(Color.FromArgb(Math.Abs(sine), sine >= 0 ? Color.White : Color.Black));
            brushTable[3] = new SolidBrush(Color.FromArgb(Math.Abs(sine), sine >= 0 ? Color.Black : Color.White));
 
            Matrix initialState = g.Transform;
            g.TranslateTransform(trans.X, trans.Y);
            g.ScaleTransform(scale, scale);
 
            g.FillRectangle(new SolidBrush(color), -0.5f, -0.5f, 1, 1);
 
            for (int i = 0; i < 4; i++)
            {
                if (!IsOpened(i * 2)) g.FillPolygon(brushTable[i], shadow[0]);
                else
                {
                    if (!IsOpened((i * 2 + 1) % 8) || !IsOpened((i * 2 + 2) % 8)) g.FillPolygon(brushTable[(i + 1) % 4], shadow[1]);
                    if (!IsOpened((i * 2 + 7) % 8) || !IsOpened((i * 2 + 6) % 8)) g.FillPolygon(brushTable[(i + 3) % 4], shadow[2]);
                    g.FillRectangle(new SolidBrush(color), -thickness / 2, -0.5f, thickness, 0.5f - thickness / 2);
                }
                g.RotateTransform(-90);
            }
            g.FillRectangle(new SolidBrush(color), -thickness / 2, -thickness / 2, thickness, thickness);
 
            g.Transform = initialState;
        }
bootmeta의 이미지


C#에서 어떻게 지원되나 살펴보니 정말 쉽군요.
단지 속성 3가지만 설정하면 된다니..

his.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);

그런데 drawing timing이 고정적인 간격이 아니라 반복적으로 loop를 도는 건가요?

leonid의 이미지

update 함수와 draw 함수를

가능한 한 자주 호출하면서 가장 최근에 update함수가 호출된 시점부터 소요된 시간을 parameter로 넣었습니다.

bootmeta의 이미지

제가 알기로 게임이나 그래픽 animation에서 보통 안정적인 drawing 기본은 timer를 사용한 일정한 tic time 구현으로 알고 있습니다.

주기적인 tic time event 발생시 현재 drawing중이거나 drawing이 필요없는 경우 drawing 루틴 호출을 무시하는 구조로 되있던 경우로 알고 있습니다.

tic time 없이 단지 loop로 돌고 중간에 sleep이 들어가는 경우라면 cpu부하와 drawing 일관성에 문제가 있지 않을까요?
drawing 시간이 고정적이지 않을 때, 기존 drawing 시간이 지난 후 timer가 호출된다면 중간 갭 없이 너무 빡빡하게 호출이 되서 부하가 많이 걸릴 것 같습니다.
더우기 미묘하게 drawing 작업 종료 전에 다시 drawing event가 걸린다면 실제 drawing작업을 하지 않더라도 새 event 무시같은 미묘한 문제가 생길 것도 같습니다.
C#이나 게임은 구경 해본적이 없습니다. 그냥 혹시나 해서 쓴 것이니 이해를 ^^;

leonid의 이미지

제 경우는

한 XNA 게임 프로젝트의 소스를 보고 비슷하게 구현봤던 겁니다..

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.