import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.BitmapFactory.Options;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
/* Private data */
private Resources res; // app resources
+ private Options options; // bitmap options
private int program; // opengl program
private float[] model; // model matrix
private Map<String,Integer> index; // card name to index map
/* Properties */
+ public Spades game; // the spades game
public String[] hand; // cards to display
+ public String[] pile; // played cards to display
/* GLSurfaceView Methods */
public Cards(Context context)
this.ylim = 0.4f;
- this.hand = new String[] {
- "As", "7s", "6s", "6h", "2h", "Ac",
- "Kc", "3c", "10d", "9d", "8d", "7d", "2d"
- };
+ this.hand = "As Ks Qs Js 10s 9s 8s 7s 6s 5s 4s 3s 2s".split(" ");
+ this.pile = "Ah Ac Ad".split(" ");
this.index = new HashMap<String,Integer>(52);
for (int i = 0; i < 52; i++)
this.tableBuf = this.loadBuffer(this.tableCoords);
this.mapBuf = this.loadBuffer(this.mapCoords);
+ /* Prevent texture scaling */
+ this.options = new BitmapFactory.Options();
+ this.options.inScaled = false;
+
/* Load textures */
for (int i = 0; i < 52; i++) {
String name = "card_" + this.cards[i].toLowerCase();
@Override
public void onDrawFrame(GL10 unused)
{
- Os.debug("Cards: onDrawFrame");
+ //Os.debug("Cards: onDrawFrame");
/* Turn on the program */
GLES20.glUseProgram(program);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glUniform1i(this.texHandle, 0);
- /* Draw "Table" */
- Matrix.setIdentityM(this.model, 0);
- GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
+ /* Draw objects */
this.drawTable();
-
- /* Draw hand */
- int num = this.hand.length;
- for (int i = 0; i < num; i++) {
- if (this.drag && this.ypos >= this.ylim && i == this.pick)
- continue;
-
- Matrix.setIdentityM(this.model, 0);
-
- Matrix.rotateM(this.model, 0, 45f, 1f, 0f, 0f);
- Matrix.translateM(this.model, 0, 0f, -0.3f, 1.20f);
-
- if (this.drag) {
- float pct = (float)(i+0.5) / num;
- float err = this.xpos - pct;
- float y = (float)this.ypos / this.ylim;
- float lim = Math.min(Math.max(y,0),1);
- float fcn = 0.1f
- * (float)Math.exp(-10*num*Math.pow(y*err,2))
- * (1f-(float)Math.pow(1-lim, 2));
- Matrix.translateM(this.model, 0, 0, fcn, 0);
- }
- float left = -20f + 20f*(1f/num);
- float right = 54f - 54f*(1f/num);
- float ang = left + i*(right-left)/num;
- Matrix.rotateM(this.model, 0, ang, 0f, 0f, -1f);
- Matrix.translateM(this.model, 0, 0f, 0.15f, 0f);
-
- GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
- this.drawCard(this.hand[i]);
- }
-
- /* Draw selected card */
- if (this.drag && this.ypos >= this.ylim) {
- Matrix.setIdentityM(this.model, 0);
- Matrix.rotateM(this.model, 0, 45f, 1f, 0f, 0f);
- Matrix.translateM(this.model, 0, 0f, 0f, 1.20f);
- GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
- this.drawCard(this.hand[this.pick]);
- }
+ this.drawPile();
+ this.drawHand();
+ this.drawPick();
}
@Override
@Override
public boolean onTouchEvent(MotionEvent event)
{
- boolean up = event.getActionMasked() == MotionEvent.ACTION_UP;
+ boolean up = event.getActionMasked() == MotionEvent.ACTION_UP;
float x = event.getX() / this.getWidth();
float y = 1-(event.getY() / this.getHeight());
if (this.pick >= num) this.pick = num-1;
}
if (y < this.ylim && !this.drag) {
- Os.debug("Cards: onTouchEvent - starting drag");
+ //Os.debug("Cards: onTouchEvent - starting drag");
this.drag = true;
}
if (this.drag) {
- Os.debug("Cards: onTouchEvent - move "
- + x + "," + y);
+ //Os.debug("Cards: onTouchEvent - move " + x + "," + y);
this.requestRender();
}
if (y >= this.ylim && this.drag && up) {
- Os.debug("Cards: onTouchEvent - playing card");
+ //Os.debug("Cards: onTouchEvent - playing card");
+ this.game.onPlay(this.hand[this.pick]);
}
if (up) {
- Os.debug("Cards: onTouchEvent - ending drag");
+ //Os.debug("Cards: onTouchEvent - ending drag");
this.drag = false;
}
return true;
private int loadTexture(String name)
{
- Os.debug("Cards: loadTexture - " + name);
+ //Os.debug("Cards: loadTexture - " + name);
final int[] tex = new int[1];
}
/* Load the bitmap */
- Bitmap bitmap = BitmapFactory.decodeResource(this.res, id);
+ Bitmap bitmap = BitmapFactory.decodeResource(this.res, id, this.options);
/* Copy into OpenGL */
GLES20.glGenTextures(1, tex, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
- GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
- GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
+ GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
+ GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
return tex[0];
}
/* Private drawing methods */
private void drawTable()
{
+ /* Setup view */
+ Matrix.setIdentityM(this.model, 0);
+ GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
+
/* Draw table */
GLES20.glVertexAttribPointer(this.vertHandle, 3, GLES20.GL_FLOAT, false, 3*4, this.tableBuf);
GLES20.glVertexAttribPointer(this.mapHandle, 2, GLES20.GL_FLOAT, false, 2*4, this.mapBuf);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
}
+ private void drawPile()
+ {
+ /* Draw played cards */
+ for (int i = 0; i < 4; i++) {
+ if (i >= this.pile.length || this.pile[i] == null)
+ continue;
+
+ float ang = i * 90f;
+
+ Matrix.setIdentityM(this.model, 0);
+
+ Matrix.rotateM(this.model, 0, -ang, 0f, 0f, 1f);
+ Matrix.translateM(this.model, 0, -0.30f, 0f, 0f);
+ Matrix.rotateM(this.model, 0, ang, 0f, 0f, 1f);
+ Matrix.scaleM(this.model, 0, 3f, 3f, 0f);
+
+ this.drawCard(this.pile[i]);
+ }
+ }
+
+ private void drawHand()
+ {
+ /* Draw hand */
+ int num = this.hand.length;
+ for (int i = 0; i < num; i++) {
+ if (this.drag && this.ypos >= this.ylim && i == this.pick)
+ continue;
+
+ Matrix.setIdentityM(this.model, 0);
+
+ Matrix.rotateM(this.model, 0, 45f, 1f, 0f, 0f);
+ Matrix.translateM(this.model, 0, 0f, -0.3f, 1.20f);
+
+ if (this.drag) {
+ float pct = (float)(i+0.5) / num;
+ float err = this.xpos - pct;
+ float y = (float)this.ypos / this.ylim;
+ float lim = Math.min(Math.max(y,0),1);
+ float fcn = 0.1f
+ * (float)Math.exp(-10*num*Math.pow(y*err,2))
+ * (1f-(float)Math.pow(1-lim, 2));
+ Matrix.translateM(this.model, 0, 0, fcn, 0);
+ }
+
+ float left = -20f + 20f*(1f/num);
+ float right = 54f - 54f*(1f/num);
+ float ang = left + i*(right-left)/num;
+ Matrix.rotateM(this.model, 0, ang, 0f, 0f, -1f);
+ Matrix.translateM(this.model, 0, 0f, 0.15f, 0f);
+
+ this.drawCard(this.hand[i]);
+ }
+ }
+
+ private void drawPick()
+ {
+ /* Draw selected card */
+ if (this.drag && this.ypos >= this.ylim) {
+ Matrix.setIdentityM(this.model, 0);
+ Matrix.rotateM(this.model, 0, 45f, 1f, 0f, 0f);
+ Matrix.translateM(this.model, 0, 0f, 0f, 1.20f);
+ this.drawCard(this.hand[this.pick]);
+ }
+ }
+
private void drawCard(String name)
{
+ if (!this.index.containsKey(name))
+ return;
int idx = this.index.get(name);
int front = this.face[idx];
int back = this.red;
+ /* Set model matrix */
+ GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
+
/* Draw front */
GLES20.glVertexAttribPointer(this.vertHandle, 3, GLES20.GL_FLOAT, false, 3*4, this.faceBuf);
GLES20.glVertexAttribPointer(this.mapHandle, 2, GLES20.GL_FLOAT, false, 2*4, this.mapBuf);