I am making a Tic-Tac-Toe game as my first ever win32 app, and it is coming along pretty good. I have everything done up until the first round is finished, with each square on the tic tac toe board being a button that when clicked becomes an X or an O based on whos turn it is. When one player wins the game, i made a small window show up underneath the tic tac toe board saying "Player 1 Wins". I also made a "NEW GAME" button at the bottom of the screen that when clicked all of the X's and O's are cleared from the board and the game restarts.
So here is my problem, when i click the "NEW GAME" button, i can't get the window saying "PLAYER 1 WINS" to go away like everything else, it just stays there. I want it to go away. Here is some of my code:
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_LOC1:
click1++;
if(click1>1)
{break;}
else{
playerobject++;
if(playerobject==1|playerobject==3|playerobject==5|playerobject==7|playerobject==9)
{ SetDlgItemText(hWnd, IDM_LOC1, "X");
loc1 = 1; }
else
{ SetDlgItemText(hWnd, IDM_LOC1, "O");
loc1 = 2; }
winner = determinewinner();
if(winner==1)
{
hwndb = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,TEXT("STATIC"),TEXT("PLAYER 1 WINS!"),WS_CHILD|SS_CENTER|WS_VISIBLE,20,210,210,18,hWnd,HMENU(NULL),GetModuleHandle(NULL),NULL);
}
else if (winner==2)
{
hwndb = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,TEXT("STATIC"),TEXT("PLAYER 2 WINS!"),WS_CHILD|SS_CENTER|WS_VISIBLE,20,210,210,18,hWnd,HMENU(NULL),GetModuleHandle(NULL),NULL);
}
break;}
That is handling the logic part (I know its pretty messy, its my first go at it). So you can see that when the "determinewinner" function returns 1, the window shows up stating that player 1 has won.
Now here is the code handling the "NEW GAME" button:
case IDM_RESTART:
SetDlgItemText(hWnd, IDM_LOC1, "");
SetDlgItemText(hWnd, IDM_LOC2, "");
SetDlgItemText(hWnd, IDM_LOC3, "");
SetDlgItemText(hWnd, IDM_LOC4, "");
SetDlgItemText(hWnd, IDM_LOC5, "");
SetDlgItemText(hWnd, IDM_LOC6, "");
SetDlgItemText(hWnd, IDM_LOC7, "");
SetDlgItemText(hWnd, IDM_LOC8, "");
SetDlgItemText(hWnd, IDM_LOC9, "");
playerobject = 0;
click1=0;
click2=0;
click3=0;
click4=0;
click5=0;
click6=0;
click7=0;
click8=0;
click9=0;
loc1=0,loc2=0,loc3=0,loc4=0,loc5=0,loc6=0,loc7=0,loc8=0,loc9=0;
DestroyWindow(hwndb);
break;
Now i think the problem is the switch statement, as both of them are just cases under the WndProc switch statement (The WM_COMMAND part). I tried moving the hwndb window into the winmain function and then just doing the ShowWindow function in the switch statement but that didn't work either of course.
How can i get the window to close? Thanks!
EDIT* So i forgot to say that when i run it, it does fine until the NEW GAME button is clicked, it says that hwndb hasn't been initialized, which is of course true for the particular part of the switch statement, so i've obviously done it wrong. How can i do it right?
Because of the "hwndb hasn't been initialized"-error I would say you have not declared:
HWND hwndb; //Global variable
If however you have made this a global variable this error can be occuring because of a call to IDM_RESTART before IDM_LOC1. This also means that should you have double-clicked your refresh button the DestroyWindow function will return false.
Related
Well, I'm back. I solved the ListBox problem by using a ContextMenuStrip — or so I thought!
It comes in perfect, then in a quarter second, two things happen: it disappears, and the TreeNode unselects.
But for that quarter second, it looks perfect!
The way that progresses is, I step through the lines of code on the right of the screenshot, 5 lines, then one more F11, and it appears for a 1/4 second, and the TreeNode UNSELECTS.
But here's another interesting thing:
In Design Mode, I clicked the reference to contextMenuStrip1 in the dialog bar beneath the Form, and it appears in the place I dropped it.
Then a click on the TreeView (white as I suppose you know) and it disappears.
Ah, but then I take the mouse and pull the TreeView over to the right, again click the reference below, again the ContextMenuStrip appears, then I click the TreeView, and AGAIN it disappears!
What am I missing, dear friends? Something to do with the focus?
Much obliged for any help.
Got it! I found that responding to Closing could be stopped for study with a break point. Then poked around in the Properties, and tried a few things. Then ultimately googled and found the answer at
Do not close ContextMenuStrip on selection of certain items. I added AppFocusChange as not a reason to close.
So far, I'm now able to click the members and select them. Progress!
private void contextMenuStrip1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
if (e.CloseReason == ToolStripDropDownCloseReason.AppClicked ||
e.CloseReason == ToolStripDropDownCloseReason.AppFocusChange)
e.Cancel = true;
}
if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
{
for (int i = 0; i < 4; i++)
{
if (contextMenuStrip1.Items[i].Selected == true)
{
bool res = DoChoice(i);
if (res == true) e.Cancel = false;
}
}
}
Then, at DoChoice, I'll invoke the Add or Edit accordingly, and always returna Close to the strip.
I am quite new to programming and decided to make a little game, so far I have only made a small block that is able to move in all 4 directions (left, right, up and down). Pretty simple and nothing extra-ordinary. However, when I run my program, sometimes it will stop working, not as in crashing causing Processing itself to crash, but my program will just end.
As far as my testing goes, I think this happens when I press two keys at the same time (like W and S). Does anyone happen to know what causes it to stop, and perhaps how to fix it as well?
void setup(){
size(1080,720);
frameRate(30);
}
int shipLR = 0; //Variable for the ship to go left/right
int shipUD = 0; //Variable for the ship to go up / down
void draw(){
background(0);
shipLR = constrain(shipLR, 0, 1040); //Constrain the ship in the window
shipUD = constrain(shipUD,0,680); // Constrain the ship in the window
move();
Shuttle();
}
void Shuttle(){
rect(shipLR, shipUD, 40,40); //Draw the ship
}
void move(){
if (keyPressed) {
if (key == 'a') {
shipLR = shipLR - 20; // Go left
return;}
if (key == 'd') {
shipLR = shipLR + 20; // Go right
return;}
if (key == 'w'){
shipUD = shipUD - 20; // Go up
return;}
if (key == 's') {
shipUD = shipUD + 20; // Go down
return;}
}
}
Any help will be greatly appreciated.
Edit: I found something that causes this problem to occur more frequent; If I implement a frameRate of a value lower than 60 (currently trying with 30) this happens more often.
Edit 2: With the suggestions below of making my move function in a single if block had a lot of good impact. The program no longer stops when I move the ship in the middle of the window it no longer stops, it now only does it at rare occasions when I bump too often against the borders of the window. Perhaps it has something to do with constrain?
in move() (java naming conventions specify that method names start with lower case) you should exit on the first key pressed found. the code can be re-organized to reduce multiple identical conditions:
void move(){
if (keyPressed) {
if (key == 'a') {
shipLR = shipLR - 20; // Go left
return;
}
if (key == 'd') { // still inside if keyPressed
shipLR = shipLR + 20; // Go right
return;
}
if (key == 'w') {
...
}
} // end of if keyPressed
}
My guess it that the program doesn't "stop working" or end- it's just that your rectangle stops moving. If you let go of all the keys, then push just one key, I'd bet that the rectangle starts moving again. (In the future, please try to be more specific- saying "it stops working" isn't very helpful.)
Anyway, that's because of the way you're handling the key presses. What happens if you press a key other than the ones you're checking for?
You'll enter the move() function, and you'll enter the if(keyPressed) block, but you won't enter any if the other if statements inside that block. The key variable only holds the most recently pressed key.
Depending on what you want to do, you should either refactor those if statements to only change the direction if the key was valid, and to ignore all other key presses. Or you might want to use a set of boolean variables to track multiple keys being pressed at the same time. More info on that approach can be found here.
If you still can't get it working, then please try to be more specific about exactly what happens.
I am developing a Java 2D Game, in which I have used a KeyListener, but as you probably can guess, it has focusing issues, mainly when the Player is running and you keep the same key pressed for long, for example pressing "W" to run forward, but after some seconds of keep pressing W, the KeyListener dies and no key works, I want to use KeyBindings, as most people suggest it for game development, but I cannot find any usefull tutorials, most of them use some form of Buttons, and other useless features for my game, so how can i avoid the KeyListener from losing focus, or how can I write a simple KeyBinding code, that only moves the player, and other simple stuff used in a game.
This is the kind of Key Binding that I want, I KNOW IT DOES NOT WORK, it is an example:
component.getInputMap().put(KeyStroke.getKeyStroke(VK_W),
"move forward")
component.getActionMap().put("released",
releasedAction);
if(releasedAction == true){
Player.playerSpeedY = 7;
} else{
Player.playerSpeedY = 0;
}
FWI: this is the current KeyListener code:
if(HUD.PlayerHealth > 0){
if(key == KeyEvent.VK_W) {Player.playerSpeedY = -5; keyDown[0]= true;}
if(key == KeyEvent.VK_S) {Player.playerSpeedY = 5; keyDown [1]= true;}
if(key == KeyEvent.VK_A) {Player.playerSpeedX = -5; keyDown [2]= true;}
if(key == KeyEvent.VK_D) {Player.playerSpeedX = 5; keyDown [3]= true;}
}
I keep looking for Actions and Input maps tutorials, or KeyBinding ones, and I just don't find anything useful, another dough, the component in action and input map, what is it for?, should my entire code be based on that, and is there any way to only make the action map move the player, and only that?
Try something like this:
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "right");
this.getActionMap().put("right", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
//Do Something Here
Player.playerSpeedX = 5;
}
});
How to use KeyBindings
I'm using a button to activate a timer. In that button's code, it turns on the timer. I'll attach the code, though I doubt it'll make sense out of context.
- (IBAction)btnStartWasClicked:(NSButton *)sender {
if ([btnStartTitle.title isEqualToString:#"Start"])
{
NSLog(#"Debug: Start button was clicked."); //Debug
//Changes the Start button to say Stop
[btnStartTitle setTitle:#"Stop"];
started = TRUE;
[self tick:nil];
NSLog(#"Debug: Timer has started."); //Debug
[btnReset setEnabled:FALSE];
[btnLap setEnabled:TRUE];
if (lapTimerIsPaused == TRUE)
{
lapTimerIsRunning = TRUE;
[self tickAfterLap:nil];
}
}
else
{
NSLog(#"Debug: Stop button was clicked."); //Debug
//Changes the Stop button to say Start
[btnStartTitle setTitle:#"Start"];
started = FALSE;
NSLog(#"Timer has been stopped."); //Debug
[btnReset setEnabled:TRUE];
lapTimerIsRunning = FALSE;
lapTimerIsPaused = TRUE;
[btnLap setEnabled:NO];
}
I currently have a nasty bug I'm not quite sure how to get rid of. If the user double-clicks the start button really quickly, it will either:
A) Do nothing, just change the start button to say stop.
B) Make the timer count twice as fast (if the double-click is REALLY quick.) THIS ONLY HAPPENS WHEN THE START BUTTON IS SET TO SAY STOP, NOT START.
My bug is B. I'm not quite sure how to squash it.
Edit: The lap timer is a different timer than the regular timer, and I don't think the bug I'm having affects it, so ignore the lap timer code.
Any ideas?
Trying to make an xna game, where the user needs to tap to stop a bar going down. The simulation is like what we see in a WWE PS3/xbox game, the give up bar.
Anyway, the way i have done it, serves the purpose. However, if the user holds the touch, touch values keep incrementing.
What I want is, if the user taps it, only 1 point will be scored. And when he taps again, he will get 1 point more. At the moment what is happening is, if the user holds it, it keeps incrementing, kind of like in a keyboard (if u hold a button, keypresses keeps going on).
foreach (TouchLocation location in TouchPanel.GetState())
{
if (location.State == TouchLocationState.Moved)
{
touchPoints++;
break;
}
}
Change from TouchLocationState.Moved to TouchLocationState.Pressed. That should only occur with each new touch.
foreach (TouchLocation location in TouchPanel.GetState())
{
TouchLocation prevLocation;
bool prevLocationAvailable = location.TryGetPreviousLocation(out prevLocation);
if (location.State == TouchLocationState.Pressed && prevLocation.State != TouchLocationState.Pressed)
{
touchPoints++;
break;
}
}
And for the future, if you're doing Keyboard input and want each press of the keyboard to increment the value but to be ignored if the player is holding down the space, you just have to store the previous state of the keyboard. Then you compare if the current keyboard state the key is being pressed and the previous keyboard state the key wasn't pressed.
(didn't actually code in compiler so there could be some code issues with the below)
KeyboardState currentKeyboardState = Keyboard.GetState();
if (currentKeyboardState.IsKeyDown(Keys.Space) && !previousKeyboardState.IsKeyDown(Keys.Space) {
//Do whatever it is you want to do with the press of the space key
}
previousKeyboardState = currentKeyboardState;
This is a snippet of my code of how i got each touch to be a individual value.
The system.diagnostics line is the test that will show you in your output box.
TouchCollection touch = TouchPanel.GetState();
foreach (TouchLocation touchLocation in touch)
{
if (touchLocation.State == TouchLocationState.Pressed)
{
base.InputPointX = touchLocation.Position.X;
base.InputPointY = touchLocation.Position.Y;
System.Diagnostics.Debug.WriteLine("X: " + base.InputPointX + \
", Y: " + base.InputPointY);
base.Update();
return true;
}
}