Rev 72 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 50 | chris | 1 | package com.gebauz.pingK.game; |
| 2 | |||
| 3 | import java.util.Vector; |
||
| 4 | |||
| 51 | chris | 5 | import javax.microedition.khronos.opengles.GL10; |
| 6 | |||
| 7 | import android.util.Log; |
||
| 8 | |||
| 9 | import com.gebauz.framework.util.GLUtil; |
||
| 58 | chris | 10 | import com.gebauz.framework.util.MathUtil; |
| 50 | chris | 11 | import com.gebauz.framework.util.Mesh; |
| 51 | chris | 12 | import com.gebauz.framework.util.Texture; |
| 50 | chris | 13 | import com.gebauz.framework.util.Vector2; |
| 60 | chris | 14 | import com.gebauz.framework.util.renderstates.BlendingStates.BlendingMode; |
| 51 | chris | 15 | import com.gebauz.framework.util.renderstates.RenderStates; |
| 16 | import com.gebauz.pingK.R; |
||
| 50 | chris | 17 | |
| 18 | public class BallTrail |
||
| 19 | { |
||
| 56 | chris | 20 | private class TrailElement |
| 21 | { |
||
| 22 | private Vector2 mPosition; |
||
| 23 | private Vector2 mNormal; |
||
| 58 | chris | 24 | private Vector2 mDirection; |
| 56 | chris | 25 | private Vector2 mPoint1; |
| 26 | private Vector2 mPoint2; |
||
| 87 | chris | 27 | private float mLifeTime = 0.0f; |
| 56 | chris | 28 | |
| 58 | chris | 29 | public TrailElement(Vector2 pos, Vector2 prevPos, float angleNormal) |
| 56 | chris | 30 | { |
| 58 | chris | 31 | mPosition = new Vector2(pos.x, pos.y); |
| 32 | mDirection = new Vector2(pos.x - prevPos.x, pos.y - prevPos.y); |
||
| 56 | chris | 33 | |
| 59 | chris | 34 | if (angleNormal < 0.0f) |
| 58 | chris | 35 | { |
| 36 | mNormal = new Vector2(mDirection.y, -mDirection.x); |
||
| 37 | } |
||
| 59 | chris | 38 | else |
| 58 | chris | 39 | { |
| 59 | chris | 40 | // 0 |
| 41 | mNormal = new Vector2((float)Math.cos(MathUtil.degToRad(angleNormal)), (float)Math.sin(MathUtil.degToRad(angleNormal))); |
||
| 42 | } |
||
| 56 | chris | 43 | mNormal.setLength(GameConsts.BALL_TRAIL_WIDTH); |
| 58 | chris | 44 | |
| 56 | chris | 45 | mPoint1 = new Vector2(mPosition.x + mNormal.x, mPosition.y + mNormal.y); |
| 87 | chris | 46 | mPoint2 = new Vector2(mPosition.x - mNormal.x, mPosition.y - mNormal.y); |
| 47 | |||
| 48 | mLifeTime = 0.0f; |
||
| 56 | chris | 49 | } |
| 50 | |||
| 51 | public Vector2 getPosition() |
||
| 52 | { |
||
| 53 | return mPosition; |
||
| 54 | } |
||
| 55 | |||
| 58 | chris | 56 | public Vector2 getDirection() |
| 57 | { |
||
| 58 | return mDirection; |
||
| 59 | } |
||
| 60 | |||
| 56 | chris | 61 | public Vector2 getNormal() |
| 62 | { |
||
| 63 | return mNormal; |
||
| 64 | } |
||
| 65 | |||
| 66 | public Vector2 getPoint1() |
||
| 67 | { |
||
| 68 | return mPoint1; |
||
| 69 | } |
||
| 70 | |||
| 71 | public Vector2 getPoint2() |
||
| 72 | { |
||
| 73 | return mPoint2; |
||
| 74 | } |
||
| 87 | chris | 75 | |
| 76 | public void update(float deltaTime) |
||
| 77 | { |
||
| 78 | mLifeTime += deltaTime; |
||
| 79 | } |
||
| 80 | |||
| 81 | public float getAlpha() |
||
| 82 | { |
||
| 83 | return (1.0f-MathUtil.clamp(mLifeTime / GameConsts.BALL_TRAIL_ELEMENT_LIFETIME, 0.0f, 1.0f)); |
||
| 84 | } |
||
| 56 | chris | 85 | } |
| 86 | |||
| 52 | chris | 87 | private Ball mBall; |
| 50 | chris | 88 | private Mesh mTrailMesh = new Mesh(); |
| 51 | chris | 89 | private Texture mTexture = new Texture(); |
| 56 | chris | 90 | //private Vector<Vector2> mTrailPoints = new Vector<Vector2>(); |
| 91 | private Vector<TrailElement> mElements = new Vector<TrailElement>(); |
||
| 58 | chris | 92 | private int mNumPrimitives = 0; |
| 52 | chris | 93 | private float mTrailTimer = 0.0f; |
| 87 | chris | 94 | //private float mTrailFadeTimer = 0.0f; |
| 50 | chris | 95 | |
| 52 | chris | 96 | public BallTrail(Ball ball) |
| 50 | chris | 97 | { |
| 52 | chris | 98 | mBall = ball; |
| 60 | chris | 99 | mTexture.loadTexture(R.drawable.trail); |
| 50 | chris | 100 | } |
| 101 | |||
| 102 | public void reset() |
||
| 103 | { |
||
| 56 | chris | 104 | //mTrailPoints.clear(); |
| 105 | mElements.clear(); |
||
| 51 | chris | 106 | mTrailMesh.setVertices(null); |
| 58 | chris | 107 | mNumPrimitives = 0; |
| 50 | chris | 108 | } |
| 57 | chris | 109 | |
| 58 | chris | 110 | /** |
| 111 | * Add new trail point |
||
| 112 | * @param x X-axis coordinate |
||
| 113 | * @param y Y-axis coordinate |
||
| 114 | * @param angleNormal if >= 0.0f, specifies the angle of the normal to be used |
||
| 115 | */ |
||
| 116 | public void addTrailPoint(float x, float y, float angleNormal) |
||
| 53 | chris | 117 | { |
| 58 | chris | 118 | mTrailTimer -= GameConsts.BALL_TRAIL_INTERVAL; |
| 56 | chris | 119 | Vector2 lastPos = new Vector2(x, y); |
| 120 | |||
| 121 | if (mElements.size() > 0) |
||
| 53 | chris | 122 | { |
| 56 | chris | 123 | lastPos = mElements.get(mElements.size()-1).getPosition(); |
| 58 | chris | 124 | |
| 125 | // do not add point if positions are the same |
||
| 126 | if (Vector2.distance(lastPos, new Vector2(x, y)) < MathUtil.EPSILON) |
||
| 127 | { |
||
| 128 | return; |
||
| 129 | } |
||
| 53 | chris | 130 | } |
| 56 | chris | 131 | |
| 58 | chris | 132 | mElements.add(new TrailElement(new Vector2(x, y), lastPos, angleNormal)); |
| 56 | chris | 133 | |
| 134 | // trim if larger than wanted |
||
| 135 | while (mElements.size() > GameConsts.BALL_TRAIL_LENGTH) |
||
| 53 | chris | 136 | { |
| 56 | chris | 137 | mElements.remove(0); |
| 138 | } |
||
| 139 | |||
| 87 | chris | 140 | //mTrailFadeTimer = 0.0f; |
| 71 | chris | 141 | buildGeometry(); |
| 142 | } |
||
| 143 | |||
| 144 | public void buildGeometry() |
||
| 145 | { |
||
| 56 | chris | 146 | // prepare geometry |
| 147 | if (mElements.size() >= 2) |
||
| 148 | { |
||
| 87 | chris | 149 | //float life = 1.0f - MathUtil.clamp(mTrailFadeTimer / 2.0f, 0.0f, 1.0f); |
| 71 | chris | 150 | |
| 56 | chris | 151 | // two vertices per trail element |
| 57 | chris | 152 | //float vertices[] = new float[mElements.size() * Mesh.COORD_ELEMENTS_COUNT * 6]; |
| 58 | chris | 153 | Mesh.AttributeArray vertices = new Mesh.AttributeArray(mElements.size() * Mesh.COORD_ELEMENTS_COUNT * 2 * 2); |
| 60 | chris | 154 | Mesh.AttributeArray texCoords = new Mesh.AttributeArray(mElements.size() * Mesh.TEX_COORD_ELEMENTS_COUNT * 2 * 2); |
| 155 | Mesh.AttributeArray colors = new Mesh.AttributeArray(mElements.size() * Mesh.COLOR_ELEMENTS_COUNT * 2 * 2); |
||
| 53 | chris | 156 | |
| 87 | chris | 157 | for (int i = mElements.size() - 1; i >= 0; i--) |
| 56 | chris | 158 | { |
| 57 | chris | 159 | TrailElement element1 = mElements.get(i); |
| 56 | chris | 160 | |
| 57 | chris | 161 | vertices.fill(element1.getPoint1().x, element1.getPoint1().y, 0.0f); |
| 162 | vertices.fill(element1.getPoint2().x, element1.getPoint2().y, 0.0f); |
||
| 56 | chris | 163 | |
| 60 | chris | 164 | texCoords.fill(0.0f, 1.0f); |
| 165 | texCoords.fill(0.0f, 0.0f); |
||
| 166 | |||
| 87 | chris | 167 | /* float alpha = (float)i / (float)(mElements.size()-1); |
| 60 | chris | 168 | alpha *= GameConsts.BALL_TRAIL_MAX_ALPHA; |
| 87 | chris | 169 | alpha *= life;*/ |
| 60 | chris | 170 | |
| 87 | chris | 171 | float lifeTime = element1.getAlpha(); |
| 60 | chris | 172 | |
| 87 | chris | 173 | if (i == 0) |
| 174 | lifeTime = 0.0f; |
||
| 175 | |||
| 176 | colors.fill(1.0f, 1.0f, 1.0f, lifeTime); |
||
| 177 | colors.fill(1.0f, 1.0f, 1.0f, lifeTime); |
||
| 178 | |||
| 58 | chris | 179 | if (i > 0) |
| 180 | { |
||
| 60 | chris | 181 | |
| 58 | chris | 182 | TrailElement element2 = mElements.get(i-1); |
| 59 | chris | 183 | if (Vector2.dotProduct(element1.getNormal(), element2.getNormal()) < 0.0f) |
| 58 | chris | 184 | { |
| 185 | // facing away -> twist |
||
| 186 | vertices.fill(element1.getPoint2().x, element1.getPoint2().y, 0.0f); |
||
| 59 | chris | 187 | vertices.fill(element1.getPoint1().x, element1.getPoint1().y, 0.0f); |
| 60 | chris | 188 | |
| 189 | texCoords.fill(0.0f, 1.0f); |
||
| 190 | texCoords.fill(0.0f, 0.0f); |
||
| 191 | |||
| 87 | chris | 192 | colors.fill(1.0f, 1.0f, 1.0f, lifeTime); |
| 193 | colors.fill(1.0f, 1.0f, 1.0f, lifeTime); |
||
| 58 | chris | 194 | } |
| 195 | } |
||
| 56 | chris | 196 | } |
| 197 | |||
| 58 | chris | 198 | mNumPrimitives = vertices.getUsedCount() / Mesh.COORD_ELEMENTS_COUNT; |
| 199 | mTrailMesh.setPrimitiveType(GL10.GL_TRIANGLE_STRIP); |
||
| 57 | chris | 200 | mTrailMesh.setVertices(vertices.getAttributeArray()); |
| 60 | chris | 201 | mTrailMesh.setTexCoords(texCoords.getAttributeArray()); |
| 202 | mTrailMesh.setColors(colors.getAttributeArray()); |
||
| 53 | chris | 203 | } |
| 50 | chris | 204 | } |
| 205 | |||
| 206 | public void update(float deltaTime) |
||
| 207 | { |
||
| 52 | chris | 208 | mTrailTimer += deltaTime; |
| 87 | chris | 209 | //mTrailFadeTimer += deltaTime; |
| 52 | chris | 210 | if (mTrailTimer > GameConsts.BALL_TRAIL_INTERVAL) |
| 211 | { |
||
| 58 | chris | 212 | addTrailPoint(mBall.getX(), mBall.getY(), -1.0f); |
| 52 | chris | 213 | } |
| 87 | chris | 214 | |
| 215 | for (int i = 0; i < mElements.size(); i++) |
||
| 216 | { |
||
| 217 | mElements.get(i).update(deltaTime); |
||
| 218 | } |
||
| 50 | chris | 219 | } |
| 220 | |||
| 72 | chris | 221 | public void updateFade(float deltaTime) |
| 222 | { |
||
| 87 | chris | 223 | //mTrailFadeTimer += deltaTime; |
| 224 | |||
| 225 | for (int i = 0; i < mElements.size(); i++) |
||
| 226 | { |
||
| 227 | mElements.get(i).update(deltaTime); |
||
| 228 | } |
||
| 229 | |||
| 72 | chris | 230 | // rebuild geometry for color fading... |
| 231 | buildGeometry(); |
||
| 232 | } |
||
| 233 | |||
| 50 | chris | 234 | public void render() |
| 235 | { |
||
| 51 | chris | 236 | GL10 gl = GLUtil.getGL(); |
| 237 | |||
| 238 | // transform |
||
| 239 | gl.glMatrixMode(GL10.GL_MODELVIEW); |
||
| 240 | gl.glPushMatrix(); |
||
| 241 | { |
||
| 242 | gl.glLoadIdentity(); |
||
| 243 | RenderStates renderStates = GLUtil.getRenderStates(); |
||
| 52 | chris | 244 | renderStates.depthTest.setEnabled(false); |
| 245 | renderStates.culling.setEnabled(false); |
||
| 60 | chris | 246 | renderStates.blending.setEnabled(true); |
| 247 | renderStates.blending.setBlendingMode(BlendingMode.ALPHABLEND); |
||
| 248 | renderStates.getTextureStage(0).bindTexture(mTexture); |
||
| 51 | chris | 249 | renderStates.activate(); |
| 58 | chris | 250 | mTrailMesh.render(mNumPrimitives); |
| 57 | chris | 251 | //mTrailMesh.render(); |
| 51 | chris | 252 | renderStates.deactivate(); |
| 60 | chris | 253 | renderStates.getTextureStage(0).bindTexture(null); |
| 51 | chris | 254 | } |
| 255 | gl.glPopMatrix(); |
||
| 50 | chris | 256 | } |
| 52 | chris | 257 | } |
| 50 | chris | 258 | |
| 52 | chris | 259 |