terjemahan acak di GLUT menjadi buruk

ini kubusku. Setelah dibuat, ia memiliki posisi x acak pada -2, -1, 0, 1, atau 2.

void cube(void)
{
    srand (time(0));

    int cube_posX;
    int lowv = -2;
    int highv = 2;

    cube_posX = rand() % (highv - lowv + 1) + lowv;

    glTranslatef(cube_posX, 0.0, cube_angle);
    glRotatef(cube_angle, 90.0, 0.0, 1.0);
    glutSolidCube(0.25);
}

dan beginilah cara saya menggerakkan kubus ke depan secara perlahan

void MOVE_CUBE(int value)
{
    cube_posZ = cube_posZ - 0.01;
    glutPostRedisplay();
    glutTimerFunc(25, MOVE_CUBE, 0);
}

dan akhirnya menampilkannya:

void init(void)
{
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
}

float cam_eyeX = 0.0, cam_eyeY = 1.5, cam_eyeZ = 5.0;
float cam_centerX = 0.0, cam_centerY = 0.0, cam_centerZ = 0.0;
void display(void)
{
    glClearColor(1.0,1.0,1.0,1.0);      //to add background color (white)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(cam_eyeX, cam_eyeY, cam_eyeZ, cam_centerX, cam_centerY, cam_centerZ, 0.0, 1.0, 0.0);  //camera! (cam position X, cam position Y, cam position Z, cam target X, cam target Y, cam target Z,  up position X, up position Y, up position Z)

    cube();

    glutSwapBuffers();
    angle += 0.05; //to affect the glRotate function
    glFlush();
}

void reshape(int w, int h)
{
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    glMatrixMode (GL_MODELVIEW);
}


int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);      // Set up display buffer 
    glutInitWindowSize(750, 500);       //window's size
    glutInitWindowPosition(100, 100);   //window's position
    glutCreateWindow("Hendra Ganteng!");  //window's title
    init();
    glutDisplayFunc(display);
    glutIdleFunc (display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard_Handler);

    MOVE_CUBE(0);

    glutMainLoop();
    return 0;
}

Namun ketika saya melihatnya beraksi, kubus tersebut bergerak maju dengan sempurna, namun terus mengubah posisi x ke 5 kemungkinan tersebut (-2,-1,0,1,2) setiap 0,5 hingga 1 detik. Jika saya menonaktifkan srand(waktu(0)), kubus mengubah posisi x dengan cepat. Saya hanya ingin membuatnya tetap di posisi 1 x sehingga saya dapat memanggil lebih banyak kubus di posisi x berbeda. Bisakah seseorang tolong jelaskan apa yang salah dalam kode saya?


person Hendra Anggrian    schedule 04.06.2013    source sumber


Jawaban (1)


Bagaimana perilaku itu tidak diharapkan? Anda menghasilkan posisi X acak setiap kali Anda menampilkan kubus Anda. Jika Anda menyemai ulang generator nomor acak menggunakan waktu, maka urutannya akan berbeda setiap kali waktu berubah (sekali per detik).

Sebaliknya, Anda harus membuat kubus Anda terlebih dahulu. Bagaimana dengan ini:

// Global cube data
struct Cube {
    int x;
    double angle;
};

vector<Cube> cubes;
const int num_cubes = 1;

// Example initialisation...
void InitCubes()
{
    cubes.reserve(num_cubes);

    for( int i = 0; i < num_cubes; i++ )
    {
        Cube cube;
        cube.x = rand() % (highv - lowv + 1) + lowv;
        cube.angle = 0.0;
        cubes.push_back(cube);
    }
}

Sekarang siklus pembaruan/tampilan hanya perlu mengubah sudutnya, tetapi bukan posisi x.

void UpdateCube( Cube & cube )
{
    cube.angle += 0.05;
}

void DisplayCube( Cube & cube )
{
    glTranslatef((double)cube.x, 0.0, cube.angle);
    glRotatef(cube.angle, 90.0, 0.0, 1.0);
    glutSolidCube(0.25);
}

Di fungsi utama Anda, panggil InitCubes() saat startup.

Di fungsi tampilan Anda, lakukan ini:

void display(void)
{
    glClearColor(1.0,1.0,1.0,1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(cam_eyeX, cam_eyeY, cam_eyeZ, cam_centerX, cam_centerY, cam_centerZ, 0.0, 1.0, 0.0);    

    // Display cubes        
    for( int i = 0; i < cubes.size(); i++ ) DisplayCube( cubes[i] );

    glutSwapBuffers();
    glFlush();

    // Update cubes for next render cycle.
    for( int i = 0; i < cubes.size(); i++ ) UpdateCube( cubes[i] );
}
person paddy    schedule 04.06.2013
comment
Sepertinya saya memiliki masalah saat membuat kubus terlebih dahulu, saya tidak mengerti di bagian mana perulangan for berada. Saya salin dan tempel kode Anda di bawah fungsi tampilan kosong (void) pada kode sumber saya di atas, hasilnya kubus masih berpindah posisi x dengan cepat.. Saya bukan ahli pemrograman seperti banyak orang di sini, saya akan menghargai penjelasan yang lebih sederhana . Terima kasih! - person Hendra Anggrian; 04.06.2013
comment
Ketika kita berbicara tentang pembuatan, dan khususnya pra-pembuatan, yang kami maksud adalah melakukannya sekali sebelum kode lainnya. Artinya, jangan membuat di dalam fungsi display Anda. Intinya adalah Anda membuat kubus dalam posisi acak sekali, lalu memperbarui dan menampilkannya berkali-kali. - person paddy; 05.06.2013
comment
Anda harus meneruskan instance Cube ke dalam fungsi! Saya mengedit jawaban saya untuk mencoba memperjelas bagaimana Anda seharusnya menggunakan kode tersebut. - person paddy; 05.06.2013
comment
Anda baik sekali, saya sangat menghargainya. Tapi entah kenapa kubusnya tetap di posisi yang sama x = 1. Tidak peduli berapa banyak num_cubes yang saya tambahkan atau berapa kali saya mencobanya, posisi x sekarang tetap di 1.. - person Hendra Anggrian; 06.06.2013
comment
Pastikan Anda tidak menggunakan variabel posisi dan sudut lama tersebut selama tampilan. Sangat mudah untuk secara tidak sengaja lupa menggunakan yang baru (dalam struktur Cube). Jika ragu, silakan edit pertanyaan Anda dan kirimkan kode Anda saat ini. Hal lain yang perlu dipertimbangkan adalah jika Anda hanya memiliki satu kubus, Anda perlu menyemai generator angka acak - cara umum untuk melakukannya adalah srand(time(0));. Lakukan ini sekali pada awal program Anda, sebelum panggilan apa pun ke rand() dilakukan. - person paddy; 06.06.2013
comment
benar-benar berfungsi setelah beberapa menit mencoba memahami logikanya, terima kasih telah sangat membantu! - person Hendra Anggrian; 06.06.2013
comment
oh saya mendapat 1 kekhawatiran lagi: Saya menggunakan glutTimerFunc untuk memindahkan posisi kubus z dengan lancar (lihat fungsi saya MOVE_CUBE di atas). bisakah itu digunakan dalam banyak kubus dalam kode Anda? atau apakah saya perlu mencari cara lain untuk melakukannya? - person Hendra Anggrian; 06.06.2013
comment
Di situlah fungsi pembaruan Anda berperan. Cukup tambahkan posisi z ke struktur Cube dan perbarui sesuai dengan itu. Daripada memanggil UpdateCube dari fungsi display Anda, mungkin Anda ingin memanggilnya dari MOVE_CUBE. - person paddy; 06.06.2013