Jump to content
  • Advertisement
phil67rpg

OpenGL sprite collision

Recommended Posts

I translated a code from this GLUT tutorial C++ 2D Pong Game to OpenGL 3. I draw using shaders and VBO. You can download the EXE file (x86, .NET 4.0, OpenGL 3.1)

Controls: W/S - for the left racket, UpArrow/DownArrow - for the right racket.

I public it here for your motivation. I use sprites to draw a text score. I get character's info from .fnt and .png that was generated by Bitmap Font Generator. I will translate the code to WebGL and TypeScript. You will be able to run this game by one click without downloading and unzipping. I will write a lot of simple game for practice.

 

Pong2DFromNoobTuts_OpenTkOpenGL11CSharp.png

Share this post


Link to post
Share on other sites
Advertisement

Did you try moving the call to "coll_plane_one()" up?

coll_plane_one();
if (collision_flag == true)
{
drawcollision_one();
}

 

I'd be equally curious if replacing that portion with just the "drawcollision_one()" call causes the collision sprite to appear.

Share this post


Link to post
Share on other sites
1 hour ago, rileyman said:

Did you try moving the call to "coll_plane_one()" up?

yes I tried that but with no success.

Share this post


Link to post
Share on other sites

You should make a normal game loop like this:

// window size and update rate (60 fps)
int width = 500;
int height = 200;
int interval = 1000 / 60;

void draw() {
    // clear (has to be done at the beginning)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    // ToDo: draw our scene

    // swap buffers (has to be done at the end)
    glutSwapBuffers();
}

void update(int value) {
   // Call update() again in 'interval' milliseconds
   glutTimerFunc(interval, update, 0);

   // Redisplay frame
   glutPostRedisplay();
}

// program entry point
int _tmain(int argc, char** argv) {
    // initialize opengl (via glut)
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(width, height);
    glutCreateWindow("noobtuts.com Pong");

    // Register callback functions   
    glutDisplayFunc(draw);
    glutTimerFunc(interval, update, 0);

    // start the whole thing
    glutMainLoop();
    return 0;
}

 

Edited by 8Observer8

Share this post


Link to post
Share on other sites

ok here is my full code

#include <freeglut.h>
#include <iostream>
#include<SOIL.h>

using namespace std;

GLuint texture[8]; 

float move_plane = 0.0f;
float up = 0.0f;
float down = 0.0f;
float screen = 0.0f;
bool collision_flag = false;

bool checkCollide(float x, float y, float oWidth, float oHeight, float xTwo, float yTwo, float oTwoWidth, float oTwoHeight)
{
	// AABB 1
	float x1Min = x;
	float x1Max = x + oWidth;
	float y1Max = y + oHeight;
	float y1Min = y;

	// AABB 2
	float x2Min = xTwo;
	float x2Max = xTwo + oTwoWidth;
	float y2Max = yTwo + oTwoHeight;
	float y2Min = yTwo;

	// Collision tests
	if (x1Max < x2Min || x1Min > x2Max) return false;
	if (y1Max < y2Min || y1Min > y2Max) return false;

	return true;
}

void drawcollision_one()
{
	glEnable(GL_TEXTURE_2D);

	glBindTexture(GL_TEXTURE_2D, texture[3]);

	glBegin(GL_POLYGON);
	glTexCoord3f(0.0f + screen, 0.0f, 0.0f);

	glVertex3f(10.0f, -10.0f, 0.0f);
	glTexCoord3f(0.167f + screen, 0.0f, 0.0f);

	glVertex3f(10.0f, 10.0f, 0.0f);
	glTexCoord3f(0.167f + screen, 1.0f, 0.0f);

	glVertex3f(-10.0f, 10.0f, 0.0f);
	glTexCoord3f(0.0f + screen, 1.0f, 0.0f);

	glVertex3f(-10.0f, -10.0f, 0.0f);
	glEnd();

	glDisable(GL_TEXTURE_2D);
}

void coll_plane_one()
{
	//draw bullet
	float x = -2.5f + move_plane;
	float y = -75.0f + up;
	float oWidth = 5.0f;
	float oHeight = 5.0f;
	//draw plane
	float xTwo = -10.0f + move_plane;
	float yTwo = 100.0f + down;
	float oTwoWidth = 20.0f;
	float oTwoHeight = 20.0f;

	if (checkCollide(x, y, oWidth, oHeight, xTwo, yTwo, oTwoWidth, oTwoHeight) == 1)
	{
		collision_flag = true;
//		cout << "Collision" << endl;
	}
}

GLuint loadTex(const char* texname)                                    
{
	/* load an image file directly as a new OpenGL texture */
	GLuint texture = SOIL_load_OGL_texture
	(
		texname,
		SOIL_LOAD_AUTO,
		SOIL_CREATE_NEW_ID,
		SOIL_FLAG_POWER_OF_TWO
	);
	return texture;
}

void init()
{
	texture[0] = loadTex("C:\\Users\\Owner\\Desktop\\plane.png");
	texture[1] = loadTex("C:\\Users\\Owner\\Desktop\\bullet.png");
	texture[2] = loadTex("C:\\Users\\Owner\\Desktop\\enemy.png");
	texture[3] = loadTex("C:\\Users\\Owner\\Desktop\\coll.png");
}

void timer(int v)
{
	down--;
	if (down <= -180.0f)
	{
		down = 0.0f;
	}
	glutPostRedisplay();
	glutTimerFunc(50, timer, 0);
}

void timer_one(int val)
{
	screen += 0.1667f;
	if (screen >= 1.0f)
	{
		screen = 1.0f;
	}
	glutPostRedisplay();
	glutTimerFunc(500, timer_one, 0);
}

void renderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture[2]);

	for (float i = -130.0f; i <= 130.0f; i += 40.0f)
	{
		glBegin(GL_QUADS);
		glTexCoord2f(0.0f, 0.0f);
		glVertex2f(i, 100.0f + down);
		glTexCoord2f(1.0f, 0.0f);
		glVertex2f(i+20.0f, 100.0f + down);
		glTexCoord2f(1.0f, 1.0f);
		glVertex2f(i+20.0f, 80.0f + down);
		glTexCoord2f(0.0f, 1.0f);
		glVertex2f(i, 80.0f + down);
		glEnd();
	}

	glBindTexture(GL_TEXTURE_2D, texture[0]);
	glBegin(GL_QUADS);
	glTexCoord2f(0.0f, 0.0f);
	glVertex2f(-10.0f+move_plane, -80.0f);
	glTexCoord2f(1.0f, 0.0f);
	glVertex2f(10.0f+move_plane, -80.0f);
	glTexCoord2f(1.0f, 1.0f);
	glVertex2f(10.0f+move_plane, -100.0f);
	glTexCoord2f(0.0f, 1.0f);
	glVertex2f(-10.0f+move_plane, -100.0f);
	glEnd();

	glBindTexture(GL_TEXTURE_2D, texture[1]);
	glBegin(GL_QUADS);
	glTexCoord2f(0.0f, 0.0f);
	glVertex2f(-2.5f+move_plane, -75.0f+up);
	glTexCoord2f(1.0f, 0.0f);
	glVertex2f(2.5f+move_plane, -75.0f+up);
	glTexCoord2f(1.0f, 1.0f);
	glVertex2f(2.5f+move_plane, -80.0f+up);
	glTexCoord2f(0.0f, 1.0f);
	glVertex2f(-2.5f+move_plane, -80.0f+up);
	glEnd();
	coll_plane_one();
	if (collision_flag == true)
	{
		drawcollision_one();
	}
	glPopMatrix();
	glutSwapBuffers();
	glDisable(GL_TEXTURE_2D);
}

void ChangeSize(GLsizei w, GLsizei h)
{
	GLfloat aspectRatio;
	if (h == 0)
		h = 1;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	aspectRatio = (GLfloat)w / (GLfloat)h;
	if (w <= h)
		glOrtho(-100.0, 100.0, -100.0 / aspectRatio, 100.0 / aspectRatio, 1.0, -1.0);
	else
		glOrtho(-100.0*aspectRatio, 100.0*aspectRatio, -100.0, 100.0, 1.0, -1.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void shoot()
{
	up++;
	if (up >= 175.0f)
	{
		up = 0.0f;
		glutIdleFunc(NULL);
	}
	glutPostRedisplay();
}

void handleKeypress(unsigned char key, int x, int y)
{
	int animate = 0;

	switch(key)
	{
	case 27:
		exit(0);
		break;
	case 32:
		animate = !animate;
		if (animate)
			glutIdleFunc(shoot);
		else
			glutIdleFunc(NULL);
		break;
	}
	glutPostRedisplay();
}

void handleSpecialKeypress(int key, int x, int y)
{
	switch (key)
	{
	case GLUT_KEY_LEFT:
		move_plane--;
		if (move_plane <= -125.0f)
		{
			move_plane = -125.0f;
		}
		break;
	case GLUT_KEY_RIGHT:
		move_plane++;
		if (move_plane >= 125.0f)
		{
			move_plane = 125.0f;
		}
		break;
	}
	glutPostRedisplay();
}

int main(int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(400, 300);
	glutInitWindowSize(800, 600);
	glutCreateWindow("Combat");
	glutDisplayFunc(renderScene);
	glutTimerFunc(500, timer, 0);
	glutTimerFunc(500, timer_one, 0);
//	glutTimerFunc(500, collision, 0);
	glutReshapeFunc(ChangeSize);
	glutKeyboardFunc(handleKeypress);
	glutSpecialFunc(handleSpecialKeypress);
	init();
	glutMainLoop();
	return 0;
}

 

Share this post


Link to post
Share on other sites
On 9/10/2019 at 9:13 PM, phil67rpg said:

glutTimerFunc(500, timer, 0);
glutTimerFunc(500, timer_one, 0);

 

You have two "Update" functions: timer() and timer_one(). It is a bad idea. Your Game Loop must have only one "Render()" function and only one "Update()" function.

Edited by 8Observer8

Share this post


Link to post
Share on other sites
1 hour ago, 8Observer8 said:

You have two "Update" functions: timer() and timer_one(). It is a bad idea. Your Game Loop must have only one "Render()" function and only one "Update()" function.

well I have adjusted my code.

void update(int value)
{
	down--;
	if (down <= -180.0f)
	{
		down = 0.0f;
	}
	screen += 0.1667f;
	if(screen >= 1.0f)
	{
		screen = 1.0f;
	}
	glutPostRedisplay();
	glutTimerFunc(50, update, 0);
}

 

Share this post


Link to post
Share on other sites
5 hours ago, phil67rpg said:

I  posted all of my code can I please get some input on it.

Variable 'screen' will get set to 1 almost immediately and never change. This is only part of the problem with your code though.

Your understanding of C++ and OpenGL after many years of supposed learning is underwhelming. It only gets more difficult and complex the further you go. I'm guessing you program by trial and error, changing a variable here, a <= to a > there, compiling, nope, change it back, etc ad nauseam. Regardless, I don't understand how you enjoy programming enough to keep piddling.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!