快乐打小鸟游戏的开发
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
快乐打小鸟游戏的开发相关推荐
- 最新H5开发飞翔的小鸟游戏微信小程序源码
正文: Java SpringMVC+H5飞翔的小鸟游戏微信小程序源码. 试验性质的一个微信小程序,用canvas做的一个类似flappy-bird的小游戏. 包含一些基本的功能:躲避障碍物.计分.排 ...
- c++飞扬的小鸟游戏_通过建立一个飞扬的鸟游戏来学习从头开始
c++飞扬的小鸟游戏 Learn how to use Scratch 3.0 by building a flappy bird game in this course developed by W ...
- 微信小游戏客户端开发环境搭建
微信小游戏客户端开发环境搭建 开发工具 环境配置 发布小游戏 一直以来,弄App形式的游戏比较多,近年来,微信小游戏火了起来.出于好奇,研究了一番,觉得还是挺有意思的,想和大家分享下. 官方手册网址: ...
- 关于小游戏初步开发的一些理解
在实际的开发中会慢慢地受到大家的一些指导以及问题的提出,希望自己可以在工作学习生活中不断的总结下这些问题.仅以此记录自己的错误,更能让这些错误成为自己以后工作的经验. 游戏的启动所需要的的指令 一个游 ...
- 游戏设计/开发的出发点——追根溯源
最近刚看完皮克斯的<心灵奇旅>,感触颇深,觉得和之前去寺庙禅修时候的感受是吻合的.在影片中一片落叶点燃了灵魂的火花后,我落下了眼泪,我时常在想,这个浮躁的社会中,我们有多久没有面对一朵路边 ...
- C语言程序设计 飞行小鸟游戏
通过C语言程序设计开发的一款飞行小鸟游戏,拥有3种游戏模式:玩家操作模式,自动游戏模式,人工智能模式 代码如下: #include <stdio.h> #include <stdli ...
- 《Unity 游戏案例开发大全》一6.5 游戏主场景
本节书摘来异步社区<Unity 游戏案例开发大全>一书中的第6章,第6.1节,作者: 吴亚峰 , 杜化美 , 于复兴 责编: 张涛,更多章节内容可以访问云栖社区"异步社区&quo ...
- 软件技术基础_软件技术(游戏软件开发)专业介绍
软件技术(游戏软件开发)专业 核心课程 C++程序设计.Java程序设计.C#程序设计.Cocos2d-x游戏开发.Unity3D游戏开发.Android游戏开发.IOS游戏开发.游戏框架设计.游戏服 ...
- 1个人70万行代码,20年持续更新,这款游戏号称开发到死,永不停更
梦晨 博雯 发自 凹非寺 量子位 报道 | 公众号 QbitAI 这是一款「开发到死」,「永不停更」的游戏. 兄弟两人,一人开发,一人剧情,共同维持了这款游戏近20年. 现在的玩家刚刚打开它,往往会发 ...
最新文章
- libsigc++库的使用
- 洛谷1522牛的旅行
- bss,data,text,rodata,堆,栈,常量段
- 虚拟机windows xp 下安装配置mysql cluster 7.3.2
- dom复制cloneNode节点与插入节点appendChild()
- android 活动说明,Android – 如何发送GCM推送通知以及要加载哪些活动的说明?
- ZooKeeper 之快速入门
- cobbler一键部署centos7.4(脚本)
- Java集合篇:集合类介绍
- 从零开始学习Sencha Touch MVC应用之十九
- zabbix agent报错 :cannot connect to [[127.0.0.1]:10051]: [111] Connection refused
- 大数据奏鸣曲,听出了什么?
- 密码学的安全性浅析2
- 汽车之家汽车详细参数之css反爬
- python格式化输出函数之format
- python获取用户输入中文,用python实现功能:用户输入英文或中文,程序即可打印出来对应的译文。...
- tableViewCell、collectionViewCell、组头组尾等总结
- 学习学习学习学习学习学习学习学习学习学习学习
- 给定一个函数做其最佳平方逼近c语言,第三章 函数逼近 — 最佳平方逼近.
- 电脑上网速度慢?这样设置后网速飞起来!
热门文章
- Cyanine5.5 phosphoramidite,5‘-terminal可用于在寡核苷酸合成器中直接标记
- esp8266 微信 提醒 server酱 使用心得
- nodejs和前端一些常用框架 教程整理
- eclipse如何汉化,把eclipse改成中文版
- 数据结构与算法python语言实现答案_数据结构与算法:Python语言实现 源代码 PPT 练习答案 源码.zip...
- unigui怎么隐藏滚动条
- 电子信息工程本科基础课程
- linux 面试答题
- 学好vue靠他就行了——vue脚手架,自定义事件,插槽等复杂内容
- typedef与typedef struct