ActionScript 3 If Else for Button Click - if-statement

I'm complete noob about this.
So, in a scene, there is an answer choice button A or B and a "next" button. In short, if we want to go to the next frame (click the "next" button), we have to click on one of the answer options first. However, I am confused about how to make the code.
Can you guys help me? (sorry for my bad english)
errorframe5.visible = false;
var pressed = "yes";
nextbutton.addEventListener(MouseEvent.CLICK, nextframe6);
function nextframe6(event:MouseEvent):void
{
if(button_a == "no" && button_b == "no")
{
errorframe5.visible = true;
}
else
{
gotoAndStop(7, "Material");
}
}

I think you need code like that:
nextbutton.enabled = false;
buttonA.addEventListener(MouseEvent.CLICK, buttonAPressed);
buttonB.addEventListener(MouseEvent.CLICK, buttonBPressed);
function buttonAPressed (MouseEvent){
trace("your answer is correct");
nextbutton.enabled = true;
buttonA.enabled= false;
buttonB.enabled = false;
}
function buttonBPressed (MouseEvent){
trace("your answer is wrong");
nextbutton.enabled = true;
buttonA.enabled= false;
buttonB.enabled = false;
}

Related

Different behavior of events in different projects

In the last question, I had a problem with placing the cursor in the right place when clicking on the LineEdit with the mouse.
The problem was solved, I, with God's help, wrote an algorithm that solves my problem. I wrote it in an EMPTY project, where there is nothing but LineEdit. Everything worked great there. Here is the code:
if(object == ui->lineEdit_newClientPhone && event->type() == QEvent::MouseButtonRelease)
{
QString line = ui->lineEdit_newClientPhone->displayText();
qDebug() << line;
ui->lineEdit_newClientPhone->setFocus();
bool isValid = true;
for(int i = 0; i<=15; i++){
if(line[i] == '_'){
ui->lineEdit_newClientPhone->setCursorPosition(i);
isValid = false;
break;
}
}
if(isValid){
ui->lineEdit_newClientPhone->setCursorPosition(16);
}
}
It worked great. You click on any place in lineEdit, the mouse cursor is placed on the first empty "_" character. I joyfully ran to transfer it to the main project.
But then I encountered a strange behavior - in the main project, exactly copied code does not give such behavior. When you click on lineEdit with the mouse, the cursor is placed in the place where you clicked. I debugged all the events associated with this LineEdit and found strange behavior - the order of the events is different. Excluding unnecessary events, which were the MOST:
if(object == ui->lineEdit_newClientPhone){
if(event->type() != QEvent::Paint && event->type() != QEvent::MouseMove && event->type() != QEvent::HoverMove){
qDebug() << event->type();
}
}
Got this result in "EMPTY" project:
QEvent::MouseButtonPress
QEvent::MouseButtonRelease
QEvent::InputMethodQuery
But in the main project, the sequence turned out to be different:
QEvent::MouseButtonPress
QEvent::InputMethodQuery
QEvent::MouseButtonRelease
I don't know if this is the case, but in this way, my logic does not work and the cursor remains in the place where you clicked. I was able to fix the situation by changing the event to QEvent::MouseButtonRelease, but this way I get mocking cursor travels first to the place where you clicked, then to the place I need. What could be the problem and how can it be fixed? Thanks to all!
I don't think this is the right decision, so I would like to hear more solutions, but QTimer::singleShot helped me
f(object == ui->lineEdit_newClientPhone && event->type() == QEvent::MouseButtonPress){
QTimer::singleShot(0,ui->lineEdit_newClientPhone,[this]
{
QString line = ui->lineEdit_newClientPhone->displayText();
qDebug() << line;
ui->lineEdit_newClientPhone->setFocus();
bool isValid = true;
for(int i = 0; i<=15; i++){
if(line[i] == '_'){
ui->lineEdit_newClientPhone->setCursorPosition(i);
isValid = false;
break;
}
}
if(isValid){
ui->lineEdit_newClientPhone->setCursorPosition(16);
}
});
}

Detecting if a key was pressed, not if it is always down

I'm new to SFML and I have trouble finding a solution to checking if a key is pressed during one frame. The problem I've been facing is the fact that with the Keyboard and Mouse classes, it seems impossible to use a system where one first checks for the current input state before any Update() call of objects and then after all Update() you get a previous input state for the next frame so that one can do the following:
bool Entity::KeyboardCheckPressed(sf::Keyboard::Key aKey)
{
//this part doesn't work
if (KeyboardState->isKeyPressed(aKey) and !PreviousKeyboardState->isKeyPressed(aKey))
{
return true;
}
return false;
}
But this doesn't seem to work with SFML, and other sources tell me that I'm suppose to use the Event class with its type and key.codelike the following example:
bool Entity::KeyboardCheckPressed(sf::Keyboard::Key aKey)
{
if (Event->type == sf::Event::KeyPressed)
{
if (Event->key.code == aKey)
{
return true;
}
}
return false;
}
But this results in the sf::Event::KeyPressed doing the same as KeyboardState->isKeyPressed(aKey), so then I tried the method where you set key repeat to false: window.setKeyRepeatEnabled(false);with no results what so ever. I also found out that the sf::Event::KeyPressed works only as intended inside of this part in the main.cpp:
while (window.pollEvent(event))
{
}
The problem with this is that I want to handle Input inside of my Entity objects' Update()function, and I can't put the whole Update loop inside of the while (window.pollEvent(event)). So here I am, struggling to find a solution. Any help is appreciated.
In general, if you have a thing which you can check the current state of, and you want to check if that state changed between frames, you simply use a variable, declared outside the application loop, to store the previous state, and compare it to the current state.
bool previousState = checkState();
while (true) {
// your main application loop
bool newState = checkState();
if (newState == true && previousState == false) {
doThingy("the thing went from false to true");
} else if (newState == false && previousState == true) {
doThingy("the thing went from true to false");
} else {
doThingy("no change in the thing");
}
// this is done unconditionally every frame
previousState = newState;
}

SDL_KEYDOWN triggering twice

I am following lazy foo's tutorial, however I realized every time I press press s or p, SDL_KEYDOWNtriggers twice. How can this be fixed?
Here is the code snippet:
while(SDL_PollEvent(&e) != 0) {
if(e.type == SDL_QUIT) {
quit = true;
}
else if(e.type == SDL_KEYDOWN) {
if(e.key.keysym.sym == SDLK_s) {
if(timer.isStarted()) {
timer.stop();
printf("stop\n");
}
else {
timer.start();
printf("start\n");
}
}
else if(e.key.keysym.sym == SDLK_p) {
if(timer.isPaused()) {
timer.unpause();
printf("unpause\n");
}
else {
timer.pause();
printf("pause\n");
}
}
}
}
Pressing s once:
start
stop
TL;DR: Check if e.key.repeat equals to 0 before handling the events.
SDL generates fake repeated keypresses if you hold a key long enough. This is used mostly for text input.
The original key press has .repeat == 0, and fake presses have .repeat == 1.
For convenience reasons probably (I'd argue that it's rather inconvenient), since SDL 2.0.5 the actual key press generates two events instead of one. One has .repeat set to 0, and other (new) one has it set to 1.

OpenGL - Left mouse click keeps removing my grid

I have created a drawGrid() function that draws a squared grid along my X and Y axis, which works fine. I have then created a menu() function (called in the main()), that toggles the grid on and off, here's the code for that:
void menu(int item)
{
switch (item)
{
case MENU_SWITCH_OFF_GRID:
{
if (gridActive == true)
{
gridActive = true;
}
}
break;
case MENU_SWITCH_ON_GRID:
{
if (gridActive == true)
{
gridActive = false;
}
}
break;
default:
{ /* Nothing */ }
break;
}
glutPostRedisplay();
return;
}
}
The menu switch works fine, as I have created a global variable called gridActive without a true or false value so it doesn't reset each time, that way it can be accessed in my display() function like so:
if (gridActive != true)
{
drawGrid();
gridActive = true;
}
All of this works just fine.
What's my issue?
My issue is, whenever I click the left mouse button, my grid disappears, which I don't want. So I've made a mouse() function like this:
case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN)
{
exit(0); // this has been added to see if
// my program will exit!
}
break;
To test if my program exits when I click the left mouse, and it does.
So instead of using exit(0); what code can i put here so that my grid doesn't disappear when I click the left mouse button? Or is the issue beyond that?
UPDATE:
Here's the mouse function:
void mouse(int button, int state, int x, int y)
{
// these have simply been set-up for me to use
// in the future
switch (button)
{
case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN)
{
}
break;
case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN)
{
}
break;
default: break;
}
}
Based on your code:
if (gridActive != true)
{
drawGrid();
gridActive = true;
}
You only draw the grid when gridActive is false. However, after every time you draw it, you set gridActive=true which will then stop it from being drawn.
Without more of your code, it's impossible to tell exactly what's going on, but these lines may not be doing what you think they are, and that may be causing some issues.
This never does anything.
if (gridActive == true)
{
gridActive = true;
}
This:
if (gridActive == true)
{
gridActive = false;
}
is the same as:
gridActive = false;
In order to tell what's going on, though, we need to know what happens when you click your mouse button when the exit call isn't there, but you didn't post that code yet.
Also, i don't quite know what you mean by:
I have created a global variable called gridActive without a true or false value so it doesn't reset each time
but it sounds like you made an uninitialized global variable and expect that it has some specific meaning because it's uninitialized?

How to make a loading screen state transition to game level state?

I am trying to make my basic loading screen transition over to game level screen. So what i wanted to do is, once the loading screen is active (or has appeared onscreen), I want at this point to start loading my game state. What it is doing at the moment is loading everything at the start, and this does take a while.
So currently my project starts off with a main menu. Then when i press enter, its starts the loading screen. I have my manual state change using keypresses like so:
void Game::update()
{
static bool enterPreviouslyPressed = false;
static bool escapePreviousPressed = false;
const Uint8 *keys = SDL_GetKeyboardState(NULL);
if (keys[::SDL_SCANCODE_ESCAPE] && !escapePreviousPressed && typeid(*fsm->getState()) == typeid(GameState))
{
fsm->setState(menuState);
}
else if (keys[::SDL_SCANCODE_RETURN] && !enterPreviouslyPressed && typeid(*fsm->getState()) == typeid(MainMenuState))
{
fsm->setState(loadingState);
}
else if ((keys[::SDL_SCANCODE_RETURN] && !enterPreviouslyPressed) && typeid(*fsm->getState()) == typeid(LoadScreenState))
{
fsm->setState(gameState);
}
else if (keys[::SDL_SCANCODE_ESCAPE] && !escapePreviousPressed && typeid(*fsm->getState()) == typeid(MainMenuState))
{
exit(0);
}
enterPreviouslyPressed = keys[::SDL_SCANCODE_RETURN] != 0;
escapePreviousPressed = keys[::SDL_SCANCODE_ESCAPE] != 0;
fsm->update();
}
I did this to initially does this so i could change states manually to check that everything works. I was wondering if there was an easy(ish) way, like boolean flags for example or another simpler way to do this. I wasn't able find any tutorials online so wondering if someone knows the best solution as to how to do this. I did see a question on here, kindda similar but I wasn't sure if it answered my question as the person did this in threads which I am not familiar with how to implement. Apologies if I dont seem to have the logic correct - so please advise otherwise.
Looks fairly standard, except I would simplify it by keeping two keyboard state variables declared as class variables, like:
const Uint8 *curKeys = SDL_GetKeyboardState(NULL), *prevKeys;
// ...
void Game::update() {
prevKeys = curKeys;
curKeys = = SDL_GetKeyboardState(NULL);
//and so then compare curKeys to prevkeys
//and ditch the booleans
// ...
}