点击它后,做一个图形变色? (像一个按钮?) [英] Make a graphic change color when I click on it? (Like a button?)

查看:157
本文介绍了点击它后,做一个图形变色? (像一个按钮?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须为我最后的学校项目重新制作游戏。该项目进展顺利,但我只是在一个部分,我需要游戏中的黑色瓷砖点击时改变颜色。我正在尝试重拍的游戏叫做Piano Tiles。要缩短故事,请观看以下内容: https://www.youtube.com/watch?v=4uZPiynHRsw [ ^ ]



那么当用户点击它时,如何让黑色瓷砖改变颜色?



*注意:我已经设置了刷子和数组准备好使用。



我添加了4个刷子代表游戏牌的颜色:



以下是变量名称

刷bsh_black,bsh_grey,bsh_white,bsh_red; 
刷bchanger1,bchanger2,bchanger3,bchanger4;
// 在Public Form1()下
bsh_black = new SolidBrush(Color.Black);
bsh_grey = new SolidBrush(Color.Gray);
bsh_white = new SolidBrush(Color.White);
bsh_red = new SolidBrush(Color.Red);
bchanger1 = bsh_white;
bchanger2 = bsh_white;
bchanger3 = bsh_white;
bchanger4 = bsh_white;







黑色 - 你要按的瓷砖

灰色 - 按下黑色瓷砖时

白色 - 你*不要按的瓷砖

红色 - 当你按下白色瓷砖时。



这是我到目前为止点击图片时所尝试的:

  if (eY == yf1)
{
if (eX == x2)
{
if (bchanger1 == bsh_black)
{
bchanger1 = bsh_grey;
Invalidate();
}
}
}

如果(eY == yf1
{
if (eX == x4)
{
if (pat_assign == pat4)
{
if (bchanger4 == bsh_black)
{
bchanger4 = bsh_grey;
Invalidate();
}
}
}
}





//yf1变量是黑色瓷砖的垂直位置。对于游戏,我决定将表单分成四列 - 我必须创建4个代表4列的变量; x1,x2,x3和x4。这些列是切片运行的位置。但是出于原型的目的,我使用x4作为临时虚拟变量。



因此,简而言之,如果用户点击的位置在同一位置作为yf1变量和x4变量,应将该特定磁贴更改为不同的颜色。不幸的是,那没有用。



PS:对不起,如果我之前对此不太清楚,我只是一名高中生。



**我很抱歉,我也忘了询问如何检测到图形被点击(在这种情况下是瓷砖)。

解决方案

看起来您已经知道如何使渲染图像无效;我只想补充一点,你可以通过使用 System.Windows.Controls.Invalidate 使用参数( Rectangle Region ):

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invalidate%28v=vs .110%29.aspx [ ^ ]。



不仅用固定画笔渲染你的图形,而且制作取决于您的游戏逻辑,取决于某些方法参数或字段。如果你更换刷子,下一次失效后,这件作品会改变颜色。



我在过去的答案中解释了它是如何工作的:

什么样的俏皮方法是Paint? (DataGridViewImageCell.Paint(...)) [ ^ ],

在面板上捕获绘图 [ ^ ],

mdi子表单之间的绘制线 [ ^ ]。



顺便说一下在游戏中,您通常使用执行游戏场景的其他(非UI)线程。这是您从线程更新图形的方法:如何加速我的vb.net应用程序? [ ^ ]。



-SA


恭喜您提出体面的问题! :thumbsup:

这是我见过的最清楚的问题之一。



无论如何,在你当前的代码中,你使用这种类型结构两次:

 如果(eY == yf1)
{
if (eX == x2)
{
// 等..





有问题!

eY和eX是精确值,yf1和x2等也是如此,因此只有在点击绘制图块的确切像素时才会运行您想要运行的代码。

单击中间的tile不会导致你当前的代码执行。



相反,试试这样的东西 - 我不知道你的瓷砖有多宽,但你得到的图片:

  if (eY  -  yf1 <  tileheight)
{
if (eX - x2 < tilewidth)
{
/ / 等..





而且,当你'重新使用它,使用&&运算符以节省空间:

 如果(eY  -  yf1  <  tileheight&& eX  -  x2 <  tilewidth)
{
// 等..





告诉我如果这有帮助: - )


这取决于你如何设置按钮。

如果它们只是带文本的按钮,Click事件只需要设置BackColor :

 button1.BackColor = Color.Black; 



如果它们是带有图像的按钮,它将是最好为您需要的不同颜色创建图像,并在Click事件上交换图像。



仅当您将用户控件作为子类时,使用画笔才有效按钮并覆盖OnPaint事件。在那里你将获得Button的Graphics对象,然后应用Brush颜色。要触发Paint事件,请在Click事件中调用

  .Invalidate(); 


I'm have to basically remake a game for my final school project. The project is progressing well, but I'm only stuck on a part where I need the black tiles in the game to change color when clicked. The game I'm trying to remake is called "Piano Tiles". To shorten the story, watch this: https://www.youtube.com/watch?v=4uZPiynHRsw[^]

So how can I make the black tile(s) change its color when a user clicks on it?

*Note: I already setup the brushes and arrays to be ready for use.

I added 4 brushes that represent the colors of the game tiles:

Here are the variable names

Brush bsh_black, bsh_grey, bsh_white, bsh_red;
Brush bchanger1, bchanger2, bchanger3, bchanger4;
//Under Public Form1()
bsh_black = new SolidBrush(Color.Black);
bsh_grey = new SolidBrush(Color.Gray);
bsh_white = new SolidBrush(Color.White);
bsh_red = new SolidBrush(Color.Red);
bchanger1 = bsh_white;
bchanger2 = bsh_white;
bchanger3 = bsh_white;
bchanger4 = bsh_white;




Black - tile you have to press
Grey - When the black tile is pressed
White - The tile you *don't* press
Red - When the you do press the white tile.

Here's what I've tried so far for clicking on the graphic:

if (e.Y == yf1)
            {
                if (e.X == x2)
                {
                    if (bchanger1 == bsh_black)
                    {
                        bchanger1 = bsh_grey;
                        Invalidate();
                    }
                }
            }

            if (e.Y == yf1)
            {
                if (e.X == x4)
                {
                    if (pat_assign == pat4)
                    {
                        if (bchanger4 == bsh_black)
                        {
                            bchanger4 = bsh_grey;
                            Invalidate();
                        }
                    }
                }
            }



//The "yf1" variable is the vertical location for the black tile(s). For the game, I decided to divide the form into four columns - where I had to make 4 variables that represent the 4 columns; "x1", "x2", "x3", and an "x4". These columns is where the tiles will run through. But for "prototype" purposes, I used the x4 as the temporary "dummy" variable.

So, in short, if where the user clicks is in the same location as the "yf1" variable and the "x4" variable, that should change that specific tile to a different color. Unfortunately, that didnt work.

P.S: sorry if I wasn't more clear about this earlier, I'm just a high school student.

**I am so sorry, I also forgot to ask how to detect that a graphic has been clicked on (in this case the tile).

解决方案

It looks like you already know how to invalidate the rendered image; I would only add that you can improve performance by invalidating only part of the scheme using System.Windows.Controls.Invalidate with parameters (Rectangle or Region):
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invalidate%28v=vs.110%29.aspx[^].

Render your piece of graphics not just with fixed brush, but make is depending of some method parameter or a field, depending on your game logic. If you change the brush, the piece will change the color after next invalidation.

I explained how it works in my past answers:
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^],
capture the drawing on a panel[^],
Drawing Lines between mdi child forms[^].

By the way, in games you normally use additional (non-UI) threads which executed your game scenario. This is how you update graphics from a thread: How to speed up my vb.net application?[^].

—SA


Congratulations for asking a decent question! :thumbsup:
This is one of the clearest questions I have ever seen.

Anyway, in your current code, you use this sort of structure twice:

if (e.Y == yf1)
{
   if (e.X == x2)
   {
      //etc..



There's the problem!
e.Y and e.X are exact values, as are yf1 and x2, etc, so the code that you want to run will only run if the exact pixel where the tile is drawn is clicked.
Clicking in the middle of the tile will not cause your current code to execute.

Instead, try something like this - I don't know how wide your tiles are, but you get the picture:

if (e.Y - yf1 < tileheight)
{
   if (e.X - x2 < tilewidth)
   {
      //etc..



And, while you're at it, use the && operator to save space:

if (e.Y - yf1 < tileheight && e.X - x2 < tilewidth)
{
   //etc..



Let me know if this helps :-)


It depends how you set up your buttons.
If they are just Buttons with Text the Click event just needs to set the BackColor:

button1.BackColor=Color.Black;


If they are Buttons with Images, it would be best to create the images for the different colours you need and swap the Image on a Click event.

Using Brushes only works if you make a user control as a subclass of Button and override the OnPaint event. There you would get the Graphics object of the Button and then apply the Brush color. To trigger the Paint event, in the Click event call

this.Invalidate();


这篇关于点击它后,做一个图形变色? (像一个按钮?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆