Помогите понять некоторые вещи OpenGL - PullRequest
1 голос
/ 23 апреля 2010

Я работаю с некоторым кодом, чтобы создать треугольник, который перемещается с помощью клавиш со стрелками. Я хочу создать второй объект, который движется независимо. Вот где у меня проблемы, я создал второго актера, но не могу заставить его двигаться. Слишком много кода, чтобы опубликовать все это, поэтому я просто напишу немного и посмотрю, может ли кто-нибудь помочь.

ogl_test.cpp

#include "platform.h"
#include "srt/scheduler.h"

#include "model.h"
#include "controller.h"

#include "model_module.h"
#include "graphics_module.h"

class blob : public actor {
public:
    blob(float x, float y) : actor(math::vector2f(x, y)) { }

    void render() {
        transform();

        glBegin(GL_TRIANGLES);
            glVertex3f(0.25f, 0.0f, -5.0f);
            glVertex3f(-.5f, 0.25f, -5.0f);
            glVertex3f(-.5f, -0.25f, -5.0f);
        glEnd();
        end_transform();
    }
    void update(controller& c, float dt) {
        if (c.left_key) {
            rho += pi / 9.0f * dt;
            c.left_key = false;
        }
        if (c.right_key) {
            rho -= pi / 9.0f * dt;
            c.right_key = false;
        }
        if (c.up_key) {
            v += .1f * dt;
            c.up_key = false;
        }
        if (c.down_key) {
            v -= .1f * dt;
            if (v < 0.0) { v = 0.0; }
            c.down_key = false;
        }
        actor::update(c, dt);
    }
};

class enemyOne : public actor {
public:
    enemyOne(float x, float y) : actor(math::vector2f(x, y)) { }

    void render() {
        transform();

        glBegin(GL_TRIANGLES);
            glVertex3f(0.25f, 0.0f, -5.0f);
            glVertex3f(-.5f, 0.25f, -5.0f);
            glVertex3f(-.5f, -0.25f, -5.0f);
        glEnd();
        end_transform();
    }
    void update(controller& c, float dt) {
        if (c.left_key) {
            rho += pi / 9.0f * dt;
            c.left_key = false;
        }
        if (c.right_key) {
            rho -= pi / 9.0f * dt;
            c.right_key = false;
        }
        if (c.up_key) {
            v += .1f * dt;
            c.up_key = false;
        }
        if (c.down_key) {
            v -= .1f * dt;
            if (v < 0.0) { v = 0.0; }
            c.down_key = false;
        }
        actor::update(c, dt);
    }
};

int APIENTRY WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    char* lpCmdLine,
    int nCmdShow
)
{

    model m;
    controller control(m);

    srt::scheduler scheduler(33);
    srt::frame* model_frame = new srt::frame(scheduler.timer(), 0, 1, 2);
    srt::frame* render_frame = new srt::frame(scheduler.timer(), 1, 1, 2);
    model_frame->add(new model_module(m, control));

    render_frame->add(new graphics_module(m));

    scheduler.add(model_frame);
    scheduler.add(render_frame);

    blob* prime = new blob(0.0f, 0.0f);
    m.add(prime);
    m.set_prime(prime);

    enemyOne* primeTwo = new enemyOne(2.0f, 0.0f);
    m.add(primeTwo);
    m.set_prime(primeTwo);

    scheduler.start();
    control.start();

    return 0;
}

model.h

#include <vector>
#include "vec.h"

const double pi = 3.14159265358979323;

class controller;

using math::vector2f;

class actor {
public:
    vector2f P;
    float theta;
    float v;
    float rho;

    actor(const vector2f& init_location) :
        P(init_location),
        rho(0.0),
        v(0.0),
        theta(0.0)
    { }
    virtual void render() = 0;
    virtual void update(controller&, float dt) {
        float v1 = v;
        float theta1 = theta + rho * dt;
        vector2f P1 = P + v1 * vector2f(cos(theta1), sin(theta1));
        if (P1.x < -4.5f || P1.x > 4.5f) { P1.x = -P1.x; }
        if (P1.y < -4.5f || P1.y > 4.5f) { P1.y = -P1.y; }
        v = v1;
        theta = theta1;
        P = P1;
    }

protected:
    void transform() {
        glPushMatrix();
        glTranslatef(P.x, P.y, 0.0f);
        glRotatef(theta * 180.0f / pi, 0.0f, 0.0f, 1.0f); //Rotate about the z-axis
    }
    void end_transform() {
        glPopMatrix();
    }
};

class model {
private:
    typedef std::vector<actor*> actor_vector;
    actor_vector actors;
public:
    actor* _prime;

    model() { }

    void add(actor* a) {
        actors.push_back(a);
    }
    void set_prime(actor* a) {
        _prime = a;
    }
    void update(controller& control, float dt) {
        for (actor_vector::iterator i = actors.begin(); i != actors.end(); ++i) {
            (*i)->update(control, dt);
        }
    }
    void render() {
        for (actor_vector::iterator i = actors.begin(); i != actors.end(); ++i) {
            (*i)->render();
        }
    }
};

Ответы [ 2 ]

3 голосов
/ 16 марта 2011

Ваш blob стирает нажатия клавиш до того, как их увидит второй актер:

if (c.left_key) {
   rho += pi / 9.0f * dt;
   c.left_key = false; // <-- HERE
}

Очистка состояния клавиатуры после каждого кадра не должна касаться какого-либо отдельного субъекта, это должен делать сам контроллер.

1 голос
/ 16 марта 2011

И blob, и врагиOne имеют функцию обновления, которая проверяет клавиши со стрелками, чтобы увидеть, нужно ли двигаться. Если вы закомментировали все операторы if внутри одной из функций обновления, то он больше не должен двигаться. В качестве альтернативы вы можете изменить операторы if в функции обновления, чтобы проверить другие ключи и использовать их для управления другим объектом.

РЕДАКТИРОВАТЬ: Как отмечено в другом ответе, когда вы устанавливаете c.left_key = false; (или одну на других клавишах) вы не позволяете другим актерам видеть, что клавиша была нажата. Либо не передавая контроллер в качестве ссылки, либо удаляя эти строки кода, это должно исправить.

...