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的从零开始的学习.仍 ...
随机推荐
- web测试实践
参会人员:赵天宇,周静,张双双,张玉 参会地点:微信群 参会内容:决定评测软件 最后会议结论:决定了选择用中国大学mooc(https://www.icourse163.org/)和结合竞品对象-清华 ...
- mysql Alter table设置default的问题,是bug么?
不用不知道,用了没用? 昨天在线上创建了一个表,其中有两个列是timestamp类型的,创建语句假设是这样的: create table timetest(id int, createtime tim ...
- Sqlserver的Transaction做Rollback的时候要小心(转载)
仔细研究了下,发现sql server里面的explicit transaction(显示事务)还是有点复杂的.以下是有些总结: Commit transaction 会提交所有嵌套的transact ...
- excel表格中添加单引号的方法
今天碰到需要插入大量数据的excel表格,其中有很多文本,需要添加单引号. 方法如下: 左边是原始数据,右边是我即将添加单引号的空白区域. 第一步:在需要添加的位置输入= 第二步:输入等号之后点击需要 ...
- Win7下设置护眼的电脑豆沙绿界面
控制面板\所有控制面板项\个性化\窗口颜色和外观 "色调"(Hue)设为85,"饱和度"(Sat)设为90,"亮度" (Lum)设为205. ...
- 巧用foxmail同步qq邮箱的通讯录
如果您企业使用的qq企业邮箱,那么你在web端登陆邮箱并填写收件人时,发现QQ邮箱是可以自动完成,并且中文名称自动完成. 如何在使用foxmail邮件客户端的情况下也同步这些邮箱信息呢?需要七步,看截 ...
- SDN2017 期末作业验收
GIT仓库:GITHUB 负载均衡程序 拓扑如图 目的 实现一个负载均衡的北向程序: 服务器host 2 ,host 3,host 4上各自有不同的服务,host 1是客户端 当host 2,host ...
- 【Alpha】团队课程展示
团队展示报告 团队分工 陈涵 PM + 后端开发 ,统筹全队安排,完成了登录界面,以及一部分部门模块和课程中教室模块的编写. 张鹏 后端开发,主要完成了主界面和其他功能界面的编写,课程界面的编写,以及 ...
- 028、HTML 标签2超链接,框架标签
内容:超链接,框架标签############################################################## <!-- 超链接 --> <a h ...
- MySQL Error Code文档手册---摘自MySQL官方网站
This chapter lists the errors that may appear when you call MySQL from any host language. The first ...