📜 ⬆️ ⬇️

We write a game for Android using AndEngine. Part 2

Hello!
As promised, the second part of the article.
To avoid misunderstanding, read the first part of the article before reading .
Already familiar? Then welcome under the cat where I introduce the reader to the game objects.

And so summing up the first part, we learned how to load and display textures, but for a full-fledged game this is very small, and the textures themselves will not help us much. In order for the textures to perform everything that may be required of them, we will create game objects, which, in turn, will contain these textures.

Now about everything in order.

Step 1: Entity
')
Entity is the AndEngine class, I won’t explain for a long time why it is needed, I’ll just say that it is a kind of analogue of the ViewGroup class. We will need it for our game objects.

We will have 2 types of objects: static and dynamic. Dynamic can be rotated, and static, respectively, no.

Step 2: Static Object

To make it easier, let's create a class GameObject.

public abstract class GameObject extends Entity {

protected Sprite mSprite;

public GameObject(final int posX, final int posY, final TextureRegion region) {
mSprite = new Sprite(posX * GameObjectsMap.CELL_SIZE, posY
* GameObjectsMap.CELL_SIZE, region);
attachChild(mSprite);
}

protected Sprite getSprite() {
return mSprite;
}

public static enum Type {
lasergun, mirror, target
}

abstract int onLaser( int angle);

abstract void attachTo(Scene scene);

}


* This source code was highlighted with Source Code Highlighter .


I want to draw your attention to the onLaser method which takes the angle value at which the laser hits our game object. And it will return a negative value if nothing is reflected from the object and the angle of reflection in the opposite case.

Step 3: Dynamic Object

The above class is suitable for static objects. For dynamic we will have to expand it a bit.

public abstract class DynamicGameObject extends GameObject {

public static final int DEG_0 = 0;
public static final int DEG_45 = 1;
public static final int DEG_90 = 2;
public static final int DEG_135 = 3;
public static final int DEG_180 = 4;
public static final int DEG_225 = 5;
public static final int DEG_270 = 6;
public static final int DEG_315 = 7;

private static final float ANGLE = 45f;

private int mAngle;

public DynamicGameObject(final int posX, final int posY, final int angle,
final TextureRegion region) {
super(posX, posY, region);
setAngle(angle);
}

public int getAngle() {
return mAngle;
}

public void setAngle( int angle) {
this .mAngle = angle;
rotateSprite();
}

public void rotateLeft() {
mAngle--;
if (mAngle < DEG_0) {
mAngle = DEG_315;
}
rotateSprite();
}

public void rotateRigth() {
mAngle++;
if (mAngle > DEG_315) {
mAngle = DEG_0;
}
rotateSprite();
}

public float getRotationAngle() {
return ANGLE * mAngle;
}

protected void rotateSprite() {
mSprite.setRotation(getRotationAngle());
}

}


* This source code was highlighted with Source Code Highlighter .


Here, now we are ready for great things, we can turn our object and its sprite as we like. But it’s still far from testing the code, and we don’t have a laser. What do we need for a laser? To begin, choose the primitive that we will use. Obviously, this will be a line, but given that our laser will be reflected from objects, we will need something more.

Step 4: Difficult game object

public class LaserLine extends Entity {

private static final float LINE_WIDTH = 3f;

LinkedList<Point> mPoints;
private final Point mStartPosition;
private int mAngle;

public LaserLine(Point startPosition, int angle) {
init();
mStartPosition = startPosition;
mPoints.add(mStartPosition);
mAngle = angle;
}

public void init() {
mPoints = new LinkedList<Point>();
}

public void clearPoints() {
mPoints.clear();
mPoints.add(mStartPosition);
}

public void addPoint(final int cellNumX, final int cellNumY) {
mPoints.add( new Point(cellNumX, cellNumY));
}

public void addPoint(Point point) {
mPoints.add( new Point(point));
}

public void buildLines() {
detachChildren();
Point previousPoint = null ;
for (Point point : mPoints) {
Ln.i(point.x + " " + point.y);
if (previousPoint != null ) {
attachChild(makeLine(previousPoint, point));
}
previousPoint = point;
}
Ln.i( "-------------" );
}

public final Line makeLine(final Point start, final Point end) {
final Line line = new Line(
(start.x + 0.5f) * GameObjectsMap.CELL_SIZE_X,
(start.y + 0.5f) * GameObjectsMap.CELL_SIZE_Y,
(end.x + 0.5f) * GameObjectsMap.CELL_SIZE_X,
(end.y + 0.5f) * GameObjectsMap.CELL_SIZE_Y);
line.setLineWidth(LINE_WIDTH);
line.setColor(1f, 0.1f, 0.1f, 0.75f);
return line;
}

public Point getStartPosition() {
return mStartPosition;
}

public void setAngle( int angle) {
mAngle = angle;
}

public int getAngle() {
return mAngle;
}
}


* This source code was highlighted with Source Code Highlighter .


Here we have a lot of interesting things. Looking ahead, I will say that all our objects will be stored in one two-dimensional array. This fact explains the presence of the CELL_SIZE fields, as well as the need to add 0.5f in the makeLine method, hoping to be in the middle of the cell. To build a laser, we need a list of points. Each segment of the laser will be "attached" to the LaserLine. As a result, when adding our object to the scene, we will see all the segments of the laser.

The last thing left to do to see the result of our work is to write another small class.

public class LaserGun extends DynamicGameObject {

public LaserGun(final int posX, final int posY, final int angle,
final TextureRegion region) {
super(posX, posY, angle, region);
}

@Override
int onLaser( int angle) {
return -1;
}

@Override
void attachTo(Scene scene) {
scene.getChild(GameObjectsMap.GAME_OBJECTS_LAYER).attachChild(getSprite());
}

}


* This source code was highlighted with Source Code Highlighter .


Lasers are not reflected from our gun, and the sprite is displayed on the layer of game objects.

Step 5: Draw Objects

Now we’ll add code to our StageActivity that will allow us to see all this.
public Scene onLoadScene() {
this .mEngine.registerUpdateHandler( new FPSLogger());

final Scene scene = new Scene(NUMBER_OF_LAYERS);
scene.setBackground( new SpriteBackground( new Sprite(0, 0, mTextures
.getBackground())));
LaserLine line = new LaserLine( new Point(3, 3), 0);
line.addPoint( new Point(4, 4));
line.addPoint( new Point(5, 2));
line.buildLines();
scene.getChild(GameObjectsMap.LASER_LAYER).attachChild(line);
LaserGun gun = new LaserGun(3, 3, 4, mTextures.getLaserGun());
gun.attachTo(scene);
return scene;
}


* This source code was highlighted with Source Code Highlighter .

On my Hero, I saw this picture:


We are looking for code here .

That's all for today. Expect the third part.

As always, suggestions, constructive suggestions and questions are accepted.

PS For some unknown reason, Hero's laser thickness is always 1px, so don't get scared.
PPS In the code, the GameObjectsMap class is repeatedly mentioned, also not frightened, about it in the next article. And here she is

Source: https://habr.com/ru/post/120863/


All Articles