So a new concept came to mind of timing an operation within the code behind of a page. I am presenting a slideshow of sorts, and every few seconds I would like to rotate the images on a page from left to right. What I want to do is place a pivot control in a page, insert the images into each PivotItem, and every 3 seconds set the SelectedItem index of the Pivot control to the next available index, and repeat continuously.
How might I time the operation to change the selected PivotItem indices?
EDIT
Constructor
// DispatcherTimer setup
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0,0,3);
dispatcherTimer.Start();
How to set up event handler to continuously rotate PivotItems?
A DispatchTimer object. This will ensure that when your Tick callback is called it is called on the UI thread and you can perform actions on page controls without causing an exception
Related
Right now I'm building a simulation of a sports match, played in 2 linear halves, divided in 2 separate scenes. Goals that have been scored in-match appear as a button on the stage as scoring occurs. The button works as a reference to replay the goal. Goals scored in let's say the first half (scene 1) should be accessible to replay whilst in the second half (scene 2).
I've created extra scenes per goal that serve as individual replays to refer to.
What I would like to have the user be able to, is to click that replay button at any chosen time, view the replay, and then return to the exact frame it originally jumped from, and play on from there when preferred.
The reason why I 'cannot' use movieClips and addChild methods, is that I want the final SWF to keep its transparent background, as I will embed it in html later on.
If (and how?) I use the addChild method, you see 2 partially transparent movieClips on top of each other, running at the same time.
If I'd find out how to replace the one with the other, this could be suited method.
Another would be using currentFrame and/or currentLabel methods I guess but I wouldn't know how to.
I have the project .fla file to give you a clearer insight on things.
Let's assume you have a replay button with the instance name of replayBtn. Here is one way to set this up:
On the first frame of your timeline, create the following vars and functions:
//define a variable to hold the last replay frame
var lastReplayFrame:int = 0;
//define a variable to hold the frame to go back to once a replay is done
var replayReturnFrame:int = 0;
//create a function to call after a replay is done
function replayReturn(){
//if we've set a frame to jump back to
if(replayReturnFrame > 0){
//go there and resume playing
this.gotoAndPlay(replayReturnFrame);
//reset the return frame so we don't go back there the next time if the button isn't hit
replayReturnFrame = 0;
}
}
//create the click handler for the replay button:
function replayClick(e:Event):void {
//check if there is a replay available
if(lastReplayFrame > 0){
//store the current frame before jumping back
replayReturnFrame = this.currentFrame;
gotoAndPlay(lastReplayFrame);
}
}
//add the click event listener to the replay button instance
replayBtn.addEventListener(MouseEvent.CLICK, replayClick);
Now, in your timeline, whenever a goal starts (eg the first frame of where a replay should start), put the following code on a keyframe:
lastReplayFrame = this.currentFrame;
Then, on the last frame of a replay, put this code on a keyframe:
replayReturn();
I'm seeing an excessive paint operation which is taking over 1 second to render in Google Chrome. Is there any way for me to diagnose further what the root cause is? I can see that it's caused by lots of calls to "update layer tree", but I'm not sure where to go from here. The code is just replacing some innerHTML on a single DOM node handled in a scroll event, so I would expect a single recalculate style and then a single paint, why would i see all these update layer tree and separate paint calls?
You can delay the update on the scroll event by using a so-called debouncing, or, delaying the update until a timeout occur using a timer that is reset every time an event is received:
Example
There is no code shown so this is just a general approach. Implement as needed:
var timerID = null; // for the timer. must be in parent or global scope
window.addEventListener("scroll", function() {
clearTimeout(timerID); // clear current running timer (none is ok!)
timerID = setTimeout(update, 150); // set new timer, here with 150ms timeout
});
function update() {
// do the update here
}
Every time the page is scrolled, an scroll event is broadcast and received in the handler.
If the timer is still running it will be reset, a new timer invoked.
If the scroll event takes more than 150ms (in this case, tweak as needed), the actual update is performed.
This will allow the browser to broadcast a bunch of events without spawning a bunch of updates. In your case the update will affect the DOM tree and paint so it is best to reduce it to an absolute minimum.
I can't for the life of me get the following functionality to work:
User taps item
Item's image becomes visible via changing visibility property of image
After a short period of time image becomes invisible again (with no user input) via changing the
visibility property
Or, more simply:
Make visible UI change
Pause so user can see UI change
Reverse step 1's UI change
Step 2 happens before steps 1 and 3 regardless of where the code is because the UI is not updating until the logic finishes (I assume).
I am setting the visibility of the image via data binding with INotifyPropertyChanged. All works as expected except when I'm trying to introduce the pause.
I'm trying to pause with this simple method:
private void Pause()
{
new System.Threading.ManualResetEvent(false).WaitOne(1000);
}
It does pause, but the UI changes wait until after that pause even though a change to the bound data happen befores the pause is called, and the other change after.
I have tried using the dispatcher, but it doesn't change anything, and I don't understand it enough:
await dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
{
clickedCard.IsFaceDown = false; // makes the image visible via data binding
}
);
Pause();
I think I need to do something with threading, but I am going in circles.
Any ideas?
You should never do something like this inside the UI thread of your app:
new System.Threading.ManualResetEvent(false).WaitOne(1000);
There are various reasons for not doing it, but in your particular case the problem is that XAML only re-draws once your event-handler completes. So basically this happens:
The item is invisible
Your event handler is called
You set it to visible (but the UI doesn't refresh yet)
You freeze the thread for a second
You set it to invisible again
The event-handler completes
Now the UI updates based on the current value (which is invisible)
I suggest you look at building a Storyboard to do this - Blend can help. See here.
Is posible something like this: in frame1 I have some user interaction (drag drop graphics etc), when user click some button I open frame2 or frame3 where are fields for taking some input from user, then when user finish, I back him to frame1 but frame is not "reset"? I tried what described here, and I can even send data from frame 2 to frame 1 using global vars, but frame 1 is "reset" all user actions are clean, so is there a way in this situation to keep frame1 in memory or something?
Previous or next go to a frame if the frame is being initialized is natural. There's no way to save it. In other words, move the frame is The following concepts, removeChild(previous-stage), addChild(next-stage)
In my experience, the script code to control the frame, increasing complexity are highly undesirable. Maintenance is difficult and in the future, the readability of the code is very poor. Recommend to handle than that in a single frame. Something like a single frame of the object location, size, status, and stored as a variable because it can restore it, it's more reasonable to think that.
If you are working with Flash & AS3 together you can put the code:
gotoAndStop(3); // 3 is the number of the frame
If you are using:
gotoAndPlay(3); // it will begin to play the frames from 3 till the timeline finds a stop mark.
So, you'll need to put a stop on the frame you want.
e.g. stop();
check out this tutorial: http://www.youtube.com/watch?v=9N9vE7wjoc4
I'd like to make a simple game where "discs" fall from the top of the screen and the user must catch them. I have a MovieClip which I want to resize to one of three randomly chosen sizes.
As I see it, there are four things that must be done.
Create and size the MovieClip
Position the MovieClip
Make the MovieClip fall
Determine when it is finished "falling" and see if the user has "caught" it.
My question is: How do I create, size and position the MovieClip? I've given it an identifier of "disc". Now what? Do I make an ENTER_FRAME event and do my creation there? How do I move the disc downwards? Do I use tweens, something else?
I'm primarily asking this as a sanity check.
I would use some kind of factory class that would be responsible for dropping random discs from the top of the stage.
Beside what you correctly mentioned, you will also need to:
define if the speed for falling is constant or not, you may need some acceleration tween. To move the objects downwards, you could use a native tween method, you will need to apply it to every disk that gets dropped.
define where the disk will start falling, it can be random or always from the same place.
you can find out if two objects are colliding using the AS3 hitTestObject method which belongs to the DisplayObject class.
you factory class could have a start() and stop() method. Once start() is fired, an infinite or ENTER_FRAME loop is started and disks start falling. If you want to create disks at a specific rate you could combine your loop with a timer to run code on a defined interval. For instance, every 3 seconds create 10 disks (using main loop) and drop them onto the stage.
Assuming that you have MovieClips named 'disc' & 'userHand' exported into actionscript, I'll summarize it in the foll way:
Generate the no of discs & Randomize their location. Start with something like:
var n:int = 30; //Total no of Discs
for(i:int=0;i<n;i++)
{
var mc:disc = new disc();
mc.x=Math.random()*stage.width(); //to scatter the discs across the stage
mc.y=-mc.height; //initially hide out a disc
addchild(mc);
}
Also add the Movie clip 'userhand' to stage.
Add enterframe handler function.
Fill in the enterframe handler to update (keep increasing) the y position of each disc.
Use hitTestObject() in the enterframe handler to determine hit among each 'disc' & 'userHand'.
Reset position of all the 'disc' clips which fall off the screen to random positions as initially.
You might want to look at programming particles.
http://r3dux.org/2010/01/actionscript-3-0-particle-systems-3-rain-effect/
At a very high level what you would do is.
You need to create a disc class.
You could give this class some variable properties like width, height,x etc.
In an enter frame in your main class you would add an enterframe function that creates new instances of disc passing it random values for each property.
Each instance of disc could also have its own entframe which increases its y position until it reaches the bottom of the screen. The disc would then remove its self from the stage. You could use an easing function passing it a random number to determine the rate at which its falls.
Say if its y position is greater than the stage height, remove the disc. If the user catches it (using a hit test maybe) also remove it.
It really recommend having a look at that link I posted.