Compare commits
4 Commits
b754c535f4
...
5932062e0c
| Author | SHA1 | Date |
|---|---|---|
|
|
5932062e0c | |
|
|
0def898084 | |
|
|
08b192a6a5 | |
|
|
fd02dcffd1 |
|
|
@ -9,7 +9,7 @@
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity android:name=".FillGrid">
|
<activity android:name=".FillGrid" android:screenOrientation="portrait">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 09.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class Area {
|
||||||
|
public final int top;
|
||||||
|
public final int left;
|
||||||
|
public final int bottom;
|
||||||
|
public final int right;
|
||||||
|
|
||||||
|
public Area(int top, int left, int bottom, int right) {
|
||||||
|
this.top = top;
|
||||||
|
this.left = left;
|
||||||
|
this.bottom = bottom;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Area{" +
|
||||||
|
"top=" + top +
|
||||||
|
", left=" + left +
|
||||||
|
", bottom=" + bottom +
|
||||||
|
", right=" + right +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
Area area = (Area) o;
|
||||||
|
|
||||||
|
if (top != area.top) return false;
|
||||||
|
if (left != area.left) return false;
|
||||||
|
if (bottom != area.bottom) return false;
|
||||||
|
return right == area.right;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = top;
|
||||||
|
result = 31 * result + left;
|
||||||
|
result = 31 * result + bottom;
|
||||||
|
result = 31 * result + right;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.agp8x.android.games.fillgrid.data.Cell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 09.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface CellPaintProvider<C extends Cell> {
|
||||||
|
@NonNull
|
||||||
|
Paint getPaint(C cell);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.agp8x.android.games.fillgrid.data.Cell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 09.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CellPaintProviderBackground<C extends Cell> implements CellPaintProvider<C> {
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Paint getPaint(C cell) {
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setAlpha(128);
|
||||||
|
return paint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.agp8x.android.games.fillgrid.data.Cell;
|
||||||
|
import org.agp8x.android.games.fillgrid.data.GroupCell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 09.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CellPaintProviderDefault<C extends Cell> implements CellPaintProvider<C> {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Paint getPaint(C cell) {
|
||||||
|
Paint paint = new Paint();
|
||||||
|
if (cell instanceof GroupCell) {
|
||||||
|
GroupCell groupCell = (GroupCell) cell;
|
||||||
|
switch (groupCell.getGroup()) {
|
||||||
|
case 0:
|
||||||
|
paint.setColor(Color.RED);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
paint.setColor(Color.GREEN);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
paint.setColor(Color.BLUE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
paint.setColor(Color.MAGENTA);
|
||||||
|
}
|
||||||
|
paint.setAlpha(192);
|
||||||
|
}
|
||||||
|
return paint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,9 @@ package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Pair;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.agp8x.android.games.fillgrid.data.GridBlock;
|
import org.agp8x.android.games.fillgrid.data.GridBlock;
|
||||||
import org.agp8x.android.games.fillgrid.data.GridObject;
|
import org.agp8x.android.games.fillgrid.data.GridObject;
|
||||||
|
|
@ -15,8 +18,17 @@ public class FillGrid extends AppCompatActivity {
|
||||||
|
|
||||||
//GridObject<String> sgo = new GridBlock<>("asdf");
|
//GridObject<String> sgo = new GridBlock<>("asdf");
|
||||||
//GridObject<Asdf> ago = new GridBlock<>(Asdf.A);
|
//GridObject<Asdf> ago = new GridBlock<>(Asdf.A);
|
||||||
|
RelativeLayout layout = (RelativeLayout) findViewById(R.id.mainLayout);
|
||||||
|
|
||||||
|
/* Pair<Float, Float> fp = new Pair<>(1.0f, 2.0f);
|
||||||
|
Pair<Integer, Integer> ip = new Pair<>(1, 2);
|
||||||
|
ip = new Pair<>(fp.first.intValue(), fp.second.intValue());*/
|
||||||
|
FillGridView gridview = new FillGridView(this);
|
||||||
|
layout.addView(gridview);
|
||||||
|
gridview.setScoreView((TextView) findViewById(R.id.textView));
|
||||||
}
|
}
|
||||||
private enum Asdf{
|
|
||||||
A,B,C;
|
/* private enum Asdf {
|
||||||
}
|
A, B, C;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,320 @@
|
||||||
|
package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.widget.TextViewCompat;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.Pair;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.agp8x.android.games.fillgrid.data.GridBlock;
|
||||||
|
import org.agp8x.android.games.fillgrid.data.GridBoard;
|
||||||
|
import org.agp8x.android.games.fillgrid.data.GroupCell;
|
||||||
|
import org.agp8x.android.games.fillgrid.data.Offset;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.agp8x.android.games.fillgrid.Util.TAG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 07.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class FillGridView extends View {
|
||||||
|
protected Pair<Integer, Integer> contentSize = null;
|
||||||
|
protected Pair<Integer, Integer> spawnSize = null;
|
||||||
|
protected Area spawnBoundaries;
|
||||||
|
protected GridBoard<GridBlock<GroupCell>, GroupCell> board;
|
||||||
|
protected List<GridBlock<GroupCell>> blocks;
|
||||||
|
protected Map<Offset, GroupCell> background;
|
||||||
|
protected Map<Offset, GridBlock<GroupCell>> spawnGrid;
|
||||||
|
protected GroupGridPainter<GroupCell> painter;
|
||||||
|
protected GroupGridPainter<GroupCell> bgPainter;
|
||||||
|
private float divison;
|
||||||
|
private int spawnCount;
|
||||||
|
private SpawnPainterGroup<GridBlock<GroupCell>, GroupCell> spawnPainter;
|
||||||
|
private Dragging dragging;
|
||||||
|
private Offset dimensions;
|
||||||
|
private Map<GridBlock<GroupCell>, Pair<Integer, Integer>> spawnPositions;
|
||||||
|
private TextView scoreView;
|
||||||
|
private int score = 0;
|
||||||
|
|
||||||
|
public FillGridView(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(null, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FillGridView(Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init(attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FillGridView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
init(attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FillGridView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
init(attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init(AttributeSet attrs, int defStyleAttr) {
|
||||||
|
dimensions = new Offset(10, 10);
|
||||||
|
board = new GridBoard<>(dimensions);
|
||||||
|
|
||||||
|
blocks = new ArrayList<>();
|
||||||
|
|
||||||
|
background = new HashMap<>();
|
||||||
|
GroupCell bgCell = new GroupCell(-1);
|
||||||
|
for (int i = 0; i < dimensions.x; i++) {
|
||||||
|
for (int j = 0; j < dimensions.y; j++) {
|
||||||
|
background.put(new Offset(i, j), bgCell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spawnGrid = new HashMap<>();
|
||||||
|
|
||||||
|
CellPaintProvider<GroupCell> bgCpp = new CellPaintProviderBackground<>();
|
||||||
|
bgPainter = new GroupGridPainter<>(dimensions, bgCpp);
|
||||||
|
|
||||||
|
CellPaintProvider<GroupCell> cpp = new CellPaintProviderDefault<>();
|
||||||
|
painter = new GroupGridPainter<>(dimensions, cpp);
|
||||||
|
|
||||||
|
spawnPainter = new SpawnPainterGroup<>(new CellPaintProviderDefault<>());
|
||||||
|
|
||||||
|
// TODO: create configuration
|
||||||
|
spawnCount = 3;
|
||||||
|
|
||||||
|
divison = 0.5625f; // divides *HD-resolutions in a square and a non-square
|
||||||
|
|
||||||
|
GridBlock<GroupCell> block0 = new GridBlock<>();
|
||||||
|
block0.getObjects().put(new Offset(0, 0), new GroupCell(0));
|
||||||
|
blocks.add(block0);
|
||||||
|
block0 = new GridBlock<>();
|
||||||
|
block0.getObjects().put(new Offset(0, 0), new GroupCell(1));
|
||||||
|
block0.getObjects().put(new Offset(0, 1), new GroupCell(1));
|
||||||
|
blocks.add(block0);
|
||||||
|
block0 = new GridBlock<>();
|
||||||
|
block0.getObjects().put(new Offset(0, 0), new GroupCell(2));
|
||||||
|
block0.getObjects().put(new Offset(0, 1), new GroupCell(2));
|
||||||
|
block0.getObjects().put(new Offset(0, 2), new GroupCell(2));
|
||||||
|
blocks.add(block0);
|
||||||
|
|
||||||
|
board.drop(new Offset(4, 4), makeSquare());
|
||||||
|
board.drop(new Offset(4, 4), makeAngle());
|
||||||
|
//end TODO
|
||||||
|
|
||||||
|
populateSpawnArea();
|
||||||
|
setOnTouchListener(new FillGridTouchListener());
|
||||||
|
dragging = new Dragging();
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridBlock<GroupCell> makeSquare() {
|
||||||
|
GridBlock<GroupCell> grid = new GridBlock<>(new HashMap<>());
|
||||||
|
grid.getObjects().put(new Offset(0, 0), new GroupCell(0));
|
||||||
|
grid.getObjects().put(new Offset(0, 1), new GroupCell(0));
|
||||||
|
grid.getObjects().put(new Offset(1, 0), new GroupCell(0));
|
||||||
|
grid.getObjects().put(new Offset(1, 1), new GroupCell(0));
|
||||||
|
blocks.add(grid);
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridBlock<GroupCell> makeAngle() {
|
||||||
|
GridBlock<GroupCell> grid = new GridBlock<>(new HashMap<>());
|
||||||
|
grid.getObjects().put(new Offset(0, 2), new GroupCell(1));
|
||||||
|
grid.getObjects().put(new Offset(1, 2), new GroupCell(1));
|
||||||
|
grid.getObjects().put(new Offset(2, 2), new GroupCell(1));
|
||||||
|
grid.getObjects().put(new Offset(2, 1), new GroupCell(1));
|
||||||
|
grid.getObjects().put(new Offset(2, 0), new GroupCell(1));
|
||||||
|
blocks.add(grid);
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
if (contentSize == null || spawnSize == null) {
|
||||||
|
calculateAreaSizes();
|
||||||
|
System.out.println(contentSize + " :: " + spawnSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
bgPainter.draw(canvas, background, contentSize);
|
||||||
|
painter.draw(canvas, board.getGrid(), contentSize);
|
||||||
|
spawnPositions = spawnPainter.draw(canvas, spawnGrid, spawnBoundaries);
|
||||||
|
if (dragging.object != null) {
|
||||||
|
Log.d(TAG, "draw dragging");
|
||||||
|
spawnPainter.drawDragging(canvas, dragging.xy, dragging.object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateAreaSizes() {
|
||||||
|
int paddingTop = getPaddingTop();
|
||||||
|
int paddingBottom = getPaddingBottom();
|
||||||
|
int paddingLeft = getPaddingLeft();
|
||||||
|
int paddingRight = getPaddingRight();
|
||||||
|
int height = getHeight();
|
||||||
|
int width = getWidth();
|
||||||
|
int contentHeight = height - paddingTop - paddingBottom;
|
||||||
|
int contentWidth = width - paddingLeft - paddingRight;
|
||||||
|
int spawnHeight = contentHeight;
|
||||||
|
int spawnWidth = contentWidth;
|
||||||
|
if (contentHeight > contentWidth) {
|
||||||
|
spawnHeight = contentHeight - contentWidth;
|
||||||
|
contentHeight = contentWidth;
|
||||||
|
} else {
|
||||||
|
spawnWidth = contentWidth - contentHeight;
|
||||||
|
contentWidth = contentHeight;
|
||||||
|
}
|
||||||
|
contentSize = new Pair<>(contentHeight, contentWidth);
|
||||||
|
spawnSize = new Pair<>(spawnHeight, spawnWidth);
|
||||||
|
spawnBoundaries = new Area(contentHeight, paddingLeft, spawnHeight + contentHeight, spawnWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int divideSide(int sideLength) {
|
||||||
|
return (int) (sideLength * divison);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateSpawnArea() {
|
||||||
|
for (int i = 0; i < spawnCount; i++) {
|
||||||
|
spawnGrid.put(new Offset(i, 0), getRandomGroupCellGridBlock());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridBlock<GroupCell> getRandomGroupCellGridBlock() {
|
||||||
|
return (GridBlock<GroupCell>) blocks.get((int) (blocks.size() * Math.random())).duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Offset coordinate2offset(Pair<Float, Float> xy) {
|
||||||
|
return new Offset((int) ((xy.second / contentSize.first) * dimensions.y), (int) ((xy.first / contentSize.second) * dimensions.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Offset coordinate2spawnOffset(Pair<Float, Float> xy) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScoreView(TextView scoreView) {
|
||||||
|
this.scoreView = scoreView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FillGridTouchListener implements OnTouchListener {
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
System.out.println("EVENT!");
|
||||||
|
;
|
||||||
|
Log.d(TAG, "EVENT");
|
||||||
|
Pair<Float, Float> position = Util.event2pair(event);
|
||||||
|
boolean updated = false;
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
Log.d(TAG, "EVENT: AcitonDown");
|
||||||
|
if (Util.in(position, spawnBoundaries)) {
|
||||||
|
Log.d(TAG, " in boundary");
|
||||||
|
Log.d(TAG, "");
|
||||||
|
updated = handleStart(event, position);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
updated = handleMove(event, position);
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
//TODO: drop
|
||||||
|
updated = handleStop(event, position);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (updated) {
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleMove(MotionEvent event, Pair<Float, Float> position) {
|
||||||
|
boolean updated = false;
|
||||||
|
if (dragging.object != null) {
|
||||||
|
dragging.xy = position;
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleStart(MotionEvent event, Pair<Float, Float> position) {
|
||||||
|
if (dragging.object != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean updated = false;
|
||||||
|
Log.d(TAG, "no object dragged aleady");
|
||||||
|
// spawnPositions.entrySet().stream().filter(entry -> selects(position, entry.getValue())).findFirst().ifPresent(entry -> startDragging(entry, position));
|
||||||
|
for (Map.Entry<GridBlock<GroupCell>, Pair<Integer, Integer>> entry : spawnPositions.entrySet()) {
|
||||||
|
Log.d(TAG, "handleStart: "+position+"");
|
||||||
|
if (selects(position, entry.getValue())) {
|
||||||
|
Log.d(TAG, "handleStart: SELECTED");
|
||||||
|
Log.d(TAG, "now we drag");
|
||||||
|
dragging.object = entry.getKey();
|
||||||
|
dragging.xy = position;
|
||||||
|
updated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(spawnPositions);
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleStop(MotionEvent event, Pair<Float, Float> position) {
|
||||||
|
boolean updated = false;
|
||||||
|
if (dragging.object != null) {
|
||||||
|
if (board.drop(coordinate2offset(position), dragging.object)) {
|
||||||
|
System.out.println(spawnGrid);
|
||||||
|
System.out.println(dragging.object);
|
||||||
|
//Offset key = spawnGrid.entrySet().stream().filter(entry -> entry==dragging.object).findFirst().get().getKey();
|
||||||
|
Offset key=null;
|
||||||
|
for (Map.Entry<Offset, GridBlock<GroupCell>> entry : spawnGrid.entrySet()) {
|
||||||
|
if (entry.getValue() == dragging.object){
|
||||||
|
key= entry.getKey();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spawnGrid.remove(key);
|
||||||
|
spawnPositions.remove(dragging.object);
|
||||||
|
}
|
||||||
|
dragging.object = null;
|
||||||
|
if (spawnGrid.isEmpty()){
|
||||||
|
populateSpawnArea();
|
||||||
|
}
|
||||||
|
score += board.collapseFilledLines();
|
||||||
|
if (scoreView != null) {
|
||||||
|
scoreView.setText(String.valueOf(score));
|
||||||
|
}
|
||||||
|
board.removeCollapsed();
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* private void startDragging(Map.Entry<GridBlock<GroupCell>, Pair<Integer, Integer>> entry, Pair<Float, Float> position) {
|
||||||
|
Log.d(TAG, "now we drag");
|
||||||
|
dragging.object = entry.getKey();
|
||||||
|
dragging.xy = position;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
private boolean selects(Pair<Float, Float> eventPos, Pair<Integer, Integer> spawnPos) {
|
||||||
|
float xdiff = Math.abs(eventPos.first - spawnPos.first);
|
||||||
|
float ydiff = Math.abs(eventPos.second - spawnPos.second);
|
||||||
|
System.out.println("diffs: " + xdiff + " --- " + ydiff);
|
||||||
|
return xdiff < 40 && ydiff < 40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Dragging {
|
||||||
|
GridBlock<GroupCell> object;
|
||||||
|
Pair<Float, Float> xy;
|
||||||
|
Offset key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import org.agp8x.android.games.fillgrid.data.Cell;
|
||||||
|
import org.agp8x.android.games.fillgrid.data.Offset;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 07.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface GridPainter<C extends Cell> {
|
||||||
|
|
||||||
|
void draw(Canvas canvas, Map<Offset, C> cells, Pair<Integer,Integer> realDimensions);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import org.agp8x.android.games.fillgrid.data.GroupCell;
|
||||||
|
import org.agp8x.android.games.fillgrid.data.Offset;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 07.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class GroupGridPainter<C extends GroupCell> implements GridPainter<C> {
|
||||||
|
private Offset dimensions;
|
||||||
|
private CellPaintProvider<C> styleInfo;
|
||||||
|
private int margin;
|
||||||
|
private int radius;
|
||||||
|
|
||||||
|
public GroupGridPainter(Offset dimensions, CellPaintProvider<C> styleInfo) {
|
||||||
|
this.dimensions = dimensions;
|
||||||
|
this.styleInfo = styleInfo;
|
||||||
|
radius = 30;//TODO dynamic radius to fill area
|
||||||
|
margin = radius + radius / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Map<Offset, C> cells, Pair<Integer, Integer> realDimensions) {
|
||||||
|
cells.forEach((offset, groupCell) -> drawCell(canvas, offset, groupCell, realDimensions));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawCell(Canvas canvas, Offset offset, C cell, Pair<Integer, Integer> realDimensions) {
|
||||||
|
Pair<Float, Float> origin = new Pair<>((offset.x / (float) dimensions.x) * realDimensions.first, (offset.y / (float) dimensions.y) * realDimensions.second);
|
||||||
|
canvas.drawCircle(origin.second + margin, origin.first + margin, radius, styleInfo.getPaint(cell));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import org.agp8x.android.games.fillgrid.data.Cell;
|
||||||
|
import org.agp8x.android.games.fillgrid.data.GridObject;
|
||||||
|
import org.agp8x.android.games.fillgrid.data.Offset;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 09.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface SpawnPainter<G extends GridObject<C>, C extends Cell> {
|
||||||
|
Map<G, Pair<Integer, Integer>> draw(Canvas canvas, Map<Offset, G> spawnGrid, Area spawnSize);
|
||||||
|
|
||||||
|
void drawDragging(Canvas canvas, Pair<Float, Float> xy, G object);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import org.agp8x.android.games.fillgrid.data.GridObject;
|
||||||
|
import org.agp8x.android.games.fillgrid.data.GroupCell;
|
||||||
|
import org.agp8x.android.games.fillgrid.data.Offset;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 09.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SpawnPainterGroup<G extends GridObject<C>, C extends GroupCell> implements SpawnPainter<G, C> {
|
||||||
|
private int radius;
|
||||||
|
private int margin;
|
||||||
|
private CellPaintProvider<C> styleInfo;
|
||||||
|
private int diameter;
|
||||||
|
private Map<G, Pair<Integer, Integer>> positions;
|
||||||
|
|
||||||
|
public SpawnPainterGroup(CellPaintProvider<C> styleInfo) {
|
||||||
|
this.styleInfo = styleInfo;
|
||||||
|
radius = 30;//TODO dynamic radius to fill area
|
||||||
|
margin = radius * 3 + radius / 4;
|
||||||
|
diameter = radius * 2;
|
||||||
|
positions = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<G, Pair<Integer, Integer>> draw(Canvas canvas, Map<Offset, G> spawnGrid, Area spawnSize) {
|
||||||
|
int count = spawnGrid.size();
|
||||||
|
if (positions.isEmpty()) {
|
||||||
|
for (Offset offset : spawnGrid.keySet()) {
|
||||||
|
G obj = spawnGrid.get(offset);
|
||||||
|
positions.put(obj, getPosition(offset, obj, count, spawnSize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//spawnGrid.forEach((offset, groupCellGridBlock) -> drawBlock(canvas, groupCellGridBlock));
|
||||||
|
for (Offset offset : spawnGrid.keySet()) {
|
||||||
|
drawBlock(canvas,spawnGrid.get(offset));
|
||||||
|
}
|
||||||
|
return positions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawDragging(Canvas canvas, Pair<Float, Float> xy, G object) {
|
||||||
|
object.getObjects().forEach((offset, c) -> drawCellDragging(canvas, xy, offset, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<Integer, Integer> getPosition(Offset offset, G obj, int count, Area spawnSize) {
|
||||||
|
return new Pair<>(((offset.x / count) * spawnSize.right) + margin * (offset.x+1), ((offset.y / count) * spawnSize.bottom) + margin + spawnSize.top);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawCellDragging(Canvas canvas, Pair<Float, Float> xy, Offset offset, C c) {
|
||||||
|
canvas.drawCircle(xy.first + diameter * offset.y, xy.second + diameter * offset.x, radius, styleInfo.getPaint(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawBlock(Canvas canvas, G groupCellGridBlock) {
|
||||||
|
Pair<Integer, Integer> origin = positions.get(groupCellGridBlock);
|
||||||
|
groupCellGridBlock.getObjects().forEach((offset1, groupCell) -> drawCell(canvas, origin, offset1, groupCell));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawCell(Canvas canvas, Pair<Integer, Integer> origin, Offset offset1, C cell) {
|
||||||
|
canvas.drawCircle(
|
||||||
|
origin.first + getCx(offset1),
|
||||||
|
origin.second + getCy(offset1),
|
||||||
|
radius, styleInfo.getPaint(cell));
|
||||||
|
}
|
||||||
|
|
||||||
|
private float getCx(Offset offset1) {
|
||||||
|
return offset1.y * diameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float getCy(Offset offset1) {
|
||||||
|
return offset1.x * diameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package org.agp8x.android.games.fillgrid;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.Pair;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 09.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Util {
|
||||||
|
public static final String TAG = "FillGrid";
|
||||||
|
|
||||||
|
public static Pair<Float, Float> event2pair(MotionEvent event) {
|
||||||
|
return new Pair<>(event.getX(), event.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean in(Pair<Float, Float> probe, Area area) {
|
||||||
|
Log.d(TAG,"probe: "+probe+" ;area: "+area);
|
||||||
|
Log.d(TAG, "("+(area.top < probe.second)+" && "+(probe.second < area.bottom)+") && ("+(area.left < probe.first) +" && "+ (probe.first < area.right)+")");
|
||||||
|
boolean contained = (area.top < probe.second && probe.second < area.bottom) && (area.left < probe.first && probe.first < area.right);
|
||||||
|
return contained;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,4 +8,5 @@ public interface Cell {
|
||||||
String getTableSymbol();
|
String getTableSymbol();
|
||||||
|
|
||||||
void markCollapsed();
|
void markCollapsed();
|
||||||
|
boolean isCollapsed();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
package org.agp8x.android.games.fillgrid.data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by clemensk on 29.03.17.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class Coordinate {
|
|
||||||
private double x;
|
|
||||||
private double y;
|
|
||||||
|
|
||||||
public Coordinate() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Coordinate(double x, double y) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getX() {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setX(double x) {
|
|
||||||
this.x = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getY() {
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setY(double y) {
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
Coordinate that = (Coordinate) o;
|
|
||||||
|
|
||||||
if (Double.compare(that.x, x) != 0) return false;
|
|
||||||
return Double.compare(that.y, y) == 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result;
|
|
||||||
long temp;
|
|
||||||
temp = Double.doubleToLongBits(x);
|
|
||||||
result = (int) (temp ^ (temp >>> 32));
|
|
||||||
temp = Double.doubleToLongBits(y);
|
|
||||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,6 +10,10 @@ import java.util.Map;
|
||||||
public class GridBlock<C extends Cell> implements GridObject<C> {
|
public class GridBlock<C extends Cell> implements GridObject<C> {
|
||||||
private final Map<Offset, C> content;
|
private final Map<Offset, C> content;
|
||||||
|
|
||||||
|
public GridBlock() {
|
||||||
|
content = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
public GridBlock(Map<Offset, C> content) {
|
public GridBlock(Map<Offset, C> content) {
|
||||||
this.content = new HashMap<>(content);
|
this.content = new HashMap<>(content);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a GridBoard in its entirety, i.e. Top level object
|
* Represents a GridBoard in its entirety, i.e. Top level object
|
||||||
|
|
@ -17,8 +18,12 @@ public class GridBoard<G extends GridObject<C>, C extends Cell> implements Grid<
|
||||||
private final Offset dimensions;
|
private final Offset dimensions;
|
||||||
|
|
||||||
public GridBoard(int heigth, int width) {
|
public GridBoard(int heigth, int width) {
|
||||||
|
this(new Offset(width, heigth));
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridBoard(Offset dimensions) {
|
||||||
this.contents = new HashMap<>();
|
this.contents = new HashMap<>();
|
||||||
dimensions = new Offset(width, heigth);
|
this.dimensions = dimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -45,6 +50,12 @@ public class GridBoard<G extends GridObject<C>, C extends Cell> implements Grid<
|
||||||
contents.clear();
|
contents.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeCollapsed() {
|
||||||
|
List<Offset> removals = contents.entrySet().stream().filter(offsetCEntry -> offsetCEntry.getValue().isCollapsed()).map(Map.Entry::getKey).collect(Collectors.toList());
|
||||||
|
removals.forEach(contents::remove);
|
||||||
|
removals.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find lines with all cells filled and mark them as collapsed
|
* Find lines with all cells filled and mark them as collapsed
|
||||||
*
|
*
|
||||||
|
|
@ -53,7 +64,9 @@ public class GridBoard<G extends GridObject<C>, C extends Cell> implements Grid<
|
||||||
public int collapseFilledLines() {
|
public int collapseFilledLines() {
|
||||||
List<Offset> deletionQueue = findFullLines();
|
List<Offset> deletionQueue = findFullLines();
|
||||||
deletionQueue.stream().map(contents::get).forEach(Cell::markCollapsed);
|
deletionQueue.stream().map(contents::get).forEach(Cell::markCollapsed);
|
||||||
return deletionQueue.size();
|
int count = deletionQueue.size();
|
||||||
|
deletionQueue.clear();
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Offset> findFullLines() {
|
public List<Offset> findFullLines() {
|
||||||
|
|
@ -126,7 +139,7 @@ public class GridBoard<G extends GridObject<C>, C extends Cell> implements Grid<
|
||||||
*/
|
*/
|
||||||
private boolean isSettable(Offset origin, Offset offset) {
|
private boolean isSettable(Offset origin, Offset offset) {
|
||||||
Offset xy = Offset.add(origin, offset);
|
Offset xy = Offset.add(origin, offset);
|
||||||
if ((xy.x < 0 || xy.x > dimensions.x) || (xy.y < 0 || xy.y > dimensions.y)) {
|
if ((xy.x < 0 || xy.x >= dimensions.x) || (xy.y < 0 || xy.y >= dimensions.y)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
C obj1 = contents.get(xy);
|
C obj1 = contents.get(xy);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package org.agp8x.android.games.fillgrid.data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by clemensk on 07.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class GroupCell implements Cell {
|
||||||
|
private int group;
|
||||||
|
private boolean collapsed = false;
|
||||||
|
private boolean collapsionMark = false;
|
||||||
|
|
||||||
|
public GroupCell(int group) {
|
||||||
|
this.group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGroup() {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCollapsionMark() {
|
||||||
|
return collapsionMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTableSymbol() {
|
||||||
|
return "" + group;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markCollapsed() {
|
||||||
|
collapsionMark = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCollapsed() {
|
||||||
|
return collapsionMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ package org.agp8x.android.games.fillgrid.data;
|
||||||
* Created by clemensk on 29.03.17.
|
* Created by clemensk on 29.03.17.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Offset {
|
public class Offset {
|
||||||
public final int x;
|
public final int x;
|
||||||
public final int y;
|
public final int y;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,4 +35,9 @@ public class StringCell implements Cell {
|
||||||
public void markCollapsed() {
|
public void markCollapsed() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCollapsed() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,21 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout
|
<RelativeLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="org.agp8x.android.games.fillgrid.FillGrid">
|
tools:context="org.agp8x.android.games.fillgrid.FillGrid"
|
||||||
|
android:id="@+id/mainLayout">
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/textView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Hello World!"
|
android:layout_marginBottom="15dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:text="TextView"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
android:layout_alignParentBottom="true"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
android:layout_alignParentEnd="true"
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
android:layout_marginEnd="26dp"/>
|
||||||
|
</RelativeLayout>
|
||||||
</android.support.constraint.ConstraintLayout>
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ buildscript {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.3.0'
|
classpath 'com.android.tools.build:gradle:2.3.1'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue