📄 abstractdicesanim.java
字号:
// Copyright (c) 2005 Sony Ericsson Mobile Communications AB
//
// This software is provided "AS IS," without a warranty of any kind.
// ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
// INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
//
// THIS SOFTWARE IS COMPLEMENTARY OF JAYWAY AB (www.jayway.se)
package bluegammon.gui.animation;
import javax.microedition.lcdui.Graphics;
import javax.microedition.m3g.Graphics3D;
import javax.microedition.m3g.Transform;
import bluegammon.Audio;
import bluegammon.gui.BoardCanvas;
import bluegammon.gui.Context3D;
import bluegammon.logic.Rand;
import bluegammon.logic.BoardMediator;
/**
* An abstract animation of two dices - we do not have
* a case where we ever show only one dice. This is an
* general handler for rolling two dices that will have
* specified color and dice-value each.
*
* @author Peter Andersson
*/
abstract public class AbstractDicesAnim extends Animation
{
/** Dice property index constants */
protected static final int X = 0, Y = 1, Z = 2,
DX = 3, DY = 4, DZ = 5,
RX = 6, RY = 7, RZ = 8,
DRZ = 9,
WRX = 10, WRY = 11;
/** Z index where board is */
protected static final float Z_ON_BOARD = -35f;
/** Gravity constant */
protected static final float G = -0.05f;
/** X-axis rotation per dice value */
protected static final float[] XROT =
{ 0, 90, 0, 0, -90, 180 };
/** Y-axis rotation per dice value */
protected static final float[] YROT =
{ 0, 0, 90, -90, 0, 0 };
/** Physic properties for dice 1 */
protected float[] diceProps1 = new float[12];
/** Physic properties for dice 2 */
protected float[] diceProps2 = new float[12];
/** White dice 1 flag */
protected boolean m_dice1White;
/** White dice 2 flag */
protected boolean m_dice2White;
/** Values of dices */
protected int m_dice1, m_dice2;
/** Current step in animation */
protected int m_step;
/** The step from which both dices are still */
protected int m_diceStillStep;
/** The time from which both dices are still */
protected long m_diceStillTime;
/** Flag indicating if we played sound of dices hitting board */
protected boolean m_playedSound = false;
/** Cached transform object */
protected Transform m_trans = new Transform();
/** Shadow rgb buffer */
protected static int[] m_shadow = null;
/** Size of the dice in correspondance to the canvas */
protected static int m_factor;
/**
* Initializes this animation, must be called before
* displaying any diceanimations.
* @param factor The size factor of the dices, depends
* on the canvas size of the device.
*/
public static void init(int factor)
{
// Create semi transparant shadow as rgb buffer
m_factor = factor * 7;
m_shadow = Context3D.createShadowRGB(factor * 14, 1);
}
/**
* Called when the animation starts, resets the state of the sound.
*/
public void onStart()
{
m_playedSound = false;
}
/**
* Initiates this animation. Specifies color and values for both dices.
* @param dice1White True if left dice is white, false for black,
* @param dice2White True if right dice is white, false for black,
* @param dice1Val Left dice value, 1 to 6.
* @param dice2Val Right dice value, 1 to 6.
*/
public AbstractDicesAnim(boolean dice1White, boolean dice2White, int dice1Val, int dice2Val)
{
m_dice1White = dice1White;
m_dice2White = dice2White;
m_dice1 = dice1Val;
m_dice2 = dice2Val;
// Initiate dice positions, vectors and rotations
int drz0, drz1;
BoardCanvas canvas = BoardCanvas.getInstance();
diceProps1[X] = (canvas.getWidth() / 2 - m_factor);
diceProps1[DX] = (Rand.randomFloat() - 0.7f) * ((float) canvas.getWidth() / 200.0f);
diceProps1[Y] = canvas.getHeight() - m_factor;
diceProps1[DY] = -((float) canvas.getBoardHeight() / 150.0f) +
(Rand.randomFloat() - 2f) * ((float) canvas.getBoardHeight() / 400.0f);
diceProps1[Z] = -10f + 5f * Rand.randomFloat();
diceProps1[DZ] = 0;
diceProps1[RX] = 180.0f * Rand.randomFloat();
diceProps1[RY] = 180.0f * Rand.randomFloat();
diceProps1[WRX] = XROT[dice1Val - 1];
diceProps1[WRY] = YROT[dice1Val - 1];
drz0 = (Rand.random() & 0xf) + 8;
drz1 = -(Rand.random() & 0xf) - 8;
if (-drz1 > drz0) drz0 = drz1;
diceProps1[DRZ] = drz0;
diceProps2[X] = (canvas.getWidth() / 2 + m_factor);
diceProps2[DX] = diceProps1[DX] +
(float)((Rand.randomFloat() + 1.5f) * canvas.getWidth() / 300.0f);
diceProps2[Y] = diceProps1[Y];
diceProps2[DY] = -((float)canvas.getBoardHeight() / 150.0f) +
(Rand.randomFloat() - 2f) * ((float) canvas.getBoardHeight() / 400.0f);
diceProps2[Z] = -10f + 5f * Rand.randomFloat();
diceProps2[DZ] = 0;
diceProps2[RX] = 180.0f * Rand.randomFloat();
diceProps2[RY] = 180.0f * Rand.randomFloat();
diceProps2[WRX] = XROT[dice2Val - 1];
diceProps2[WRY] = YROT[dice2Val - 1];
drz0 = (Rand.random() & 0xf) + 8;
drz1 = -(Rand.random() & 0xf) - 8;
if (-drz1 > drz0) drz0 = drz1;
diceProps2[DRZ] = drz0;
m_diceStillStep = -1;
}
public void paint(Graphics g)
{
Context3D c3d = Context3D.getInstance();
int factor2 = m_factor * 2;
float x0 = diceProps1[X];
float y0 = diceProps1[Y];
float z0 = diceProps1[Z];
float x1 = diceProps2[X];
float y1 = diceProps2[Y];
float z1 = diceProps2[Z];
// Draw shadows
g.drawRGB(m_shadow, 0, factor2,
(int)(x0 - m_factor - c3d.toScreenCoordinateX(c3d.getShadowProjectionDeltaX(z0 - Z_ON_BOARD), z0)),
(int)(y0 - m_factor), factor2, factor2, true);
g.drawRGB(m_shadow, 0, factor2,
(int)(x1 - m_factor - c3d.toScreenCoordinateX(c3d.getShadowProjectionDeltaX(z1 - Z_ON_BOARD), z1)),
(int)(y1 - m_factor), factor2, factor2, true);
// Draw dices
Graphics3D g3d = c3d.bindScene(g);
// Dice 1
m_trans.setIdentity();
m_trans.postTranslate(c3d.to3DCoordinateX(x0, Z_ON_BOARD), c3d.to3DCoordinateY(
y0, Z_ON_BOARD), z0);
// In air rotation
m_trans.postRotate(diceProps1[RX], 1, 0, 0);
m_trans.postRotate(diceProps1[RY], 0, 1, 0);
m_trans.postRotate(diceProps1[RZ], 0, 0, 1);
// Dice value rotation
m_trans.postRotate(diceProps1[WRX], 1, 0, 0);
m_trans.postRotate(diceProps1[WRY], 0, 1, 0);
g3d.render( c3d.getDiceVertexBuffer(),
c3d.getDiceIndexBuffer(),
c3d.getDiceAppearance(m_dice1White),
m_trans);
// Dice 2
m_trans.setIdentity();
m_trans.postTranslate(c3d.to3DCoordinateX(x1, Z_ON_BOARD),
c3d.to3DCoordinateY(y1, Z_ON_BOARD),
z1);
// In air rotation
m_trans.postRotate(diceProps2[RX], 1, 0, 0);
m_trans.postRotate(diceProps2[RY], 0, 1, 0);
m_trans.postRotate(diceProps2[RZ], 0, 0, 1);
// Dice value rotation
m_trans.postRotate(diceProps2[WRX], 1, 0, 0);
m_trans.postRotate(diceProps2[WRY], 0, 1, 0);
g3d.render( c3d.getDiceVertexBuffer(),
c3d.getDiceIndexBuffer(),
c3d.getDiceAppearance(m_dice2White),
m_trans);
g3d.releaseTarget();
}
public void next()
{
boolean hitGround = false;
hitGround = updateDicePhysics(diceProps1);
hitGround |= updateDicePhysics(diceProps2);
if (hitGround && !m_playedSound)
{
m_playedSound = true;
if (Math.abs(diceProps1[DRZ]) + Math.abs(diceProps2[DRZ]) > 19*2)
{
Audio.playSound(Audio.DICES_LONG);
}
else
{
Audio.playSound(Audio.DICES_SHORT);
}
}
if (m_diceStillStep == -1)
{
if (isStill(diceProps1) && isStill(diceProps2))
{
m_diceStillTime = System.currentTimeMillis();
m_diceStillStep = m_step;
}
}
BoardCanvas.getInstance().requestRepaint();
m_step++;
}
public boolean isFinished()
{
return (m_diceStillStep > 0 && (m_step > m_diceStillStep + 14 ||
System.currentTimeMillis() > m_diceStillTime + 1500)) ||
BoardMediator.isGameFinished();
}
public long getInterval()
{
return 20;
}
// Helpers
/**
* Updates the dices vectors and positions. If dice is on board, friction is
* applied.
*/
protected boolean updateDicePhysics(float[] diceProps)
{
boolean hitGround = false;
BoardCanvas canvas = BoardCanvas.getInstance();
// Update position
diceProps[X] += diceProps[DX];
diceProps[Y] += diceProps[DY];
// Bounce against middle wall on board?
if (diceProps[Y] < (canvas.getBoardHeight() / 2 + m_factor)
&& diceProps[DY] < 0)
{
diceProps[DY] = -diceProps[DY];
diceProps[Y] = (canvas.getBoardHeight() / 2 + m_factor);
}
// in air
if (diceProps[Z] > Z_ON_BOARD)
{
diceProps[Z] += diceProps[DZ];
diceProps[DZ] += G;
diceProps[RZ] += diceProps[DRZ];
// boink
if (diceProps[Z] <= Z_ON_BOARD)
{
diceProps[DZ] = 0;
diceProps[Z] = Z_ON_BOARD;
hitGround = true;
}
}
// on board
else
{
// Decrease in air rotations
diceProps[RX] %= 360;
if (Math.abs(diceProps[RX]) < 13) diceProps[RX] = 0;
else if (diceProps[RX] > 180) diceProps[RX] += 12;
else if (diceProps[RX] < 180) diceProps[RX] -= 12;
diceProps[RY] %= 360;
if (Math.abs(diceProps[RY]) < 13) diceProps[RY] = 0;
else if (diceProps[RY] > 180) diceProps[RY] += 12;
else if (diceProps[RY] < 180) diceProps[RY] -= 12;
// friction, positions and in air z-rotation
diceProps[DRZ] *= 0.95f;
if (Math.abs(diceProps[DRZ]) < 2) diceProps[DRZ] = 0;
diceProps[RZ] += diceProps[DRZ];
diceProps[DX] *= 0.95f;
if (Math.abs(diceProps[DX]) < 1) diceProps[DX] = 0;
diceProps[DY] *= 0.95f;
if (Math.abs(diceProps[DY]) < 1) diceProps[DY] = 0;
}
return hitGround;
}
/**
* Returns if a dice is still
*
* @param diceProps The dice properties
* @return true if dice is still
*/
protected boolean isStill(float[] diceProps)
{
return diceProps[Z] == Z_ON_BOARD & diceProps[DRZ] == 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -