Advertisement

c# bug invaders

Started by March 05, 2019 11:57 PM
46 comments, last by NubDevice 5 years, 9 months ago

well I am able to draw space ship a bullet and a bug. everything works ok so far but when the bullet moves the screen flickers, is there anyway to optimize my code.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Imaging;

    
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            timer1.Interval = 20;
            timer1.Start();
        }

        public void Form1_Load(object sender, EventArgs e)
        {

        }
        int x = 0, y = 0;
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Left)
            {
                x-=5;
                if(x<=-350)
                {
                    x = -350;
                }
            }
            if(e.KeyCode == Keys.Right)
            {
                x+=5;
                if(x>=375)
                {
                    x = 375;
                }
            }
            if (e.KeyCode == Keys.Space)
            {
                y -= 5;
                if (y <= -530)
                {
                    y = 0;
                }
            }
            Invalidate();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            y -= 5;
            Invalidate();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Bitmap ship = new Bitmap("ship.bmp", true);
            Bitmap bullet = new Bitmap("bullet.bmp", true);
            Bitmap bug_one = new Bitmap("bug_one.bmp", true);
            Graphics g1 = this.CreateGraphics();
            g1.DrawImage(ship, 350+x, 530);
            g1.DrawImage(bullet, 375+x, 520 + y);
            g1.DrawImage(bug_one, 350, 0);
            g1.Dispose();
        }
    }
}

 

I haven't tried it as I wouldn't use GDI painting for a game, but check both the property DoubleBuffered in your main control plus use the Graphics member of PaintEventArgs instead of creating a second one.

e.g.:

e.Graphics.DrawImage ...

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Advertisement

I tried doublebuffered but it makes it worse. where is my main control?

I looked up non flickering using gdi+ but I think it is flickering because of how gdi+ works.

you might consider only invalidating the subset rectangle of pixels that have changed since the last frame and manage your own background state. l feel there will be a need to get creative with the technology you've chosen, considering animation performance with head room is in play here.

Dev careful. Pixel on board.

how do I manage my own background state? I have also worked with the invalidate command but with still no good results.

Advertisement

well everything works ok, but the bug still flickers.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Imaging;

    
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            timer1.Interval = 20;
            timer1.Start();
        }
        public void Form1_Load(object sender, EventArgs e)
        {

        }
        int x = 0, y = 0;
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Left)
            {
                x-=5;
                if(x<=-350)
                {
                    x = -350;
                }
            }
            if(e.KeyCode == Keys.Right)
            {
                x+=5;
                if(x>=375)
                {
                    x = 375;
                }
            }
            if (e.KeyCode == Keys.Space)
            {
                if (y <= -530)
                {
                    y = 0;
                }
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            y -= 5;
            Invalidate();
        }
        protected override void OnPaintBackground(PaintEventArgs e)
        {

        }
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Bitmap bug_one = new Bitmap("bug_one.bmp", true);
            Bitmap ship = new Bitmap("ship.bmp", true);
            Bitmap bullet = new Bitmap("bullet.bmp", true);
            e.Graphics.Clear(this.BackColor);
            e.Graphics.DrawImage(ship, 350 + x, 530);
            e.Graphics.DrawImage(bullet, 375 + x, 520 + y);
            e.Graphics.DrawImage(bug_one, 350, 0);
            e.Graphics.Dispose();
        }
    }
}

 

I suspect initializing the bitmap objects in your Form1_Paint function takes enough time to create a noticeable flicker. I suggest moving the code that creates the new bitmaps to the same place you declare your x and y variables.

 

I moved my bitmaps to where I declare my x and y variables but it still flickers.

what I'm suggesting is


private void Form1_Paint(object sender, PaintEventArgs e)
{
   // test screen flicker with a draw method swap...
   // don't clear all the screen pixels, handle your own background (later)
   //   e.Graphics.Clear(this.BackColor);

   e.Graphics.DrawImage(shipMask, 350 + previous_x, 530); // clear previous image
   e.Graphics.DrawImage(ship, 350 + x, 530);

   e.Graphics.DrawImage(bulletMask, 375 + previous_x, 520 + previous_y);
   e.Graphics.DrawImage(bullet, 375 + x, 520 + y);

   e.Graphics.DrawImage(bug_one, 350, 0); // does not animate
   e.Graphics.Dispose();
}

the mask images are the same dimension size as the ones they go with. The trade off is more texture memory but heavily reduced fill requirements. I feel that would run at reduced load or at best 60 hrz.. 

Does GDI+ have monitor retrace synchronization? Probably not. What about sticking with GDI+ for what it provides, draw to your own surface and add a rendering API that bumps you up to a hardware screen surface blit. Flicker has potential to become a non issue making the next problem frame lag/skip by not being able to fill your user surface fast enough.

May I ask a question please? When you do these experiments, what typical goal do you have in mind. What motivation is it here? Fun? Improving to become hire-able? Stimulation for mental health? You seem to struggle and it's a little hard to watch. I learned to program so I could see my art come alive, why do you do it? If it's not too forward. No disrespect intended. Curious what the long term desired outcome is.

<check>

 

Dev careful. Pixel on board.

This topic is closed to new replies.

Advertisement