Libgdx или Unity?
Что изучить — Libgdx или Unity? Немного ковырял и то и другое, пока вроде Libgdx ближе, немного освоился в нем. Однако большинство игр делается на Unity, я со своим libgdx боюсь остаться никому не нужным.
Плюсы Libgdx:
Полностью бесплатный без ограничений
Простой для понимания, легкий порог вхождения
Придется много кодить, почти все в игре делается написанием кода. Также придется думать над структурой проекта, организацией кода, что для меня является плюсом, так как развиваются навыки программирования
Минусы Libgdx:
Недоразвитое 3D, хотя пока это мне не нужно, пока только занимаюсь 2D
Плюсы Unity
Больше коммюнити
Полностью готовый игровой редактор, в котором многое можно сделать простым кликом мышкой
Освоившись в движке можно создавать моды для игр на Unity
Развитое 3D
Много готовых модулей
Минусы Unity
Относительно высокий порог вхождения
Дорогие модули для начинающего игродела
Пишут что большой овэрхед, хотя сам перепроверял
Как мы писали арифметическую головоломку на LibGDX под ведроид. Часть 2
Историю создания и все предисловия вы можете найти в первой части статьи: http://pikabu.ru/story/kak_myi_pisali_arifmeticheskuyu_golov.... В этой статье будет больше конкретики. Хотелось бы рассказать о том, каким образом реализованы уровни в игре, и начнём с основополагающей сущности – треугольника.
С треугольником всё довольно просто. У него есть значение value, которое используется для последующих подсчётов сумы в пунктирной области, также по этому значению выбирается подходящая текстура для актёра. К слову, как и полагается, все текстуры упакованы в атласы. Также, у треугольника есть boolean переменная, которая определяет, скрыт ли треугольник (влияет только на подбор текстуры, если скрыт – текстура со знаком вопроса).
Итак, класс треугольника как он есть:
public class Triangle extends Actor {
public GdxGameCore game;
private int value;
private int placeNumber;
private boolean isHidden;
private TextureAtlas.AtlasRegion texture;
public void draw(Batch batch, float parentAlpha) {
batch.draw(texture, getX(), getY(), getWidth(), getHeight());
super.draw(batch, parentAlpha);
}
/**
* Конструктор для создания объекта Triangle
* @param value - числовое значение треугольника (0-9)
* @param isHidden - флаг скрытия теугольника (0 - не скрыт, 1- скрыт)
* @param placeNumber - положение треугольника на площадке уровня
*/
public Triangle (int value, boolean isHidden, int placeNumber, GdxGameCore game) {
this.game = game;
this.value = value;
this.isHidden = isHidden;
this.placeNumber = placeNumber;
/*
* Определение текстуры
*/
if (isHidden) {
this.texture = game.hidden;
} else {
switch (value) {
case 0:
this.texture = game.zero;
break;
case 1:
this.texture = game.one;
break;
case 2:
this.texture = game.two;
break;
case 3:
this.texture = game.three;
break;
case 4:
this.texture = game.four;
break;
case 5:
this.texture = game.five;
break;
case 6:
this.texture = game.six;
break;
case 7:
this.texture = game.seven;
break;
case 8:
this.texture = game.eight;
break;
case 9:
this.texture = game.nine;
break;
}
}
}
public boolean isHidden() {
return isHidden;
}
public int getPlaceNumber() {
return placeNumber;
}
public int getValue() {
return value;
}
public TextureAtlas.AtlasRegion getTexture() {
return texture;
}
public String toString() {
return super.toString();
}
}
Следующим шагом хочу рассказать о кнопке, с помощью которой осуществляется движение группы треугольников (по кругу, в заданном направлении). Класс кнопки также очень прост. У него есть переменная направления движения, с помощью которой мы определяем, в какую сторону прокручивать группу треугольников. По этой же переменной подбирается и текстура актёра.
Собственно, класс кнопки:
public class MoveButton extends Actor{
final GdxGameCore game;
private int direction;
private TextureAtlas.AtlasRegion texture, texturePressed;
private boolean isPressed = false;
public void draw(Batch batch, float parentAlpha) {
if (!isPressed) {
batch.draw(texture, getX(), getY(), getWidth(), getHeight());
} else {
batch.draw(texturePressed, getX(), getY(), getWidth(), getHeight());
}
super.draw(batch, parentAlpha);
}
/**
* Конструктор кнопки движения
* (Подбирает нужную текстуру и генерирует актёра)
* @param direction - направление (0 - влево, 1 - вправо)
*/
public MoveButton (int direction, GdxGameCore game) {
this.game = game;
this.direction = direction;
if (direction == 0) {
// LEFT BUTTON TEXTURE
this.texture = game.move_left;
this.texturePressed = game.move_left_pressed;
} else {
// RIGHT BUTTON TEXTURE
this.texture = game.move_right;
this.texturePressed = game.move_right_pressed;
}
}
public int getDirection() {
return direction;
}
public void setPressed () {
isPressed = true;
this.act(0.3f);
isPressed = false;
this.act(0.3f);
}
public TextureAtlas.AtlasRegion getTexture() {
return texture;
}
public String toString() {
return super.toString();
}
}
Далее, хочу рассказать о классе уровня. Класс уровня вмещает в себе конструктор, который создаёт объекты треугольников и кнопок, а также, ограничения на количество движений и времени. В классе есть три различных конструктора под каждую из трёх сложностей. В классе игры (GameScreen) осуществляется работа с объектом Level, что довольно удобно. Особых пояснений, думаю, не требуется, поэтому, просто покажу код:
public class Level {
GdxGameCore game;
private int levelNum;
// HARDNESS 1
private int triangle_1, triangle_2, triangle_3, triangle_4, triangle_5, triangle_6;
private boolean b_hide_1, b_hide_2, b_hide_3, b_hide_4, b_hide_5, b_hide_6;
private int btn_1, btn_2, btn_3; // 0 - LEFT, 1 - RIGHT;
// HARDNESS 2
private int triangle_7, triangle_8, triangle_9, triangle_10;
private int hide_1, hide_2, hide_3, hide_4, hide_5, hide_6;
private int hide_7, hide_8, hide_9, hide_10;
private boolean b_hide_7, b_hide_8, b_hide_9, b_hide_10;
private int btn_4, btn_5, btn_6; // 0 - LEFT, 1 - RIGHT;
// Ограничения
private int time_sec;
private int moves;
private int goal;
private List <Triangle> triangles;
private List <MoveButton> moveButtons;
/**
* HARDNESS EASY
* @param levelNum - номер уровня
* @param triangle_1 - значение треугольника
* @param triangle_2 - значение треугольника
* @param triangle_3 - значение треугольника
* @param triangle_4 - значение треугольника
* @param triangle_5 - значение треугольника
* @param triangle_6 - значение треугольника
* @param time_sec - ограничение во времени в секундах
* @param moves - ограничение в движениях
* @param goal - цель (необходимая сумма в главном треугольнике)
* @param btn_1 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param btn_2 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param btn_3 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param game - основной класс core модуля
*/
public Level (int levelNum, int triangle_1, int triangle_2, int triangle_3, int triangle_4,
int triangle_5, int triangle_6, int time_sec, int moves, int goal, int btn_1, int btn_2,
int btn_3, GdxGameCore game) {
this.game = game;
this.levelNum = levelNum;
this.triangle_1 = triangle_1;
this.triangle_2 = triangle_2;
this.triangle_3 = triangle_3;
this.triangle_4 = triangle_4;
this.triangle_5 = triangle_5;
this.triangle_6 = triangle_6;
this.time_sec = time_sec;
this.moves = moves;
this.goal = goal;
this.btn_1 = btn_1;
this.btn_2 = btn_2;
this.btn_3 = btn_3;
Triangle tr1 = new Triangle(triangle_1, false, 1, game);
Triangle tr2 = new Triangle(triangle_2, false, 2, game);
Triangle tr3 = new Triangle(triangle_3, false, 3, game);
Triangle tr4 = new Triangle(triangle_4, false, 4, game);
Triangle tr5 = new Triangle(triangle_5, false, 5, game);
Triangle tr6 = new Triangle(triangle_6, false, 6, game);
MoveButton mb1 = new MoveButton(btn_1, game);
MoveButton mb2 = new MoveButton(btn_2, game);
MoveButton mb3 = new MoveButton(btn_3, game);
triangles = new ArrayList<Triangle>();
triangles.add(tr1);
triangles.add(tr2);
triangles.add(tr3);
triangles.add(tr4);
triangles.add(tr5);
triangles.add(tr6);
moveButtons = new ArrayList<MoveButton>();
moveButtons.add(mb1);
moveButtons.add(mb2);
moveButtons.add(mb3);
}
/**
* HARDNESS MEDIUM
* @param levelNum - номер уровня
* @param triangle_1 - значение треугольника
* @param triangle_2 - значение треугольника
* @param triangle_3 - значение треугольника
* @param triangle_4 - значение треугольника
* @param triangle_5 - значение треугольника
* @param triangle_6 - значение треугольника
* @param hide_1 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_2 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_3 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_4 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_5 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_6 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param time_sec - ограничение во времени в секундах
* @param moves - ограничение в движениях
* @param goal - цель (необходимая сумма в главном треугольнике)
* @param btn_1 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param btn_2 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param btn_3 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param game - - основной класс core модуля
*/
public Level (int levelNum, int triangle_1, int triangle_2, int triangle_3, int triangle_4,
int triangle_5, int triangle_6, int hide_1, int hide_2, int hide_3, int hide_4,
int hide_5, int hide_6, int time_sec, int moves, int goal, int btn_1, int btn_2,
int btn_3, GdxGameCore game) {
this.game = game;
this.levelNum = levelNum;
this.triangle_1 = triangle_1;
this.triangle_2 = triangle_2;
this.triangle_3 = triangle_3;
this.triangle_4 = triangle_4;
this.triangle_5 = triangle_5;
this.triangle_6 = triangle_6;
this.hide_1 = hide_1;
this.hide_2 = hide_2;
this.hide_3 = hide_3;
this.hide_4 = hide_4;
this.hide_5 = hide_5;
this.hide_6 = hide_6;
this.time_sec = time_sec;
this.moves = moves;
this.goal = goal;
this.btn_1 = btn_1;
this.btn_2 = btn_2;
this.btn_3 = btn_3;
checkHidden(6);
Triangle tr1 = new Triangle(triangle_1, b_hide_1, 1, game);
Triangle tr2 = new Triangle(triangle_2, b_hide_2, 2, game);
Triangle tr3 = new Triangle(triangle_3, b_hide_3, 3, game);
Triangle tr4 = new Triangle(triangle_4, b_hide_4, 4, game);
Triangle tr5 = new Triangle(triangle_5, b_hide_5, 5, game);
Triangle tr6 = new Triangle(triangle_6, b_hide_6, 6, game);
MoveButton mb1 = new MoveButton(btn_1, game);
MoveButton mb2 = new MoveButton(btn_2, game);
MoveButton mb3 = new MoveButton(btn_3, game);
triangles = new ArrayList<Triangle>();
triangles.add(tr1);
triangles.add(tr2);
triangles.add(tr3);
triangles.add(tr4);
triangles.add(tr5);
triangles.add(tr6);
moveButtons = new ArrayList<MoveButton>();
moveButtons.add(mb1);
moveButtons.add(mb2);
moveButtons.add(mb3);
}
/**
* HARDNESS HARD
* @param levelNum - номер уровня
* @param triangle_1 - значение треугольника
* @param triangle_2 - значение треугольника
* @param triangle_3 - значение треугольника
* @param triangle_4 - значение треугольника
* @param triangle_5 - значение треугольника
* @param triangle_6 - значение треугольника
* @param triangle_7 - значение треугольника
* @param triangle_8 - значение треугольника
* @param triangle_9 - значение треугольника
* @param triangle_10 - значение треугольника
* @param hide_1 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_2 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_3 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_4 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_5 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_6 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_7 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_8 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_9 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param hide_10 - флаг скрытия треугольника (0 - не скрыт, 1 - скрыт)
* @param time_sec - ограничение во времени в секундах
* @param moves - ограничение в движениях
* @param goal - цель (необходимая сумма в главном треугольнике)
* @param btn_1 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param btn_2 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param btn_3 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param btn_4 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param btn_5 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param btn_6 - флаг кнопки движения (0 - влево, 1 - вправо)
* @param game - основной класс core модуля
*/
public Level (int levelNum, int triangle_1, int triangle_2, int triangle_3, int triangle_4,
int triangle_5, int triangle_6, int triangle_7, int triangle_8, int triangle_9,
int triangle_10, int hide_1, int hide_2, int hide_3, int hide_4, int hide_5,
int hide_6, int hide_7, int hide_8, int hide_9, int hide_10, int time_sec,
int moves, int goal, int btn_1, int btn_2, int btn_3, int btn_4, int btn_5,
int btn_6, GdxGameCore game) {
this.game = game;
this.levelNum = levelNum;
this.triangle_1 = triangle_1;
this.triangle_2 = triangle_2;
this.triangle_3 = triangle_3;
this.triangle_4 = triangle_4;
this.triangle_5 = triangle_5;
this.triangle_6 = triangle_6;
this.triangle_7 = triangle_7;
this.triangle_8 = triangle_8;
this.triangle_9 = triangle_9;
this.triangle_10 = triangle_10;
this.hide_1 = hide_1;
this.hide_2 = hide_2;
this.hide_3 = hide_3;
this.hide_4 = hide_4;
this.hide_5 = hide_5;
this.hide_6 = hide_6;
this.hide_7 = hide_7;
this.hide_8 = hide_8;
this.hide_9 = hide_9;
this.hide_10 = hide_10;
this.time_sec = time_sec;
this.moves = moves;
this.goal = goal;
this.btn_1 = btn_1;
this.btn_2 = btn_2;
this.btn_3 = btn_3;
this.btn_4 = btn_4;
this.btn_5 = btn_5;
this.btn_6 = btn_6;
checkHidden(10);
Triangle tr1 = new Triangle(triangle_1, b_hide_1, 1, game);
Triangle tr2 = new Triangle(triangle_2, b_hide_2, 2, game);
Triangle tr3 = new Triangle(triangle_3, b_hide_3, 3, game);
Triangle tr4 = new Triangle(triangle_4, b_hide_4, 4, game);
Triangle tr5 = new Triangle(triangle_5, b_hide_5, 5, game);
Triangle tr6 = new Triangle(triangle_6, b_hide_6, 6, game);
Triangle tr7 = new Triangle(triangle_7, b_hide_7, 7, game);
Triangle tr8 = new Triangle(triangle_8, b_hide_8, 8, game);
Triangle tr9 = new Triangle(triangle_9, b_hide_9, 9, game);
Triangle tr10 = new Triangle(triangle_10, b_hide_10, 10, game);
MoveButton mb1 = new MoveButton(btn_1, game);
MoveButton mb2 = new MoveButton(btn_2, game);
MoveButton mb3 = new MoveButton(btn_3, game);
MoveButton mb4 = new MoveButton(btn_4, game);
MoveButton mb5 = new MoveButton(btn_5, game);
MoveButton mb6 = new MoveButton(btn_6, game);
triangles = new ArrayList<Triangle>();
triangles.add(tr1);
triangles.add(tr2);
triangles.add(tr3);
triangles.add(tr4);
triangles.add(tr5);
triangles.add(tr6);
triangles.add(tr7);
triangles.add(tr8);
triangles.add(tr9);
triangles.add(tr10);
moveButtons = new ArrayList<MoveButton>();
moveButtons.add(mb1);
moveButtons.add(mb2);
moveButtons.add(mb3);
moveButtons.add(mb4);
moveButtons.add(mb5);
moveButtons.add(mb6);
}
/**
* Переобразование значений 1 & 0 в тип boolean для создания объектов треугольников
* @param triangleQuantity - кол-во треугольников на площадке уровня
*/
public void checkHidden (int triangleQuantity) {
if (triangleQuantity == 6) {
// HARDNESS MEDIUM
if (hide_1 == 0) {
b_hide_1 = false;
} else {
b_hide_1 = true;
}
if (hide_2 == 0) {
b_hide_2 = false;
} else {
b_hide_2 = true;
}
if (hide_3 == 0) {
b_hide_3 = false;
} else {
b_hide_3 = true;
}
if (hide_4 == 0) {
b_hide_4 = false;
} else {
b_hide_4 = true;
}
if (hide_5 == 0) {
b_hide_5 = false;
} else {
b_hide_5 = true;
}
if (hide_6 == 0) {
b_hide_6 = false;
} else {
b_hide_6 = true;
}
} else {
// HARDNESS HARD
if (hide_1 == 0) {
b_hide_1 = false;
} else {
b_hide_1 = true;
}
if (hide_2 == 0) {
b_hide_2 = false;
} else {
b_hide_2 = true;
}
if (hide_3 == 0) {
b_hide_3 = false;
} else {
b_hide_3 = true;
}
if (hide_4 == 0) {
b_hide_4 = false;
} else {
b_hide_4 = true;
}
if (hide_5 == 0) {
b_hide_5 = false;
} else {
b_hide_5 = true;
}
if (hide_6 == 0) {
b_hide_6 = false;
} else {
b_hide_6 = true;
}
if (hide_7 == 0) {
b_hide_7 = false;
} else {
b_hide_7 = true;
}
if (hide_8 == 0) {
b_hide_8 = false;
} else {
b_hide_8 = true;
}
if (hide_9 == 0) {
b_hide_9 = false;
} else {
b_hide_9 = true;
}
if (hide_10 == 0) {
b_hide_10 = false;
} else {
b_hide_10 = true;
}
}
}
public int getLevelNum() {
return levelNum;
}
public int getGoal() {
return goal;
}
public int getMoves() {
return moves;
}
public int getTime_sec() {
return time_sec;
}
public List<Triangle> getTriangles() {
return triangles;
}
public List<MoveButton> getMoveButtons() {
return moveButtons;
}
public String toString() {
return super.toString();
}
}
В данном методе происходит перемещение треугольников, происходит оно по нажатию на определенную кнопку, которая передает треугольники которые стоят возле неё.
Мы запоминаем координаты треугольников и потом меняем их местами.
После этого они еще меняются местами в массиве, при помощи Коллекций.
public void swapTrianglesLeft(Triangle triangle1, Triangle triangle2, Triangle triangle3){
// sound
game.playMoveSound();
float tr1X, tr1Y, tr2X, tr2Y, tr3X, tr3Y;
tr1X = triangle1.getX();
tr1Y = triangle1.getY();
tr2X = triangle2.getX();
tr2Y = triangle2.getY();
tr3X = triangle3.getX();
tr3Y = triangle3.getY();
triangle1.addAction(Actions.moveTo(tr3X, tr3Y, 0.5f));
triangle2.addAction(Actions.moveTo(tr1X, tr1Y, 0.5f));
triangle3.addAction(Actions.moveTo(tr2X, tr2Y, 0.5f));
}
Надеюсь, эта статья была более конструктивной, чем предыдущая, и интересно дополнила её. Спасибо за внимание, ставьте плюсик, если понравилось и, конечно же, всем добра :)
Ссылка на Play Market: https://play.google.com/store/apps/details?id=com.dailytoys....
Игра Screw. Java и Libgdx.
Создание Android игры на Libgdx
В Питере шаверма и мосты, в Казани эчпочмаки и казан. А что в других городах?
Мы постарались сделать каждый город, с которого начинается еженедельный заед в нашей новой игре, по-настоящему уникальным. Оценить можно на странице совместной игры Torero и Пикабу.
Реклама АО «Кордиант», ИНН 7601001509