package com.gebauz.pingK.game;
import java.util.Vector;
import javax.microedition.khronos.opengles.GL10;
import android.util.Log;
import com.gebauz.framework.util.GLUtil;
import com.gebauz.framework.util.Mesh;
import com.gebauz.framework.util.Texture;
import com.gebauz.framework.util.Vector2;
import com.gebauz.framework.util.renderstates.RenderStates;
import com.gebauz.pingK.R;
public class BallTrail
{
private Ball mBall
;
private Mesh mTrailMesh =
new Mesh
();
private Texture mTexture =
new Texture
();
private Vector<Vector2
> mTrailPoints =
new Vector<Vector2
>();
private float mTrailTimer = 0.0f
;
public BallTrail
(Ball ball
)
{
mBall = ball
;
mTexture.
loadTexture(R.
drawable.
icon_hourglass);
}
public void reset
()
{
mTrailPoints.
clear();
mTrailMesh.
setVertices(null);
}
private void addTrailGeometryForPoint
(int i
)
{
if (i ==
0)
{
// first point
if (mTrailPoints.
size() >=
2)
{
Vector2 p0 = mTrailPoints.
get(0);
Vector2 p1 = mTrailPoints.
get(1);
}
}
else
{
}
}
public void addTrailPoint
(float x,
float y
)
{
mTrailPoints.
add(new Vector2
(x, y
));
while (mTrailPoints.
size() > GameConsts.
BALL_TRAIL_LENGTH)
{
mTrailPoints.
remove(0);
}
if (mTrailPoints.
size() >=
2)
{
// generate geometry
// for triangle strips, we have two points per trail point
float[] vertices =
new float[mTrailPoints.
size() * Mesh.
COORD_ELEMENTS_COUNT * 2];
float[] colors =
new float[mTrailPoints.
size() * Mesh.
COLOR_ELEMENTS_COUNT * 2];
// first point
{
Vector2 a = mTrailPoints.
get(0);
Vector2 b = mTrailPoints.
get(1);
Vector2 direction =
new Vector2
(b.
x - a.
x, b.
y - a.
y);
Vector2 normal =
new Vector2
(direction.
y, -direction.
x);
normal.
setLength(GameConsts.
BALL_TRAIL_WIDTH);
vertices
[0] = a.
x + normal.
x;
vertices
[1] = a.
y + normal.
y;
vertices
[2] = 0.0f
;
vertices
[3] = a.
x - normal.
x;
vertices
[4] = a.
y - normal.
y;
vertices
[5] = 0.0f
;
colors
[0] = 1.0f
; colors
[1] = 0.0f
; colors
[2] = 0.0f
; colors
[3] = 1.0f
;
colors
[4] = 0.0f
; colors
[5] = 1.0f
; colors
[6] = 0.0f
; colors
[7] = 1.0f
;
}
for (int i =
1; i
< mTrailPoints.
size(); i++
)
{
Vector2 a = mTrailPoints.
get(i-
1);
Vector2 b = mTrailPoints.
get(i
);
Vector2 direction =
new Vector2
(b.
x - a.
x, b.
y - a.
y);
Vector2 normal =
new Vector2
(direction.
y, -direction.
x);
normal.
setLength(GameConsts.
BALL_TRAIL_WIDTH);
if (i
< (mTrailPoints.
size()-
1))
{
// there is a next segment, so average current normal with next
Vector2 nextPoint = mTrailPoints.
get(i+
1);
Vector2 nextDirection =
new Vector2
(nextPoint.
x - b.
x, nextPoint.
y - b.
y);
Vector2 nextNormal =
new Vector2
(nextDirection.
y, -nextDirection.
x);
nextNormal.
normalize();
normal.
normalize();
normal.
addVector(nextNormal
);
normal.
setLength(GameConsts.
BALL_TRAIL_WIDTH);
}
else
{
Log.
v(GameConsts.
LOG_TAG,
"P=" + b.
x +
", " + b.
y);
}
vertices
[i
* Mesh.
COORD_ELEMENTS_COUNT * 2 +
0] = b.
x + normal.
x;
vertices
[i
* Mesh.
COORD_ELEMENTS_COUNT * 2 +
1] = b.
y + normal.
y;
vertices
[i
* Mesh.
COORD_ELEMENTS_COUNT * 2 +
2] = 0.0f
;
vertices
[i
* Mesh.
COORD_ELEMENTS_COUNT * 2 +
3] = b.
x - normal.
x;
vertices
[i
* Mesh.
COORD_ELEMENTS_COUNT * 2 +
4] = b.
y - normal.
y;
vertices
[i
* Mesh.
COORD_ELEMENTS_COUNT * 2 +
5] = 0.0f
;
colors
[i
* Mesh.
COLOR_ELEMENTS_COUNT * 2 +
0] = 1.0f
;
colors
[i
* Mesh.
COLOR_ELEMENTS_COUNT * 2 +
1] = 0.0f
;
colors
[i
* Mesh.
COLOR_ELEMENTS_COUNT * 2 +
2] = 0.0f
;
colors
[i
* Mesh.
COLOR_ELEMENTS_COUNT * 2 +
3] = 1.0f
;
colors
[i
* Mesh.
COLOR_ELEMENTS_COUNT * 2 +
4] = 0.0f
;
colors
[i
* Mesh.
COLOR_ELEMENTS_COUNT * 2 +
5] = 1.0f
;
colors
[i
* Mesh.
COLOR_ELEMENTS_COUNT * 2 +
6] = 0.0f
;
colors
[i
* Mesh.
COLOR_ELEMENTS_COUNT * 2 +
7] = 1.0f
;
}
mTrailMesh.
setPrimitiveType(GL10.
GL_TRIANGLE_STRIP);
mTrailMesh.
setVertices(vertices
);
mTrailMesh.
setColors(colors
);
/* float[] vertices = new float[(mTrailPoints.size()-1) * 3 * 4];
float[] colors = new float[(mTrailPoints.size()-1) * 4 * 4];
short[] indices = new short[(mTrailPoints.size()-1) * 6];
float[] texCoords = new float[(mTrailPoints.size()-1) * 2 * 4];
int idx = 0;
Vector2 a = mTrailPoints.get(0);
Vector2 b = mTrailPoints.get(1);
for (int i = 1; i < mTrailPoints.size(); i++)
{
Vector2 lineDirectionA = new Vector2(b.x - a.x, b.y - a.y);
Vector2 lineNormalA = new Vector2(-lineDirectionA.y, lineDirectionA.x);
Vector2 lineDirectionB = new Vector2(b.x - a.x, b.y - a.y);
Vector2 lineNormalB = new Vector2(-lineDirectionA.y, lineDirectionA.x);
// average if there is a next segment
if (i < (mTrailPoints.size() - 1))
{
Vector2 c = mTrailPoints.get(i+1);
Vector2 lineDirectionC = new Vector2(c.x - b.x, c.y - b.y);
Vector2 lineNormalC = new Vector2(-lineDirectionC.y, lineDirectionC.x);
lineNormalB.addVector(lineNormalC);
// prepare for next loop round
a = mTrailPoints.get(i);
b = mTrailPoints.get(i+1);
}
lineNormalA.setLength(GameConsts.BALL_TRAIL_WIDTH);
lineNormalB.setLength(GameConsts.BALL_TRAIL_WIDTH);
int i1 = (i-1)*4;
int i2 = (i-1)*4+1;
int i3 = (i-1)*4+2;
int i4 = (i-1)*4+3;
vertices[i1*3+0] = a.x + lineNormalA.x;
vertices[i1*3+1] = a.y + lineNormalA.y;
vertices[i1*3+2] = 0.0f;
vertices[i2*3+0] = b.x + lineNormalB.x;
vertices[i2*3+1] = b.y + lineNormalB.y;
vertices[i2*3+2] = 0.0f;
vertices[i3*3+0] = b.x - lineNormalB.x;
vertices[i3*3+1] = b.y - lineNormalB.y;
vertices[i3*3+2] = 0.0f;
vertices[i4*3+0] = a.x - lineNormalA.x;
vertices[i4*3+1] = a.y - lineNormalA.y;
vertices[i4*3+2] = 0.0f;
colors[i1*4+0] = 1.0f; colors[i1*4+1] = 1.0f; colors[i1*4+2] = 1.0f; colors[i1*4+3] = 1.0f;
colors[i2*4+0] = 1.0f; colors[i2*4+1] = 1.0f; colors[i2*4+2] = 1.0f; colors[i2*4+3] = 1.0f;
colors[i3*4+0] = 1.0f; colors[i3*4+1] = 1.0f; colors[i3*4+2] = 1.0f; colors[i3*4+3] = 1.0f;
colors[i4*4+0] = 1.0f; colors[i4*4+1] = 1.0f; colors[i4*4+2] = 1.0f; colors[i4*4+3] = 1.0f;
indices[i1] = (short)i1;
indices[i2] = (short)i2;
indices[i3] = (short)i3;
indices[i4] = (short)i4;
texCoords[idx] = 0; idx++;
texCoords[idx] = 1; idx++;
texCoords[idx] = 2; idx++;
texCoords[idx] = 0; idx++;
texCoords[idx] = 2; idx++;
texCoords[idx] = 3; idx++;
}
mTrailMesh.setVertices(vertices);
mTrailMesh.setColors(colors);
mTrailMesh.setIndices(indices);
mTrailMesh.setTexCoords(texCoords);*/
}
}
public void update
(float deltaTime
)
{
mTrailTimer += deltaTime
;
if (mTrailTimer
> GameConsts.
BALL_TRAIL_INTERVAL)
{
mTrailTimer -= GameConsts.
BALL_TRAIL_INTERVAL;
addTrailPoint
(mBall.
getX(), mBall.
getY());
}
//mBall
}
public void render
()
{
GL10 gl = GLUtil.
getGL();
// transform
gl.
glMatrixMode(GL10.
GL_MODELVIEW);
gl.
glPushMatrix();
{
gl.
glLoadIdentity();
RenderStates renderStates = GLUtil.
getRenderStates();
renderStates.
depthTest.
setEnabled(false);
renderStates.
culling.
setEnabled(false);
renderStates.
activate();
mTrailMesh.
render(mTrailPoints.
size()*2);
renderStates.
deactivate();
}
gl.
glPopMatrix();
}
}