【问题标题】:SDL2.0 moving Sprite with keyboardSDL2.0 带键盘的移动精灵
【发布时间】:2014-04-14 00:28:28
【问题描述】:

我一直在使用 SDL2.0 和 C++ 开发这款游戏,但遇到了麻烦。我已经创建了移动函数并调用了正确的矩形。并且在主循环中调用了 move 函数,它就是不动。

这是代码。

//
//  Window.cpp
//  Galaxy Shooter
//
//  Created by Samrith on 02/03/14.
//  Copyright (c) 2014 Sam Shankar. All rights reserved.
//

#include "Window.h"

void Window::create() {
    Resources r;

    SDL_Init(SDL_INIT_EVERYTHING);

    window = SDL_CreateWindow("Galaxy Shooter", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    screen = SDL_GetWindowSurface(window);

    if(window == NULL)
        std::cout << " Window cannot be created. Error: " << SDL_GetError();

    else {
        r.load();
        SDL_UpdateWindowSurface(window);
    }
}

void Window::destroy() {
    Resources r;
    SDL_DestroyWindow(window);
    r.free();
    SDL_Quit();
}

void Window::run() {
    bool done = false;
    Resources r;
    create();
    while(!done)
    {
        while(SDL_PollEvent(&event) != 0)
        {
            if(event.type == SDL_QUIT)
            {
                done = true;
                destroy();
            }
            r.move(event); //This is the move function
            SDL_UpdateWindowSurface(window);
        }
        r.projectile();
        SDL_UpdateWindowSurface(window);
    }
}

SDL_Window * Window::getWindow() {
    return window;
}

SDL_Surface * Window::getSurface() {
    return screen;
}

这里是包含移动功能的资源源文件:

//
//  Resources.cpp
//  Galaxy Shooter
//
//  Created by Samrith on 06/03/14.
//  Copyright (c) 2014 Sam Shankar. All rights reserved.
//

#include "Resources.h"

bool b[4] = {0, 0, 0, 0};

void Resources::load() {

    background();
    rocket();
    //r.create();
}

void Resources::free() {
    Sound s;

    SDL_FreeSurface(bgimage);
    SDL_FreeSurface(rimage);
    //SDL_FreeSurface(screen);
    s.destroy();
}

//void Resources::run() {
//    Window w;
//    w.run();
//}

void Resources::background() {
    Window w;
    Sound s;

    //Load screen
    screen = SDL_GetWindowSurface(w.getWindow());

    if(screen == NULL)
        std::cout << "Surface (background) error: " << SDL_GetError();

    //Load image
    bgimage = IMG_Load("bg2.jpg");

    if(bgimage == NULL)
        std::cout << "Image (background) error: " << SDL_GetError();

    //Load rectangle and set values
    bgrect.x = 0;
    bgrect.y = 0;
    bgrect.h = w.screenH();
    bgrect.w = w.screenW();

    //Blit image to screen
    SDL_BlitScaled(bgimage, NULL, screen, &bgrect);
    s.init(1);
}

void Resources::rocket() {
    Window w;
    Sound s;

    //Load screen
    screen = SDL_GetWindowSurface(w.getWindow());

    if(screen == NULL)
        std::cout << "Surface (rocket) error: " << SDL_GetError();

    //Load image
    rimage = IMG_Load("rocket.png");

    if(rimage == NULL)
        std::cout << "Image (rocket) error: " << SDL_GetError();

    //Load rectangle and set values
    rrect.x = 15;
    rrect.y = w.screenH()/2;
    rrect.h = 75;
    rrect.w = 75;

    //Blit image to screen
    SDL_BlitScaled(rimage, NULL, screen, &rrect);
    //s.init(2);
}

void Resources::move(SDL_Event event) {
    //bool done = false;
    Window w;

    switch(event.type)
    {
        case SDL_KEYDOWN:
            switch(event.key.keysym.sym)
            {
                case SDLK_UP:
                    b[0] = 1; break;

                case SDLK_DOWN:
                    b[1] = 1; break;

                case SDLK_RIGHT:
                    b[2] = 1; break;

                case SDLK_LEFT:
                    b[3] = 1; break;
            }
            break;

        case SDL_KEYUP:
            switch(event.key.keysym.sym)
            {
                case SDLK_UP:
                    b[0] = 0; break;

                case SDLK_DOWN:
                    b[1] = 0; break;

                case SDLK_RIGHT:
                    b[2] = 0; break;

                case SDLK_LEFT:
                    b[3] = 0; break;
            }
            break;
    }

    if(b[0]==true)
        rrect.y += 10;
    if(b[1]==true)
        rrect.y -= 10;
    if(b[2]==true)
        rrect.x += 10;
    if(b[3]==true)
        rrect.x -= 10;
}

void Resources::projectile() {
    Window w;
    SDL_PumpEvents();
    int x, y;
    SDL_GetMouseState(&x, &y);
    if(SDL_GetMouseState(&x, &y) & SDL_BUTTON(1))
    {
        rrect.x = x;
        rrect.y = y;
        SDL_BlitScaled(rimage, NULL, screen, &rrect);
        for(int i=rrect.x; i<=w.screenW(); i++)
            rrect.x+=2;

    }
}

另外,我用谷歌搜索了这个问题并尝试了各种教程和文档。这是我最后的手段,而不是我第一次求助于这个问题。所以请善待。 :)

【问题讨论】:

  • 在我看来,您的问题是您声明了 Resources r;在每个函数的堆栈上。例如,当您调用 void Window::create() 时,您声明 r 并加载它加载的任何内容,但只要函数返回 r 就会被销毁。所以你在 run 中声明的 r 永远不会调用它的 load() 函数。
  • @Hjorthenify 我明白你的意思。所以我应该理想地创建一个全局 r 并在整个函数中使用它,以确保它不会超出范围?
  • 全局变量被认为是不好的做法,您应该将其作为窗口类的成员变量。
  • @Hjorthenify 是的,我确实将“Resources r”定义为 Window 类的私有成员,但它给了我构建错误。谷歌了一下,有些地方说不允许。
  • 那么在这种情况下,你的问题不在于移动你的精灵,而是如何进行正确的面向对象编程。

标签: c++ sdl-2


【解决方案1】:

通过在每个函数中声明Resource r,您每次都会创建Resource 类的新实例,从而创建许多不同的Resource 对象。

您在 Resource 类的每个函数中声明的 Window w 变量也是如此:每个函数调用都会创建一个新窗口。

我建议您阅读有关面向对象编程和变量作用域的内容。

此外,C++ 并不是开始学习面向对象编程的最友好的语言。

如果您刚开始,我建议您切换到更简单的语言,例如 Java 或 C#。

祝你好运。

【讨论】:

    猜你喜欢
    • 2021-03-30
    • 1970-01-01
    • 2018-03-21
    • 2016-01-21
    • 1970-01-01
    • 2015-05-20
    • 1970-01-01
    • 2021-06-15
    • 2015-01-11
    相关资源
    最近更新 更多