更新一个对象的图像属性,每个计时器滴答c#
本文关键字:计时器 滴答 一个对象 图像 属性 更新 | 更新日期: 2023-09-27 18:14:30
我有一个精灵类,它有一个绘制爆炸的方法。这个类有一个image属性,用来作为将要绘制的图像。
我希望有这样的图像,即绘制是改变每5秒左右。
我的问题是:使用计时器控制,我怎么能编码它,使图像属性改为不同的图像每tick?
例如:Image 1 '5 seconds'> Image 2 '5 seconds'> Image 3 '5 seconds'> remove Image .
下面是绘制方法:
public void DrawExplosion(Graphics graphics)
{
graphics.DrawImage(explosion_, xPos_, yPos_);
}
和类
的Image属性 public Image Explosion
{
get {return explosion_;}
set {explosion_ = value;}
}
感谢您的帮助/指导。
我注意到我的回答对于这个简单的问题来说太复杂了。虽然我不认为这是不正确的,但我确实认为这使问题复杂化了。我想把它留在那里,以防别人发现它有用。但这里有一个简单的尝试。它使用了Sprite类外部的计时器、按钮和面板。我希望这对你有帮助。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace CustomControl
{
public partial class Form1 : Form
{
Sprites Explosion = new Sprites();
public Form1()
{
InitializeComponent();
//insert your images in this next line
Explosion.Images=new Image[]{Properties.Resources.explode1,Properties.Resources.explode2,Properties.Resources.explode3};
Explosion.ImageIndex = 0;
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
//Draw the first image right away
Explosion.Draw(panel1.CreateGraphics(), 0, 0);
//set the index to the next image
Explosion.ImageIndex++;
}
private void timer1_Tick(object sender, EventArgs e)
{
//if the Imageindex is not greater then the number of images
if (Explosion.ImageIndex < Explosion.Images.Count() )
{
Explosion.Draw(panel1.CreateGraphics(), 0, 0);
Explosion.ImageIndex++;
}
//if it is greater then reset the imageIndex and turn off the timer
else
{
Explosion.ImageIndex = 0;
timer1.Enabled = false;
//Clear your images, however you need to do that
panel1.CreateGraphics().Clear(Color.White);
}
}
}
public class Sprites
{
public Image DisplayedImage { get { return Images[ImageIndex]; } }
public int ImageIndex;
public Image[] Images;
public void Draw(Graphics graphics, int x, int y)
{
graphics.DrawImage(DisplayedImage, x, y);
}
}
}
如果我的猜测是正确的,并且你正在编写一款游戏,那么你可能不希望在这里使用计时器。有很多关于游戏循环编程的文章都适合你的场景。
它们基本上将你的屏幕元素(这里是一个精灵)的逻辑更新从渲染中分离出来,并使用OS钩子来保持高性能。
编辑:我在下面添加了另一个答案。我发现这个答案对于这个问题来说太复杂了。
JRoughan可能是对的,可能有更好的方法来做到这一点。但根据你的要求,我写了一个类,将采取图像你提供和绘制他们一个时间到图形对象,然后清除图形对象。
我在一个方法中实例化了类,所以不能保证它不会超出作用域并在完全运行之前被收集,为了防止这种情况,你可能想让它成为全局的,然后每次你想使用它时都重新实例化它,用新的图像。但是如果你调用它两次,第一次就会丢失,所以我发现这个方法更好,它取决于上下文,你打算一次使用多少不同的动画等等。我还添加了一个ImageindexChanged事件,该事件可用于知道图像何时在类外更改。享受吧!我希望这就是你要找的。
我只是添加了一个按钮和一个面板。将按钮的click事件绑定到Button1_Click方法
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace CustomControl
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//insert your images in this next line
}
private void button1_Click(object sender, EventArgs e)
{
Image[] explodingImages = new Image[] { Properties.Resources.explode1, Properties.Resources.explode2, Properties.Resources.explode3 };
//initialize the explosion with the images from above
Sprites Explosion = new Sprites(explodingImages,panel1.CreateGraphics());
//the timer will start and it will draw all images from the above collection, then clear itself, then dispose of itself.
Explosion.ImageIndex = 0;
}
}
public class Sprites
{
private Image _DisplayedImage;
public Image DisplayedImage
{
get { return _DisplayedImage; }
}
private Image[] Images{get;set;}
private int _ImageIndex = 0;
public event EventHandler ImageIndexChanged;
public int ImageIndex
{
get { return _ImageIndex; }
set
{
//Changes thh ImageIndexNumber
_ImageIndex = value;
//Updates the Displayed Image with the current Image as per index
_DisplayedImage = Images[ImageIndex];
//fires the ImageIndexChanged Event (if required)
if (ImageIndexChanged != null)
ImageIndexChanged(this, EventArgs.Empty);
//draws the explosion to the graphics object
DrawExplosion(G, 0, 0);
//starts the timer
changeImageTimer.Enabled = true;
}
}
//local variable for the graphics object
private Graphics G;
//creats a timer for changing the Images
Timer changeImageTimer = new Timer();
//Constructor
public Sprites(Image[] images,Graphics g)
{
//set the starting Images
Images = images;
//set the interval time to 5 seconds- in my opinion this number is rediculously high, but if that is what you want
changeImageTimer.Interval = 5000;
//Get the Tick event of the timer
changeImageTimer.Tick += new EventHandler(changeImageTimer_Tick);
//set the Graphics that you want to draw on
G = g;
}
void changeImageTimer_Tick(object sender, EventArgs e)
{
int temp=ImageIndex+1;
//if there are no more pictures to display stop the timer
if (temp > Images.Count() - 1)
{
//stop the timer
changeImageTimer.Enabled = false;
//Clear the image, replace with your own background color, or draw an image or whatever you need to do to clear the images
G.Clear(Color.White);
}
//if there are more pictures select the next picture
else
//Changeing the imageindex fires the draw method and the imageindexchanged event
ImageIndex++;
}
public void DrawExplosion(Graphics graphics,int x, int y)
{
graphics.DrawImage(DisplayedImage, x, y);
}
}
}