效果图:
1、MainActivity
package com.example.groupactiontest;
import android.os.Bundle;
import com.badlogic.gdx.backends.android.AndroidApplication;
public class MainActivity extends AndroidApplication {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initialize(new Drop(), false);//如果第二个参数为true的话,当GL20可用的时候会使用GL20
}
}
2、Drop
package com.example.groupactiontest;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class Drop extends Game{
public SpriteBatch batch;
public BitmapFont font;
@Override
public void create() {
batch = new SpriteBatch();
//Use LibGDX's default Arial font.
font = new BitmapFont();
this.setScreen(new MainMenuScreen(this));
}
@Override
public void dispose() {//程序退出以后记得要销毁资源
batch.dispose();
font.dispose();
}
@Override
public void pause() {
// TODO Auto-generated method stub
}
@Override
public void render() {
super.render();//这个一定要有,否则MainMenuScreen可能出不来
}
@Override
public void resize(int arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void resume() {
// TODO Auto-generated method stub
}
}
3、MainMenuScreen
package com.example.groupactiontest;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
public class MainMenuScreen implements Screen {
final Drop game;
OrthographicCamera camera;
public MainMenuScreen(final Drop gam) {//资源、变量的初始化要尽量的放在构造函数中
this.game = gam;
camera = new OrthographicCamera();
camera.setToOrtho(false, 480, 800);
}
@Override
public void dispose() {
// TODO Auto-generated method stub
}
@Override
public void hide() {
// TODO Auto-generated method stub
}
@Override
public void pause() {
// TODO Auto-generated method stub
}
@Override
public void render(float arg0) {
Gdx.gl.glClearColor(0,0,0.2f,1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);//获取game里面自带的batch
game.batch.begin();
game.font.draw(game.batch, "Welcome to Drop!!", 100, 150);//使用game里面自带的font进行绘画
game.font.draw(game.batch, "Tap anywhere to begin!", 100, 100);
game.batch.end();
if(Gdx.input.isTouched()){
game.setScreen(new GameScreen(game));
dispose();//切换界面的时候销毁当前界面
}
}
@Override
public void resize(int arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void resume() {
// TODO Auto-generated method stub
}
@Override
public void show() {
// TODO Auto-generated method stub
}
}
4、GameScreen
package com.example.groupactiontest;
import java.util.Iterator;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;
public class GameScreen implements Screen {
final Drop game;
Texture dropImage;//雨滴的图片
Texture bucketImage;//水桶的图片
Sound dropSound; //碰撞时候的音乐
Music rainMusic;//游戏的背景音乐
OrthographicCamera camera;
Rectangle bucket;//水桶
Array<Rectangle> raindrops;//雨滴的集合
long lastDropTime;//用来存储时间
int dropGathered;//雨滴的收集到的数量
public GameScreen(final Drop gam) {
this.game = gam;
dropImage = new Texture(Gdx.files.internal("droplet.png"));
bucketImage = new Texture(Gdx.files.internal("bucket.png"));
dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));
rainMusic.setLooping(true);
camera = new OrthographicCamera();
camera.setToOrtho(false, 480, 800);
//在这里水桶的初始位置给定了
bucket = new Rectangle();//设置水桶的初始位置
bucket.x = 800/2 - 64/2;
bucket.y = 20;
bucket.width = 64;//设置矩形区域的大小(就是水滴遇到这个区域就算被收集到了)
bucket.height = 64;//这个区域不一定能被看到(并不是图片的大小)
raindrops = new Array<Rectangle>();
spawnRaindrop();//spawn: 大量产生水滴
}
/**
* 产生水滴(产生一个水滴),将其添加到水滴集合中....
* 水滴集合里面的水底的数量其实一般只是维持在2~4之间而已
*/
private void spawnRaindrop() {
Rectangle raindrop = new Rectangle();
raindrop.x = MathUtils.random(0, 800 - 64);//设置水地产生的位置
raindrop.y = 480;
raindrop.width = 64;//设置水底的碰撞矩形
raindrop.height = 64;
raindrops.add(raindrop);
lastDropTime = TimeUtils.nanoTime();
}
@Override
public void dispose() {//用于销毁资源
dropImage.dispose();
bucketImage.dispose();
dropSound.dispose();
rainMusic.dispose();
}
@Override
public void hide() {
// TODO Auto-generated method stub
}
@Override
public void pause() {
// TODO Auto-generated method stub
}
@Override
public void render(float arg0) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
System.out.println("---------->raindrops.size: " + raindrops.size);
camera.update();//告诉摄像机去更新它的矩阵
game.batch.setProjectionMatrix(camera.combined);//告诉batch按照camera的坐标系统来进行渲染
game.batch.begin();
game.font.draw(game.batch, "Drops Collected: " + dropGathered, 0, 480);//绘画收集到的水滴数
game.batch.draw(bucketImage, bucket.x, bucket.y);//绘画水桶的位置...这一点时要特别注意的
for(Rectangle raindrop : raindrops){//把水滴集合里面的水滴都会画出来
game.batch.draw(dropImage, raindrop.x, raindrop.y);
}
game.batch.end();
if(Gdx.input.isTouched()){//如果移动了,则更新水桶位置
Vector3 touchPos = new Vector3();
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);//将窗口的坐标系转换成世界坐标系
bucket.x = touchPos.x - 64/2;//设置水桶的位置
}
if(Gdx.input.isKeyPressed(Keys.LEFT)){//向左移动水桶
bucket.x -= 200 * Gdx.graphics.getDeltaTime();
}
if(Gdx.input.isKeyPressed(Keys.RIGHT)){//向右移动水桶
bucket.x += 200 * Gdx.graphics.getDeltaTime();
}
/**
* 设置水桶活动范围的左边界
*/
if(bucket.x < 0){
bucket.x = 0;
}
/**
* 设置水桶活动范围的右边界
*/
if(bucket.x > 800 - 64){
bucket.x = 800 - 64;
}
/**
* 如果产生水底的时间超过了一定的时间,则产生新的水滴
*/
if(TimeUtils.nanoTime() - lastDropTime > 1000000000){
spawnRaindrop();
}
Iterator<Rectangle> iter = raindrops.iterator();
while(iter.hasNext()){
Rectangle raindrop = iter.next();
raindrop.y -= 200*Gdx.graphics.getDeltaTime();//模拟水滴下落的画面
if(raindrop.y + 64 < 0){//如果水滴没有被收集到(也就是超越了底边界一定的距离)
iter.remove();//将其从水滴集合中移除
}
if(raindrop.overlaps(bucket)){//如果两个矩形区域重叠(形象的说就是如果水滴和水桶碰到一起了)
dropGathered++;//将收集到的水滴数+1
dropSound.play();//播放水滴的声音
iter.remove();//将其从水滴集合中移除
}
}
}
@Override
public void resize(int arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void resume() {
// TODO Auto-generated method stub
}
@Override
public void show() {
rainMusic.play();
}
}