Android research-Game Development camera update

Source: Internet
Author: User
Tags android games

Android research-Game Development camera update
Zookeeper

Introduction to the principle of cameras in games

Updating the camera position in game development determines the content displayed on the screen, especially the RPG Game camera, for example, sometimes, when playing an RPG Game, we enter a new scenario to trigger a script and find that the camera starts to move up. Based on the camera, the player can roughly view what is in this scenario, what kind of story is triggered. This is how the game camera works. In the previous chapter, I learned how to develop a map editor for Android games.

: First, the area displayed by the camera is also the area displayed on the screen of the mobile phone. If you need to change the camera position, you actually need to change the background map position. Using a program to drag the background map gives the player an illusion that the player feels like a camera in move rather than move the background map.



In the game, the principle of map drawing is introduced. Based on the ID of each tile in the array generated by the map editor, find the XY coordinates of the original map file of each tile to calculate the display position of the image. the cutting method is used to cut each tile out and display it on the mobile phone screen. The image cutting code is as follows:

/*** Draw a part of the image ** @ param canvas * @ param paint * @ param bitmap * @ param x * @ param y * @ param src_x * @ param src_y *@ param src_width * @ param src_Height */private void DrawClipImage (Canvas canvas, paint paint, Bitmap bitmap, int x, int y, int src_x, int src_y, int src_xp, int src_yp) {canvas. save (); canvas. clipRect (x, y, x + src_xp, y + src_yp); canvas. drawBitmap (bitmap, x-src_x, y-src_y, paint); canvas. restore ();}

Canvas. save ();
Save the Canvas before cutting the image, and then after the cutting is finished
Canvas. restore ();
Reset the Canvas status. If this is not done, the first image is cut and all the images will be blocked. Therefore, you must remember this.

As shown in the figure: this is how every tile is drawn. When talking about this, some friends may ask if my map is infinitely large, isn't it necessary to loop through this method infinitely? In fact, the number of tile to be drawn on the screen only needs to be drawn within the display area of the screen, we do not need to consider drawing outside the actual area of the screen, just need to update the map coordinate data, for example, if the screen size of my simulator is 320X480, then the number of tile I actually drew is only 10X15 (blocks ). In fact, a more important rendering technology in Game Development and plotting is the dual Buffer technology which can be used to solve the problem of screen flickering. I will introduce it in detail in the next chapter.

Yesterday, a friend told me that using arrays to draw maps is unscientific. I agree with him. Why is it unscientific? The reason is that we only have one scenario. We use one array to draw a map. If our game has 100 scenarios, wouldn't we write 100 arrays in the program? In fact, in actual development, we convert the map information into xml files and hit the game package. When switching the game scenario, players will read the xml map file in the current game scenario. In fact, these xml files also store the two arrays of the map, but the advantage of doing so is that the data-driven programmer does not need to define N Arrays for N kinds of judgments only need to be based on the ID of the current switching scenario the map information is very convenient, and you can avoid mistakes in the code.

However, no matter how data is processed, the rendering principle is the same.

How to update the camera in the game

: The app retrieves random numbers to update the game camera.

Currently, the camera location is updated every 10000 milliseconds (random number) after we have the camera position, we can figure out the relative display position of the background image, move the background image position, and then create an illusion for players that the camera is moving.

The map block is the tile block with a new length and width, which is 20X20.


Copy with CTRL + C and paste with CTRL + V. Package cn. m15.xys; import java. io. InputStream;
Import java. util. Random; import android. app. Activity;
Import android. content. Context;
Import android. content. res. Resources;
Import android. graphics. Bitmap;
Import android. graphics. BitmapFactory;
Import android. graphics. Canvas;
Import android. graphics. Color;
Import android. graphics. Paint;
Import android. OS. Bundle;
Import android. view. Display;
Import android. view. View;
Import android. view. Window;
Import android. view. WindowManager; public class CameraAcitvity extends Activity {MapView mMapView = null;
@ Override
Public void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
// Full screen display window
RequestWindowFeature (Window. FEATURE_NO_TITLE );
GetWindow (). setFlags (WindowManager. LayoutParams. FLAG_FULLSCREEN,
WindowManager. LayoutParams. FLAG_FULLSCREEN );
// Obtain the screen width and height
Display display = getWindowManager (). getDefaultDisplay ();
// Display a custom game View
MMapView = new MapView (this, display. getWidth (), display. getHeight ());
SetContentView (mMapView );
} Public class MapView extends View {// width and height of the tile block
Public final static int TILE_WIDTH = 32;
Public final static int TILE_HEIGHT = 32; // Number of tile blocks with a higher width
Public final static int TILE_WIDTH_COUNT = 20;
Public final static int TILE_HEIGHT_COUNT = 20; // map width and height
Public final static int MAP_WIDTH = 640;
Public final static int MAP_HEIGHT = 640; // lens movement range
Public final static int CAMERA_MOVE = 10; // width and height of the screen
Public int mScreenWidth = 0;
Public int mScreenHeight = 0; // If the array element is 0, nothing is painted.
Public final static int TILE_NULL = 0;
// Game View map array at the first layer
Public int [] [] mMapView = {
{1, 1, 1, 1, 1, 1, 1, 1, 1,137,137,137,137,137, 1, 1, 1,
1, 1, 1 },
{1, 1, 1, 1, 1, 1, 1,137,137,137,137,137,137, 1, 1,
1, 1, 1, 1 },
{1, 1, 1, 1, 1, 1, 1, 1,137,137,137,137,137, 1, 1, 1, 1,
1, 1, 1 },
{1, 1, 1, 1, 1,137,137,137,137,137,137,137,137, 1, 1,
1, 1, 1, 1, 1 },
{0, 137,137,137,137,137,137,137,137,137,137,137,137,
137,137,137,137,137, 1, 1, 1 },
{0, 137,137,137,137,137,137,137,137,137,137,137,137,
137,137,137,137,137, 1, 1, 1 },
{137,137,137, 1, 1,137,137,137,137,137,137,137,137,
137,137,137, 1, 1, 1, 1 },
{1,137,137, 1, 1, 1,137,137,137,137,137,137,137,137,
137,137,137, 1,137, 1 },
{1, 1, 1, 1, 1, 1, 1, 1,137,137,137,137,137,137,137,137,
137,137,137,137, 1 },
{1, 1, 1, 1, 1, 1, 1,137,137,137,137, 1, 1, 1,137,137,
137,137,137,137 },
{1, 1, 1, 1, 1, 1, 1, 1,137,137,137,137, 1, 1, 1,137,
137,137,137, 1 },
{1, 1, 1, 1, 1, 1,137,137,137,137,137,137,137, 1, 1, 1,
1,137,137,137 },
{1, 1, 1, 1, 1, 1,137,137,137,137,137, 1, 1, 1, 1, 1,
1,137,137 },
{1, 1, 1, 1, 1, 1, 1,137,137,137,137, 1, 1, 1, 1, 1,
137,137,137 },
{1, 1, 1, 1, 1,137,137,137,137,137,137,137, 1, 1, 1, 1,
1,137,137,137 },
{1, 1, 1, 1, 1, 1,137,137,137,137,137,137, 1, 1, 1,
1, 1, 1, 1 },
{1, 1, 1, 1, 1, 1,137,137,137,137,137, 1, 1, 1, 1, 1,
1, 1, 1 },
{1, 1, 1, 1, 1, 1,137,137,137,137,137, 1, 1, 1, 1, 1,
1, 1, 1 },
{1, 1, 1, 1, 1, 1,137,137,137,137,137, 1, 1, 1, 1, 1,
1, 1, 1 },
{1, 1, 1, 1, 1, 1, 1,137,137,137, 1, 1, 1, 1, 1, 1, 1,
1, 1 }}; // Layer 2 game entity actor Array
Public int [] [] mmapactor = {
{143,144, 0,102,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185,186,187,188 },
{151,152, 0,110,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
193,194,195,196 },
{159,160, 0,110,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
201,202,203,204 },
{0, 0, 0,126,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
209,210,211,212 },
{0, 0, 0,134,136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,218,219,220 },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,227,228 },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 },
{102,103,103,103,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 },
{110,111,111,111,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 },
{110,111,111,111,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 },
{126,127,127,127,128, 0, 0, 0, 0, 0, 0, 0,165,166, 0, 0,
0, 0, 0, 0 },
{123,124,124,124,125, 0, 0, 0, 0, 0, 0, 0,173,174,175,176,
0, 0, 0, 0 },
{229,230,231,232, 0, 0, 0, 0, 0, 0, 0, 0,181,182,183,184,
0, 0, 0, 0 },
{237,238,239,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 },
{245,246,247,248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 },
{0,254,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,233,234,235,
236, 0, 0, 0 },
{0,262,263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241,242,243,
244, 0, 0, 0 },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250,251,
0, 0, 0, 0 },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,258,259,
0, 0,143,144}
}; // Layer-3 game collision physical layer Array
// Next chapter
// .................... // Game map Resource
Bitmap mBitmap = null; // resource file
Resources mResources = null; // game paint brush
Paint mPaint = null; // number of horizontal vertical tile Blocks
Int mWidthTileCount = 0;
Int mHeightTileCount = 0; // number of horizontal vertical tile Blocks
Int mBitMapWidth = 0;
Int mBitMapHeight = 0; // the camera's focus is 0.0 points in the center.
Int mCameraPosX = 0;
Int mCameraPosY = 0; // coordinates of the anchor in the upper left corner of the map
Int mMapPosX = 0;
Int mMapPosY = 0; // record the last time private long statrTime = 0 ;/**
* Constructor
*
* @ Param context
*/
Public MapView (Context context, int screenWidth, int screenHeight ){
Super (context );
MScreenHeight = screenHeight;
MScreenWidth = screenWidth;
MPaint = new Paint ();
MBitmap = ReadBitMap (context, R. drawable. map );
MBitMapWidth = mBitmap. getWidth ();
MBitMapHeight = mBitmap. getHeight ();
MWidthTileCount = mBitMapWidth/TILE_WIDTH;
MHeightTileCount = mBitMapHeight/TILE_HEIGHT;
StatrTime = System. currentTimeMillis ();
} @ Override
Protected void onDraw (Canvas canvas ){
UpdateCamera ();
DrawMap (canvas, mBitmap );
DrawRectText (canvas );
Super. onDraw (canvas );
Invalidate ();
} Private void DrawMap (Canvas canvas, Bitmap bitmap ){
Int I, j;
For (I = 0; I & lt; TILE_HEIGHT_COUNT; I ++ ){
For (j = 0; j & lt; TILE_WIDTH_COUNT; j ++ ){
Int ViewID = mMapView [I] [j];
Int ActorID = mMapAcotor [I] [j];
Int x = (j * TILE_WIDTH) + mMapPosX;
Int y = (I * TILE_HEIGHT) + mMapPosY;
// Draw the first layer of the map
If (ViewID & gt; TILE_NULL ){
DrawMapTile (ViewID, canvas, mPaint, bitmap, x, y );
} // Second layer of the map
If (ActorID & gt; TILE_NULL ){
DrawMapTile (ActorID, canvas, mPaint, bitmap, x, y );
}
}
}
}
Private void DrawRectText (Canvas canvas ){
Canvas. clipRect (0, 0, mScreenWidth, 30 );
MPaint. setColor (Color. WHITE );
Canvas. drawRect (0, 0, mScreenWidth, 30, mPaint );
MPaint. setColor (Color. RED );
Canvas. drawText ("X coordinate of the Current Camera:" + mCameraPosX + "Y coordinate of the Current Camera:" + mCameraPosY, 0, 20, mPaint );
}
Private void UpdateCamera (){
Long nowTime = System. currentTimeMillis ();
// Update the camera position every 100 milliseconds
If (nowTime-statrTime & gt; 1000 ){
// Obtain the coordinates of the camera at random.
MCameraPosX = UtilRandom (0, MAP_WIDTH-mScreenWidth );
MCameraPosY = UtilRandom (0, MAP_HEIGHT-mScreenHeight );
// Update the map coordinates based on the camera coordinates
MMapPosX =-mCameraPosX;
MMapPosY =-mCameraPosY;
StatrTime = nowTime;
}
}/**
* Returns a random number.
* @ Param botton
* @ Param top
* @ Return
*/
Private int UtilRandom (int botton, int top ){
Return (Math. abs (new Random (). nextInt () % (top-botton) + botton );
}
/**
* Draw a tile block by ID
*
* @ Param id
* @ Param canvas
* @ Param paint
* @ Param bitmap
*/
Private void DrawMapTile (int id, Canvas canvas, Paint paint,
Bitmap bitmap, int x, int y ){
// Calculate the XY coordinates in the map Resource Based on the ID in the array.
// Because the editor defaults to 0, the ID of the first tile is not 0 but 1. So here-1
Id --;
Int count = id/mWidthTileCount;
Int bitmapX = (id-(count * mWidthTileCount) * TILE_WIDTH;
Int bitmapY = count * TILE_HEIGHT;
DrawClipImage (canvas, paint, bitmap, x, y, bitmapX, bitmapY,
TILE_WIDTH, TILE_HEIGHT );
}/**
* Read images of local resources
*
* @ Param context
* @ Param resId
* @ Return
*/
Public Bitmap ReadBitMap (Context context, int resId ){
BitmapFactory. Options opt = new BitmapFactory. Options ();
Opt. inPreferredConfig = Bitmap. Config. RGB_565;
Opt. inPurgeable = true;
Opt. ininputtransferable = true;
// Obtain the resource Image
InputStream is = context. getResources (). openRawResource (resId );
Return BitmapFactory. decodeStream (is, null, opt );
}/**
* Draw a part of the image
*
* @ Param canvas
* @ Param paint
* @ Param bitmap
* @ Param x
* @ Param y
* @ Param src_x
* @ Param src_y
* @ Param src_width
* @ Param src_Height
*/
Private void DrawClipImage (Canvas canvas, Paint paint, Bitmap bitmap,
Int x, int y, int src_x, int src_y, int src_xp, int src_yp ){
Canvas. save ();
Canvas. clipRect (x, y, x + src_xp, y + src_yp );
Canvas. drawBitmap (bitmap, x-src_x, y-src_y, paint );
Canvas. restore ();
}}
}

In the end, if you still think that I am not writing enough details, it doesn't matter if I post the source code. You are welcome to discuss and study it together.

Download the source code: CameraView

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.