سورس بازی Breakout در اندروید
چهارشنبه 27 اردیبهشت 1396در این مقاله قصد داریم که یک سورس بازی بزاریم این سورس بازی به این صورت است که یک توپ دارید و شما باید با حرکت دادن به چپ و راست توپ را هدایت کنید و خانه ها را از بین ببرید ولی نباید توپ به زمین بیفتد و گرنه می بازید.
در این بازی لایه ی xml به صورت زیر خواهد بود:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
و کلاس جاوای آن به صورت زیر خواهد بود:
import java.util.ArrayList;
import java.util.List;
import org.anddev.andengine.audio.sound.Sound;
import org.anddev.andengine.audio.sound.SoundFactory;
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.text.ChangeableText;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.font.Font;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.Debug;
import android.graphics.Color;
import android.graphics.Typeface;
public class Breakout extends BaseGameActivity
{
// the width of the game screen
private static final int CAMERA_WIDTH = 720;
// the height of the game screen
private static final int CAMERA_HEIGHT = 480;
// the speed of the game
private static final float DEMO_VELOCITY = 200.0f;
// variable used to manipulate the camera
private Camera mCamera;
// texture for the entire screen
private Texture mTexture;
// texture region for the ball
private TextureRegion mPongTextureRegion;
// texture region for the paddle
private TextureRegion mBoxTextureRegion;
// texture region for the tiles
private TiledTextureRegion mBallTextureRegion;
// List that holds all of the boxes
private List<Sprite> boxSpritesList = new ArrayList<Sprite>();
// holds the font for the scoreboard
private Font mFont;
// holds the texture for the scoreboard
private Texture mFontTexture;
// the actual text of the scoreboard
ChangeableText scoreText;
// initialize score to 0 when the game loads
private int score = 0;
// sounds used in the program
private Sound mTileHit;
private Sound mPaddleHit;
private Sound mDeath;
// the point where the engine starts drawing the tiles
int startX;
// the width of the blocks to be drawn
final int blockWidth = 32;
// number of rows to draw on the scene
final int numRows = 5;
// this is run when the game is first loaded.
// i.e. when the application is launched
@Override
public Engine onLoadEngine()
{
// sets the camera to the dimensions declared above
this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
// returns an engine with the properties set by the passed arguments
// below
// true: fullscreen
// ScreenOrientation.LANDSCAPE: sets to landscape orientation
// RatioResolutionPolicy({width},{height}): sets the software renderer's
// resolution policy
// this.mCamera: sets to this class' instantiation of the camera
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
this.mCamera).setNeedsSound(true));
}
// runs when resources are loaded
// that is, when the actual pictures and textures are being loaded into the
// game
@Override
public void onLoadResources()
{
initTextures();
initSounds();
setupScoreBoard();
}
@Override
public Scene onLoadScene()
{
this.mEngine.registerUpdateHandler(new FPSLogger());
// creates a Scene with 1 player
final Scene scene = new Scene(1);
// this is an example of how to place a background image rather than a
// solid color
// scene.setBackground(new RepeatingSpriteBackground(CAMERA_WIDTH,
// CAMERA_HEIGHT, this.mEngine.getTextureManager(), new
// AssetTextureSource(this, "gfx/background.png")));
scene.setBackground(new ColorBackground(0.1f, 0.5f, 0.5f));
// sets the score display with the given font
scoreText = new ChangeableText(0, CAMERA_HEIGHT - 50, this.mFont,
"Score: ", "Score: xxxxx".length());
// adds the score display to the screen
scene.getTopLayer().addEntity(scoreText);
// these are used to set the position for the paddle sprite
final int centerX = (CAMERA_WIDTH - this.mPongTextureRegion.getWidth()) / 2;
final int centerY = CAMERA_HEIGHT - this.mPongTextureRegion.getHeight();
final Sprite paddle = setupPaddle(centerX, centerY);
// creates the ball object that bounces around
final Ball ball = new Ball(CAMERA_WIDTH / 2, CAMERA_HEIGHT / 3,
this.mBallTextureRegion);
// sets the speed of the ball according to the demo velocity
ball.setVelocity(DEMO_VELOCITY, DEMO_VELOCITY);
// adds the paddle and the ball to the current scene
scene.getTopLayer().addEntity(paddle);
scene.getTopLayer().addEntity(ball);
fillBoxArea(scene);
// adds a listener for the paddle in order to receive input
scene.registerTouchArea(paddle);
scene.setTouchAreaBindingEnabled(true);
// handles all updates (frames) for the game
scene.registerUpdateHandler(new IUpdateHandler()
{
@Override
public void reset()
{
}
@Override
public void onUpdate(final float pSecondsElapsed)
{
// detects if the ball falls below the paddle
// i.e. lose condition
// this subtracts 1 point from the score
// this may be changed to have more drastic consequences such as
// restarting the entire game
if (ballBelowPaddle(paddle, ball))
{
playerDeath(ball);
}
// reflect the ball when it hits the paddle
if (paddle.collidesWith(ball))
{
Breakout.this.mPaddleHit.play();
ball.setVelocityY(-DEMO_VELOCITY);
}
final List<Sprite> toRemoved = checkForCollisions(ball);
removeSprite(scene, toRemoved);
}
});
return scene;
}
private List<Sprite> checkForCollisions(final Ball ball)
{
final List<Sprite> toRemoved = new ArrayList<Sprite>();
boxCheckLoop: for (Sprite box : boxSpritesList)
{
// if the ball collides with the box
// AND it hits the bottom specifically
if (ball.collidesWith(box))
{
// increment the score and change the text
score++;
scoreText.setText("Score: " + score);
// add the box to the list of sprites to remove
toRemoved.add(box);
// play the "tile hit" sound
Breakout.this.mTileHit.play();
checkCollisionDirection(ball, box);
break boxCheckLoop;
}
}
return toRemoved;
}
private void removeSprite(final Scene scene, final List<Sprite> toRemoved)
{
// this runs once per update/frame
Breakout.this.runOnUpdateThread(new Runnable()
{
@Override
public void run()
{
for (Sprite sprite : toRemoved)
{
// remove all of the sprites in the "toRemoved" list
scene.getTopLayer().removeEntity(sprite);
boxSpritesList.remove(sprite);
}
}
});
}
private void fillBoxArea(final Scene scene)
{
// this places blocks until there is no more room on the screen
for (int h = 0; h < numRows * blockWidth; h += blockWidth)
{
startX = 10;
for (int i = 0; i < Math.floor(CAMERA_WIDTH / blockWidth); i++)
{
Sprite boxSprite = new Sprite(startX, 10 + h,
this.mBoxTextureRegion);
boxSpritesList.add(boxSprite);
startX += blockWidth;
}
}
// adds all boxes to the screen
for (Sprite boxSprite : boxSpritesList)
{
scene.getTopLayer().addEntity(boxSprite);
}
}
private Sprite setupPaddle(final int centerX, final int centerY)
{
final Sprite paddle = new Sprite(centerX, centerY,
this.mPongTextureRegion)
{
@Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
final float pTouchAreaLocalX, final float pTouchAreaLocalY)
{
// this gets the X coordinate of the finger touch,
// then subtracts the width of the paddle,
// setting the paddle location to the bottom even if
// the touch is not directly on top of the paddle.
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,
centerY);
return true;
}
};
return paddle;
}
@Override
public void onLoadComplete()
{
}
// used to hold game logic information for the ball
private static class Ball extends AnimatedSprite
{
public Ball(final float pX, final float pY,
final TiledTextureRegion pTextureRegion)
{
super(pX, pY, pTextureRegion);
}
// occurs every update/frame
// this handles the bouncing on the borders of the window
@Override
protected void onManagedUpdate(final float pSecondsElapsed)
{
// if the ball hits the left border
if (this.mX < 0)
{
this.setVelocityX(DEMO_VELOCITY);
} //
// if the ball hits the right border
else if (this.mX + this.getWidth() > CAMERA_WIDTH)
{
this.setVelocityX(-DEMO_VELOCITY);
}
// if the ball hits the bottom border
if (this.mY < 0)
{
this.setVelocityY(DEMO_VELOCITY);
} //
// if the ball hits the top border
else if (this.mY + this.getHeight() > CAMERA_HEIGHT)
{
this.setVelocityY(-DEMO_VELOCITY);
}
super.onManagedUpdate(pSecondsElapsed);
}
}
private void initSounds()
{
// sets the root for the sound effects to the mfx folder
SoundFactory.setAssetBasePath("mfx/");
// initialize all the sounds
try
{
this.mTileHit = SoundFactory.createSoundFromAsset(
this.mEngine.getSoundManager(), this, "crush.ogg");
this.mPaddleHit = SoundFactory.createSoundFromAsset(
this.mEngine.getSoundManager(), this, "paddlehit.ogg");
this.mDeath = SoundFactory.createSoundFromAsset(
this.mEngine.getSoundManager(), this, "death.ogg");
} catch (Exception e)
{
Debug.e("Error: " + e);
}
}
private void initTextures()
{
// initializes all of the texture regions
// do not change this area unless you know what you're doing
this.mTexture = new Texture(256, 32,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mPongTextureRegion = TextureRegionFactory.createFromAsset(
this.mTexture, this, "gfx/pong.png", 0, 0);
this.mBallTextureRegion = TextureRegionFactory.createTiledFromAsset(
this.mTexture, this, "gfx/ball.png", 97, 0, 1, 1);
this.mBoxTextureRegion = TextureRegionFactory.createFromAsset(
this.mTexture, this, "gfx/box.png", 114, 0);
// end initialize textures
// loads the texture for the entire screen
this.mEngine.getTextureManager().loadTexture(this.mTexture);
}
private void setupScoreBoard()
{
// sets up font for scoreboard
this.mFontTexture = new Texture(256, 256, TextureOptions.BILINEAR);
this.mFont = new Font(this.mFontTexture, Typeface.create(
Typeface.DEFAULT, Typeface.BOLD), 48, true, Color.BLACK);
this.mEngine.getTextureManager().loadTexture(this.mFontTexture);
this.mEngine.getFontManager().loadFont(this.mFont);
}
private void checkCollisionDirection(final Ball ball, Sprite box)
{
// the tolerance for collision detection
float eps = 0.2f;
// coordinates for top left of the ball
float aX = ball.getX();
float aY = ball.getY();
// height and width of the ball
float aH = ball.getBaseHeight();
float aW = ball.getBaseWidth();
// coordinates for top left of the collided box
float bX = box.getX();
float bY = box.getY();
// height and width of the collided box
float bH = box.getBaseHeight();
float bW = box.getBaseWidth();
// bottom of ball hits the top of a block
if (Math.abs((aY + aH) - bY) <= bH * eps)
{
ball.setVelocityY(-ball.getVelocityY());
} // top of ball hits the bottom of a block
else if (Math.abs(aY - (bH + bY)) <= bH * eps)
{
ball.setVelocityY(-ball.getVelocityY());
} // right side of ball hits the left side of a block
else if (Math.abs((aX + aW) - bX) <= bW * eps)
{
ball.setVelocityX(-ball.getVelocityX());
} // left side of ball hits the right side of a block
else if (Math.abs(aX - (bW + bX)) <= bW * eps)
{
ball.setVelocityX(-ball.getVelocityX());
}
}
private void playerDeath(final Ball ball)
{
Breakout.this.mDeath.play();
score -= 1;
scoreText.setText("Score: " + score);
ball.setPosition(CAMERA_WIDTH / 2, CAMERA_HEIGHT / 3);
}
private boolean ballBelowPaddle(final Sprite paddle, final Ball ball)
{
return ball.getY() + ball.getBaseHeight() > paddle.getY() * 1.05;
}
}
در کلاس بالا رویدادی است که شما با آن صفحه ی گوشی خود را مدیریت می کنید
خروجی بازی به صورت زیر خواهد بود:

- Android
- 2k بازدید
- 1 تشکر