i am drawing an array of pool balls in opengl using c++
the problem i am facing is the array draws in a straight line.
when i use gltranslate the balls still only translate along the line when i edit the z and y axis
what i want to do is set the balls up in a triangle shape like the breaking of a pool match
how do i use the array code to set the balls up like this?
any help would be much appreciated
balls[7];
for (int x = ball-start; x<ball-end;x++)
{
glTranslatef(0,0,0.5);
glColor3f(1,0,0);
ball[x].drawball();
}
assuming:
struct Ball {
double x,y,z;
void drawball(void);
/* ... */
} ball[7];
try:
for(int i=0; i<7 ;i++)
{
glPushMatrix();
glTranslated(ball[i].x,ball[i].y,ball[i].z);
glColor3f(1,0,0);
ball[i].drawball();
glPopMatrix();
}
details probably vary, but hopefully you get the idea.
Do something like this:
// first of all, include the x,y position (assuming 2D, since pool) in the Ball object:
class Ball
{
//...
private:
float xpos, ypos;
//...
};
Then when you construct the array of balls, rather than just making 8 balls, you're going to want to allocate the memory on the heap so that it will last throughout your entire game. So do this:
Ball *ball= new Ball*[8];
ball[0] = new Ball(x0,y0);
ball[1] = new Ball(x1,y1);
ball[2] = new Ball(x2,y2);
ball[3] = new Ball(x3,y3);
// ...
Make sure that when your game is over, you clean up after yourself.
for (int i = 0; i < 8; i++)
delete ball[i];
delete [] ball;
Then in your Ball::draw() do something like this:
Ball::draw()
{
glColor3f(/*yellow*/); // Set the color to yellow
glTranslatef(-xpos, -ypos, 0); // Move to the position of the ball
// Draw the ball
glTranslatef(xpos, ypos, 0); // Move back to the default position
}
All you have to do is come up with the correct (x0,y0),(x1,y1),(x2,y2)... to form a triangle! Does this make sense/answer your question?
Related
I want to make my player, make the ball move in a certain direction, roughly 120 degrees up. At the moment the ball goes in al direction, but the ball goes up not down. The ball also goes at 4 different speeds.
if(CGRectIntersectsRect(BallA.frame, PlayerA1.frame)){
Y = arc4random() %5;
Y = 0-Y;
}
}
Ball movement
timer = [NSTimer scheduledTimerWithTimeInterval:0.006 target:self selector:#selector(BallMovement4) userInfo:nil repeats:YES];
-(void)BallMovement4{
[self Computer4Movement];
[self Collision4];
Ball4.center = CGPointMake(Ball4.center.x + X, Ball4.center.y + Y);
if (Ball4.center.x < 15) {
X = 0 - X;
}
if (Ball4.center.x > 305) {
X = 0 - X;
}
Please Help,
Thank You
Milan
It's a little unclear what you're trying to do and how your classes work, but in general, if you want to move things around, one good way to do that is to use vectors. For example, if you want the ball to move 3 pixels per frame in a given direction, the ball would have a position and a velocity vector, like this:
typedef struct Ball { // could be a class if that makes sense for your use
CGPoint position;
CGPoint velocity;
} Ball;
You'd set them to some initial value, like this:
Ball ball = { { 0.0, 0.0 }, // Ball starts at the origin
{ 1.0, 2.0 } }; // Ball starts out moving 1 pixel to the right and 2 pixels up
Then on each frame of gameplay, you'd add the velocity to the position, like this:
ball.position.x += ball.velocity.x;
ball.position.y += ball.velocity.y;
You can change the velocity, for example, when the ball hits a wall. If you're trying to simulate something real, you'd need to find the angle at which the ball hit the wall and reverse that.
I have a dynamic body with many polygon shapes for my game character. In order to turn back the game character I flip vertices using this code:
void Box2dManager::flipFixtures(bool horizzontally, b2Body* physBody)
{
b2Fixture* fix = physBody->GetFixtureList();
while(fix)
{
b2Shape* shape = fix->GetShape();
if(shape->GetType()== b2Shape::e_polygon)
{
// flipping x or y coordinates
b2PolygonShape* ps = (b2PolygonShape*)shape;
for(int i=0; i < ps->GetVertexCount(); i++)
horizzontally ? ps->m_vertices[i].x *= -1 : ps->m_vertices[i].y *= -1;
// revert the vertices (no need after Box2D 2.3.0 as polygon creation computes the convex hull)
b2Vec2* reVert = new b2Vec2[ps->GetVertexCount()];
int j = ps->GetVertexCount() -1;
for(int i=0; i<ps->GetVertexCount();i++)
reVert[i] = ps->m_vertices[j--];
ps->Set(&reVert[0], ps->GetVertexCount());
}
fix = fix->GetNext();
}
}
I also have static edge shapes as walls. And it happens, that when I flip the character, sometimes vertices of the same polygon appear to be in different sides of the same static edge shape. As a result my character sticks to the wall (it is being trapped in the static edge shape). How I should handle this situation?
I am really new to OpenGL and I am trying to just make a surface from two triangles. I don't know where I am going wrong with this code. I know that all the positions and colors are getting into the triangles class and that the Triangles are being made, but it's not getting outputted. Can someone help?
I tried to get just the output from the Triangle class but it doesn't seem to be working. I don't think there's anything wrong with the way I am calling the Display function.
Code:
#include<GL/gl.h>
#include<GL/glu.h>
#include<GL/glut.h>
#include<iostream>
#include<vector>
using namespace std;
class Triangle
{
public:
float position[9],color[3];
Triangle()
{}
Triangle(float position_t[], float color_t[])
{
for(int i=0;i<9;i++)
{position[i] = position_t[i];}
for(int i=0;i<3;i++)
{color[i]= color_t[i];}
}
void makeTriangle()
{
glBegin(GL_TRIANGLES);
glColor3f(color[0],color[1],color[2]);glVertex3f(position[0],position[1],position[2]);
glColor3f(color[0],color[1],color[2]);glVertex3f(position[3],position[4],position[5]);
glColor3f(color[0],color[1],color[2]);glVertex3f(position[6],position[7],position[8]);
glEnd();}
};
class Mesh
{
public:
/*float center[3],position[9],color[3];
float size;*/
vector<Triangle> elements;
float center[3],position[9],color[3];
float size;
Mesh(){}
Mesh(float center_in[3], float color_in[3])
{
for (int i=0;i<3;i++)
{
color[i] = color_in[i];
center[i] = center_in[i];
}
}
void getPositions()
{
position[0] = 1;position[1] = 1; position[2] = 1;
position[3] = -1;position[4] = -1; position[5] = 1;
position[6] = 1;position[7] = -1; position[8] = 1;
}
void getColor()
{
color[0] = 1; color[1]=0; color[2]=0;
}
static Mesh makeMesh()
{
Mesh a;
a.elements.resize(2);
a.getPositions();
a.getColor();
Triangle T(a.position,a.color);
a.elements[0] = T;
//Triangle O(2);
//a.elements[1] = 0;
return a;
}
};
void render()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
Mesh a;
a.elements.resize(2);
a.getPositions();
a.getColor();
Triangle T(a.position,a.color);
//vector<Mesh> m;
//m.push_back(Mesh::makeMesh());
glPushMatrix();
T.makeTriangle();
glPopMatrix();
glFlush();
glutSwapBuffers();
glutPostRedisplay();
}
Full Code: http://pastebin.com/xa3B7166
As I suggested you in the comments, you are not setting the gluLookat() function. Everything is being drawn but you are just not looking at it!
Docs: https://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml
Your code does not specify any transformations. Therefore, your coordinates need to be within the default view volume, which is [-1, 1] in all coordinate directions.
Or more technically, the model/view/projection transformations (or all the transformations applied in your vertex shader if you use the programmable pipeline) transform the coordinates into the clip coordinate space, and after perspective division into the normalized device coordinate (aka NDC) space. The range of the NDC space is [-1, 1] for all coordinates.
If you don't apply any transformations, like is the case in your code, your original coordinates already have to be in NDC space.
With your current coordinates:
position[0] = 1;position[1] = 1; position[2] = 1;
position[3] = -1;position[4] = -1; position[5] = 1;
position[6] = 1;position[7] = -1; position[8] = 1;
all the z-coordinates have values of 1, which means that the whole triangle is right on the boundary of the clip volume. To make it visible, you can simply set the z-coordinates to 0:
position[0] = 1;position[1] = 1; position[2] = 0;
position[3] = -1;position[4] = -1; position[5] = 0;
position[6] = 1;position[7] = -1; position[8] = 0;
This centers it within the NDC space in z-direction, with the vertices being on 3 of the corners in the xy-plane. You will therefore see half of your window covered by the triangle, cutting it in half along the diagonal.
It's of course common in OpenGL to have the original coordinates in a different coordinate space, and then apply transformations to place them within the view volume.
You're probably already aware of this, but I thought I'd mention it anyway: If you're just starting to learn OpenGL, I would suggest that you learn what people often call "modern OpenGL". This includes the OpenGL Core Profile, or OpenGL ES 2.0 or later. The calls you are using now are mostly deprecated in newer versions of OpenGL, and not available anymore in the Core Profile and ES. The initial hurdle is somewhat higher for "modern OpenGL", particularly since you have to write your own shaders, but you will get on the path to acquiring knowledge that is still current.
Is it possible to calculate distance at which the body will fly off in method
-(BOOL)ccPhysicsCollisionBegin:typeA:typeB
I need the exact point, where the body would end up after collision. In other words, will it fly off towards boundary or not; whether the force is strong enough to push it to the boundary or not.
Any ideas? Thanks!
UPDATE:
Found some code. I was told, it's exactly what I want. But I'm not familiar with 'pure' Chipmunk. So, I can't use it anyway yet. The code needs to be inserted in draw method.
// We need a copy of the body and shape to simulate them forwards without doing a full step.
// For performance sake, let's just copy them onto the stack using the C-API.
cpBody body = *(cage.body.body);
cpPolyShape shape = *((cpPolyShape *)cage.shape.shape);
shape.shape.body = &body;
cpVect gravity = space.gravity;
// Check ahead up to 300 frames for a collision.
for(int i=0; i<300; i++){
// Manually update the position and velocity of the body
cpBodyUpdatePosition(&body, FIXED_TIMESTEP);
cpBodyUpdateVelocity(&body, gravity, 1.0f, FIXED_TIMESTEP);
// Perform a shape query to see if the cage hit anything.
if(cpSpaceShapeQuery(space.space, (cpShape *)&shape, NULL, NULL)){
// If it did, draw the box's outline.
cpVect verts[4];
for(int i=0; i<4; i++){
verts[i] = cpBodyLocal2World(&body, cpPolyShapeGetVert((cpShape *)&shape, i));
}
[self drawPolyWithVerts:verts count:4 fillColor:ccc4f(0, 0, 0, 0) borderWidth:1.0 borderColor:ccc4f(0, 0, 0, 1)];
break;
} else if(i%3==0){
// Otherwise, just draw a dot every 10 frames along the path.
[self drawDot:body.p radius:5.0 color:ccc4f(0, 0, 0, 0.5)];
}
}
[super draw];
[self clear];
I'm trying to follow this online tutorial to create some waves
http://nehe.gamedev.net/tutorial/flag_effect_(waving_texture)/16002/.
I want to make the wave much bigger, but I'm not sure if I'm going about it the right way, the current mesh of quads is sized 45 in the tutorial, so i have increased to 450, however the size doesn't seem to increase that much.
Can someone point me in the right direction as to what needs to be modified to make the quads bigger.
If you just want to make the quads bigger, then you need to modify the vertex position code. In the NeHe tutorial you posted change this part:
// Loop Through The X Plane
for(int x=0; x<45; x++)
{
// Loop Through The Y Plane
for(int y=0; y<45; y++)
{
// Apply The Wave To Our Mesh
points[x][y][0]=float((x/5.0f)-4.5f);
points[x][y][1]=float((y/5.0f)-4.5f);
points[x][y][2]=float(sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));
}
}
To this:
// Loop Through The X Plane
float spacing = 0.5f;
float spacingInv = 1.0f/spacing;
float offset = (45 / spacingInv) / 2.0f; // The 45 comes from the number of points (if you change this, change the for loop and the variable creation)
for(int x=0; x<45; x++)
{
// Loop Through The Y Plane
for(int y=0; y<45; y++)
{
// Apply The Wave To Our Mesh
// We change the x/5.0f-4.5f to change the size of the quads
// See text after for more details
points[x][y][0]=float((x/spacingInv)-offset);
points[x][y][1]=float((y/spacingInv)-offset);
points[x][y][2]=float(sin((((x/spacingInv)*40.0f)/360.0f)*3.141592654*2.0f));
}
}
Explanation:
x/5.0f gives you values 0, 0.2, 0.4, 0.6, 0.8, 1.0, ......, 9.0.
If you were to take just those values, you would now have an off center grid of quads. Now taking x/5.0f - 4.5f gives you values -4.5 -4.3, -4.1, ...... 4.1, 4.3, 4.5
If you wanted to make the quads bigger, you need to increase the spacing between the points (i.e. change the x/5.0f to something like x/2.0f (which is what happens in the example I gave)). And then you want to recenter (i.e. change the -4.5f).