libgdx自制简易Flappy Bird
Flappy Bird,好吧,无需多说。今天年初不知咋的,一下子就火了,而且直接跃居榜首,在ios和android平台都是如此,实在难以理解。传说其作者每天收入能达到5w刀,着实碉堡了。。。
好吧,咱没创意,不过山寨一个还是可以的,话说!!!
好了,不罗嗦了,直接代码了。
我使用libgdx框架(你要说是引擎也行)实现的,版本为0.9.9。就设计了一个开始画面和一个游戏画面。
游戏入口和主类:
package com.fxb.flappy; import com.badlogic.gdx.Game; public class FlappyBird extends Game{ //static Skin skin;
StartScreen startScreen;
GameScreen gameScreen;
LevelScreen levelScreen; @Override
public void create() {
// TODO Auto-generated method stub Assets.init(); startScreen = new StartScreen(this);
gameScreen = new GameScreen(this);
levelScreen = new LevelScreen(this); setScreen( startScreen );
} @Override
public void render() {
// TODO Auto-generated method stub
super.render();
} @Override
public void dispose() {
// TODO Auto-generated method stub
//skin.dispose();
Assets.clean();
super.dispose();
} }
开始画面:
package com.fxb.flappy; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.ScreenAdapter;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton; public class StartScreen extends ScreenAdapter{ FlappyBird game;
Stage stage;
TextButton btnStart, btnMode; public StartScreen(FlappyBird game0){
game = game0;
stage = new Stage(); btnStart = new TextButton( "Start Game", Assets.skin, "default" );
btnStart.setSize( 150, 70 );
Constant.CenterInStage( btnStart, stage );
stage.addActor( btnStart ); btnStart.addListener(new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
// TODO Auto-generated method stub
return true;
}
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
// TODO Auto-generated method stub
game.setScreen( game.gameScreen );
Constant.state = Constant.GameState.game_on;
}
}); } @Override
public void show() {
// TODO Auto-generated method stub
Gdx.input.setInputProcessor( stage );
} @Override
public void render(float delta) {
// TODO Auto-generated method stub
Gdx.gl.glClearColor( 0, 1, 1, 1 );
Gdx.gl.glClear( GL10.GL_COLOR_BUFFER_BIT ); stage.act();
stage.draw();
} @Override
public void dispose() {
// TODO Auto-generated method stub
stage.dispose();
super.dispose();
} }
游戏场景:
package com.fxb.flappy; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.ScreenAdapter;
import com.badlogic.gdx.graphics.GL10; public class GameScreen extends ScreenAdapter{ FlappyBird game;
GameStage gameStage;
OverStage overStage; public GameScreen(FlappyBird game0){
game = game0;
gameStage = new GameStage(this);
overStage = new OverStage(this);
} @Override
public void show() {
// TODO Auto-generated method stub
Gdx.input.setInputProcessor( gameStage );
} @Override
public void render(float delta) {
// TODO Auto-generated method stub
Gdx.gl.glClearColor( 0, 1, 1, 1 );
Gdx.gl.glClear( GL10.GL_COLOR_BUFFER_BIT ); if( Constant.state == Constant.GameState.game_on ){
gameStage.act();
gameStage.draw();
Gdx.input.setInputProcessor( gameStage );
}
else if( Constant.state == Constant.GameState.game_preover ){
gameStage.draw();
overStage.act();
overStage.draw();
Gdx.input.setInputProcessor( overStage );
} } @Override
public void dispose() {
// TODO Auto-generated method stub
super.dispose();
} }
游戏舞台:
package com.fxb.flappy; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.utils.Pools; public class GameStage extends Stage{ GameScreen gameScreen;
Group groupUp, groupDown;
Pool<PipeUp> poolUp;
Pool<PipeDown> poolDown;
Bird bird;
Image imgBack;
OrthographicCamera camera; int xIndex;
float leftX = 0;
float speed;
float currentTime;
float lastTouchTime; public GameStage( GameScreen gameScreen0 ){
gameScreen = gameScreen0; groupUp = new Group();
groupDown = new Group(); poolUp = Pools.get( PipeUp.class );
poolDown = Pools.get( PipeDown.class ); bird = new Bird();
imgBack = Constant.CreateImage( Assets.regionBack );
camera = new OrthographicCamera( Assets.regionBack.getRegionWidth(), Assets.regionBack.getRegionHeight() );
camera.position.set( Assets.regionBack.getRegionWidth()/2, Assets.regionBack.getRegionHeight()/2, 0 ); //addActor( imgBack );
addActor( bird );
addActor( groupUp );
addActor( groupDown ); this.addListener(new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
// TODO Auto-generated method stub
if( currentTime - lastTouchTime > 0.15f ){
if( bird.speedY < 0 ){
bird.speedY += 15;
}
else if( bird.speedY < 5 ){
bird.speedY += 15;
}
else if( bird.speedY < 8 ){
bird.speedY += 8;
}
else{
bird.speedY += 4;
} if( bird.speedY > 25 ){
bird.speedY = 25;
}
lastTouchTime = currentTime;
}
return true;
}
}); Clear();
} public void Clear(){
xIndex = 3;
//this.camera.translate( -leftX, 0 );
//this.camera.position.set( getWidth()/2, getHeight()/2, 0 );
this.getCamera().translate( -leftX, 0, 0 );
leftX = 0; speed = 2f;
currentTime = 0;
lastTouchTime = -1f; bird.Clear(); groupUp.clear();
groupDown.clear();
poolUp.clear();
poolDown.clear(); for( int i=0; i<xIndex; ++i ){
AddPipe(i);
} Gdx.input.setInputProcessor(this);
} public void AddPipe( int xIndex0 ){
PipeUp pipeup = poolUp.obtain();
PipeDown pipedown = poolDown.obtain(); groupUp.addActor( pipeup );
groupDown.addActor( pipedown ); float rate1 = MathUtils.random( 0.2f, 1.3f );
float rate2 = 1.5f - rate1; //rate1 = 0.8f;
//rate2 = 0.2f; int height1 = (int)( Assets.regionPipeUp.getRegionHeight()*rate1 );
int height2 = (int)( Assets.regionPipeDown.getRegionHeight()*rate2 ); if( rate1 < 1 ){
pipeup.region = new TextureRegion( Assets.regionPipeUp, 0, Assets.regionPipeUp.getRegionHeight()-height1, Assets.regionPipeUp.getRegionWidth(), height1 );
pipeup.setHeight( height1 );
}
else{
pipeup.region = Assets.regionPipeUp;
pipeup.setHeight( height1 );
} if( rate2 < 1 ){
pipedown.region = new TextureRegion( Assets.regionPipeDown, 0, 0, Assets.regionPipeDown.getRegionWidth(), height2 );
pipedown.setHeight( height2 );
}
else{
pipedown.region = Assets.regionPipeDown;
pipedown.setHeight( height2 );
} //pipedown
pipeup.setPosition( getWidth()+xIndex0*300, getHeight()-pipeup.getHeight() );
pipedown.setPosition( getWidth()+xIndex0*300, 0 );
} @Override
public void act() {
// TODO Auto-generated method stub leftX += speed;
this.getCamera().translate( speed, 0, 0 );
bird.translate( speed, bird.speedY ); currentTime += Gdx.graphics.getDeltaTime(); boolean isDis = false;
for( int i=0; i<groupUp.getChildren().size; ++i ){
PipeUp pipeup = (PipeUp)groupUp.getChildren().items[i];
if( pipeup.getRight() < leftX ){
groupUp.removeActor( pipeup );
poolUp.free( pipeup );
if( !isDis ){
isDis = true;
}
} if( Constant.IsCollsion( pipeup, bird ) ){
//Gdx.app.exit();
Constant.state = Constant.GameState.game_preover;
}
} for( int i=0; i<groupDown.getChildren().size; ++i ){
PipeDown pipedown = (PipeDown)groupDown.getChildren().items[i];
if( pipedown.getRight() < leftX ){
groupDown.removeActor( pipedown );
poolDown.free( pipedown );
if( !isDis ){
isDis = true;
}
} if( Constant.IsCollsion( pipedown, bird ) ){
//Gdx.app.exit();
Constant.state = Constant.GameState.game_preover;
}
} if( isDis ){
AddPipe( xIndex );
xIndex++;
} if( bird.getY() < 0 ){
Constant.state = Constant.GameState.game_preover;
} super.act();
} @Override
public void draw() {
// TODO Auto-generated method stub
camera.update(); SpriteBatch batch = this.getSpriteBatch();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw( Assets.regionBack, 0, 0 );
batch.end(); super.draw();
} @Override
public void dispose() {
// TODO Auto-generated method stub
super.dispose();
} }
游戏结束舞台:
package com.fxb.flappy; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.Window; public class OverStage extends Stage{ Window window;
TextButton button1;
TextButton button2;
Label label;
GameScreen gameScreen; public OverStage(GameScreen gameScreen0){
gameScreen = gameScreen0; window = new Window( "", Assets.skin );
//window.add( "GAME OVER\n" ); label = new Label( "GAME OVER", Assets.skin );
//label.setFontScale( 1.0f ); button1 = new TextButton( "Again", Assets.skin );
button2 = new TextButton( "Exit", Assets.skin ); button1.addListener( new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
// TODO Auto-generated method stub
return true;
} @Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
// TODO Auto-generated method stub
Constant.state = Constant.GameState.game_on;
gameScreen.gameStage.Clear();
}
}); button2.addListener( new InputListener(){
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
// TODO Auto-generated method stub
return true;
} @Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
// TODO Auto-generated method stub
//Constant.state = Constant.GameState.game_on;
Gdx.app.exit();
}
}); window.setSize( getWidth()/2, getHeight()/6 );
window.addActor( button1 );
window.addActor( button2 );
window.addActor( label ); button1.setSize( 60, 30 );
button2.setSize( 60, 30 );
label.setSize( 100, 50 );
button1.setPosition( window.getWidth()/8, 10 );
button2.setPosition( window.getWidth()*7/8-button2.getWidth(), 10 );
label.setPosition( window.getWidth()/2-label.getWidth()/2, button2.getTop()+20 ); this.addActor( window );
Constant.CenterInStage( window, this );
} }
游戏主角类,即那只鸟
package com.fxb.flappy; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor; public class Bird extends Actor{ Animation animation;
float currentTime;
float speedY; public Bird(){
animation = new Animation( 0.15f, Assets.sRegionBird );
setSize( Assets.sRegionBird[0].getRegionWidth(), Assets.sRegionBird[0].getRegionHeight() );
setOrigin( getWidth()/2, getHeight()/2 );
//setPosition( );
Clear();
} public void Clear(){
currentTime = 0;
setPosition( 100, Gdx.graphics.getHeight()/2-getHeight()/2 );
speedY = Constant.speedY;
} @Override
public void act(float delta) {
// TODO Auto-generated method stub
currentTime += delta; //this.translate( 0, speedY );
//speedY -= 0.5f; if( speedY > -10f ){
speedY += Constant.speedInc;
} super.act(delta);
} @Override
public void draw(SpriteBatch batch, float parentAlpha) {
// TODO Auto-generated method stub TextureRegion keyFrame = animation.getKeyFrame( currentTime, true ); batch.draw( keyFrame, getX(), getY(), getOriginX(), getOriginY(), getWidth(), getHeight(), getScaleX(), getScaleY(), getRotation() ); super.draw(batch, parentAlpha);
} }
上面管道类
package com.fxb.flappy; import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor; public class PipeUp extends Actor{ TextureRegion region; public PipeUp(){
region = new TextureRegion( Assets.regionPipeUp );
setSize( region.getRegionWidth(), region.getRegionHeight() );
} /*
public UpdateRegion(){
region = new TextureRegion( Assets.regionPipeUp );
}
*/
@Override
public void act(float delta) {
// TODO Auto-generated method stub
super.act(delta);
} @Override
public void draw(SpriteBatch batch, float parentAlpha) {
// TODO Auto-generated method stub //batch.draw( region, region.getRegionX(), region.getRegionY(), region.getRegionWidth(), region.getRegionHeight() );
batch.draw( region, getX(), getY(), getWidth(), getHeight() ); super.draw(batch, parentAlpha);
}
}
下面管道类:
package com.fxb.flappy; import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor; public class PipeDown extends Actor{ TextureRegion region; public PipeDown(){
region = new TextureRegion( Assets.regionPipeDown );
setSize( region.getRegionWidth(), region.getRegionHeight() );
} @Override
public void act(float delta) {
// TODO Auto-generated method stub
super.act(delta);
} @Override
public void draw(SpriteBatch batch, float parentAlpha) {
// TODO Auto-generated method stub
//batch.draw( region, region.getRegionX(), region.getRegionY(), region.getRegionWidth(), region.getRegionHeight() );
batch.draw( region, getX(), getY(), getWidth(), getHeight() );
super.draw(batch, parentAlpha);
}
}
资源类:
package com.fxb.flappy; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.ui.Skin; public class Assets {
public static Skin skin;
public static AssetManager manager;
public static TextureAtlas atlas;
public static TextureRegion[] sRegionBird; public static TextureRegion regionPipeUp;
public static TextureRegion regionPipeDown;
public static TextureRegion regionBack; public static void init(){
skin = new Skin( Gdx.files.internal( "skin/uiskin.json" ) );
atlas = new TextureAtlas( Gdx.files.internal( "data/bird.pack" ) ); sRegionBird = new TextureRegion[3];
for( int i=0; i<sRegionBird.length; ++i ){
sRegionBird[i] = atlas.findRegion( "bird_blue", i );
} regionPipeUp = atlas.findRegion( "bound_up" );
regionPipeDown = atlas.findRegion( "bound_down" );
regionBack = atlas.findRegion( "background" ); } public static void clean(){
if( skin != null ) skin.dispose();
if( atlas != null ) atlas.dispose(); }
}
常量及功能函数类:
package com.fxb.flappy; import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image; public class Constant { enum GameState{ game_ready, game_on, game_preover, game_over };
public static GameState state = GameState.game_ready; public static float speedY = -1f;
public static float speedInc = -0.5f; public static void CenterInStage( Actor actor, Stage stage ){
actor.setPosition( stage.getWidth()/2-actor.getWidth()/2, stage.getHeight()/2-actor.getHeight()/2 );
} public static Image CreateImage( TextureRegion region0 ){
Image img = new Image( region0 );
img.setSize( region0.getRegionWidth(), region0.getRegionHeight() );
return img;
} public static boolean IsCollsion( Actor actor1, Actor actor2 ){
float x1 = actor1.getX(), y1 = actor1.getY(), w1 = actor1.getWidth(), h1 = actor1.getHeight();
float x2 = actor2.getX(), y2 = actor2.getY(), w2 = actor2.getWidth(), h2 = actor2.getHeight();
if( x1<x2 && x1+w1<x2 ){
return false;
}
else if( x2<x1 && x2+w2<x1 ){
return false;
}
else if( y1<y2 && y1+h1<y2 ){
return false;
}
else if( y2<y1 && y2+h2<y1 ){
return false;
} return true;
} }
大概就这样了,也是比较粗糙。自己试验了下,在android平台下感觉操作不太顺手,可能里面一些参数还是没有调整好,提升的空间挺大的!!
libgdx自制简易Flappy Bird的更多相关文章
- libgdx自制简易版Don't Touch The White Tile
Don't Toutch The White说来也奇快,本来没什么难的,但是在欧美ios榜上却雄踞榜首好长时间.即使是在国内,也很火,还真是想不通,谁能解释下,难道真是所谓的抓住了用户的G点,或是这些 ...
- 65行 JavaScript 代码实现 Flappy Bird 游戏
飞扬的小鸟(Flappy Bird)无疑是2014年全世界最受关注的一款游戏.这款游戏是一位来自越南河内的独立游戏开发者阮哈东开发,形式简易但难度极高的休闲游戏,很容易让人上瘾. 这里给大家分享一篇这 ...
- [MFC] 高仿Flappy bird 桌面版
这是今年年初做的东西,一直没有时间整理,现在拿出来分享下~ 目录 开发背景 开发语言及运行环境 效果展示 游戏框架说明 游戏状态及逻辑说明 经典算法说明 重量级问题解决 开发感想 一.开发背景: fl ...
- 技术宅之flappy bird 二逼鸟
师雪坤和刘阳 风靡一时的虐心小游戏<Flappy Bird>,以玩法简单.难度超高著称,不过,最近这款让全世界玩家几欲怒摔手机的游戏,被两位中国技术宅设计的"玩鸟机器人" ...
- 教你从头到尾利用DQN自动玩flappy bird(全程命令提示,GPU+CPU版)【转】
转自:http://blog.csdn.net/v_JULY_v/article/details/52810219?locationNum=3&fps=1 目录(?)[-] 教你从头到尾利用D ...
- canvas 制作flappy bird(像素小鸟)全流程
flappy bird制作全流程: 一.前言 像素小鸟这个简单的游戏于2014年在网络上爆红,游戏上线一段时间内appleStore上的下载量一度达到5000万次,风靡一时, 近年来移动web的普及为 ...
- 自己动手写游戏:Flappy Bird
START:最近闲来无事,看了看一下<C#开发Flappy Bird游戏>的教程,自己也试着做了一下,实现了一个超级简单版(十分简陋)的Flappy Bird,使用的语言是C#,技术采用了 ...
- C语言版flappy bird黑白框游戏
在此记录下本人在大一暑假,2014.6~8这段时间复习C语言,随手编的一个模仿之前很火热的小游戏----flappy bird.代码bug基本被我找光了,如果有哪位兄弟找到其他的就帮我留言下吧,谢谢了 ...
- 闲扯游戏编程之html5篇--山寨版《flappy bird》源码
新年新气象,最近事情不多,继续闲暇学习记点随笔,欢迎拍砖.之前的〈简单游戏学编程语言python篇〉写的比较幼稚和粗糙,且告一段落.开启新的一篇关于javascript+html5的从零开始的学习.仍 ...
随机推荐
- HTIML5 真的打败了Flash?新测试结果出人意料
[编者按]本文最早发布于 2010 年,通过 Flash 与 HTML5 在 Mac 及 Windows 平台不同浏览器中的测试表现,比较两者的性能并分析背后的原因.虽然是一篇老文,但其客观冷静的分析 ...
- 基于MSMQ绑定的WCF服务实现总结
一. 创建消息队列 1 1) 创建一个非事物性的私有队列 1 2)设置消息队列访问权限 2 二.创建WCF服务并绑定消息队列 4 1)创建HelloService服务 4 ...
- 更改 Windows VM 的可用性集
以下步骤说明如何使用 Azure PowerShell 来更改 VM 的可用性集. 只能在创建 VM 时将 VM 添加到可用性集. 如果要更改可用性集,必须将虚拟机删除,并重新创建虚拟机. 使用 Po ...
- Solving the SQL Server Multiple Cascade Path Issue with a Trigger (转载)
Problem I am trying to use the ON DELETE CASCADE option when creating a foreign key on my database, ...
- 转:C#常用的集合类型(ArrayList类、Stack类、Queue类、Hashtable类、Sort)
C#常用的集合类型(ArrayList类.Stack类.Queue类.Hashtable类.Sort) .ArrayList类 ArrayList类主要用于对一个数组中的元素进行各种处理.在Array ...
- Windows 常识大全【all】
解决电脑卡顿问题 电脑常见技巧大全 电脑运行命令CMD集锦 开启Windows 7系统的“上帝模式” Win7下设置护眼的电脑豆沙绿界面 零基础如何组装电脑?装机之家手把手教您电脑组装教程图解 [Ex ...
- Mysql查询缓存Query_cache的功用
MySQL的查询缓存并非缓存执行计划,而是查询及其结果集,这就意味着只有相同的查询操作才能命中缓存,因此MySQL的查询缓存命中率很低,另一方面,对于大结果集的查询,其查询结果可以从cache中直接读 ...
- PTA-B 1039 到底买不买 解题思路记录
#include <cstdio> #include <string> #include <iostream> using namespace std; int m ...
- 展示博客(Alpha版本)
小队名称:PHILOSOPHER 小组成员 [组长]金盛昌(201421122043).刘文钊(20142112255).陈笑林(201421122042) 张俊逸(201421122044).陈志建 ...
- libcurl.dll 7.60.0静态库包含openssl/zlib
最近做个QT的小程序需要使用LIBCURL支持HTTPS,结果查资料发现官方默认的是不支持的,需要手动重新编译,编译的时候加入SSL支持. 看着就好麻烦的样子, 找了一圈,还真有现成的,但是现在写程序 ...