1.程序主界面:

屏幕有猎枪,每一轮5发子弹,游戏可以一直玩下去。通过晃动手机,可以重力加速度传感器控制准星和猎枪角度的移动。为了增加啊趣味性,同时增加了小鸟移动的场景,白云也是可以移动的。

2在游戏开始的过程中,可以点击返回键暂停游戏。

下面从源码角度以及代码功能角度讲解一下快乐打小鸟的游戏。

首先,游戏含有5部分,移动的小鸟,移动的云,小鸟散落的羽毛,游戏相关的场景布局和设置以及射击小鸟部分。下面将分别对这5各部分进行介绍。

(1)   移动的小鸟。

关于小鸟的各种属性设置其实在bird.java文件中,在eclipse中的目录文件层次结构如下图所示:

Bird有以下几种状态,下落状态,已下落,正在飞行,已经飞走,是否受惊吓(枪声),小鸟的速度。分别对应如下几个属性:

private boolean falling = false; //下落状态

private boolean fallen = false;  //已落下

private boolean flying = true;   //正在飞

private boolean flyAway = false; //已经飞走

private boolean wasScared = true; //是否受惊吓

private int deadRotation = 0; //死亡时旋转角度

private float xSpeed = 1, ySpeed = 0;

private int speed = 4;  //速度

private Random r = new Random();

private final long creationTime;

private long pauseTime=0;

private final long lifeTime = 30*1000;//存活时间,默认30 secs

调用update函数可以对小鸟的各种状态进行更新,从而在画面上实时显示,达到动态的效果。

public void update()

{

float currX = getX();

float currY = getY();

if(System.currentTimeMillis() - creationTime-pauseTime > lifeTime && isFlying())

{

setFlyAway(true);

}

if(flying)

{

if(wasScared)

{

ySpeed=-ySpeed;

wasScared = false;

}

currX =currX + speed * xSpeed;

if(currX<0)

{

currX= 0;

getTextureRegion().setFlippedHorizontal(!getTextureRegion().isFlippedHorizontal());

xSpeed=-xSpeed;

}

else if(currX+getWidth()>ShotBirdGame.CAMERA_WIDTH)

{

currX= ShotBirdGame.CAMERA_WIDTH-getWidth();

getTextureRegion().setFlippedHorizontal(!getTextureRegion().isFlippedHorizontal());

xSpeed=-xSpeed;

}

currY =currY + speed * ySpeed;

if(currY<0)

{

currY= 0;

ySpeed=-ySpeed;

}

else if(currY+getHeight()>ShotBirdGame.CAMERA_HEIGHT-ShotBirdGame.grass.getHeight())

{

currY= ShotBirdGame.CAMERA_HEIGHT-ShotBirdGame.grass.getHeight()-getWidth();

ySpeed=-ySpeed;

}

int rotCoeff = 1;

if(xSpeed>0)

{

rotCoeff= 1;

}

else

{

rotCoeff= -1;

}

if(ySpeed>0)

{

setRotation(15*rotCoeff);

}

else

{

setRotation(-15*rotCoeff);

}

setPosition(currX,currY);

}

else if(flyAway)

{

ySpeed =Math.abs(ySpeed)*-1;

currX =currX + speed * xSpeed*2;

currY =currY + speed * ySpeed*2;

if(currX+getWidth()<0)

{

fallen = true;

}else if(currX>ShotBirdGame.CAMERA_WIDTH)

{

fallen = true;

}

if(currY+getHeight()<0)

{

fallen = true;

}

int rotCoeff = 1;

if(xSpeed>0)

{

rotCoeff= 1;

}

else

{

rotCoeff= -1;

}

setRotation(-15*rotCoeff);

setPosition(currX,currY);

}

else if (falling)

{

currX =currX + 2 * xSpeed;

if(currX+getWidth()<0)

{

currX= ShotBirdGame.CAMERA_WIDTH;

}else if(currX>ShotBirdGame.CAMERA_WIDTH)

{

currX= 0-getWidth();

}

currY+=10;

if(currY > ShotBirdGame.CAMERA_HEIGHT-ShotBirdGame.grass.getHeight())

{

currY= ShotBirdGame.CAMERA_HEIGHT-ShotBirdGame.grass.getHeight();

fallen = true;

falling = false;

}

setPosition(currX,currY);

deadRotation += 5*xSpeed;

setRotation(deadRotation);

}

}

(2)  移动的云。

为了是游戏的画面感更具动态性,增加了移动的云朵。云朵主要含有速度这一个属性,对应的class文件为Cloud.java。其中定时对云朵的状态进行更新,可以达到动态的效果。更新状态的功能主要如下:

//更新云朵的位置信息

public void update()

{

float currX = getX() + cloudSpeed;

if(currX+getWidth()<0)

{

currX =ShotBirdGame.CAMERA_WIDTH;

}else if(currX>ShotBirdGame.CAMERA_WIDTH)

{

currX =0-getWidth();

}

setPosition(currX,getY());

}

(3)  散落的羽毛。

散落的羽毛主要是在小鸟被子弹打中时出现,含有动态的散落的效果。主要对应的是class文件为Feather.java文件。更新羽毛所在的位置信息的代码如下:

//更新羽毛所在的位置信息

public void update()

{

if(System.currentTimeMillis()-creationTime<lifeTime)

{

if(random.nextBoolean())

{

setPosition(getX()+random.nextInt(10), getY()+1);

}

else

{

setPosition(getX()+random.nextInt(10)*-1, getY()+1);

}

}

else

{

dead  = true;

}

}

(4)快乐打小鸟游戏的主要部分。

这部分包含应用程序的入口,已经游戏所需资源文件的一些初始化操作。游戏场景的加载和游戏中涉及的对象的初始化。比如山,陆地,草坪,小的云朵,射击的音效等。加载UI元素的代码如下:

private final int add = 50;

protected static final String PREFS_NAME = "GAME_SETTINGS";

protected static final String USE_SOUND = "SOUND";

protected static final String USE_VIBRO = "VIBRO";

protected static final String USE_ACC = "ACC";

protected static final String USE_TOUCH = "TOUCH";

public static int CAMERA_WIDTH = 800;//480;

public static int CAMERA_HEIGHT = 480;//320;

private Camera mCamera;

private Texture mTexture,mTexture2,mTexture3;

public static TextureRegion /*background,*/

hills,

sky,

largeCloud,

mediumCloud,

smallCloud,

grass,

aim,

barrel,

feather,

featherFlipped,

shootbutton,

shell,

flash,

shot,

logo,

startButton,

settingsButton;

public static TiledTextureRegion birdFly,birdFlyFlipped;

public static Sound sShotReload;

public static Font mDuckFont;

public static Texture mDuckFontTexture;

private Game game;

private boolean musicPaused;

本游戏主要用到了andengine游戏开发引擎,加载游戏引擎的带阿妈如下(其中本游戏的最小分辨率是320X480,最佳分辨率是480x800):

//加载游戏引擎

public Engine onLoadEngine() {

Displaydisplay = getWindowManager().getDefaultDisplay();

CAMERA_WIDTH = display.getWidth();

CAMERA_HEIGHT = display.getHeight();

if(CAMERA_WIDTH<=480 && CAMERA_HEIGHT<=320)

{

CAMERA_WIDTH=480;

CAMERA_HEIGHT=320;

}

this.mCamera = new Camera(0,0,CAMERA_WIDTH,CAMERA_HEIGHT);

return new Engine(newEngineOptions(true,ScreenOrientation.LANDSCAPE,new RatioResolutionPolicy(CAMERA_WIDTH,CAMERA_HEIGHT),this.mCamera).setNeedsSound(true).setNeedsMusic(true));

}

加载游戏所用的所有资源:

//加载游戏所需的资源

public void onLoadResources() {

Log.i("WIDTHxHEIGHT", CAMERA_WIDTH+"x"+CAMERA_HEIGHT);

if(CAMERA_WIDTH<=480 && CAMERA_HEIGHT<=320)

{

this.mTexture = newTexture(1024,1024,TextureOptions.BILINEAR);

ShotBirdGame.hills = TextureRegionFactory.createFromAsset(this.mTexture, this, "graphics/background480hills.png",0,0);

ShotBirdGame.sky = TextureRegionFactory.createFromAsset(this.mTexture, this, "graphics/background480sky.png",0,306);

ShotBirdGame.grass= TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/background480grass.png",0,642);

ShotBirdGame.barrel= TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/barrel480.png",802,0);

ShotBirdGame.aim= TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/crosshairs480.png",802,352);

ShotBirdGame.birdFly = TextureRegionFactory.createTiledFromAsset(this.mTexture, this,"graphics/birdallframes480.png",0,642+82,4,4);

ShotBirdGame.birdFlyFlipped = birdFly.clone();

ShotBirdGame.birdFlyFlipped.setFlippedHorizontal(true);

ShotBirdGame.shell= TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/shell480.png",322,642+82);

ShotBirdGame.shootbutton= TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/shootbutton480.png",322+50,642+82);

ShotBirdGame.feather = TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/feather.png",0,642+82+256);

ShotBirdGame.featherFlipped = feather.clone();

ShotBirdGame.featherFlipped.setFlippedHorizontal(true);

this.mEngine.getTextureManager().loadTexture(this.mTexture);

//no enough space in mTexture left :)

this.mTexture2 = newTexture(1024,1024,TextureOptions.BILINEAR);

ShotBirdGame.largeCloud = TextureRegionFactory.createFromAsset(this.mTexture2, this, "graphics/largecloud.png",0,0);

ShotBirdGame.mediumCloud = TextureRegionFactory.createFromAsset(this.mTexture2, this, "graphics/mediumcloud.png",242,0);

ShotBirdGame.smallCloud = TextureRegionFactory.createFromAsset(this.mTexture2, this, "graphics/smallcloud.png",242+130,0);

ShotBirdGame.flash= TextureRegionFactory.createFromAsset(this.mTexture2, this, "graphics/muzzleflash480.png",0,66);

ShotBirdGame.shot= TextureRegionFactory.createFromAsset(this.mTexture2, this, "graphics/shot480.png",98,66);

this.mEngine.getTextureManager().loadTexture(this.mTexture2);

this.mTexture3 = newTexture(1024,1024,TextureOptions.BILINEAR);

ShotBirdGame.logo = TextureRegionFactory.createFromAsset(this.mTexture3, this, "graphics/title480.png",0,0);

ShotBirdGame.startButton = TextureRegionFactory.createFromAsset(this.mTexture3, this, "graphics/startbutton.png",0,226);

ShotBirdGame.settingsButton = TextureRegionFactory.createFromAsset(this.mTexture3, this, "graphics/settingsbutton.png",0,226+50);

this.mEngine.getTextureManager().loadTexture(this.mTexture3);

ShotBirdGame.mDuckFontTexture = new Texture(256,256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

FontFactory.setAssetBasePath("font/");

ShotBirdGame.mDuckFont = FontFactory.createFromAsset(ShotBirdGame.mDuckFontTexture, this, "comixheavy.ttf", 28, true, Color.BLACK);

this.mEngine.getTextureManager().loadTexture(ShotBirdGame.mDuckFontTexture);

this.mEngine.getFontManager().loadFont(ShotBirdGame.mDuckFont);

}

else

{

this.mTexture = newTexture(1024,1024,TextureOptions.BILINEAR);

ShotBirdGame.hills = TextureRegionFactory.createFromAsset(this.mTexture, this, "graphics/background800hills.png",0,0);

ShotBirdGame.sky = TextureRegionFactory.createFromAsset(this.mTexture, this, "graphics/background800sky.png",0,306+add);

ShotBirdGame.grass= TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/background800grass.png",0,642+add);

ShotBirdGame.barrel= TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/barrel800.png",802+add,0);

ShotBirdGame.aim= TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/crosshairs800.png",802+add,352);

ShotBirdGame.birdFly = TextureRegionFactory.createTiledFromAsset(this.mTexture, this,"graphics/birdallframes800.png",0,642+82+add*4/5,4,4);

ShotBirdGame.birdFlyFlipped = birdFly.clone();

ShotBirdGame.birdFlyFlipped.setFlippedHorizontal(true);

ShotBirdGame.shell= TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/shell800.png",322,642+82+add);

ShotBirdGame.shootbutton= TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/shootbutton800.png",322+50,642+82+add);

ShotBirdGame.feather = TextureRegionFactory.createFromAsset(this.mTexture, this,"graphics/feather.png",0,642+82+256);

ShotBirdGame.featherFlipped = feather.clone();

ShotBirdGame.featherFlipped.setFlippedHorizontal(true);

this.mEngine.getTextureManager().loadTexture(this.mTexture);

//no enough space in mTexture left :)

this.mTexture2 = newTexture(1024,1024,TextureOptions.BILINEAR);

ShotBirdGame.largeCloud = TextureRegionFactory.createFromAsset(this.mTexture2, this, "graphics/largecloud.png",0,0);

ShotBirdGame.mediumCloud = TextureRegionFactory.createFromAsset(this.mTexture2, this, "graphics/mediumcloud.png",242+add,0);

ShotBirdGame.smallCloud = TextureRegionFactory.createFromAsset(this.mTexture2, this, "graphics/smallcloud.png",242+130+add,0);

ShotBirdGame.flash= TextureRegionFactory.createFromAsset(this.mTexture2, this, "graphics/muzzleflash800.png",0,66);

ShotBirdGame.shot= TextureRegionFactory.createFromAsset(this.mTexture2, this, "graphics/shot800.png",98,66);

this.mEngine.getTextureManager().loadTexture(this.mTexture2);

this.mTexture3 = newTexture(1024,1024,TextureOptions.BILINEAR);

ShotBirdGame.logo = TextureRegionFactory.createFromAsset(this.mTexture3, this, "graphics/title800.png",0,0);

ShotBirdGame.startButton = TextureRegionFactory.createFromAsset(this.mTexture3, this, "graphics/startbutton.png",0,226+add);

ShotBirdGame.settingsButton = TextureRegionFactory.createFromAsset(this.mTexture3, this, "graphics/settingsbutton.png",0,226+50+add);

this.mEngine.getTextureManager().loadTexture(this.mTexture3);

ShotBirdGame.mDuckFontTexture = new Texture(256,256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

FontFactory.setAssetBasePath("font/");

ShotBirdGame.mDuckFont = FontFactory.createFromAsset(ShotBirdGame.mDuckFontTexture, this, "comixheavy.ttf", 48, true, Color.BLACK);

this.mEngine.getTextureManager().loadTexture(ShotBirdGame.mDuckFontTexture);

this.mEngine.getFontManager().loadFont(ShotBirdGame.mDuckFont);

}

SoundFactory.setAssetBasePath("sounds/");

MusicFactory.setAssetBasePath("sounds/");

try {

ShotBirdGame.sShotReload = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "gunshotreload.ogg");

} catch (final IOException e) {

Debug.e("Error", e);

}

}

(4)  Game也是本游戏中很重要的一个类,仅次于ShotBirdGame类,主要是游戏中场景对象的一些控制,游戏画面的更新等。Game类中定义了一些基本的属性,比如每一轮子弹数量的多少(一般为5发),云朵数量的最大值,更新数据的时间,手机返回键的获取,游戏状态的设置(开始,暂停,继续)等。其属性信息如下:

private int GAME_STATE;

public static final int STATE_MENU=0;

public static final int STATE_RUN=1;

public static final int STATE_DIALOGS=2;

private Random random = new Random();

private ArrayList<Bird> birds = new ArrayList<Bird>();

private ArrayList<Bird> birdsToRemove = new ArrayList<Bird>();

private ArrayList<Feather> feathers = new ArrayList<Feather>();

private ArrayList<Feather> feathersBuffer = new ArrayList<Feather>();

private ArrayList<Feather> feathersToRemove = new ArrayList<Feather>();

private ArrayList<Cloud> clouds = new ArrayList<Cloud>();

private int maxClouds = 5;

private Sprite grass, /*background,*/shootbutton,hills,sky;

private Sprite aim;

private float aimXSpeed = 0;

private float aimYSpeed = 0;

private Sprite barrel;

private Sprite flash;

private Sprite shot;

private int shells=5;

private boolean updateShells = false;

private ArrayList<Sprite> shellSprites = new ArrayList<Sprite>();

private boolean roundOver = false;

private final int birdsLeft = 1000;

private int birdsCreated = 0;

private float birdSpeed = 0.6f;

private Text nextLevelMsg;

private Scene gameScene;

射击小鸟的函数主要代码如下:

private void makeShoot() {

if(useSound)ShotBirdGame.sShotReload.play();

flash.setAlpha(1.0f);

shot.setPosition(aim.getX()+aim.getWidth()/2-shot.getWidth()/2, aim.getY()+aim.getHeight()/2-shot.getHeight()/2);

shot.setAlpha(1.0f);

//

for(final Bird bird: birds)

{

if(bird.isFlying() && aim.collidesWith(bird))

{

//如果子弹碰到小鸟,小鸟会死

float birdCenterX =bird.getX()+bird.getWidth()/2;

float birdCenterY =bird.getY()+bird.getHeight()/2;

float shotCenterX =shot.getX()+shot.getWidth()/2;

float shotCenterY =shot.getY()+shot.getHeight()/2;

if(BaseCollisionChecker.checkAxisAlignedRectangleCollision(

birdCenterX-bird.getWidth()*0.6f/2,

birdCenterY-bird.getHeight()*0.6f/2,

birdCenterX+bird.getWidth()*0.6f/2,

birdCenterY+bird.getHeight()*0.6f/2,

shotCenterX-shot.getWidth()*0.9f/2,

shotCenterY-shot.getHeight()*0.9f/2,

shotCenterX+shot.getWidth()*0.9f/2,

shotCenterY+shot.getHeight()*0.9f/2))

{

bird.setFalling(true);

bird.stopAnimation(12);

synchronized (feathersBuffer) {

for(int i=0;i<10;i++)

{

float featherSize = 1+(1+random.nextInt(9))/10;

//first bird

Featherfeather;

if(random.nextBoolean())

{

feather= newFeather(bird.getX()-bird.getWidth()*featherSize/2+random.nextInt((int) (bird.getWidth())),

bird.getY()-bird.getHeight()*featherSize/2+random.nextInt((int) (bird.getHeight()))/*random.nextInt(320-40grass*/,

ShotBirdGame.feather.getWidth()*featherSize,

ShotBirdGame.feather.getHeight()*featherSize,ShotBirdGame.feather);

}

else

{

feather= new Feather(/*-20*/bird.getX()-bird.getWidth()*featherSize/2+random.nextInt((int) (bird.getWidth())),

bird.getY()-bird.getHeight()*featherSize/2+random.nextInt((int) (bird.getHeight()))/*random.nextInt(320-40grass*/,

ShotBirdGame.featherFlipped.getWidth()*featherSize,

ShotBirdGame.featherFlipped.getHeight()*featherSize,ShotBirdGame.featherFlipped);

}

feathersBuffer.add(feather);

gameScene.getLayer(1).addEntity(feather);

}

}

break;

}

else

{

bird.setWasScared(true);

bird.animate(new long[]{100,100,100,100}, 8, 11, 4,new IAnimationListener()

{

public void onAnimationEnd(

AnimatedSpriteanimatedSprite) {

bird.animate(new long[]{100,100,100,100}, 0, 3, true);

}

});

}

}

}

shells--;//子弹数量减一

if(shells<0)

{

shells=0;//如果没有子弹了,子弹数量为0

}

updateShells = true;

if(birds.size()>0 && shells == 0)

{

roundOver = true;

}

}

更新游戏状态信息:

public void update() {

if(!loadComplete)//游戏是否加载完成

{

loadComplete = true;

gameActivity.hideScoreLoop(false,true);

}

{

for (Cloud cloud : clouds) {

cloud.update();

}

}

if(GAME_STATE == STATE_RUN && !paused)

{

updateCrosshair();

updateFeathers();

if(updateShells)

{

updateShellsIndicator();

updateShells = false;

}

if(birds.size() == 0 )

{

if(birdsCreated<birdsLeft)

{

//第一只鸟

Birdbird = new Bird(0, random.nextInt((int) (grass.getY()-grass.getHeight())),

ShotBirdGame.birdFly.getTileWidth(),

ShotBirdGame.birdFly.getTileHeight(),ShotBirdGame.birdFly,useSound);

birds.add(bird);

gameScene.getLayer(1).addEntity( bird);

bird.setXSpeed(birdSpeed);

ShotBirdGame.birdFly.setFlippedHorizontal(false);

bird.animate(new long[]{100,100,100,100}, 0, 3, true);

//第二只鸟飞向另一边

bird= new Bird(ShotBirdGame.CAMERA_WIDTH-ShotBirdGame.birdFlyFlipped.getTileWidth(),  random.nextInt((int) (grass.getY()-grass.getHeight())),

ShotBirdGame.birdFlyFlipped.getTileWidth(),

ShotBirdGame.birdFlyFlipped.getTileHeight(),ShotBirdGame.birdFlyFlipped,useSound);

birds.add(bird);

bird.setXSpeed(-birdSpeed);

gameScene.getLayer(1).addEntity(bird);

ShotBirdGame.birdFlyFlipped.setFlippedHorizontal(true);

bird.animate(new long[]{100,100,100,100}, 0, 3, true);

shells = 5;

updateShells = true;

birdsCreated+=2;

}

}

else

{

for (Bird bird : birds) {

if(roundOver && !bird.isFalling() && !bird.isFallen())

{

bird.setFlyAway(true);

}

bird.update();

if(bird.isFallen())

{

birdsToRemove.add(bird);

}

}

roundOver = false;

for(Bird bird: birdsToRemove)

{

birds.remove(bird);

gameScene.getLayer(1).removeEntity(bird);

}

birdsToRemove.clear();

}

}

else if(GAME_STATE == STATE_MENU)

{

if(birds.size()>0)

{

for(Bird bird:birds)

{

gameScene.getLayer(1).removeEntity(bird);

}

birds.clear();

}

if(feathers.size()>0)

{

for(Feather feather:feathers)

{

gameScene.getLayer(1).removeEntity(feather);

}

feathers.clear();

}

if(feathersBuffer.size()>0)

{

for(Feather feather:feathersBuffer)

{

gameScene.getLayer(1).removeEntity(feather);

}

feathersBuffer.clear();

}

}

}

对获取的加速度计的数值进行处理,从而通过调整手机的姿态信息达到调整猎枪准心角度的目的。监听加速度计数值变化的代码如下:

public void onAccelerometerChanged(AccelerometerDataaccelerometerData) {

if(accelerometer){

aimYSpeed = (accelerometerData.getX()-5)*2;

if(aimYSpeed>0)aimYSpeed*=1.5f;

aimXSpeed = accelerometerData.getY()*3;

}

}

没开枪一下,更新子弹数量的指示器函数的代码如下:

public void updateShellsIndicator()

{

float shellOffset = 0;

while (shells<shellSprites.size()) {

gameScene.getLayer(2).removeEntity(shellSprites.get(0));

shellSprites.remove(0);

}

for(int i=0;i<shells;i++)

{

Spriteshell;

if(i+1>shellSprites.size()){

shell= new Sprite(ShotBirdGame.shell.getWidth()/2 + shellOffset,ShotBirdGame.CAMERA_HEIGHT-ShotBirdGame.shell.getHeight()*1.5f,ShotBirdGame.shell.getWidth(),ShotBirdGame.shell.getHeight(),ShotBirdGame.shell);

gameScene.getLayer(2).addEntity(shell);

shellSprites.add(shell);

}

else

{

shell= shellSprites.get(i);

shell.setPosition(ShotBirdGame.shell.getWidth()/2 + shellOffset, shell.getY());

}

shellOffset+= shell.getWidth();

}

}

更新猎枪的准心状态的显示函数主要如下:

public void updateCrosshair()

{

aim.setPosition(aim.getX() + aimXSpeed, aim.getY()+aimYSpeed);

if(aim.getY()+aim.getHeight()/2>grass.getY())

{

aim.setPosition(aim.getX(),grass.getY()-aim.getHeight()/2);

}

else if(aim.getY()+aim.getHeight()/2<0)

{

aim.setPosition(aim.getX(),0-aim.getHeight()/2);

}

if(aim.getX()+aim.getWidth()/2>ShotBirdGame.CAMERA_WIDTH)

{

aim.setPosition(ShotBirdGame.CAMERA_WIDTH-aim.getWidth()/2,aim.getY());

}

else if(aim.getX()+aim.getWidth()/2<0)

{

aim.setPosition(0-aim.getWidth()/2,aim.getY());

}

//移动枪的位置

float barrelYOffset = aim.getY()*(barrel.getHeight()*0.2f)/grass.getY();

barrel.setPosition(barrel.getX(),

ShotBirdGame.CAMERA_HEIGHT-barrel.getHeight()/2

+barrelYOffset);

//旋转枪

Vector2 src =new Vector2(barrel.getX()+barrel.getWidth()/2,barrel.getY()+barrel.getHeight()/2);

Vector2 dst =new Vector2(aim.getX()+aim.getWidth()/2, aim.getY()+aim.getHeight()/2);

float angle = (float) (Math.atan2(src.y-dst.y,src.x-dst.x)*180/Math.PI-90);

barrel.setRotation(angle);

//枪射击效果

flash.setPosition(barrel.getX()+barrel.getWidth()/2-flash.getWidth()/2, barrel.getY()-flash.getHeight()/2);

flash.setRotationCenter(flash.getWidth()/2, barrel.getHeight()-flash.getHeight());

flash.setRotation(barrel.getRotation());

if(flash.getAlpha()>0)

{

flash.setAlpha(flash.getAlpha()-0.4f);

if(flash.getAlpha()<0)

{

flash.setAlpha(0);

}

}

if(shot.getAlpha()>0)

{

shot.setAlpha(shot.getAlpha()-0.3f);

if(shot.getAlpha()<0)

{

shot.setAlpha(0);

}

}

if(nextLevelMsg.getAlpha()>0)

{

nextLevelMsg.setAlpha(nextLevelMsg.getAlpha()-0.025f);

if(nextLevelMsg.getAlpha()<0)

{

nextLevelMsg.setAlpha(0);

}

}

}a

快乐打小鸟游戏的开发相关推荐

  1. 最新H5开发飞翔的小鸟游戏微信小程序源码

    正文: Java SpringMVC+H5飞翔的小鸟游戏微信小程序源码. 试验性质的一个微信小程序,用canvas做的一个类似flappy-bird的小游戏. 包含一些基本的功能:躲避障碍物.计分.排 ...

  2. c++飞扬的小鸟游戏_通过建立一个飞扬的鸟游戏来学习从头开始

    c++飞扬的小鸟游戏 Learn how to use Scratch 3.0 by building a flappy bird game in this course developed by W ...

  3. 微信小游戏客户端开发环境搭建

    微信小游戏客户端开发环境搭建 开发工具 环境配置 发布小游戏 一直以来,弄App形式的游戏比较多,近年来,微信小游戏火了起来.出于好奇,研究了一番,觉得还是挺有意思的,想和大家分享下. 官方手册网址: ...

  4. 关于小游戏初步开发的一些理解

    在实际的开发中会慢慢地受到大家的一些指导以及问题的提出,希望自己可以在工作学习生活中不断的总结下这些问题.仅以此记录自己的错误,更能让这些错误成为自己以后工作的经验. 游戏的启动所需要的的指令 一个游 ...

  5. 游戏设计/开发的出发点——追根溯源

    最近刚看完皮克斯的<心灵奇旅>,感触颇深,觉得和之前去寺庙禅修时候的感受是吻合的.在影片中一片落叶点燃了灵魂的火花后,我落下了眼泪,我时常在想,这个浮躁的社会中,我们有多久没有面对一朵路边 ...

  6. C语言程序设计 飞行小鸟游戏

    通过C语言程序设计开发的一款飞行小鸟游戏,拥有3种游戏模式:玩家操作模式,自动游戏模式,人工智能模式 代码如下: #include <stdio.h> #include <stdli ...

  7. 《Unity 游戏案例开发大全》一6.5 游戏主场景

    本节书摘来异步社区<Unity 游戏案例开发大全>一书中的第6章,第6.1节,作者: 吴亚峰 , 杜化美 , 于复兴 责编: 张涛,更多章节内容可以访问云栖社区"异步社区&quo ...

  8. 软件技术基础_软件技术(游戏软件开发)专业介绍

    软件技术(游戏软件开发)专业 核心课程 C++程序设计.Java程序设计.C#程序设计.Cocos2d-x游戏开发.Unity3D游戏开发.Android游戏开发.IOS游戏开发.游戏框架设计.游戏服 ...

  9. 1个人70万行代码,20年持续更新,这款游戏号称开发到死,永不停更

    梦晨 博雯 发自 凹非寺 量子位 报道 | 公众号 QbitAI 这是一款「开发到死」,「永不停更」的游戏. 兄弟两人,一人开发,一人剧情,共同维持了这款游戏近20年. 现在的玩家刚刚打开它,往往会发 ...

最新文章

  1. libsigc++库的使用
  2. 洛谷1522牛的旅行
  3. bss,data,text,rodata,堆,栈,常量段
  4. 虚拟机windows xp 下安装配置mysql cluster 7.3.2
  5. dom复制cloneNode节点与插入节点appendChild()
  6. android 活动说明,Android – 如何发送GCM推送通知以及要加载哪些活动的说明?
  7. ZooKeeper 之快速入门
  8. cobbler一键部署centos7.4(脚本)
  9. Java集合篇:集合类介绍
  10. 从零开始学习Sencha Touch MVC应用之十九
  11. zabbix agent报错 :cannot connect to [[127.0.0.1]:10051]: [111] Connection refused
  12. 大数据奏鸣曲,听出了什么?
  13. 密码学的安全性浅析2
  14. 汽车之家汽车详细参数之css反爬
  15. python格式化输出函数之format
  16. python获取用户输入中文,用python实现功能:用户输入英文或中文,程序即可打印出来对应的译文。...
  17. tableViewCell、collectionViewCell、组头组尾等总结
  18. 学习学习学习学习学习学习学习学习学习学习学习
  19. 给定一个函数做其最佳平方逼近c语言,第三章 函数逼近 — 最佳平方逼近.
  20. 电脑上网速度慢?这样设置后网速飞起来!

热门文章

  1. Cyanine5.5 phosphoramidite,5‘-terminal可用于在寡核苷酸合成器中直接标记
  2. esp8266 微信 提醒 server酱 使用心得
  3. nodejs和前端一些常用框架 教程整理
  4. eclipse如何汉化,把eclipse改成中文版
  5. 数据结构与算法python语言实现答案_数据结构与算法:Python语言实现 源代码 PPT 练习答案 源码.zip...
  6. unigui怎么隐藏滚动条
  7. 电子信息工程本科基础课程
  8. linux 面试答题
  9. 学好vue靠他就行了——vue脚手架,自定义事件,插槽等复杂内容
  10. typedef与typedef struct