My question is as follows. In most tutorials that I've seen there is a setup part of DirectX11 where you do something like this:
// Set the refresh rate of the back buffer.
if(m_vsync_enabled)
{
swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator;
swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator;
}
else
{
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
}
Which either sets the refresh to be as fast as possible or synched with the monitor.
However in the application that I need I only want to refresh the screen when I tell the system to do it. Is there any way to do this?
These numbers have nothing to do with the actual refreshing, which happens when you invoke Present. You can call it once per second and screen will be refreshed just once.
Related
Can Any one help Me on How to Implement on Handling Pagination on Scrolling of listview in xamarin.android .any link or any sample wil be helpful
Well, Android pagination is quite easy in comparison to iOS and can be done as follows:
public class EndlessScrollListener : Java.Lang.Object, Android.Widget.AbsListView.IOnScrollListener
{
private int visibleThreshold = 5;
private int currentPage = 0;
private int previousTotal = 0;
private bool loading = true;
public EndlessScrollListener()
{
}
public EndlessScrollListener(int visibleThreshold)
{
this.visibleThreshold = visibleThreshold;
}
public void OnScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
if (loading)
{
if (totalItemCount > previousTotal)
{
loading = false;
previousTotal = totalItemCount;
currentPage++;
}
}
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold))
{
// I load the next page of gigs using a background task,
// but you can call any function here.
//new LoadGigsTask().execute(currentPage + 1);
loading = true;
}
}
public void OnScrollStateChanged(AbsListView view, [GeneratedEnum] ScrollState scrollState)
{
// throw new NotImplementedException();
}
}
Then set it to the listview as follows:
List.SetOnScrollListener(new EndlessScrollListener());
Working of code:
visibleThreshold – The minimum amount of items to have below your current scroll position, before loading more.
currentPage – The current page of data you have loaded.
previousTotal – The total number of items in the dataset after the last load.
loading – True if we are still waiting for the last set of data to load.
Next, we have a couple of constructors that allow us to set the visibleThreshold inline if we want.
The first overridden method we have is called every time the list is scrolled. This happens many times a second during a scroll, so be wary of the code you place here. We are given a few useful parameters to help us work out if we need to load some more data, but first, we check if we are waiting for the previous load to finish.
If it’s still loading, we check to see if the dataset count has changed, if so we conclude it has finished loading and update the current page number and total item count.
If it isn’t currently loading, we check to see if we have breached the visibleThreshold and need to reload more data. If we do need to reload some more data, we execute a background task and set the loading flag to true. Thus solving the problem forever!
The last method in the class we do not need, however, if you’re interested, it is primarily used for tracking changes in the scroll action itself via the scrollState parameter.
Finally, the code to call the class creates a new instance of EndlessScrollListener and bind’s it to a ListView of mine. Of course, put your own ListView in place of List.
I have 3 SkSpriteNodes: A man a background and a groundType. These are all pngs and sit ontop of each other to create a scene. I add them using addChild by adding the background then the groundType and then the man. This works fine. When the user gets to the end of the screen I erase all except the man and change the background and the groundType. Similar to the way Pitfall works. When I remove them and add them back in they appear in wrong order. I call cleanScreen() then loadBackground() then loadLevelType(). Which you would think would add the background then the level type. What I see instead is leveltype below then background, so you can't see the level type. Even if I switch the order of the functions this still happens. I cannot seems to find anywhere that gives me information on how the ordering of sprites work when removed and added back in. It seems inconsistent. I have thoroughly read the docs for Obj-C and I also tried using insertChild:atIndex but that did not seem to work for me either.
...
cleanScreen()
loadBackground()
loadLevelType()
...
func cleanScreen() {
levelType.removeFromParent()
bg.removeFromParent()
}
func loadBackground() {
var bgNum = currentLevelData["bg"]! as String // resolves to "2"
bg = SKSpriteNode(imageNamed: "bg_\(bgNum)")
bg.name = "bg"
scene.addChild(bg)
}
func loadLevelType() {
var levelTypeInfo = currentLevelData["type"]! as String // resolves to "lake"
levelType = SKSpriteNode(imageNamed: levelTypeInfo)
println(levelTypeInfo)
levelType.name = "level_type"
levelType.position.y = -140
scene.addChild(levelType)
}
When I loop over scene.children the object are in the correct order. I have never played around with zPosition before. The names come back as:
man
bg
level_type
But they appear on screen as man level_type bg. I added opacity to the background and I see now for sure that they are not being rendered in the correct order now that I can see through the background.
First off, as a disclaimer, I am new to objective-c, xcode, and cocos2d. I have found a way in my app to refresh a screen conveniently, but I don't know if it is bad practice. Here's what I am doing. I have a class called Player with a variable NSString *name. I am displaying this and several other variables on the screen using this code in a function:
label = [CCLabelTTF labelWithString:string fontName:GLOBAL_FONT fontSize:font_size ];
label.color = color_back;
label.position = ccp(x+1, y-1);
[self addChild:label];
When a button is pressed, I am modifying player->name along with several other variables. Because several variable are changing (on this screen and eventually others) when the button is pressed I also set a flag to indicate that the screen needs to be refreshed. I then check this code with a scheduler:
if(panelPrev != currentPanel || refreshScreen) //do we need to initialize the panel?
{
[self removeAllChildrenWithCleanup:true]; //clear all objects from display
//Decide which objects to display
switch (G_display_panel) {
case P_Main:
[Display_Main init_Panel:self];
break;
case P_NewGame:
[Display_New init_Panel:self];
break;
default:
break;
}
refreshScreen = false;
}
My first question: Is this an acceptable way to display things to the screen and refresh them? It seemed much more convenient than updating every variable that is being displayed. The buttons are not being pressed very often so I am not concerned about performance.
Second: If it is ok to do it this way, why is it that when I press a button and change the value of player->name I am getting this: "Thread 1: EXC_BAD_ACCESS (code=1, address=...)"? If I step through with the debugger the value gets assigned to player->name correctly and the screen refresh works. But if I just let it run it gets the EXC_BAD_ACCESS when I try to access player->name and the data looks corrupted (e.g. (NSString *) name = 0x15927f80 when I am expecting (NSString *) name = #"Bob").
Some additional details.
I am not setting refreshScreen to 'true' until after changing the value of player->name
To prevent refreshing before the value was truly changed, I set a delay on the refresh. After the button was pressed I would modify player->name and wait about 10 seconds but I would still see the same problem.
Any ideas? Thanks.
try this:
[self addChild:label];
I figured out the problem. It was a memory management issue. I added a getter and setter for the variable using the example specified here: developer.apple.com/library/mac/documentation/Cocoa/Conceptual/… –
I have a scroll bar ( fl.controls.UIScrollBar ), which i create dynamically in a class, and add it to the stage.
public class Slider extends Sprite
{
private var scroll:UIScrollBar = new UIScrollBar();
// etc.
// constructor
addChild(scroll);
scroll.setSize(15.75, 205.3);
scroll.direction = ScrollBarDirection.HORIZONTAL;
scroll.setScrollProperties(150, minScrollPos, maxScrollPos,snapInterval);
scroll.addEventListener(ScrollEvent.SCROLL, scrollHandler);
}
Then, I try to call
scroll.scrollPosition = 30;
My method call will not update the scroll thumb.Any ideas why?
Salut Mihai,
I found that odd at first. I expected setting the value would suffice.
If I set scrollPosition in an enter frame loop, it works, but not if I use the setter straight away. This probably means that if you make the calls right after creating/setting up the component, internally, it's not ready yet. UIComponents(like UIScrollBar) have a whole lifecycle to deal with. Jeff Kamerer has a nice set of devnet articles on this, if you're interested.
Long story short, the component is not ready right away, so the best bet is to wait for it to be ready by listening to the RENDER event:
scroll.addEventListener(Event.RENDER,rendered);
function rendered(event:Event):void {
scroll.removeEventListener(Event.RENDER,rendered);
scroll.scrollPosition = 30;
}
I'm just going to explain the context so it is clearer.
I made this menu : my menu
I am looking to make an improved and more advanced version of the same menu.
I made an animation of waves on the cofee's surface and am looking to make it loop when the mouse is moving and to stop looping when it's not.
Sorry for the lack of specifications as I am quite new to actionscript, but I hope somebody will be able to help me. :)
Thanks,
Mathieu
Well, you said it - leverage MouseEvent.MOUSE_MOVE to set a conditional in your looping routine.
private var _isMoving:Boolean = false;
stage.addEventListener(MouseEvent.MOUSE_MOVE, checkMouse);
this.addEventListener(Event.ENTER_FRAME, doLoop);
private function checkMouse(e:MouseEvent):void
{
_isMoving = true;
}
private function doLoop(e:Event):void
{
trace("moving =" + _isMoving);
if(_isMoving)
{
// loop animation
}
_isMoving = false;
}
depending on how you want it to work I would do this as follows:
create an animation of wavy coffee
ensure the animation loops
note that clips loop by default, so all you have to do is match the first and last frames!
place the clip at the edge of your current coffee graphic
double click on the graphic to edit it
drag an instance of the looping animation from the library onto the "edge" of the graphic
OR just replace your entire light brown graphic with an animated one that loops
when the mouse is moving, call play on the animated loop clip
when the mouse stops, call stop on the animated loop clip
Some example code would be along the lines of:
public function init():void {
menuClip.addEventListener(MouseEvent.MOUSE_OVER, onMenuRollOver);
menuClip.addEventListener(MouseEvent.MOUSE_OUT, onMenuRollOut);
}
public function onMenuRollOver(event:MouseEvent):void {
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
/* do the stuff you're currently doing to animate the clip here.
something like: coffee graphic height = ease to mouseHeight */
}
public function onMenuRollOut(event:MouseEvent):void {
/* do the stuff you're currently doing to stop the clip here. */
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
coffeeClip.stop();
}
public function onMove(event:MouseEvent):void {
resetTimer();
coffeeClip.play(); //note: play has no effect when movie is playing (that's ideal in this case)
}
public function resetTimer():void {
if(mouseMovementTimer == null) createTimer();
mouseMovementTimer.reset();
mouseMovementTimer.start();
}
public function createTimer():Timer {
mouseMovementTimer = new Timer(DELAY, 1); //fiddle with the delay variable. Try 500, at first
mouseMovementTimer.addEventListener(TimerEvent.TIMER, stopAnimationLoop);
}
public function stopAnimationLoop(event:TimerEvent):void {
mouseMovementTimer.removeEventListener(TimerEvent.TIMER, stopAnimationLoop); //optional but recommended
mouseMovementTimer = null;
coffeClip.stop();
}
Of course, you would need to do things like call init() and import flash.utils.Timer and initialize variables like mouseMovementTimer, menuClip, coffeeClip and DELAY.
Warning: This code is off the top of my head and untested. So there's likely to be small bugs in it but you should get the general idea:
add a mouse listener when the user mouses over the menu
remove that listener if the user mouses out of the menu
have that listener play the looping movie clip
trigger an event that will stop the looping clip if movement hasn't been detected in a while
once the trigger goes of, stop the clip
The key is in detecting when the mouse stops moving. Flash detects interaction well but does not detect NON-INTERACTION for obvious reasons. One easy way to solve that is to trigger a timer that will go off once too much time has elapsed since the last activity. Then, when the timer triggers, you know action has stopped!
I think that's the key piece to solving your problem. I hope that helps someone in some way.
~gmale