修复使用枚举组织事件处理的代码
Fixing code that uses enums to organize event handling
当我运行下面的代码时,我期望的结果是按下三个按钮中的每一个都会触发一个匹配状态,该状态会呈现与这些按钮相邻的匹配图像,从而允许我在新图像之间旋转每次连续按下按钮都在闲暇。
不是那个令人愉快的场景,任何初始按钮按下都会直接跳到最后一个图像...或者什么也不做...或者呈现空白屏幕,具体取决于我 fiddle 我如何放置初始状态声明以及我是否将状态开关置于事件处理开关之内或之外。整个系统崩溃并停在了轨道上。这是怎么回事,我该如何解决?
#include <string>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include "cleanup.h"
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Rect* clip = NULL;
const int LONGBUTTON_HEIGHT = 128;
const int LONGBUTTON_WIDTH = 256;
int Screen_Width = 640;
int Screen_Height = 480;
int mouse_x;
int mouse_y;
int alphabutton_x = 0;
int alphabutton_y = 5;
int alphabutton_h = Screen_Width / 10;
int alphabutton_w = Screen_Width / 5;
int betabutton_x = 0;
int betabutton_y = 0.5 * (Screen_Width / 5) + 5;
int betabutton_h = Screen_Width / 10;
int betabutton_w = Screen_Width / 5;
int gammabutton_x = 0;
int gammabutton_y = 1 * (Screen_Width / 5) + 5;
int gammabutton_h = Screen_Width / 10;
int gammabutton_w = Screen_Width / 5;
int alpha_x = Screen_Width / 5;
int alpha_y = 0;
int alpha_h = Screen_Height;
int alpha_w = (4* Screen_Width)/5;
int beta_x = Screen_Width / 5;
int beta_y = 0;
int beta_h = Screen_Height;
int beta_w = (4* Screen_Width)/5;
int gamma_x = Screen_Width / 5;
int gamma_y = 0;
int gamma_h = Screen_Height;
int gamma_w = (4* Screen_Width)/5;
enum alphaButtonSprite {ALPHA_DEFAULT, ALPHA_HOVER, ALPHA_INACTIVE, ALPHA_PRESSED, ALPHA_TOTAL};
enum betaButtonSprite {BETA_DEFAULT, BETA_HOVER, BETA_INACTIVE, BETA_PRESSED, BETA_TOTAL};
enum gammaButtonSprite {GAMMA_DEFAULT, GAMMA_HOVER, GAMMA_INACTIVE, GAMMA_PRESSED, GAMMA_TOTAL};
enum State {ALPHA_STATE, BETA_STATE, GAMMA_STATE};
State state;
SDL_Texture* loadTexture(const std::string& file, SDL_Renderer* renderer)
{
SDL_Texture* texture = IMG_LoadTexture(renderer, file.c_str());
return texture;
}
void renderTexture(SDL_Texture* texture, SDL_Renderer* renderer, SDL_Rect dest,
SDL_Rect* clip = nullptr)
{
SDL_RenderCopy(renderer, texture, clip, &dest);
}
void renderTexture(SDL_Texture* texture, SDL_Renderer* renderer, int x, int y, int h, int w,
SDL_Rect* clip = nullptr)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
dest.h = h;
dest.w = w;
renderTexture(texture, renderer, dest, clip);
}
// Main Function
int main(int, char**)
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("New Window", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, Screen_Width, Screen_Height, SDL_WINDOW_RESIZABLE);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Texture* longbutton_image = loadTexture("longbuttonSpriteSheet.png", renderer);
SDL_Texture* alpha_image = loadTexture("alphaImage.png", renderer);
SDL_Texture* beta_image = loadTexture("betaImage.png", renderer);
SDL_Texture* gamma_image = loadTexture("gammaImage.png", renderer);
state = BETA_STATE;
SDL_Rect alpha_clips[alphaButtonSprite::ALPHA_TOTAL];
for (int i = 0; i < alphaButtonSprite::ALPHA_TOTAL; i++)
{
alpha_clips[i].x = i * LONGBUTTON_WIDTH;
alpha_clips[i].y = 0;
alpha_clips[i].w = LONGBUTTON_WIDTH;
alpha_clips[i].h = LONGBUTTON_HEIGHT;
}
int usealpha_Clip = ALPHA_DEFAULT;
SDL_Rect beta_clips[betaButtonSprite::BETA_TOTAL];
for (int i = 0; i < betaButtonSprite::BETA_TOTAL; i++)
{
beta_clips[i].x = i * LONGBUTTON_WIDTH;
beta_clips[i].y = 4 * LONGBUTTON_HEIGHT;
beta_clips[i].w = LONGBUTTON_WIDTH;
beta_clips[i].h = LONGBUTTON_HEIGHT;
}
int usebeta_Clip = BETA_DEFAULT;
SDL_Rect gamma_clips[gammaButtonSprite::GAMMA_TOTAL];
for (int i = 0; i < gammaButtonSprite::GAMMA_TOTAL; i++)
{
gamma_clips[i].x = i * LONGBUTTON_WIDTH;
gamma_clips[i].y = 5 * LONGBUTTON_HEIGHT;
gamma_clips[i].w = LONGBUTTON_WIDTH;
gamma_clips[i].h = LONGBUTTON_HEIGHT;
}
int usegamma_Clip = GAMMA_DEFAULT;
SDL_Event e;
bool quit = false;
while (!quit)
{
while (SDL_PollEvent(&e))
{
switch (e.type)
{
case SDL_MOUSEBUTTONDOWN:
mouse_x = e.button.x;
mouse_y = e.button.y;
if ((mouse_x <= (alphabutton_x + alphabutton_w)) && (mouse_x > alphabutton_x) &&
(mouse_y <= (alphabutton_y + alphabutton_h)) && (mouse_y > alphabutton_y))
usealpha_Clip = ALPHA_PRESSED;
state = ALPHA_STATE;
if ((mouse_x <= (betabutton_x + betabutton_w)) && (mouse_x > betabutton_x) &&
(mouse_y <= (betabutton_y + betabutton_h)) && (mouse_y > betabutton_y))
usebeta_Clip = BETA_PRESSED;
state = BETA_STATE;
if ((mouse_x <= (gammabutton_x + gammabutton_w)) && (mouse_x > gammabutton_x) &&
(mouse_y <= (gammabutton_y + gammabutton_h)) && (mouse_y > gammabutton_y))
usegamma_Clip = GAMMA_PRESSED;
state = GAMMA_STATE;
break;
}
}
switch (state)
{
case ALPHA_STATE:
SDL_RenderClear(renderer);
renderTexture(longbutton_image, renderer, alphabutton_x, alphabutton_y, alphabutton_h, alphabutton_w, &alpha_clips[usealpha_Clip]);
renderTexture(longbutton_image, renderer, betabutton_x, betabutton_y, betabutton_h, betabutton_w, &beta_clips[usebeta_Clip]);
renderTexture(longbutton_image, renderer, gammabutton_x, gammabutton_y, gammabutton_h, gammabutton_w, &gamma_clips[usegamma_Clip]);
renderTexture(alpha_image, renderer, alpha_x, alpha_y, alpha_h, alpha_w, nullptr);
SDL_RenderPresent(renderer);
break;
case BETA_STATE:
SDL_RenderClear(renderer);
renderTexture(longbutton_image, renderer, alphabutton_x, alphabutton_y, alphabutton_h, alphabutton_w, &alpha_clips[usealpha_Clip]);
renderTexture(longbutton_image, renderer, betabutton_x, betabutton_y, betabutton_h, betabutton_w, &beta_clips[usebeta_Clip]);
renderTexture(longbutton_image, renderer, gammabutton_x, gammabutton_y, gammabutton_h, gammabutton_w, &gamma_clips[usegamma_Clip]);
renderTexture(beta_image, renderer, beta_x, beta_y, beta_h, beta_w, nullptr);
SDL_RenderPresent(renderer);
break;
case GAMMA_STATE:
SDL_RenderClear(renderer);
renderTexture(longbutton_image, renderer, alphabutton_x, alphabutton_y, alphabutton_h, alphabutton_w, &alpha_clips[usealpha_Clip]);
renderTexture(longbutton_image, renderer, betabutton_x, betabutton_y, betabutton_h, betabutton_w, &beta_clips[usebeta_Clip]);
renderTexture(longbutton_image, renderer, gammabutton_x, gammabutton_y, gammabutton_h, gammabutton_w, &gamma_clips[usegamma_Clip]);
renderTexture(gamma_image, renderer, gamma_x, gamma_y, gamma_h, gamma_w, nullptr);
SDL_RenderPresent(renderer);
break;
}
}
//Destroy the various items
cleanup(longbutton_image, alpha_image, beta_image, gamma_image, renderer, window);
IMG_Quit();
SDL_Quit();
return 0;
}
找到了这个问题的答案。在 mousebuttondown 事件切换的情况下,只需将状态代码放在 useclip 代码之前。为什么它会有所作为,我不知道,但它确实有效。咳咳……此外,在 mousebuttonup 开关盒中执行此操作而不是在 mousebuttondown 中执行此操作效果更好。
当我运行下面的代码时,我期望的结果是按下三个按钮中的每一个都会触发一个匹配状态,该状态会呈现与这些按钮相邻的匹配图像,从而允许我在新图像之间旋转每次连续按下按钮都在闲暇。
不是那个令人愉快的场景,任何初始按钮按下都会直接跳到最后一个图像...或者什么也不做...或者呈现空白屏幕,具体取决于我 fiddle 我如何放置初始状态声明以及我是否将状态开关置于事件处理开关之内或之外。整个系统崩溃并停在了轨道上。这是怎么回事,我该如何解决?
#include <string>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include "cleanup.h"
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Rect* clip = NULL;
const int LONGBUTTON_HEIGHT = 128;
const int LONGBUTTON_WIDTH = 256;
int Screen_Width = 640;
int Screen_Height = 480;
int mouse_x;
int mouse_y;
int alphabutton_x = 0;
int alphabutton_y = 5;
int alphabutton_h = Screen_Width / 10;
int alphabutton_w = Screen_Width / 5;
int betabutton_x = 0;
int betabutton_y = 0.5 * (Screen_Width / 5) + 5;
int betabutton_h = Screen_Width / 10;
int betabutton_w = Screen_Width / 5;
int gammabutton_x = 0;
int gammabutton_y = 1 * (Screen_Width / 5) + 5;
int gammabutton_h = Screen_Width / 10;
int gammabutton_w = Screen_Width / 5;
int alpha_x = Screen_Width / 5;
int alpha_y = 0;
int alpha_h = Screen_Height;
int alpha_w = (4* Screen_Width)/5;
int beta_x = Screen_Width / 5;
int beta_y = 0;
int beta_h = Screen_Height;
int beta_w = (4* Screen_Width)/5;
int gamma_x = Screen_Width / 5;
int gamma_y = 0;
int gamma_h = Screen_Height;
int gamma_w = (4* Screen_Width)/5;
enum alphaButtonSprite {ALPHA_DEFAULT, ALPHA_HOVER, ALPHA_INACTIVE, ALPHA_PRESSED, ALPHA_TOTAL};
enum betaButtonSprite {BETA_DEFAULT, BETA_HOVER, BETA_INACTIVE, BETA_PRESSED, BETA_TOTAL};
enum gammaButtonSprite {GAMMA_DEFAULT, GAMMA_HOVER, GAMMA_INACTIVE, GAMMA_PRESSED, GAMMA_TOTAL};
enum State {ALPHA_STATE, BETA_STATE, GAMMA_STATE};
State state;
SDL_Texture* loadTexture(const std::string& file, SDL_Renderer* renderer)
{
SDL_Texture* texture = IMG_LoadTexture(renderer, file.c_str());
return texture;
}
void renderTexture(SDL_Texture* texture, SDL_Renderer* renderer, SDL_Rect dest,
SDL_Rect* clip = nullptr)
{
SDL_RenderCopy(renderer, texture, clip, &dest);
}
void renderTexture(SDL_Texture* texture, SDL_Renderer* renderer, int x, int y, int h, int w,
SDL_Rect* clip = nullptr)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
dest.h = h;
dest.w = w;
renderTexture(texture, renderer, dest, clip);
}
// Main Function
int main(int, char**)
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("New Window", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, Screen_Width, Screen_Height, SDL_WINDOW_RESIZABLE);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Texture* longbutton_image = loadTexture("longbuttonSpriteSheet.png", renderer);
SDL_Texture* alpha_image = loadTexture("alphaImage.png", renderer);
SDL_Texture* beta_image = loadTexture("betaImage.png", renderer);
SDL_Texture* gamma_image = loadTexture("gammaImage.png", renderer);
state = BETA_STATE;
SDL_Rect alpha_clips[alphaButtonSprite::ALPHA_TOTAL];
for (int i = 0; i < alphaButtonSprite::ALPHA_TOTAL; i++)
{
alpha_clips[i].x = i * LONGBUTTON_WIDTH;
alpha_clips[i].y = 0;
alpha_clips[i].w = LONGBUTTON_WIDTH;
alpha_clips[i].h = LONGBUTTON_HEIGHT;
}
int usealpha_Clip = ALPHA_DEFAULT;
SDL_Rect beta_clips[betaButtonSprite::BETA_TOTAL];
for (int i = 0; i < betaButtonSprite::BETA_TOTAL; i++)
{
beta_clips[i].x = i * LONGBUTTON_WIDTH;
beta_clips[i].y = 4 * LONGBUTTON_HEIGHT;
beta_clips[i].w = LONGBUTTON_WIDTH;
beta_clips[i].h = LONGBUTTON_HEIGHT;
}
int usebeta_Clip = BETA_DEFAULT;
SDL_Rect gamma_clips[gammaButtonSprite::GAMMA_TOTAL];
for (int i = 0; i < gammaButtonSprite::GAMMA_TOTAL; i++)
{
gamma_clips[i].x = i * LONGBUTTON_WIDTH;
gamma_clips[i].y = 5 * LONGBUTTON_HEIGHT;
gamma_clips[i].w = LONGBUTTON_WIDTH;
gamma_clips[i].h = LONGBUTTON_HEIGHT;
}
int usegamma_Clip = GAMMA_DEFAULT;
SDL_Event e;
bool quit = false;
while (!quit)
{
while (SDL_PollEvent(&e))
{
switch (e.type)
{
case SDL_MOUSEBUTTONDOWN:
mouse_x = e.button.x;
mouse_y = e.button.y;
if ((mouse_x <= (alphabutton_x + alphabutton_w)) && (mouse_x > alphabutton_x) &&
(mouse_y <= (alphabutton_y + alphabutton_h)) && (mouse_y > alphabutton_y))
usealpha_Clip = ALPHA_PRESSED;
state = ALPHA_STATE;
if ((mouse_x <= (betabutton_x + betabutton_w)) && (mouse_x > betabutton_x) &&
(mouse_y <= (betabutton_y + betabutton_h)) && (mouse_y > betabutton_y))
usebeta_Clip = BETA_PRESSED;
state = BETA_STATE;
if ((mouse_x <= (gammabutton_x + gammabutton_w)) && (mouse_x > gammabutton_x) &&
(mouse_y <= (gammabutton_y + gammabutton_h)) && (mouse_y > gammabutton_y))
usegamma_Clip = GAMMA_PRESSED;
state = GAMMA_STATE;
break;
}
}
switch (state)
{
case ALPHA_STATE:
SDL_RenderClear(renderer);
renderTexture(longbutton_image, renderer, alphabutton_x, alphabutton_y, alphabutton_h, alphabutton_w, &alpha_clips[usealpha_Clip]);
renderTexture(longbutton_image, renderer, betabutton_x, betabutton_y, betabutton_h, betabutton_w, &beta_clips[usebeta_Clip]);
renderTexture(longbutton_image, renderer, gammabutton_x, gammabutton_y, gammabutton_h, gammabutton_w, &gamma_clips[usegamma_Clip]);
renderTexture(alpha_image, renderer, alpha_x, alpha_y, alpha_h, alpha_w, nullptr);
SDL_RenderPresent(renderer);
break;
case BETA_STATE:
SDL_RenderClear(renderer);
renderTexture(longbutton_image, renderer, alphabutton_x, alphabutton_y, alphabutton_h, alphabutton_w, &alpha_clips[usealpha_Clip]);
renderTexture(longbutton_image, renderer, betabutton_x, betabutton_y, betabutton_h, betabutton_w, &beta_clips[usebeta_Clip]);
renderTexture(longbutton_image, renderer, gammabutton_x, gammabutton_y, gammabutton_h, gammabutton_w, &gamma_clips[usegamma_Clip]);
renderTexture(beta_image, renderer, beta_x, beta_y, beta_h, beta_w, nullptr);
SDL_RenderPresent(renderer);
break;
case GAMMA_STATE:
SDL_RenderClear(renderer);
renderTexture(longbutton_image, renderer, alphabutton_x, alphabutton_y, alphabutton_h, alphabutton_w, &alpha_clips[usealpha_Clip]);
renderTexture(longbutton_image, renderer, betabutton_x, betabutton_y, betabutton_h, betabutton_w, &beta_clips[usebeta_Clip]);
renderTexture(longbutton_image, renderer, gammabutton_x, gammabutton_y, gammabutton_h, gammabutton_w, &gamma_clips[usegamma_Clip]);
renderTexture(gamma_image, renderer, gamma_x, gamma_y, gamma_h, gamma_w, nullptr);
SDL_RenderPresent(renderer);
break;
}
}
//Destroy the various items
cleanup(longbutton_image, alpha_image, beta_image, gamma_image, renderer, window);
IMG_Quit();
SDL_Quit();
return 0;
}
找到了这个问题的答案。在 mousebuttondown 事件切换的情况下,只需将状态代码放在 useclip 代码之前。为什么它会有所作为,我不知道,但它确实有效。咳咳……此外,在 mousebuttonup 开关盒中执行此操作而不是在 mousebuttondown 中执行此操作效果更好。