When a specific condition is met I disable my picturebox and the image freeze's, whenever it runs again the gif starts all over again not from where it was stopped is there anyway to resume it ?
Stopping picturebox : http://prntscr.com/b6gg7a
"Resuming" picturebox : http://prntscr.com/b6gglb
I believe indeed this is a rather tedious/unlikely to perform with an animated gif.
What you could/should do IMO is the following:
Instead of making the background a gif, break it into multiple frames(pictures).
Set up a timer that triggers the background to change to the next image.
You can pause and resume that timer the same as you would enable and disable the picturebox.
Your background change function could look something like this:
int bgCount = 8; //Amount of frames your background uses
int bgCurrent = 0;
string[] bgImg = {
"bg1.png",
"bg2.png",
"bg3.png",
"bg4.png",
"bg5.png",
"bg6.png",
"bg7.png",
"bg8.png",
};
void changeBG()
{
if(bgCurrent > bgCount-1) //If not displaying the last background image go to the next one
{
bgCurrent++;
imgBox.image = bgImg[bgCurrent];
}else //If displaying the last background image -> Start with the first one
{
bgCurrent = 0;
imgBox.image = bgImg[bgCurrent];
}
}
}
And you just let the timer trigger this event. And you simply start and stop the timer.
Sidenote:
1* You might experiment with, instead of changing the source, just make 8 imageboxed and call/display them as they are needed.
Related
I have a simple goal for my Unity application running on Android: create a function, which disables my GUI, creates a screenshot, stores the image and enables the GUI again.
This is my current code:
The whole UI is stored in a GameObject which my handler class holds as property:
private bool makeScreenshotFlag;
public GameObject UserInterface;
makeScreenshotFlag above is used in the Update function:
// Update is called once per frame
void Update()
{
if (makeScreenshotFlag)
{
// Working with this flag is necessary,
// since we need to wait for the next frame,
// where the gui is not visible;
MakeScreenShot();
}
}
If the corresponding button gets pressed I fire the following Method:
public void OnCreateScreenshotButtonPressed()
{
UserInterface.SetActive(false);
makeScreenshotFlag = true;
}
And at last the method for the screenshot itself:
private void MakeScreenShot()
{
if (UserInterface.activeSelf) return; // wait for the next frame if the gui is still active
try
{
string filename = "screenshot_" + DateTime.Now.ToString("HH-mm-ss--dd-MM-yyyy") + ".png";
ScreenCapture.CaptureScreenshot(filename);
}
catch (Exception e)
{
DebugHelper.NewLog = "Error capturing screenshot: " + e.Message;
}
finally
{
makeScreenshotFlag = false;
UserInterface.SetActive(true);
}
}
In theory this should work, however the documentation for ScreenCapture.CaptureScreenshot() states the following:
The CaptureScreenshot returns immediately on Android. The screen capture continues in the background. The resulting screen shot is saved in the file system after a few seconds.
In practice this means, when my screenshot is made, the GUI is already enabled again. So far I couldn't find any event or similar to get notified as soon as the screenshot is made. The only thing I can think of is to store the screenshot filename and check if the file exists each frame after the screenshot is started.
Is there any other, more practical way?
Most probably, you are capturing the frame with UI itself. It's better to wait till the end of the frame using Coroutine.
public IEnumerator MakeScreenShot()
{
// Wait till the last possible moment before screen rendering to hide the UI
yield return null;
// Disable UI
UserInterface.SetActive(false);
// Wait for screen rendering to complete
yield return new WaitForEndOfFrame();
// Take screenshot
Application.CaptureScreenshot("screenshot.png");
// Show UI after we're done
UserInterface.SetActive(true);
}
I have an activity indicator on my Page called indicator.
I want to Animate it, so that it cycles through every color. For this i'm using this method:
public static async Task ActivityIndicatorRainbow(ActivityIndicator indicator, int colorDelay)
{
for (double i = 0; i < 1; i += 0.01)
{
Color c = Color.FromHsla(i, 0.5, 0.5);
indicator.Dispatcher.BeginInvokeOnMainThread(()=> indicator.Color = c);
await Task.Delay(colorDelay);
}
}
And in my ButtonPressed Method i call that using this:
activityIndicator.IsRunning = true;
await Task.Run(() => ActivityIndicatorRainbow(activityIndicator, 10));
On Android this works fine, the Indicator spins while changing colors. But on iOS the Indicator stands still until the Rainbow Task finishes and then it starts spinning.
I have already tried Device.InvokeOnMainThreadAsync() with the same results
I have tested in iOS Native Develop Tools (Xcode) by using Objective-C to change color each time less than 1 second, it occurs the same phenomnenon with Xamarin Forms . Then I think ActivityIndicator in iOS not supports changing color each time less than one seconds .
Therefore ,the easy way to make it work is to modfiy code as follow with every one second to change color :
activityIndicator.IsRunning = true;
await Task.Run(() => ActivityIndicatorRainbow(activityIndicator, 1000));
If need to less than one second to change color in iOS ,you can have a try with custom renderer to custom a ActivityIndicator by using Navtive mtethod CADisplayLink or DispatchSource.Timer .
my code for my game had a paint system where is draws then redraws a car (or a box) every 50 ticks. i have really bad flickering when running the code (even when not moving) anything else you need i can grab :)
i have tried:
-Double buffering
-Putting everything into a panel and refreshing that
//My Paint Code
Bitmap greenCar = new
e.Graphics.FillRectangle(car.getDrawingbrushColor(),
car.getCarposition());
e.Graphics.DrawImage(greenCar,car2.getCarposition());
}
my timer code
scoreTimer.Tick += new EventHandler(Tick2);
scoreTimer.Interval = 100;
scoreTimer.Start();
DoubleBuffered = true;
My Refresh Code
{
this.Counter.Text = Scorecounter.ToString();
Scorecounter += 1;
panel1.Refresh();
}
i just dont want it to flicker, i is really holding me back.
I know that there are lot of different threads about horizontal text animation/text scrolling, but unfortunately none of them give smooth scrolling with repeatable text. I have tried double/thickness animation using various WPF controls containing text. Also tried animating with visual brush which gives me by far the most elegant scrolling compared to other approaches (for e.g. playing with Canvas.Left property etc.) but that too goes blur the text, if the text length or the animation speed is too high.
I'm over to a pure DirectX C# implementation using SharpDX library. Should also mention that I'm a beginner with DirectX programming. Here is the code:
public void RunMethod()
{
// Make window active and hide mouse cursor.
window.PointerCursor = null;
window.Activate();
var str = "This is an example of a moving TextLayout object with no snapped pixel boundaries.";
// Infinite loop to prevent the application from exiting.
while (true)
{
// Dispatch all pending events in the queue.
window.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);
// Quit if the users presses Escape key.
if (window.GetAsyncKeyState(VirtualKey.Escape) == CoreVirtualKeyStates.Down)
{
return;
}
// Set the Direct2D drawing target.
d2dContext.Target = d2dTarget;
// Clear the target.
d2dContext.BeginDraw();
d2dContext.Clear(Color.CornflowerBlue);
//float layoutXOffset = 0;
float layoutXOffset = layoutX;
// Create the DirectWrite factory objet.
SharpDX.DirectWrite.Factory fontFactory = new SharpDX.DirectWrite.Factory();
// Create a TextFormat object that will use the Segoe UI font with a size of 24 DIPs.
textFormat = new TextFormat(fontFactory, "Verdana", 100.0f);
textLayout2 = new TextLayout(fontFactory, str, textFormat, 2000.0f, 100.0f);
// Draw moving text without pixel snapping, thus giving a smoother movement.
// d2dContext.FillRectangle(new RectangleF(layoutXOffset, 1000, 1000, 100), backgroundBrush);
d2dContext.DrawTextLayout(new Vector2(layoutXOffset, 0), textLayout2, textBrush, DrawTextOptions.NoSnap);
d2dContext.EndDraw();
//var character = str.Substring(0, 1);
//str = str.Remove(0, 1);
//str += character;
layoutX -= 3.0f;
if (layoutX <= -1000)
{
layoutX = 0;
}
// Present the current buffer to the screen.
swapChain.Present(1, PresentFlags.None);
}
}
Basically it creates an endless loop and subtracts the horizontal offset. Here are the challenges: I need repeatable text similar to HTML marquee without any gaps, Would probably need to extend it to multiple monitors.
Please suggest.
I don't know neither how to use DirectX nor sharpdx, but if you want you can consider this solution
I had a similar problem a while ago, but with the text inside a combobox. After a bounty i got what i was looking for. I'm posting the relevant piece of code as an example, but you can check the complete answer here
Basically, whenever you have a textblock/textbox that contain a string that cannot be displayed completely, cause the length exceed the textblock/box lenght you can use this kind of approach. You can define a custom usercontrol derived from the base you need (e.g. SlidingComboBox : Combobox) and define an animation for you storyboard like the following
_animation = new DoubleAnimation()
{
From = 0,
RepeatBehavior = SlideForever ? RepeatBehavior.Forever : new RepeatBehavior(1), //repeat only if slide-forever is true
AutoReverse = SlideForever
};
In my example i wanted this behaviour to be active only when the mouse was on the combobox, so in my custom OnMouse enter i had this piece of code
if (_parent.ActualWidth < textBlock.ActualWidth)
{
_animation.Duration = TimeSpan.FromMilliseconds(((int)textBlock.Text?.Length * 100));
_animation.To = _parent.ActualWidth - textBlock.ActualWidth;
_storyBoard.Begin(textBlock);
}
Where _parent represent the container of the selected item. After a check on the text lenght vs combobox lenght i start the animation and end it at the end of the text to be displayed
Note that in the question i mentioned there are also other soltions. I'm posting the one that worked for me
One problem was solved, another followed: In a C#-program I use following method to set a labels color to green, then playing a mp3-file and finally setting the color back to black.
The problem is that the sound seems to be played in an extra thread, thus the time between the change of the two colors is too short (in fact, it should have the green color while the file is played).
private void playSound()
{
label1.ForeColor = Color.LimeGreen;
Application.DoEvents();
WMPLib.WindowsMediaPlayer wmp = new WMPLib.WindowsMediaPlayer();
wmp.URL = #"C:\examplesound.mp3"; // duration about 30s
wmp.controls.play();
label1.ForeColor = Color.Black;
}
Is there anything can be done to force the label to keep the green color whilst the mp3-file is played?
Don't set the colour back to black straight away as the playback is in another thread.
When the current track ends WMPLib sends out a PlayStateChange event.
So add a handler:
wmp.PlayStateChange += this.Player_PlayStateChange;
private void Player_PlayStateChange(int newState)
{
if ((WMPLib.WMPPlayState)newState == WMPLib.WMPPlayState.wmppsStopped)
{
label1.ForeColor = Color.Black;
}
}
The page for playState has a list of values:
8 - MediaEnded - Media item has completed playback.
You'll need to make sure this is done on the UI thread.
Try hooking the PlayStateChanged event and put the label1.ForeColor = Color.Black; in there.
At the moment there's nothing in your code saying that it should only change to black when it finishes, only after it has started to play.