Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Game design : Smooth movement of an object

  1. #1
    Newbie Newbie
    Join Date
    May 2013
    Posts
    2

    Game design : Smooth movement of an object

    Hey guys,
    I was coding brick breaker game and i have written code so as to move the paddle when the user presses LEFT/RIGHT arrow key.but it doesnt move smoothly.. please help me to code it so as to move smoothly and one more thing - whenever i move the paddle, the ball in the game gets redrawn. I guess bricks also gets redrawn. I dont want that to happen is there any way i could bypass it??

    /*Re-post
    one more thing, if you observe the output, some bricks tend a bit offside(though x cordinates are same for every row) example, just see the red-row . Do you know why this happens?? are there any corrections ??
    Here is the code
    */

    Code :
    #include<stdlib.h>
    #include<dos.h>
    #include<time.h>
    #include<windows.h>
    #include<stdio.h>
    #include <cmath>
    #include<GL/glut.h>
    float fx1=46,ex1=114.9,fx2=115.9,ex2=184.8,fx3=185.8,ex3=254.7,fx4=255.7,ex4=324.6,fx5=325.6,ex5=394.5,fx6=395.5,ex6=464.4,fx7=465.4,ex7=534.3,fx8=535.3,ex8=604.2,fx9=605.2,ex9=674.1,fx10=675.1,ex10=744;
     
    float fy1=700,ey1=670,fy2=668,ey2=638,fy3=636,ey3=606,fy4=604,ey4=574,fy5=572,ey5=542,fy6=540,ey6=510;
     
    float bx=395,by=53;
    float px=325,py=10,pz=0;
    float move_unit = 1;
    float dx=1;
    float cx=3;
    void keyboardown(int key, int x, int y)
    {
        switch (key){
            case GLUT_KEY_RIGHT:
    			for(int i=0;i<25;i++)
                px+=move_unit*dx*cx;;
                break;
     
            case GLUT_KEY_LEFT:
               for(int i=0;i<25;i++)
                px-=move_unit*dx*cx;;
            break;
     
           default:
             break;
        }
        glutPostRedisplay();
    }
     
    void border()
    {
    	glClear(GL_COLOR_BUFFER_BIT);
    	glLineWidth(30);
    	glColor3f(0.4,0.4,0.4);
    	glBegin(GL_LINE_STRIP);
    	glVertex2f(30,5);
    	glVertex2f(30,770);
    	glVertex2f(760,770);
    	glVertex2f(760,5);
    	glEnd();
    	glColor3f(1,1,1);
    	glLineWidth(2);
    	glBegin(GL_LINES);
    	glVertex2f(20,5);
    	glVertex2f(20,765);
    	glEnd();
    	glBegin(GL_LINES);
    	glVertex2f(30,780);
    	glVertex2f(750,780);
    	glEnd();
    	glBegin(GL_LINES);
    	glVertex2f(750,5);
    	glVertex2f(750,730);
    	glEnd();
    	glPointSize(2);
    	glBegin(GL_POINTS);
    	glVertex2f(750,735);
    	glVertex2f(750,740);
    	glEnd();
    	glutSwapBuffers();
    	glFlush();
    }
    void outtext(char *string,float x,float y) 
    { 
    char *c;
    glRasterPos2f(x,y);
    for (c=string; *c != '\0'; c++) 
    {
    glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *c);
    }
    }
    void waitFor(unsigned int secs) {
        int retTime = time(0) + secs;     
        while (time(0) < retTime);    
    }
    void scoreboard()
    {
    	glColor3f(1,0,0);
    	outtext("Score:",820,700);
    	glutSwapBuffers();
    	waitFor(5);
    	glColor3f(0,0,0);
    	outtext("Score:",820,700);
    	glColor3f(1,0,0);
    	outtext("Test",820,700);
    	glutSwapBuffers();
    }
    void bricks()
    {
    	{
    		glLineWidth(30);
    		glColor3f(0.5,0.5,0.5);
    		glBegin(GL_LINES);
    		glVertex2f(fx1,fy1);
    		glVertex2f(ex1,fy1);
    		glVertex2f(fx2,fy1);
    		glVertex2f(ex2,fy1);
    		glVertex2f(fx3,fy1);
    		glVertex2f(ex3,fy1);
    		glVertex2f(fx4,fy1);
    		glVertex2f(ex4,fy1);
    		glVertex2f(fx5,fy1);
    		glVertex2f(ex5,fy1);
    		glVertex2f(fx6,fy1);
    		glVertex2f(ex6,fy1);
    		glVertex2f(fx7,fy1);
    		glVertex2f(ex7,fy1);
    		glVertex2f(fx8,fy1);
    		glVertex2f(ex8,fy1);
    		glVertex2f(fx9,fy1);
    		glVertex2f(ex9,fy1);
    		glVertex2f(fx10,fy1);
    		glVertex2f(ex10,fy1);
    		glEnd();
     
    		glColor3f(0.8,0.2,0);
    		glBegin(GL_LINES);
    		glVertex2f(fx1,fy2);
    		glVertex2f(ex1,fy2);
    		glVertex2f(fx2,fy2);
    		glVertex2f(ex2,fy2);
    		glVertex2f(fx3,fy2);
    		glVertex2f(ex3,fy2);
    		glVertex2f(fx4,fy2);
    		glVertex2f(ex4,fy2);
    		glVertex2f(fx5,fy2);
    		glVertex2f(ex5,fy2);
    		glVertex2f(fx6,fy2);
    		glVertex2f(ex6,fy2);
    		glVertex2f(fx7,fy2);
    		glVertex2f(ex7,fy2);
    		glVertex2f(fx8,fy2);
    		glVertex2f(ex8,fy2);
    		glVertex2f(fx9,fy2);
    		glVertex2f(ex9,fy2);
    		glVertex2f(fx10,fy2);
    		glVertex2f(ex10,fy2);
    		glEnd();
     
    		glColor3f(0,0.5,0.8);
    		glBegin(GL_LINES);
    		glVertex2f(fx1,fy3);
    		glVertex2f(ex1,fy3);
    		glVertex2f(fx2,fy3);
    		glVertex2f(ex2,fy3);
    		glVertex2f(fx3,fy3);
    		glVertex2f(ex3,fy3);
    		glVertex2f(fx4,fy3);
    		glVertex2f(ex4,fy3);
    		glVertex2f(fx5,fy3);
    		glVertex2f(ex5,fy3);
    		glVertex2f(fx6,fy3);
    		glVertex2f(ex6,fy3);
    		glVertex2f(fx7,fy3);
    		glVertex2f(ex7,fy3);
    		glVertex2f(fx8,fy3);
    		glVertex2f(ex8,fy3);
    		glVertex2f(fx9,fy3);
    		glVertex2f(ex9,fy3);
    		glVertex2f(fx10,fy3);
    		glVertex2f(ex10,fy3);
    		glEnd();
     
    		glColor3f(1.0, 0.45, 0.00);
    		glBegin(GL_LINES);
    		glVertex2f(fx1,fy4);
    		glVertex2f(ex1,fy4);
    		glVertex2f(fx2,fy4);
    		glVertex2f(ex2,fy4);
    		glVertex2f(fx3,fy4);
    		glVertex2f(ex3,fy4);
    		glVertex2f(fx4,fy4);
    		glVertex2f(ex4,fy4);
    		glVertex2f(fx5,fy4);
    		glVertex2f(ex5,fy4);
    		glVertex2f(fx6,fy4);
    		glVertex2f(ex6,fy4);
    		glVertex2f(fx7,fy4);
    		glVertex2f(ex7,fy4);
    		glVertex2f(fx8,fy4);
    		glVertex2f(ex8,fy4);
    		glVertex2f(fx9,fy4);
    		glVertex2f(ex9,fy4);
    		glVertex2f(fx10,fy4);
    		glVertex2f(ex10,fy4);
    		glEnd();
     
    		glColor3f(0.9,0,0.7);
    		glBegin(GL_LINES);
    		glVertex2f(fx1,fy5);
    		glVertex2f(ex1,fy5);
    		glVertex2f(fx2,fy5);
    		glVertex2f(ex2,fy5);
    		glVertex2f(fx3,fy5);
    		glVertex2f(ex3,fy5);
    		glVertex2f(fx4,fy5);
    		glVertex2f(ex4,fy5);
    		glVertex2f(fx5,fy5);
    		glVertex2f(ex5,fy5);
    		glVertex2f(fx6,fy5);
    		glVertex2f(ex6,fy5);
    		glVertex2f(fx7,fy5);
    		glVertex2f(ex7,fy5);
    		glVertex2f(fx8,fy5);
    		glVertex2f(ex8,fy5);
    		glVertex2f(fx9,fy5);
    		glVertex2f(ex9,fy5);
    		glVertex2f(fx10,fy5);
    		glVertex2f(ex10,fy5);
    		glEnd();
     
    		glColor3f(0,0.9,0);
    		glBegin(GL_LINES);
    		glVertex2f(fx1,fy6);
    		glVertex2f(ex1,fy6);
    		glVertex2f(fx2,fy6);
    		glVertex2f(ex2,fy6);
    		glVertex2f(fx3,fy6);
    		glVertex2f(ex3,fy6);
    		glVertex2f(fx4,fy6);
    		glVertex2f(ex4,fy6);
    		glVertex2f(fx5,fy6);
    		glVertex2f(ex5,fy6);
    		glVertex2f(fx6,fy6);
    		glVertex2f(ex6,fy6);
    		glVertex2f(fx7,fy6);
    		glVertex2f(ex7,fy6);
    		glVertex2f(fx8,fy6);
    		glVertex2f(ex8,fy6);
    		glVertex2f(fx9,fy6);
    		glVertex2f(ex9,fy6);
    		glVertex2f(fx10,fy6);
    		glVertex2f(ex10,fy6);
    		glEnd();
    	}
    	glutSwapBuffers();
    }
    void draw(float x,float y)
    {
    	glColor3f(0.7,0.3,0.1);
     
    	glBegin(GL_POINTS);
    	glVertex2f(x,y);
    	glEnd();
    	glutSwapBuffers();
    }
    void plot(int h,int k,int x,int y)
    {
    	draw(x+h,y+k);
    	draw(-x+h,y+k);
    	draw(x+h,-y+k);
    	draw(-x+h,-y+k);
    	draw(y+h,x+k);
    	draw(-y+h,x+k);
    	draw(y+h,-x+k);
    	draw(-y+h,-x+k);
    }
    void ball(int h,int k,int r)
    {
    	int x=0,d=1-r,y=r;
     
    	{
    	while(y>x)
    	{
    		plot(h,k,x,y);
    		if(d<0)
    			d+=2*x+3;
    		else
    		{
    			d+=2*(x-y)+5;
    			--y;
    		}
    		++x;
    	}
    	plot(h,k,x,y);
    	glutSwapBuffers();
    	}
    }
    void paddle()
    {
    	glLineWidth(4);
    	glColor3f(0.7,0.7,0.7);
    	if (px>=46&&px<=604)
    	{
    	glBegin(GL_LINE_LOOP);
    	glVertex2f(px,py);
    	glVertex2f(px,py+40);
    	glVertex2f(px+20,py+40);
    	glVertex2f(px+30,py+30);
    	glVertex2f(px+110,py+30);
    	glVertex2f(px+120,py+40);
    	glVertex2f(px+140,py+40);
    	glVertex2f(px+140,py);
    	glVertex2f(px+120,py);
    	glVertex2f(px+110,py+10);
    	glVertex2f(px+30,py+10);
    	glVertex2f(px+20,py);
    	glEnd();
    	glutSwapBuffers();
    	}
    	else if(px<46)
    	{
    	px=48,py=10;
    	glBegin(GL_LINE_LOOP);
    	glVertex2f(px,py);
    	glVertex2f(px,py+40);
    	glVertex2f(px+20,py+40);
    	glVertex2f(px+30,py+30);
    	glVertex2f(px+110,py+30);
    	glVertex2f(px+120,py+40);
    	glVertex2f(px+140,py+40);
    	glVertex2f(px+140,py);
    	glVertex2f(px+120,py);
    	glVertex2f(px+110,py+10);
    	glVertex2f(px+30,py+10);
    	glVertex2f(px+20,py);
    	glEnd();
    	glutSwapBuffers();
    	}
    	else if(px>604)
    	{
    	px=602,py=10;
    	glBegin(GL_LINE_LOOP);
    	glVertex2f(px,py);
    	glVertex2f(px,py+40);
    	glVertex2f(px+20,py+40);
    	glVertex2f(px+30,py+30);
    	glVertex2f(px+110,py+30);
    	glVertex2f(px+120,py+40);
    	glVertex2f(px+140,py+40);
    	glVertex2f(px+140,py);
    	glVertex2f(px+120,py);
    	glVertex2f(px+110,py+10);
    	glVertex2f(px+30,py+10);
    	glVertex2f(px+20,py);
    	glEnd();
    	glutSwapBuffers();
    	}
    }
    void display()
    {
    	glClear(GL_COLOR_BUFFER_BIT);
    	border();
    	bricks();
    	glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    	glPushMatrix();
        paddle();
    	glTranslatef(px,py,pz);
    	glPopMatrix();
    	ball(bx,by,10);
    	glutSwapBuffers();
    }
     
    void init()
    {
    	glClearColor(0,0,0,0);
    	glLoadIdentity();
    	glMatrixMode(GL_PROJECTION);
    	gluOrtho2D(0,1199,0,799);
    }
    void main(int argc,char **argv)
    {
    	glutInit(&argc,argv);
    	glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
    	glutInitWindowSize(1200,800);
    	glutCreateWindow("Arkanoid");
    	glutDisplayFunc(display);
    	init();
    	glutSpecialFunc(keyboardown);
    	glutMainLoop();
    }
    Last edited by srivatsa; 05-01-2013 at 02:18 PM.

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    Apr 2010
    Posts
    645
    Code :
    void keyboardown(int key, int x, int y)
    {
        switch (key){
            case GLUT_KEY_RIGHT:
    			for(int i=0;i<25;i++)
                px+=move_unit*dx*cx;;
                break;
     
            case GLUT_KEY_LEFT:
               for(int i=0;i<25;i++)
                px-=move_unit*dx*cx;;
            break;
     
           default:
             break;
        }
        glutPostRedisplay();
    }

    the loops in the case statements are useless, you will only see the result of the final px += 25 * move_unit * dx * cx; because there are never any images drawn with any of the intermediate values. Similarly, you don't want to call glutSwapBuffers() in the functions that draw pieces of your scene (e.g. paddle() or ball()). Instead, draw a full frame of your scene, then call glutSwapBuffers().

    To move objects smoothly you could keep track of which keys are currently pressed and each frame move the paddle by a small amount based on which keys are down. You get even smoother motion if you apply some simple form of acceleration to the paddle so that in the first few frames a key is pressed the movement distance is smaller and slowly increases up to a max. You probably also want to make the movement speed independent of your framerate (search the forums, there are threads with more details on this). For that keep track of how much time has elapsed since the last frame and use that to scale the movement distance.

    Many applications redraw the whole scene for each frame, that is quite a common approach as there is often not much/anything that is static between frames (especially if the camera moved). Your application probably has some static elements, so you could draw those into a texture using a FBO and then just draw the texture to restore the static elements. I would only recommend that if profiling shows it's worth the effort - your program has plenty of optimization potential before that, e.g. get rid of immediate mode rendering (glBegin/glEnd) and use buffer objects (keyword: VBO).

  3. #3
    Newbie Newbie
    Join Date
    May 2013
    Posts
    2
    Quote Originally Posted by carsten neumann View Post
    Code :
    void keyboardown(int key, int x, int y)
    {
        switch (key){
            case GLUT_KEY_RIGHT:
    			for(int i=0;i<25;i++)
                px+=move_unit*dx*cx;;
                break;
     
            case GLUT_KEY_LEFT:
               for(int i=0;i<25;i++)
                px-=move_unit*dx*cx;;
            break;
     
           default:
             break;
        }
        glutPostRedisplay();
    }

    the loops in the case statements are useless, you will only see the result of the final px += 25 * move_unit * dx * cx; because there are never any images drawn with any of the intermediate values. Similarly, you don't want to call glutSwapBuffers() in the functions that draw pieces of your scene (e.g. paddle() or ball()). Instead, draw a full frame of your scene, then call glutSwapBuffers().

    To move objects smoothly you could keep track of which keys are currently pressed and each frame move the paddle by a small amount based on which keys are down. You get even smoother motion if you apply some simple form of acceleration to the paddle so that in the first few frames a key is pressed the movement distance is smaller and slowly increases up to a max. You probably also want to make the movement speed independent of your framerate (search the forums, there are threads with more details on this). For that keep track of how much time has elapsed since the last frame and use that to scale the movement distance.

    Many applications redraw the whole scene for each frame, that is quite a common approach as there is often not much/anything that is static between frames (especially if the camera moved). Your application probably has some static elements, so you could draw those into a texture using a FBO and then just draw the texture to restore the static elements. I would only recommend that if profiling shows it's worth the effort - your program has plenty of optimization potential before that, e.g. get rid of immediate mode rendering (glBegin/glEnd) and use buffer objects (keyword: VBO).
    Hey, Thanks for your reply..
    i was trying to make it smooth so i introduced for() which was of no use..
    anyhow ... thanks for clearing me with glutSwapBuffers().(So, if i call glutSwapBuffers once at end of display() its ok right??. )currently, my ball getting redrawn has stopped since i removed glutSwapBuffers() everywhere else except display(). i will try to make it smooth as you said by modifying its code tomorrow Thanks bro

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •