基本图像刷新问题通过数组操作数组、图像、操作、基本

由网友(浮生思过往)分享简介:我试图做一个简单的瓷砖游戏引擎,并运行到问题。我碰到困难时,我不得不重新绘制砖。I am trying to make a simple tile game engine and running into issues. I get stuck when i have to redraw the tile.int[,...

我试图做一个简单的瓷砖游戏引擎,并运行到问题。我碰到困难时,我不得不重新绘制砖。

I am trying to make a simple tile game engine and running into issues. I get stuck when i have to redraw the tile.

        int[,] level = {
                           { 0, 0, 0, 0, 0 ,0 },
                           { 0, 0, 0, 0, 0 ,0 },
                           { 0, 0, 0, 0, 0 ,0 },
                           { 0, 0, 0, 0, 0 ,0 },
                           { 0, 0, 0, 0, 0 ,0 },
                           { 0, 0, 0, 0, 0 ,0 },
                       };

这是我的数组,所有的值都为0。因此关闭。每个相应的值被链接到一个单独的瓦片作为你preSS的钥匙,将开启和关闭。

This is my array and all the values are 0 thus off. Each corresponding value is linked to a seperate tile that will turn on and off as you press the keys.

        //Event Handler (W,A,S,D) is used for movements
    private void panel1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {

        .
        .
        .

    }



        //Responsible for movements
    private void tmrMov_Tick(object sender, EventArgs e)
    {


        level[_x, _y] = 0;

        if (_objDirection == Direction.Right)
        {

            if (_x < _boardWidth - 1 && _x >= 0 && _x + 1 < _boardWidth - 1 && _x + 1 >= 0)
                _x += 1;
            else
                _x = _boardWidth - 1;
        }

           .
           .
           .

        level[_x, _y] = _k;

        Invalidate();
    }

这是我的定时器功能是应该'操纵'数组值所以程序正在运行时,可以决定打开/关闭键,通过该瓦片。

This is my timer function that is supposed to 'manipulate' array values so when the program is running, one can decide which tile to turn on/off through keys.

不管怎么说,我的问题是刷新它涉及的无效()函数调用的形象。虽然,我有一种感觉,它可以动态改变数组的值,我似乎无法刷新图像跳转到另一个瓦。

Anyways, my problem is refreshing the image which concerns the 'invalidate()' function call. Though, i do have a feeling it can change array values on the fly, i can't seem to refresh the image to jump to another tile.

下面是链接到完整的项目,我一直在努力: http://www.mediafire.com /?g10a0zzt8hru11v

Here's the link to the complete project i've been working on: http://www.mediafire.com/?g10a0zzt8hru11v

下面是一个类似但不同的问题,我问过一些天回:Setting了基本的游戏和调试

Here's a similar but different question i asked some days back: Setting up basic game and debugging fundamental problems

在此先感谢!

推荐答案

所以...我希望你不要采取任何罪行,但我经历了和收拾了一点东西,并提出了一些建议/修正/评论/等。

So...I hope you don't take any offense to this, but I went through and tidied things up a bit and offered some suggestions/fixes/comments/etc.

希望这有助于!让我知道是否有任何建议的修改都需要解释。

Hope this helps! Let me know if any of the suggested changes need explanation.

那么,让我们开始在designer.cs文件:

So, let's start at the designer.cs file:

// Ahh, here's yer problem: the panel control doesn't raise PreviewKeyDowns - the form does, tho
this.panel1.PreviewKeyDown += 
       new System.Windows.Forms.PreviewKeyDownEventHandler(
           this.panel1_PreviewKeyDown);

    // the form will raise these, so bind the handler to it 
    // (and rename the method)
    this.PreviewKeyDown += 
       new System.Windows.Forms.PreviewKeyDownEventHandler(
           this.Form1_PreviewKeyDown);

啊,一个大问题分解 - 没有你的重要事件实际上让你的处理程序。让我们回到了流行的形式为code-落后。

Ah, one big problem down - none of your key events were actually getting to your handler. Let's pop back over to the form code-behind.

因此​​,在构造函数中 - 这一切都可以去:

So, in the constructor - all this can go:

// arrays of T (T[], int[], etc), come initialized to default(T),
// so none of this is needed.
level[0, 0] = 0;
level[0, 1] = 0;
level[0, 2] = 0;
level[0, 3] = 0;
level[0, 4] = 0;

跳转到了油漆处理程序:

// The next two checks have the x and y swapped,
    // meaning the apparent motion will not match what the
    // actual direction should be
//Empty Tile
if (level[y, x] == 0)
{
//Occupied Tile
if (level[y, x] == 1)
{

    // Now the render will mactch properly
//Empty Tile
if (level[x, y] == 0)
{
//Occupied Tile
if (level[x, y] == 1)
{

前进!到 Timer.Tick 处理程序:

#region Timer function
// doing this could cause flickering
// or flashing if the paint fires while
// we're updating things
level[_x, _y] = 0;

#region Timer function
// instead, keep track temporarily
// what they were - we'll come back to this later on
var oldX = _x;
var oldY = _y;

另外到的if / else链:

Further on to the if/else chains:

// There's a lot of replication and style choices here that
// will make it harder to debug/troubleshoot 
if (_objDirection == Direction.Right)
{
    if (_x < _boardWidth - 1 && _x >= 0 && _x + 1 < _boardWidth - 1 && _x + 1 >= 0)
        _x += 1;
    else
        _x = _boardWidth - 1;
}
else if (_objDirection == Direction.Left)

让我们看看我们是否能摆脱一些重复的:

Let's see if we can get rid of some of the repetition:

// let's figure these out ahead of time
var spaceOnLeft = _x > 0;
var spaceOnRight = _x < _boardWidth - 1;
var spaceOnTop = _y > 0;
var spaceOnBottom = _y < _boardHeight - 1;

// switch is a bit like the if/else construct you had
switch (_objDirection)
{
    case Direction.Up:
        // this means: if(spaceOnTop) y = y-1 else y = height-1
        _y = spaceOnTop ? _y - 1 : _boardHeight - 1;
        break;
    case Direction.Down:
        _y = spaceOnBottom ? _y + 1 : 0;
        break;
    case Direction.Left:
        _x = spaceOnLeft ? _x - 1 : _boardWidth - 1;
        break;
    case Direction.Right:
        _x = spaceOnRight ? _x + 1 : 0;
        break;
}

跳到结束......

Skip to the end...

// now we'll use the old position to clear...
level[oldX, oldY] = 0;
// then set the new position
level[_x, _y] = _k;

// Since we're only writing on the panel,
// we only need to rerender the panel
panel1.Refresh();

最后一个位 - 按键后处理:

One last bit - the key down handler:

// Hah - artificial difficulty due
// to awkward key choice? Out of curiosity,
// why not Keys.Up, Down, Left, Right?
if (e.KeyCode == Keys.E)
{
    _objDirection = Direction.Left;
}
else if (e.KeyCode == Keys.D)
{
    _objDirection = Direction.Right;
}
else if (e.KeyCode == Keys.W)
{
    _objDirection = Direction.Up;
}
else if (e.KeyCode == Keys.S)
{
    _objDirection = Direction.Down;
}

// same deal here, but with keys
    // Or switch to Up, Down, Left, Right :)
switch (e.KeyCode)
{
    case Keys.E: 
        _objDirection = Direction.Up;
        break;
    case Keys.D:
        _objDirection = Direction.Down;
        break;
    case Keys.W:
        _objDirection = Direction.Left;
        break;
    case Keys.S:
        _objDirection = Direction.Right;
        break;
}

全部code中的Form1.cs中类降:

Full code drop of the Form1.cs class:

//Listing all the parameters
public partial class Form1 : Form
{

    #region Declaring Parameters

    enum Direction
    {
        Left, Right, Up, Down
    }

    private int _x;
    private int _y;
    private int _k;
    private Direction _objDirection;
    Random rand = new Random();
    private int _boardWidth;
    private int _boardHeight;
    private int[,] level;

    #endregion

    //Giving values to parameters
    public Form1()
    {
        InitializeComponent();

        #region Initialial values

        _k = 1;
        _boardWidth = 6;
        _boardHeight = 6;
        _x = rand.Next(0, _boardWidth - 1);
        _y = rand.Next(0, _boardHeight - 1);
        _objDirection = Direction.Left;

        //Array that works as a board or platform which we used to distinguish tiles
        level = new int[_boardWidth, _boardHeight];
        #endregion
    }

    //Paint is used for drawing purposes only
    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        /*
               int[,] level = {
                               { 0, 0, 0, 0, 0 ,0 },
                               { 0, 0, 0, 0, 0 ,0 },
                               { 0, 0, 0, 0, 0 ,0 },
                               { 0, 0, 0, 0, 0 ,0 },
                               { 0, 0, 0, 0, 0 ,0 },
                               { 0, 0, 0, 0, 0 ,0 },
                           };
        */
        #region Looping through tiles

        //Initializing first randomly filled tile
        level[_x, _y] = _k;

        for (int y = 0; y < _boardHeight; y++)
        {
            for (int x = 0; x < _boardWidth; x++)
            {
                //Empty Tile
                if (level[x, y] == 0)
                {
                    // Create pen.
                    Pen redPen = new Pen(Color.Red, 1);

                    // Create rectangle.
                    Rectangle redRect = new Rectangle(x * 50, y * 50, 50, 50);

                    // Draw rectangle to screen.
                    e.Graphics.DrawRectangle(redPen, redRect);
                }

                //Occupied Tile
                if (level[x, y] == 1)
                {
                    // Create solid brush.
                    SolidBrush blueBrush = new SolidBrush(Color.Blue);
                    // Create rectangle.
                    Rectangle rect = new Rectangle(x * 50, y * 50, 50, 50);
                    // Fill rectangle to screen.
                    e.Graphics.FillRectangle(blueBrush, rect);
                }
            }
        }
        #endregion
    }

    //Responsible for movements
    private void tmrMov_Tick(object sender, EventArgs e)
    {
        #region Timer function
        // instead, keep track temporarily
        // what they were
        var oldX = _x;
        var oldY = _y;

        // let's figure these out ahead of time
        var spaceOnLeft = _x > 0;
        var spaceOnRight = _x < _boardWidth - 1;
        var spaceOnTop = _y > 0;
        var spaceOnBottom = _y < _boardHeight - 1;

        // switch is a bit like the if/else construct you had
        switch (_objDirection)
        {
            case Direction.Up:
                // this means: if(spaceOnTop) y = y-1 else y = height-1
                _y = spaceOnTop ? _y - 1 : _boardHeight - 1;
                break;
            case Direction.Down:
                _y = spaceOnBottom ? _y + 1 : 0;
                break;
            case Direction.Left:
                _x = spaceOnLeft ? _x - 1 : _boardWidth - 1;
                break;
            case Direction.Right:
                _x = spaceOnRight ? _x + 1 : 0;
                break;
        }

        // now we'll use the old values to clear...
        level[oldX, oldY] = 0;
        // then set the new value
        level[_x, _y] = _k;
        #endregion
        panel1.Refresh();
    }

    //Event Handler (W,A,S,D) is used for movements
    private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
        #region Controls

        // same deal here, but with keys
        switch (e.KeyCode)
        {
            case Keys.Up:
                e.IsInputKey = true;
                _objDirection = Direction.Up;
                break;
            case Keys.Down:
                e.IsInputKey = true;
                _objDirection = Direction.Down;
                break;
            case Keys.Left:
                e.IsInputKey = true;
                _objDirection = Direction.Left;
                break;
            case Keys.Right:
                e.IsInputKey = true;
                _objDirection = Direction.Right;
                break;
        }
        #endregion
    }
}

干杯!

阅读全文

相关推荐

最新文章