полноэкранная сетка не работает при касании - PullRequest
0 голосов
/ 09 ноября 2018

Здравствуйте, я создаю игру, похожую на матрицу памяти, и застрял в той части, где я должен заставить плитку светиться при касании. Иногда это работает, но не совсем, например, когда я касаюсь плитки двумя плитками вверху, загорается нижняя. Все перепутано! Извините, я новичок с кодированием и libgdx. Вот логика:

package ksmd.tiles.Screens;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
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.Vector3;
import ksmd.tiles.Tiles;
import ksmd.tiles.UI.Tile;

public class PlayScreen implements Screen, InputProcessor {

private Tile[][] tiles;
private OrthographicCamera camera;
private SpriteBatch batch;
private TextureRegion tex;
private float boardOffset;
private int TILE_SIZE;
private Tiles game;
private Vector3 mouse;
private final int MAX_FINGERS = 2;
private int boardHeight;

public PlayScreen(Tiles game) {
    this.game = game;
}

@Override
public void show() {
    Gdx.input.setInputProcessor(this);
    camera = new OrthographicCamera();
    camera.setToOrtho(false, Tiles.WIDTH, Tiles.HEIGHT);
    batch = new SpriteBatch();
    tiles = new Tile[5][5];
    TILE_SIZE = Tiles.WIDTH / tiles[0].length;
    boardHeight = TILE_SIZE * tiles.length;
    boardOffset = (Tiles.HEIGHT - (TILE_SIZE * tiles.length)) / 2;

    //Create the tiles
    for (int row = 0; row < tiles.length; row++) {
        for (int col = 0; col < tiles[0].length; col++) {
            tiles[row][col] = new Tile(col * TILE_SIZE + TILE_SIZE / 2, row * TILE_SIZE  + TILE_SIZE +boardOffset/ 2, TILE_SIZE, TILE_SIZE);
        }
    }

}

//render the Tiles
@Override
public void render(float delta) {
    batch.setProjectionMatrix(camera.combined);
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.begin();
    for (int row = 0; row < tiles.length; row++) {
        for (int col = 0; col < tiles[0].length; col++) {
            tiles[row][col].render(batch, delta); // call the render method of each tile
        }
    }
    batch.end();
}

@Override
public void resize(int width, int height) {

}

@Override
public void dispose() {
    //dispose disposable objects
    batch.dispose();
}

@Override
public void pause() {
}

@Override
public void resume() {
}

@Override
public void hide() {
}

@Override
public boolean keyDown(int keycode) {
    return false;
}

@Override
public boolean keyUp(int keycode) {
    return false;
}

@Override
public boolean keyTyped(char character) {
    return false;
}

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    mouse = new Vector3(screenX, screenY, 0);
    for (int i = 0; i < MAX_FINGERS; i++) {
        if (Gdx.input.isTouched(i)) {
            mouse.x = Gdx.input.getX(i);
            mouse.y = Gdx.input.getY(i);
            camera.unproject(mouse);
            if (mouse.x > 0 && mouse.x < Tiles.WIDTH && mouse.y >= boardOffset && mouse.y < boardOffset + boardHeight) {
                int col = (int) (mouse.x/TILE_SIZE);
                int row = (int) ((mouse.y - boardOffset) / TILE_SIZE);
                tiles[row][col].setSelected(!tiles[row][col].getSelected());
            }
        }
    }
    return false;
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    return false;
}

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
    return false;
}

@Override
public boolean mouseMoved(int screenX, int screenY) {
    return false;
}

@Override
public boolean scrolled(int amount) {
    return false;
}

}

package ksmd.tiles.UI;

import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

import ksmd.tiles.Tiles;

public class Tile extends Box {

private TextureRegion lit;
private TextureRegion dark;
private boolean selected;

public Tile(float x, float y, int width, int height) {
    this.x = x;
    this.y = y * 1.55f;
    this.width = width - 8;
    this.height = height - 8;
    lit = Tiles.res.getAtlas("pack").findRegion("lit");
    dark = Tiles.res.getAtlas("pack").findRegion("dark");
    // set bounds of Sprite
}

public void setSelected (boolean b) {
    selected = b;
}

public boolean getSelected() {return selected; }

public void render(Batch batch, float delta) {
    if (selected) {
        batch.draw(lit, x - width / 2, y - width * 3, width, height * 1.60f);
    } else {
        batch.draw(dark, x - width / 2, y - width * 3, width, height * 1.60f);
    }

}

}

Я бы хотел, чтобы помол заполнил весь экран, а при прикосновении загоралась плитка. На данный момент я перебрал его, чтобы он заполнил весь экран, но при прикосновении он не правильно выбрал плитку. Спасибо!

1 Ответ

0 голосов
/ 15 ноября 2018

Работать с плитками в сетке с промежутками между ними сложнее, чем кажется.

Во-первых, есть вещи, которые нужно решить. Размер всей доски определяется размером отдельной плитки, или размер плитки зависит от размера доски?

  1. Плитка не должна расширяться Box, плитка может быть лучше представлена ​​прямоугольником, Box жить в трех измерениях, плитка не. Плитка должна расширяться com.badlogic.gdx.math.Rectangle.

2. Я предполагаю, что Tiles.WIDTH и Tiles.HEIGHT указывают размер доски. TILE_SIZE не равно Tiles.WIDTH / tiles[0].length, не может, потому что доска больше из-за промежутков между тайлами.

@Override
public void show() {
    Gdx.input.setInputProcessor(this);
    camera = new OrthographicCamera();
    batch = new SpriteBatch();
    tiles = new Tile[5][5];
    float gapSize = 10f;
    TILE_SIZE = ((Tiles.WIDTH - ((tiles[0].length-1) * gapSize ))) / tiles[0].length;
    boardOffset = 2;
    camera.viewportHeight = Tiles.HEIGHT + boardOffset;
    camera.viewportWidth = Tiles.WIDTH + boardOffset;
    camera.position.x = Tiles.WIDTH/2;
    camera.position.y = Tiles.HEIGHT/2;
    camera.update();
    //Create the tiles
    for (int row = 0; row < tiles.length; row++) {
        for (int col = 0; col < tiles[0].length; col++) {
            tiles[row][col] = new Tile(col * (TILE_SIZE + gapSize), row * (TILE_SIZE + gapSize) + boardOffset , TILE_SIZE, TILE_SIZE);
        }
    }
    Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 0);
}

Я переместил Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 0); в метод show, потому что я не вижу причины устанавливать один и тот же цвет в каждом кадре. Также не забудьте camera.update(), если вы манипулировали его компонентами. Просто сделайте все манипуляции, а затем обновите перед использованием.

3. Я изменил класс плитки

public class Tile extends Rectangle {

    private TextureRegion lit;
    private TextureRegion dark;
    private boolean selected;
    public Tile(float x, float y, float width, float height) {
        this.x = x;
        this.y = y;
        this.width = width ;
        this.height = height;
        lit = Tiles.getLit();
        dark = Tiles.getDark();
        // set bounds of Sprite
    }

    public void setSelected(boolean b) {
        selected = b;
    }

    public boolean getSelected() {
        return selected;
    }

    public void render(Batch batch, float delta) {
        if (selected) {
            batch.draw(lit, x, y , width, height);
        }
        else {
            batch.draw(dark, x, y , width, height);
        }

    }
}

Размер и положение плитки представлены прямоугольником, поэтому нарисуйте ее в том же месте и в том же размере, что и прямоугольник.

То же самое здесь:

public Tile(float x, float y, float width, float height) {
    this.x = x;
    this.y = y;
    this.width = width ;
    this.height = height;
    lit = Tiles.res.getAtlas("pack").findRegion("lit");
    dark = Tiles.res.getAtlas("pack").findRegion("dark");
    // set bounds of Sprite
}

Не изменять данные. 4. Я также изменил ввод

@Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        if (pointer < 2) {
            mouse.x = screenX;
            mouse.y = screenY;
            camera.unproject(mouse);
            if (mouse.x > 0 && mouse.x < Tiles.WIDTH && mouse.y >= boardOffset && mouse.y < boardOffset + Tiles.HEIGHT) {
                for (int r = 0; r < tiles.length; r++) {
                    for (int c = 0; c < tiles.length; c++) {
                        if (tiles[r][c].contains(mouse.x, mouse.y)) {
                            tiles[r][c].setSelected(true);
                        }
                    }
                }
            }
        }
        return false;

    }

Я проверяю каждый прямоугольник каждой плитки, чтобы точка приземления была внутри прямоугольника. Может быть, более быстрый метод, но компьютер быстр в эти дни.

Также ваша мышь vector3 может быть финальной.

...