SFML moving two players with different buttons at the same time - sfml

I've created simple game using SFML(player can run, jump etc pressing arrows), how can i make the same for two players(second player will use WASD to move) at the same time on one computer?

You can access the keys pressed with the sf::Keyboard class. sf::Keyboard is a static class so you don't need to create a unique instance, here is a quick example:
if(sf::Keyboard::isKeypressed(sf::Keyboard::Key::W))
{
Player1.Move(1, 1);
}
if(sf::Keyboard::isKeypressed(sf::Keyboard::Key::Left))
{
Player2.Move(1, 1);
}
I'm assuming you currently are using window.PollEvent(event), the problem with that approach is that you only poll one event per loop cycle since events are added into a queue. With the above code you should be able to press multiple keys at the same time and have two actions processed.

Related

Qt C++: How to make a for loop until a button is pressed

I have been trying to make a GUI Blackjack game in C++ with Qt. However, I have hit a road block on my way. I made the game and the game logic last year in pure C++ (link below). I am trying to use the same code to build the GUI version of the game Github/Blackjack.
It's mostly done to the point that I have the cards showing up, adding the values of those cards, the dealer and the player set up.
In the C++ version I made a vector of all the players and added the dealer to the end of it, then using a for loop, I would iterate through the players to get them to play.
In Qt, I have created a widget with two buttons "Hit" and "Stand" for the player control.
"Hit" button is simple and connected the click event of the button with the hit member function of the player.
ctrl = new PlayerControl(nullptr, mainPlayer);
connect(ctrl->ui->hitButton, &QPushButton::clicked, [mainPlayer]{
mainPlayer->hit();
});
Code for iterating through the vector:
for (size_t i = 0; i < players.size(); i++)
{
if (i == playerPos - 1)
{
ctrl->setVisible(true);
//how to make the loop to pause here until the user presses the
//"Stand button", and then proceed with the rest of the loop?
}
else if (i == players.size() - 1)
dealerPlay();
else
computerPlay(players[i]);
}
I'll really appreciate any help. :)
I don't really understand the code you are showing or how it relates to the question in the title of your post. I'll just answer the question, which is:
How to make a for loop until a button is pressed
The answer is that you probably don't want to do that, because that would involve multi-threading or some kind of complicated concurrency mechanism. When you're writing a GUI, the main thread of your application usually sits in a loop waiting for event messages (like clicks and key presses) from the operating system. When it gets such a message, it is supposed to handle them quickly and then go back to waiting for the next message.
In Qt, you can handle these events by overriding functions in your QMainWindow class or by connecting Qt signals to slots.
So, instead of having a loop that iterates through each player and waits for them to make their move, you would have some long-living variables that keep track of the state of the game, and when you detect that a player has made a move (i.e. by clicking a button), you would update those variables, update any data shown on the screen, and then return from your event handler so you can handle the next event.

Search/Filtering functionality blocks the Main(GUI) thread

I have a custom table and I have implemented a search/filtering function which goes through all the elements in the table and then hides/shows the item in the table depending upon whether that item/element matches the one we are searching for.
For example, let's say I have a text control and I type "wxwidgets" in it then my custom function will go through all the elements in the table and hide the elements that do not match this "wxwidgets" entry. This works fine and I am correctly able to hide/show the elements. But the problem is that this search blocks the main thread(gui) since I am doing this in the main thread. The table has around 1000 entries or can be more in the future. My question is how can I avoid this blocking of the main thread. I am thinking of using another worker thread that will do this searching of elements. But then I read that "no secondary threads should call gui functions". But then how can i show/hide the elements of the table from the worker thread. For example, currently in the main thread I use Show(true) or Show(false) to show/hide a particular entry from the table and all this is done while I am in a for/while loop. But if i implement this(the for loop) in a worker thread then according to the quoted advice i should not use the Show() functions from inside that worker thread. What can be done in this situation? Also, is there any other way/advice of doing this searching for elements of the table. I am thinking of starting a new detachable thread every time the user enters some text in the text field. And then delete that old thread if the user appends some more text to the text field and start a new thread which starts searching from the beginning. Is this the right solution for this?
The problem is that inside my for loop i am using the wxWidgets functions. For example, this is what my for loop looks like:
void AnotherClass::onTextChanged(wxCommandEvent &event)
{
for(int i = 5; i<154;++i)
{
SomeClass *element = dynamic_cast<SomeClass*>(FindWindowById(i));
if(element.GetLabel() == textEnteredInTextCtrl)
{
element.Show(true);//element found
//update the necessary layout here using layout call
}
else
{
element.Show(false);//element not found
//update the necessary layout here using Layout() call
}
}
}
This is the main part of the search. Now inside the workerthread should/can i use the functions like FindWindowById() and GetLabel()? Are they considered GUI functions or not so that I can use them from the worker thread? Can i or can i not use FindWindowByID() and GetLabel() and other similar functions(like Layout() and Show()) from inside the worker thread. How should I make this work? I mean I know how to use wxThread and send events using QueueEvent and already have another worker thread in my program that does some other calculation but I am asking about how I should make it work in this particular case.
Another solution suggested by QuentinC would be to use a timer. His suggestion is as follows:
In my case, I don't start refreshing the list immediately after the
user has typed a letter in the search box. Instead, when the user has
typed a letter (wxEVT_TEXT), I start or restart a timer of 500ms. Only
when the timer goes out (the user stops typing for 500ms) then the list
is refreshed. Again, this is a measure to avoid a rapid succession of
useless refreshes.
But in this case of using a timer i have several queries. I am sending the wxEVT_TEXT from CustomTextCtrl's onTextChanged method to this class' onTextChanged method. I guess i could start the timer of 500ms inside the onTextChanged method of the CustomTextCtrl class when the user types a letter. But then where should i check that the timer is still running? In the CustomTextCtrl's onTextChanged method or inside the AnotherClass's onTextChanged method?
So for clarification i have two classes:
the CustomTextCtrl class which have a onTextChanged method which uses event.Skip() to forward this event to its parent.
The parent class AnotherClass which also have a onTextChanged method and this method receives this forwarded event and do the searching and updates the table.
Where and how should i start/restart/stop the timer to update the UI?
NOTE: The process of filtering the elements is working perfectly but the only problem is that the main(GUI) thread is blocked when the user type some text inside the textctrl. After lets say 6 or 7 seconds, the text appears inside the textctrl and the UI is updated. I don't want this unresponsiveness of the main UI for 6-7 seconds.
Also, note that i am not using any wxList/wxGrid. I am just using wxPanels and wxStaticText and using show/hide on them.
Edit: One improvement in the code above is that to only use Layout() call from outside the for loop. If i use the Layout() calls from outside the for loop then the search functionality works almost instantly. But this(method) still has the potential of blocking the main thread in the future if the table has many more elements. So i want to use a thread or a timer method. But i don't know how the secondary thread could use the gui functions or how can/should i use a wxTimer method(if any) to solve this problem.
I have several thoughts on this subjet
A) If you have a speed issue, then you better profile your code, to see where the bottle neck is.
B) Calling GDI functions from a not-main thread is risky. Maybe just asking for window-id and its label is not that dangerous, but I think calling Show() definitely is.
C) This piece of code is mainly GUI related. I don't think a worker thread is useful here. But stacking similar callings may improve its speed. For this, I have three advises:
Use CallAfter() passing the elemnt.Show() method
Use Freeze() before the loop and Thaw after it.
Call Layout()only once, right after the loop. About this I wonder if Show()/Hide() controls is better than Enable()/Disabñe()
D) Because you call FindWindowById() so many times, and also many user changes, it will be better to cache all affected windows in a container (a std::map with id as the key). Then, inside the loop use the container instead of 'FindWindowById()`.
E) As a last resource, if the GUI is still blocked, use wxYield() every xxx (say 100) loop-iterations. Depending of pending messages this solution may get things worse (reentrances, crossed effects, etc).

Using C++ w/ Lua in a runtime environment

I have looked this question up so many times that I am convinced I am missing a huge piece of the puzzle when it comes to integrating LUA into my C++ Game Engine. What I want to do is run my game engine, then while its running I would like to click on my ui and click "add script" and then run the script. That part is easy enough to do but what I DON'T get is how a script that seemingly gets ran in place with lua_dofile could have code that gets mouse input or moves the character based on input. I don't see anyway to do this effectively. Am I supposed to allow the LUA state to be created and destroyed every frame or do I make the script fire every frame? In an application like this:
void init();
void update();
void render();
void end();
How would I use LUA to control the movement of an entity.
Lets say I set up the lua state so that you can write lua code like this:
entity1 = Entity.new()
entity1:setPosition(4,5)
How would I give the script some input from mouse to move the entity to the mouse position?
My overarching question is what is the best way to have a script control my entities in a way that if I supply the Lua State the ability to move my entities, then a scripter could write a "game" (i.e. a interactive runtime application)
To give a concrete example, suppose you wanted to teleport a ball to the player whenever they click the mouse. Here's what you could write to do that in Lua:
local function clickHandler(event)
local x, y, z = event.player:getCoords()
local ball = event.world:getBall()
ball:teleportTo(x, y, z)
end
game.registerEventHandler('click', clickHandler)
To make that example actually work in your engine, here's what you'd need to do:
Create a registerEventHandler function that saves the given callback somewhere C can access it
Create a getCoords function that returns the coordinates of a given player
Create a getBall function that gets a ball in your gameworld
Create a teleportTo method that teleports an entity to a given location
Whenever a player clicks the mouse, run all click event handlers that you saved, with an event object containing the player and the gameworld
And as for this question in particular:
Am I supposed to allow the LUA state to be created and destroyed every frame or do I make the script fire every frame?
No. You create a lua_State when your game starts, load the scripts in it, and then just keep using that state to call the event handlers.
Essentially the Lua scripts define functions to be called at each event. So the host C++ loads the scripts and then enters its main loop and calling back Lua.
See how LÖVE does it.

How to design a Controller System and manage different actions?

I am creating a game using EntityX library which handles Entity-Component-System model, and SFML.
Right now, I just have four basic components: position, direction, velocity and renderable, plus two systems: a movement system and a render system.
I will separate my question in two:
How can I make basic controls such as moving my character? With SFML, I can get the events this way:
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
// other events ...
}
So I could create a ControllerSystem which targets entities having a Controller component, and give a reference to my window to the system so that it handles the events. But the only controllable entity would be my character so is that really efficient? Plus, it means I would have to loop through the events in my system to get KeyPressed events. Thus I can't for example do the condition to close the window except if I put it along with the events for the character.
Finally, when I get - wherever it is - a KeyPressed event and I want to do an action, how and where should I send this action so that it get realised? I mean, my controller system can deplace my character and a AI system could deplace a mob. I'm not going to write the deplacement twice in my systems, even if it's just changing direction and velocity. I could have more complex actions such as launching spells etc.
Coming to my second point, how to handle different spells/weapons? Suppose I have three keys A, B, C each one launching a totally different spell. In my Controller Component, when I would get an event saying one of these key has been pressed, I would want to launch the spell. But where should I have this spell "stored" in the code? Assuming the three spells must be coded differently as they have a different comportment, but there needs to a common pattern between them, no?
So shall spells be systems, or just normal classes out of the ECS model, having access on entity manager and components to create projectiles or I don't know what?
It remains quite blur to me and I can't really find specific enough tutorials. Thanks for your help.

cocos2d disable touches to all other views

Below is what I came up with. Wonder if there's easier way to do it.
Suppose I want only menu layer to be touchable while it's up.
I put invisible layer that will swallow touches.
bool tNoTouchLayer::init()
{
if(!CCLayer::init()) {
return false;
}
setIsTouchEnabled(true);
return true;
}
void tNoTouchLayer::registerWithTouchDispatcher()
{
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}
bool tNoTouchLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
return true;
}
Now I can add the noTouchLayer before adding menu layer, and all touches would be stolen by noTouchLayer.
Lastly, i did find more info on this:
http://code.google.com/p/cocos2d-iphone/issues/detail?id=1033
the reason that menu items are stealing touches is because menu items have their touch priority set to the highest (lowest char value) possible...
you can change kCCMenutouchPriority to be 0 instead.
That's how you do it as far as I can tell. Note however that your code will not disable any menues added to the scene. To do that you have to remove the menu from the touch dispatcher when adding the popup and add it back again when removing the popup.
To remove a menu from the touch dispatcher you can do the following:
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(menu);
and to add it back you can do this:
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(menu, kCCMenuHandlerPriority, true);
where menu is your CCMenu node.
As a tip, I created a class like the one above but I also added the popup menu to it, creating one touch blocking menu in one node. :)
this isn't exactly the answer you are looking for, but here's something up for thought:
if you're trying to do this for a pop-up, would it be possible to try to pop up a subclass of UIAlertView (one that looks the way you want it to)?
http://mobile.tutsplus.com/tutorials/iphone/ios-sdk-uialertview-custom-graphics/
Here's another approach:
keep state of the app and which layer is "on top".
in each of your menu listeners, have them all do a check to see if the state of your current layer should allow for that menu button to be pressed.
also, you can override "addchild" to see if it's a MenuItem, and if it is a MenuItem, then have it check to see if it should be enabled. if not, return immediately instead of executing the rest of the code
If I understand your question correctly, I guess you try to do something like "pause screen" to pop up and disable all other layers.
Well, you said in your comment that you won't like to enable touch event in other areas but not your pop-up's area. Basically, I would think we should think in term of layer for easier understanding, and easier to implement.
Let's see if we have "main layer" which holds other game objects to show as its childs (assume that they also are running animation). Now you touch a button and want to pop up "pause layer". You have to do the following in order to disable all touch event from others layer + objects.
Pause layers' schedule and actions [via pauseSchedulerAndActions()]
Pause all of its game objects inside the layer (ie. enemies) [via pauseSchedulerAndActions()]
Disable CCMenu object (if any), this will ignore touch event on CCMenu related object ie.CCMenuItemImage [via setEnabled(false)]
Disable touch event for layer itself [via setTouchEnabled(false)]
The first 2 points are about stop running any schedule method, and animation.
The latter 2 points are about stop accepting touch event. You can see that CCMenu* related class maintains its own touch event separately from CCLayer, thus we need to do additional effort by set to both CCMenu* object and the layer itself.
I tried this and it works well for me. Also it's better as we don't have to involve setting dispatcher directly in my opinion.