Added Game View.

This commit is contained in:
Alexei KADIR 2024-04-04 02:12:58 +02:00
parent 47fe1a7d47
commit 5f85daa682

View File

@ -0,0 +1,267 @@
package fr.iutfbleau.sae;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class GameView extends View implements View.OnTouchListener {
public static final int CELL_SIZE = 96;
public static final int LINE_SIZE = 12;
private GameModel model;
private final Point offset;
private final Paint paint;
private int linePointerId;
private int movementPointerId;
private float movementX;
private float movementY;
private GameListener listener;
public GameView(Context context, @Nullable AttributeSet attributes) {
super(context, attributes);
this.offset = new Point(0, 0);
this.paint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.setOnTouchListener(this);
this.linePointerId = -1;
this.movementPointerId = -1;
}
public void setModel(GameModel model) {
this.model = model;
}
public void setListener(GameListener listener) {
this.listener = listener;
}
public void applyOffset(int dx, int dy) {
this.offset.offset(dx, dy);
}
public void setOffset(int x, int y) {
this.offset.x = x;
this.offset.y = y;
}
public Point getOffset() {
return new Point(offset);
}
private Cell pixelToCell(float x, float y) {
int ox = this.offset.x + (this.getWidth() - this.model.getSize() * CELL_SIZE + CELL_SIZE) / 2;
int oy = this.offset.y + (this.getHeight() - this.model.getSize() * CELL_SIZE + CELL_SIZE) / 2;
return new Cell(Math.round((x - ox) / CELL_SIZE), Math.round((y - oy) / CELL_SIZE));
}
private Cell pixelToCell(Point point) {
return pixelToCell(point.x, point.y);
}
private Point cellToPixel(Cell cell) {
int ox = this.offset.x + (this.getWidth() - this.model.getSize() * CELL_SIZE + CELL_SIZE) / 2;
int oy = this.offset.y + (this.getHeight() - this.model.getSize() * CELL_SIZE + CELL_SIZE) / 2;
return new Point(ox + cell.x * CELL_SIZE, oy + cell.y * CELL_SIZE);
}
private void drawGrid(Canvas canvas) {
int w = this.getWidth();
int h = this.getHeight();
this.paint.setColor(this.getResources().getColor(R.color.grid));
this.paint.setStrokeWidth(LINE_SIZE);
Point pixelOffset = this.cellToPixel(new Cell(0, 0));
for (int x = pixelOffset.x % CELL_SIZE; x < w; x += CELL_SIZE)
canvas.drawLine(x, 0, x, h, this.paint);
for (int y = pixelOffset.y % CELL_SIZE; y < h; y += CELL_SIZE)
canvas.drawLine(0, y, w, y, this.paint);
}
private void drawCrosses(Canvas canvas) {
this.paint.setColor(this.getResources().getColor(R.color.cross));
this.paint.setStrokeWidth(LINE_SIZE);
for (Cell cell : this.model.getCells())
this.drawCross(canvas, cell);
}
private void drawCross(Canvas canvas, Cell cell) {
float size = CELL_SIZE / 4.0F;
Point position = this.cellToPixel(cell);
canvas.drawLine(position.x, position.y - size, position.x, position.y + size, this.paint);
canvas.drawLine(position.x - size, position.y, position.x + size, position.y, this.paint);
}
private void drawInputLine(Canvas canvas) {
if (!this.model.hasInputLine())
return;
if (this.model.isInputLineValid())
this.paint.setColor(this.getResources().getColor(R.color.valid_input_line));
else
this.paint.setColor(this.getResources().getColor(R.color.invalid_input_line));
this.paint.setStrokeWidth(LINE_SIZE);
Point start = this.cellToPixel(this.model.getInputLineStart());
Point end = this.cellToPixel(this.model.getInputLineEnd());
canvas.drawLine(start.x, start.y, end.x, end.y, paint);
}
private void drawLines(Canvas canvas) {
this.paint.setColor(this.getResources().getColor(R.color.line));
this.paint.setStrokeWidth(LINE_SIZE);
for (Line line : this.model.getLines()) {
Point start = this.cellToPixel(line.getStart());
Point end = this.cellToPixel(line.getEnd());
canvas.drawLine(start.x, start.y, end.x, end.y, paint);
}
}
@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
this.drawGrid(canvas);
if (this.model != null)
return;
this.drawLines(canvas);
this.drawCrosses(canvas);
this.drawInputLine(canvas);
}
@Override
public boolean onTouch(View view, MotionEvent event) {
if (this != view)
return false;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
if (this.linePointerId != -1)
break;
int index = event.getActionIndex();
this.linePointerId = event.getPointerId(index);
if (this.listener != null)
this.listener.onLineStarted(this, this.pixelToCell(event.getX(index), event.getY(index)));
break;
}
case MotionEvent.ACTION_POINTER_DOWN: {
if (this.movementPointerId != -1)
break;
int index = event.getActionIndex();
this.movementPointerId = event.getPointerId(index);
this.movementX = event.getX(index);
this.movementY = event.getY(index);
break;
}
case MotionEvent.ACTION_MOVE: {
if (this.movementPointerId != -1) {
int index = event.findPointerIndex(this.movementPointerId);
float x = event.getX(index);
float y = event.getY(index);
if (x != this.movementX || y != this.movementY) {
this.applyOffset(Math.round(x - this.movementX), Math.round(y - this.movementY));
this.movementX = x;
this.movementY = y;
this.invalidate();
}
}
if (this.linePointerId != -1) {
int index = event.findPointerIndex(this.linePointerId);
if (this.listener != null)
this.listener.onLineEndMoved(this, this.pixelToCell(event.getX(index), event.getY(index)));
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP: {
int index = event.getActionIndex();
int id = event.getPointerId(index);
if (this.linePointerId == id) {
this.linePointerId = -1;
if (this.listener != null)
this.listener.onLineEnded(this, this.pixelToCell(event.getX(index), event.getY(index)));
}
if (this.movementPointerId == id)
this.movementPointerId = -1;
}
}
return true;
}
}