Здравствуйте, сегодня создадим простую Android игру с помощью бесплатного фреймворка LibGDX и Android Studio.
Суть игры: помочь пони собрать как можно больше яблок за 60 секунд.
Изменения кода игры от 01.07.16
Скачать исходники для статьи можно ниже
Также рекомендую изучить видео-инструкцию для новичков по созданию простой android игры, на основе её и была создана нижеуказанная игра:
Урок 1: “youtu.be/e75He5HE9iE”
Урок 2: “youtu.be/C34m2XN4gzo”
Урок 3: “youtu.be/oRgBRm60jXY”
Урок 4: “youtu.be/F2h7E2VpY0Y”
Скачать apk данной игры можно по следующей ссылке:
Скачать Android игру “Собери яблоки”
Первое, создаём проект в бесплатном фреймворке – LibGDX, указываем:
Name: PonyGame3
Package: ru.mnogoblog
Game class: PonyGame3
Отмечаем галочкой:
– Desktop и Android;
– Freetype (так как будем подключать русские шрифты).
Для игры “Собери яблоки” вам понадобится создать 4 класса:
– Drop
– GameOverScreen
– MainMenuScreen
– PonyGame3
Скачать данные файлы можно по следующей ссылке – скачать файлы классов к игре “Собери яблоки” – их можно открыть с помощью редактора кода, например: NotePad++ или с помощью обычного – Блокнота (Windows).
Код данных классов приведу ниже!
Содержимое папки assets, где лежат все картинки, шрифты и музыка для игры можно скачать по следующей ссылке:
Скачать папку assets для игры “Собери яблоки”.
Главным классом игры – будет класс Drop, поэтому в файле AndroidLauncher пропишем ссылку на него:
package ru.mnogoblog;
import android.os.Bundle;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
public class AndroidLauncher extends AndroidApplication {
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new Drop(), config);
}
}
Аналогично с DesktopLauncher – если вы создаёте desctop версию игры:
Код файла DesktopLauncher:
package ru.mnogoblog.desktop;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import ru.mnogoblog.Drop;
public class DesktopLauncher {
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
new LwjglApplication(new Drop(), config);
}
}
Теперь приведу код классов.
Код класса Drop:
package ru.mnogoblog;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import java.util.Locale;
public class Drop extends Game {
SpriteBatch batch;
BitmapFont font;
BitmapFont myfont;
@Override
public void create() {
batch = new SpriteBatch();
font = new BitmapFont();
myfont = new BitmapFont();
final String FONT_CHARS = "абвгдежзийклмнопрстуфхцчшщъыьэюяabcdefghijklmnopqrstuvwxyzАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789][_!$%#@|\\\\/?-+=()*&.;:,{}\\\"´`'<>";
final String FONT_PATH = "fonts/Imperial Web.ttf";
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal(FONT_PATH));
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
parameter.characters = FONT_CHARS;
parameter.size = 17;
parameter.color = Color.BROWN;
myfont = generator.generateFont(parameter);
generator.dispose();
this.setScreen(new MainMenuScreen(this));
font.setColor(1f, 0f, 0f, 1f);
}
@Override
public void render() {
super.render();
}
@Override
public void dispose() {
super.dispose();
batch.dispose();
font.dispose();
}
}
Код класса PonyGame3:
package ru.mnogoblog;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.GL20;
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;
import java.util.Iterator;
public class PonyGame3 implements Screen {
final Drop game;
OrthographicCamera camera;
Texture dropImage;
Texture myPony;
Texture bucketImage;
Sound dropSound;
Music rainMusic;
Rectangle bucket;
Vector3 touchPos;
Array<Rectangle> raindrops;
long lastDropTime;
static int dropsGatchered;
static int dropsGatchered2;
String dropString;
public static Texture backgroundTexture;
float timer = 0f;
int time = 0;
public PonyGame3 (final Drop gam) {
this.game = gam;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
touchPos = new Vector3();
dropImage = new Texture("apple.png");
myPony = new Texture("pony.png");
bucketImage = new Texture("bucket2.png");
backgroundTexture = new Texture("bg.png");
dropSound = Gdx.audio.newSound(Gdx.files.internal("mpput.mp3"));
rainMusic = Gdx.audio.newMusic(Gdx.files.internal("ponyfongame.mp3"));
rainMusic.setLooping(true);
rainMusic.play();
bucket = new Rectangle();
bucket.x = 800 / 2 - 64 / 2;
bucket.y = 20;
bucket.width = 64;
bucket.height = 64;
raindrops = new Array<Rectangle>();
spawnRaindrop();
}
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 render (float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.batch.draw(backgroundTexture, 0, 0, 800, 480);
game.batch.draw(dropImage, 0,440,64,64);
game.myfont.draw(game.batch, "Время:" + (6100-time)/100, 350, 460);
game.myfont.draw(game.batch, ": " + dropsGatchered, 60, 460);
game.batch.draw(bucketImage, bucket.x, bucket.y);
for (Rectangle raindrop: raindrops){
game.batch.draw(dropImage, raindrop.x, raindrop.y);
}
game.batch.draw(myPony, 0,0,200,100);
game.batch.end();
timer = delta;
if (timer >= 0) {
time++;
}
if (time>6000) {
game.setScreen(new GameOverScreen(game));
dropsGatchered2=dropsGatchered;
dropsGatchered=0;
dispose();
}
if(Gdx.input.isTouched()){
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
if (touchPos.x<400) bucket.x -= 200 * Gdx.graphics.getDeltaTime();
if(touchPos.x>400) bucket.x += 200 * Gdx.graphics.getDeltaTime();
}
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)) bucket.x -= 200 * Gdx.graphics.getDeltaTime();
if(Gdx.input.isKeyPressed(Input.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)){
dropsGatchered++;
dropSound.play();
iter.remove();
}
}
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
}
@Override
public void dispose() {
dropImage.dispose();
bucketImage.dispose();
dropSound.dispose();
rainMusic.dispose();
}
@Override
public void show() {
rainMusic.play();
}
}
Код класса MainMenuScreen:
package ru.mnogoblog;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Vector3;
import java.util.Locale;
public class MainMenuScreen implements Screen {
Vector3 touchPos;
final Drop game;
OrthographicCamera camera;
public static Texture backgroundTexture1;
Texture btnStart;
Texture ponyMain;
public MainMenuScreen(final Drop gam) {
game = gam;
touchPos = new Vector3();
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
backgroundTexture1 = new Texture("bg.png");
btnStart = new Texture("btnStart.png");
ponyMain = new Texture("ponymain.png");
}
@Override
public void show() {
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.batch.draw(backgroundTexture1, 0, 0, 800, 480);
game.batch.draw(ponyMain, 10, 0, 780, 309);
game.batch.draw (btnStart, 275, 205, 250, 70);
game.myfont.draw(game.batch, "Помоги пони собрать яблоки!", 240, 450);
game.batch.end();
if (Gdx.input.isTouched()){
game.setScreen(new PonyGame3(game));
dispose();
}
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
}
@Override
public void dispose() {
}
}
Код класса GameOverScreen:
package ru.mnogoblog;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Vector3;
/**
* Created by Константин on 09.06.16.
*/
public class GameOverScreen implements Screen {
final Drop game;
OrthographicCamera camera;
public static Texture backgroundTexture1;
Texture btnReload;
Texture korzina;
Vector3 touchPos;
public GameOverScreen(final Drop gam2) {
game = gam2;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
backgroundTexture1 = new Texture("bg.png");
btnReload = new Texture("btnReload.png");
korzina = new Texture("bucket3.png");
touchPos = new Vector3();
}
@Override
public void show() {
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.batch.draw(backgroundTexture1, 0, 0, 800, 480);
game.batch.draw(btnReload, 350, 190, 110, 100);
game.batch.draw(korzina, 275, 10, 250, 160);
game.myfont.draw(game.batch, "Количество набранных яблок: " + PonyGame3.dropsGatchered2, 235, 450);
game.batch.end();
if (Gdx.input.isTouched()){
game.setScreen(new PonyGame3(game));
dispose();
}
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
}
@Override
public void dispose() {
}
}
На этом всё – игра готова!

