I am using the haxeflixel game framework to create a game and I was making a pause menu. I tried using the default FlxButton but the collision with the mouse never lined up properly. So I tried using FlxButtonPlus because it had some cool hooks but the button will not respond to any inputs. here is my code declaring the button in the pause menu
final unpausebut = new FlxButtonPlus((FlxG.width / 2) - 80,(FlxG.height / 2) - 10,unpause,"unpause",48,16); unpausebut.loadButtonGraphic(buttonNormal,buttonHovered); add(unpausebut);
Here is a picture of the pause menu itself so far.
but the button doesn't seem to respond to anything. I am also getting no errors inside of the terminal. unpause is a function inside of the code that also closes the substate. Can anybody help?
Related
I'm new to Phaser3 and before starting a crazy project, I want to know how I should start, switch between scenes. I saw that there are several functions, start, launch, switch, run, resume, pause, etc.
Example, lets say I want to have 2 scenes, a Menu and a Game. I boot on the Menu and I want to go to the Game scene and if I click on a button then come back to the Menu scene.
I've achieved this by calling the start function, but I noticed that the all, init, preload and create functions are called every time and therefore I'm loading all the images, setting all the listener over and over again.
This seems wrong, should I be using the launch or switch functions and pausing and resuming? But how do I hide the previous scene?
Thanks in advance.
This question might be a little too broad, but with Phaser 3 in mind, it still depends upon what purpose your menu serves.
I think most games have a main menu that will generally be called when the game first starts, and then won't be called again.
If this is an in-game menu, where settings can be changed or part of the game can be reset/restarted, then it might not make sense to redirect to a completely different scene.
With Phaser 3's support of multiple scenes - with Dev Log #119 and Dev Log #121 probably being the best current sources of information - another option would be to start a new scene within the current scene to handle this.
However, if this is really just UI, there's nothing to stop you from creating an overlay, instead of spawning an entire scene.
If you're concerned about performance I might think about whether the entire menu needs to be called, or if a simplified menu would work. Also, make sure that you're preloading assets before you're in the menu and main game.
I personally use Boot > Preloader > Splash Screen > Main Menu > Main Game scenes, where the Preloader loads the majority of the assets I'll need. This has the downside of a longer initial load, but the upside of minimal loading after this point.
Scene Transitions
How I handle these in my starter templates is to add the scenes to the Scene Manager when creating the scene. Then I transition by start to the first scene.
this.scene.add(Boot.Name, Boot);
this.scene.add(Preloader.Name, Preloader);
this.scene.add(SplashScreen.Name, SplashScreen);
this.scene.add(MainMenu.Name, MainMenu);
this.scene.start(Boot.Name);
Then I simply keep starting the next scenes as needed.
this.scene.start(Preloader.Name);
For another game that uses multiple scenes I ended up creating the following function (TypeScript) to handle this:
private sleepPreviousParallelScene(sceneToStart: string): Phaser.Scene {
if (this.uiSceneRunning !== sceneToStart) {
// Make sure that we properly handle the initial state, when no scene is set as running yet.
if (this.uiSceneRunning !== "") {
this.scene.get(this.uiSceneRunning).scene.sleep();
}
const newScene = this.scene.get(sceneToStart);
newScene.scene.start();
this.scene.bringToTop(sceneToStart);
this.uiSceneRunning = sceneToStart;
return newScene;
} else {
return this.scene.get(this.uiSceneRunning);
}
}
In the game I was using this for, I was trying to replicate a standard tab interface (like what's see in the Dev Logs above with the file folder-like interface).
Ok, here is the deal. In phaser 3, the start function actually SHUTS DOWN the previous scene as it starts the new one. This is why you see the init, preload ext every time. If however, you 'launch' your scenes instead, then they will not go through the whole shut down, restart sequence. You can move them to the top or bottom, set to receive input or not, etc. HOWEVER, BEWARE! As of phaser 3.16, sleep or pause of a scene does NOT shut down the update. As a result, if you launch a scene, then sleep it, it basically does nothing other than maybe set the flag, saying it's asleep even though it really isn't. So any update processing will continue in any launched scene. You can short circuit the update with a flag of some sort at the beginning, (that's what I've resorted to), but the other gotcha is the camera size. All the scenes must therefore have the same camera size or they will render (even if "sleeping") and mess up your display.
So, bottom line, it's going to be messy until sleep and pause actually work.
We have a Form that is shown as a Dialogue above the main Form.
DialogResult rslt = cvForm.ShowDialog();
In Coded UI test, immediately when the Dialogue is lunched, the Mouse.Click tries to close it by clicking the "x" button of the Form.
However, seems the x button cannot respond the click event sometimes, on a certain machine it always fails to close the Form unless we put a wait before the click.
All WaitForControlxxx() does not serve as wait because they immediately returns.
Only putting PlayWait(1000) before the click works and can close the Form.
And the failure only happens on our lab machine. On my laptop, even without PlayWait(1000), it works fine.
Seems it's only a timing issue.
Is there anything I can wait for instead of blindly wait for 1 second in order for it to work on the lab machine?
//this.UIAUDIO_TX_HPF_IIRWindow refers to the Form shown as a Dialogue:
// this.UIAUDIO_TX_HPF_IIRWindow
//ulCloseButton refers to the "x" button on the Form:
WinButton uICloseButton = this.UIAUDIO_TX_HPF_IIRWindow.UIAUDIO_TX_HPF_IIRTitleBar.UICloseButton;
The following code cannot close the WinForm window on our lab machine, but CAN close it on my laptop machine:
uICloseButton.WaitForControlExist();
uICloseButton.WaitForControlReady();
uICloseButton.WaitForControlEnabled();
this.UIAUDIO_TX_HPF_IIRWindow.WaitForControlReady();
//Mouse.Click(uICloseButton, new Point(15, 9));
Mouse.Click(uICloseButton);
The following code CAN close the WinForm window on our lab machine:
Playback.Wait(1000);
Mouse.Click(uICloseButton);
Any comments?
It seems dialog is not completely ready to change focus on dialog.
Before focus gets ready, test is trying to close it.
Try with following code.
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.AllThreads;
Here WaitForReadyLevel.UIThreads option also present.
This will increase test execution time.
Let me quickly explain the background to this. I'm developing a custom menu system inside a 3D application called Softimage XSI. It has a PyQt application object created already and ProcessEvents is being called a certain number of times every second so that PyQt applications can exist in a non-modal state within XSI.
To implement the menu, I've got a webpage embedded in a toolbar which is calling a plugin for XSI that I've written to show a PyQt menu. This all works fine (albeit, slightly contrived!).
The issue is that when I show the menu, it won't disappear when I click away from it. If I move the mouse over the menu, and then click away from it, it will disappear. It's only when it first pops up.
I've tried everything I can think of. Here's a list:
Using QtGui.qApp.installEventFilter(menu) to try and catch the mousepressed signal. It never gets triggered. I suspect the application itself isn't receiving the click.
Using menu.raise_() makes no difference
Neither does QtGui.qApp.setActiveWindow(menu)
Or menu.setFocus()
I've also tried:
event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier)
QtGui.qApp.sendEvent(menu, event)
I had a go writing my own QEventLoop, but it just crashed XSI. I suspect trying to run a modal loop inside the other one probably isn't a legal thing to do. Either that, or I really don't know what I'm doing (equally probable)
The only thing I have partial success with is using grabMouse(). This is what makes the menu close if I click away from the menu (only after the mouse has passed over the menu once), but I have to call it a couple of times for it to "stick".
So this is my code at the moment:
class MyMenu (QtGui.QMenu):
def __init__(self, parent = None):
QtGui.QMenu.__init__(self, parent)
self.grabbed=2
def getMouse(self):
if self.grabbed>0:
self.grabMouse()
self.grabbed-=1
def paintEvent(self, event):
QtGui.QMenu.paintEvent(self, event)
self.getMouse()
def hideEvent(self, event):
self.releaseMouse()
def ShowMenu():
menu = MyMenu()
menu.addAction("A")
menu.addAction("B")
menu.addAction("C")
submenu = MyMenu()
submenu.addAction("D")
submenu.addAction("E")
submenu.addAction("F")
menu.addMenu(submenu)
menu.setTearOffEnabled(True)
menu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setTitle("Window")
submenu.setTearOffEnabled(True)
pos = QtGui.QCursor.pos()
pos.setX(105)
menu.popup(pos)
#Prevent garbage collection
QtGui.XSIMenu=menu
QtGui.XSISubMenu=submenu
#Desperate acts!
menu.raise_()
QtGui.qApp.setActiveWindow(menu)
menu.setFocus()
Any thoughts or random suggestions would be very gratefully received as this is driving me nuts! Don't be afraid to suggest modifications to stuff I've already tried, as I'm relatively new to PyQt and I may well have missed something.
Many thanks,
Andy
Just before calling popup with self.trayMenu.popup(QtGui.QCursor.pos()), call self.trayMenu.activateWindow(). Putting activateWindow before popup makes the left-click menu work the same as the right-click menu and it goes away when you click elsewhere. :)
I've made my app play music in the background, I also successfully made it become the media player by calling BeginReceivingRemoteControlEvents. however, the RemoteControlReceived method never gets called. the same logic in Objective C is working fine. Any samples or guidelines appreciated.
You need to ensure it is placed on the First responder view, and if not, the event needs to be passed up along the chain of responders until it reaches your remote events. Try to imagine remote control events the same as keypresses on the keyboard. For example, If the app is focused on a button, and you press some keyboard keys, nothing will happen, as a button isn't listening for key presses.
A similar situation is occurring in your code. Try to create a basic, single viewed project with the BeginReceivingRemoteControlEvents and the method override to receive the event (cant remember what it is, RemoteEventReceived() or something similar.) This should get fired when you press a remote button.
(sorry I cant give sample code, not in front of mac at the minute)
You might want to try using a later mechanism to listen for remote control events. For example, if you want to listen to the headset button:
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
[commandCenter.togglePlayPauseCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
NSLog(#"toggle button pressed");
return MPRemoteCommandHandlerStatusSuccess;
}];
or, if you prefer to use a method instead of a block:
[commandCenter.togglePlayPauseCommand addTarget:self action:#selector(toggleButtonAction)];
To stop:
[commandCenter.togglePlayPauseCommand removeTarget:self];
or:
[commandCenter.togglePlayPauseCommand removeTarget:self action:#selector(toggleButtonAction)];
You'll need to add this to the includes area of your file:
#import MediaPlayer;
This works in the background, ONLY if you are an audio app playing in the background (i.e. you have to set that background mode in your app capabilities).
I am coding up a program for automated testing which randomly clicks an open application window using various User32.dll library calls. My current problem is this, if a click would open a dialog, using Process.WaitForInputIdle() does not wait long enough for that dialog to be detected the next trip around the loop, which means several clicks get cued and if those clicks happen to be on something in the dialog I want to avoid (say an exit button) there is no way of telling that in advance. My question is this. Is there a way of waiting for the process or thread to finish all processing and only be waiting in the message loop again?
I hope that made sense.
Cheers
Ross
EDIT
Failing this, would it be somehow possible to set the process / threads of the target program and my program to both use the same processor and adjust the prioritorys of each so that the target program gets preference?
WaitForInputIdle will unfortunately return as soon as the app is in a message loop with no input messages waiting.
If you own the code to the dialog, you could have the dialog call SetEvent in its WM_INITDIALOG to signal your automation that it is ready for testing. Alternatively, you could look at using SetWinEventHook on the process and wait for the dialog to actually be created before sending input events to it.
The way around this it seems is to use the SendMessage API instead of the mouse_event or SendInput API. The reason for this is that SendMessage blocks until it has been processed. Just make sure you always get the handle of the window immediatly under where you want to click (using WindowFromPoint) and convert the mouse coordinates from screen to client coords using ScreenToClient. Pack the coordinates into the lParam parameter by using ((pt.Y << 16) + pt.X). This will block until processed and so any modal dialogs shown will block this call.