📄 gamecanvas.java
字号:
static final int SCORES_HEIGHT = 52;
/**
* Image and Context for the scores sprite
*/
private Image m_imgScores;
private Graphics m_objScoresContext;
/**
* GameCanvas Constructor.
* The GameCanvas object is constructed by the ErixMIDlet object
* in its startApp() method.
* This constructor also creates all the images required by application. For the image files which contain more than one image (which are not frames for a sprite), the different images are extracted into individual Image objects.
*/
public GameCanvas(ErixMIDlet objMIDlet) {
m_bytDifficulty = 1;
m_nFrameCount = 1;
m_nSplashAnimationLoopsElapsed = 0;
nSplashAnimationPhase = 1;
m_nSplashMovementSkipCounter = 0;
m_nFrameNum = 0;
m_bMessagePaintedOnce = false;
/* Store the ErixMIDlet reference for calling back methods of ErixMIDlet */
m_objMIDlet = objMIDlet;
/* Getting the refrence of current display */
m_objDisplay = Display.getDisplay(m_objMIDlet);
m_nScreenWidth = getWidth();
m_nScreenHeight = getHeight();
/* Create main off screen buffer */
m_imgOffscreen = Image.createImage(m_nScreenWidth, m_nScreenHeight);
m_objOffscreenContext = m_imgOffscreen.getGraphics();
/* Create scores sprite */
m_imgScores = Image.createImage(SCORES_WIDTH, SCORES_HEIGHT);
m_objScoresContext = m_imgScores.getGraphics();
m_arrLinesFrame = new byte[m_nScreenHeight][MAX_NUMBER_X_COORD];
m_arrLinesFrameFillDir = new byte[m_nScreenHeight][MAX_NUMBER_X_COORD];
// Calculate the absolute coordinates of the locations
// where the characters are meant to be present at
// the end of phase 2 of the splash animation.
// Iterate through the array which
// contains phase 1 and phase 2 data for all characters:
for (int i=0; i<m_arrSplashCharacters.length; i++) {
// Calculate the absolute X-coordinate of the character
m_arrSplashCharacters[i][4] = ((m_arrSplashCharacters[i][4]
* m_nScreenWidth)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
// Calculate the absolute Y-coordinate of the character
m_arrSplashCharacters[i][5] = ((m_arrSplashCharacters[i][5]
* m_nScreenHeight)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
}
// Calculate the absolute coordinates of the clip rectangles.
// Iterate through the array which
// contains the coordinates for the clip rectangles.
for (int i=0; i<m_arrSplashRectangles.length; i++) {
m_arrSplashRectangles[i][0] = ((m_arrSplashRectangles[i][0]
* m_nScreenWidth)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
m_arrSplashRectangles[i][1] = ((m_arrSplashRectangles[i][1]
* m_nScreenHeight)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
m_arrSplashRectangles[i][2] = ((m_arrSplashRectangles[i][2]
* m_nScreenWidth)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
m_arrSplashRectangles[i][3] = ((m_arrSplashRectangles[i][3]
* m_nScreenHeight)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
}
m_nPrevEngineMode = -1;
// Set the variable in ErixMIDlet which governs how long the splash
//screen is to be shown
m_objMIDlet.nGameSplashScreenWait = SPLASH_PHASE4_END;
// Determine the initial positions of the various characters in the
//splash animation
// Initial position = Final position - (Increment per movement
// * Number of movements)
// = Final position - (Increment per movement
// * Number of iterations
// / Number of iterations per movement)
for (int i=0; i < m_arrSplashCharacters.length; i++) {
m_arrSplashCharacters[i][0] = m_arrSplashCharacters[i][4] -
(m_arrSplashCharacters[i][2] * SPLASH_PHASE2_END / (SPLASH_ITERATIONS_SKIP + 1));
m_arrSplashCharacters[i][1] = m_arrSplashCharacters[i][5] -
(m_arrSplashCharacters[i][3] * SPLASH_PHASE2_END / (SPLASH_ITERATIONS_SKIP + 1));
}
// Determine the parameters needed for phase 3 of the splash animation.
m_nCurrentShape = 0;
m_nNumVertices = m_arrSplashAnimVertices[m_nCurrentShape].length;
m_nCurrentVertex = 0;
m_nXTwo = ((m_arrSplashAnimVertices[m_nCurrentShape]
[m_nCurrentVertex][0]
* m_nScreenWidth)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
m_nYTwo = ((m_arrSplashAnimVertices[m_nCurrentShape]
[m_nCurrentVertex][1]
* m_nScreenHeight)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
m_nXZero = m_nXOne = m_nXTwo;
m_nYZero = m_nYOne = m_nYTwo;
// Dynamic choosing of font for the highscore screen:
// Number of columns of data to be displayed in
// the highscores screen.
int nNumColumns = 5;
// This array is used to list the widest and the largest
// number of characters that can be contained in a row in
// the highscore screen.
char arrWidestColumnData[] = {'#',
'W', 'W', 'W',
'D', 'i', 'f',
'L', 'v', 'l',
'9', '9', '9', '9', '9', '9', '9'};
// Size of the font
int nFontSize =-1;//uninitialised
m_nColumnGap = 0;//uninitialised
do {
// We want the horizontal distance between
// two successive columns to be atleast 3 pixels.
if (m_nColumnGap < 6) {
if (nFontSize == -1) {
nFontSize = Font.SIZE_LARGE;
}
else if (nFontSize == Font.SIZE_LARGE) {
nFontSize = Font.SIZE_MEDIUM;
}
else if (nFontSize == Font.SIZE_MEDIUM) {
nFontSize = Font.SIZE_SMALL;
}
}
else {
// We have found a font size at
// which we have sufficient spacing.
break;
}
m_objHighscoresFont = Font.getFont(Font.FACE_MONOSPACE,
Font.STYLE_BOLD, nFontSize);
m_objHighscoresFontHeight = m_objHighscoresFont.getHeight();
// Horizontal distance (in pixels) between any two
// successive columns of data in the highscores screen.
m_nColumnGap = (m_nScreenWidth -
m_objHighscoresFont.charsWidth(arrWidestColumnData, 0, arrWidestColumnData.length))
/ (nNumColumns - 1);
// System.out.println("m_objHighscoresFontHeight = " + m_objHighscoresFontHeight);
} while (nFontSize != Font.SIZE_SMALL);
// Calculate the starting X coordinate for the column which
// contains the players' signatures.
// arrWidestColumnData[0] = '#';
m_nSignatureColumnStartX = m_nRankColumnStartX
+ m_objHighscoresFont.charsWidth(arrWidestColumnData, 0, 1)
+ m_nColumnGap;
// Calculate the starting X coordinate for the column which
// contains the difficulty level for the various entries.
/*
arrWidestColumnData[0] = 'W';
arrWidestColumnData[1] = 'W';
arrWidestColumnData[2] = 'W';
*/
m_nDifficultyColumnStartX = m_nSignatureColumnStartX
+ m_objHighscoresFont.charsWidth(arrWidestColumnData, 1, 3)
+ m_nColumnGap;
// Calculate the starting X coordinate for the column which
// contains the level number for the various entries.
/*
arrWidestColumnData[0] = 'D';
arrWidestColumnData[1] = 'i';
arrWidestColumnData[2] = 'f';
*/
m_nLevelColumnStartX = m_nDifficultyColumnStartX
+ m_objHighscoresFont.charsWidth(arrWidestColumnData, 4, 3)
+ m_nColumnGap;
// Calculate the starting X coordinate for the column which
// contains the score for the various entries.
/*
arrWidestColumnData[0] = 'L';
arrWidestColumnData[1] = 'v';
arrWidestColumnData[2] = 'l';
*/
m_nScoreColumnStartX = m_nLevelColumnStartX
+ m_objHighscoresFont.charsWidth(arrWidestColumnData, 7, 3)
+ (m_nColumnGap >> 1)
+ (m_objHighscoresFont.charWidth('0') * 7);
arrWidestColumnData = null;
}
/**
* Generates the splash screen animation.
*/
private void splashAnimation(Graphics g) {
// Determine the current phase of animation
if (m_nSplashAnimationLoopsElapsed <= SPLASH_PHASE1_END) {
nSplashAnimationPhase = 1;
}
else if (m_nSplashAnimationLoopsElapsed <= SPLASH_PHASE2_END) {
nSplashAnimationPhase = 2;
}
else if (m_nSplashAnimationLoopsElapsed <= SPLASH_PHASE3_END) {
nSplashAnimationPhase = 3;
}
else {
nSplashAnimationPhase = 4;
}
// If we are entering the third or the fourth phase,
// Set the appropriate draw color for the two buffers.
if (m_nSplashAnimationLoopsElapsed == (SPLASH_PHASE2_END + 1)) {
// Set the color needed for drawing the "current line" in the anim.
g.setColor(SPLASH_PHASE3_NEWLINE_COLOR);
// Set the color needed for drawing the "old line" in the anim.
m_objOffscreenContext.setColor(SPLASH_PHASE3_OLDLINE_COLOR);
}
else if (m_nSplashAnimationLoopsElapsed == (SPLASH_PHASE3_END + 1)) {
// Set the color needed for the parts of the image outside
// the letters "E" "R" "I" "X".
g.setColor(0x000000); // Black
// Set the color needed for painting the background of the anim.
m_objOffscreenContext.setColor(0x4AC7F7); // A shade of blue.
}
// Generate the required animation depending upon the phase:
// The animation for phase 3 is different from that for other phases
if (nSplashAnimationPhase == 3) {
// Store the values of the vertices between which
// the previous "current line" was drawn.
m_nXZero = m_nXOne;
m_nYZero = m_nYOne;
m_nXOne = m_nXTwo;
m_nYOne = m_nYTwo;
// Draw the "old" line
// (the "current line" of the previous iteration).
m_objOffscreenContext.drawLine(m_nXZero, m_nYZero,
m_nXOne, m_nYOne);
// Copy the updated scene to buffer two
g.drawImage
(m_imgOffscreen,
0, 0,
Graphics.TOP|Graphics.LEFT);
// If there are more vertices in the current shape,
// continue with this shape.
if (m_nCurrentVertex < m_nNumVertices) {
m_nXTwo = ((m_arrSplashAnimVertices[m_nCurrentShape]
[m_nCurrentVertex][0]
* m_nScreenWidth)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
m_nYTwo = ((m_arrSplashAnimVertices[m_nCurrentShape]
[m_nCurrentVertex][1]
* m_nScreenHeight)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
m_nCurrentVertex++;
}
else {
// No more vertices in the current shape.
// If there is atleast one shape we haven't yet drawn ...
if (m_nCurrentShape < m_arrSplashAnimVertices.length - 1) {
// ... get the next shape
m_nCurrentShape++;
// Find out the number of vertices in the next shape.
m_nNumVertices = m_arrSplashAnimVertices[m_nCurrentShape].length;
// Reset the coordinates and the vertex count.
m_nCurrentVertex = 0;
m_nXTwo = ((m_arrSplashAnimVertices[m_nCurrentShape][0][0]
* m_nScreenWidth)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
m_nYTwo = ((m_arrSplashAnimVertices[m_nCurrentShape][0][1]
* m_nScreenHeight)
+ HALF_OF_STANDARD_SCREEN_DIMENSION)
>> TWOS_EXPONENT_FOR_STANDARD_SCREEN_DIMENSION;
m_nXZero = m_nXOne = m_nXTwo;
m_nYZero = m_nYOne = m_nYTwo;
} // End of if of whether there are undrawn shapes.
} //End of else of if there are more vertices in the current shape
// Add the current line (drawn in a different color) to the scene.
g.drawLine(m_nXOne, m_nYOne, m_nXTwo, m_nYTwo);
// Draw Erix at the end point of the newly drawn line,
// to give the effect that it is Erix that is drawing it.
g.setClip(m_nXTwo - ACTIVE_POINT_X_OFFSET,
m_nYTwo - MAX_FRAME_HEIGHT,
FRAME_WIDTH, MAX_FRAME_HEIGHT);
g.drawImage(m_imgErix,
m_nXTwo - ACTIVE_POINT_X_OFFSET,
m_nYTwo - MAX_FRAME_HEIGHT,
Graphics.TOP|Graphics.LEFT);
// Reset the clip on the second buffer.
g.setClip(0, 0, m_nScreenWidth, m_nScreenHeight);
}
// The animation for phases 1, 2, and 4 is quite similar
else {
// Fill the buffer with the draw color, to erase the contents.
m_objOffscreenContext.fillRect(0, 0, m_nScreenWidth, m_nScreenHeight);
// If we are in phases 1 or 2, make the characters move
if ((nSplashAnimationPhase == 1) || (nSplashAnimationPhase == 2)) {
// Update the movement skip counter
m_nSplashMovementSkipCounter++;
if (m_nSplashMovementSkipCounter > SPLASH_ITERATIONS_SKIP) {
// Update the positions of the characters
for (int i=0; i < m_arrSplashCharacters.length; i++) {
m_arrSplashCharacters[i][0] += m_arrSplashCharacters[i][2];
m_arrSplashCharacters[i][1] += m_arrSplashCharacters[i][3];
}
m_nSplashMovementSkipCounter = 0;
} //End of if required number of iterations have been skipped.
} // End of if we are in phases 1 or 2
// Draw the various characters:
// Set the frame to be painted for each of the characters.
// Update the time we have waited before updating the frame.
m_nFrameChangeWaitCounter++;
// Is it time to change the chracters' frames?
if (m_nFrameChangeWaitCounter == FRAME_CHANGE_WAIT) {
// Yes. Change the frame number to be painted.
m_nFrameNum++;
if (m_nFrameNum == NUM_FRAMES) {
m_nFrameNum = 0;
}
// Reset the counter.
m_nFrameChangeWaitCounter = 0;
}
// Draw the enemies
for (int i=1; i < m_arrSplashCharacters.length; i++) {
m_objOffscreenContext.setClip
(m_arrSplashCharacters[i][0] - ACTIVE_POINT_X_OFFSET,
m_arrSplashCharacters[i][1],
FRAME_WIDTH, MAX_FRAME_HEIGHT);
m_objOffscreenContext.drawImage
(m_arrimgEnemy[(m_arrSplashCharacters[i][6] - 1)],
/* ^^ Image of the appropriate type ^^ */
m_arrSplashCharacters[i][0] - (m_nFrameNum * FRAME_WIDTH) - ACTIVE_POINT_X_OFFSET,
m_arrSplashCharacters[i][1],
Graphics.TOP|Graphics.LEFT);
}
// Reset the clip on the first buffer.
m_objOffscreenContext.setClip(0, 0, m_nScreenWidth, m_nScreenHeight);
// If we are in phase 4, copy
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -