243 lines
9.5 KiB
Java
243 lines
9.5 KiB
Java
package de.craftix.chess;
|
|
|
|
import de.craftix.engine.GameEngine;
|
|
import de.craftix.engine.InputManager;
|
|
import de.craftix.engine.SpriteMap;
|
|
import de.craftix.engine.objects.GameObject;
|
|
import de.craftix.engine.objects.Texture;
|
|
import de.craftix.engine.var.Inputs;
|
|
import de.craftix.engine.var.Vector2;
|
|
|
|
import java.awt.*;
|
|
import java.awt.event.MouseEvent;
|
|
import java.awt.geom.Line2D;
|
|
import java.util.ArrayList;
|
|
|
|
public class Main extends GameEngine {
|
|
static SpriteMap figures = new SpriteMap(6, loadImage("figures.png"), 95, 95);
|
|
static ArrayList<Figure> player1 = new ArrayList<>();
|
|
static ArrayList<Figure> player2 = new ArrayList<>();
|
|
static Texture[][] grid = new Texture[8][8];
|
|
static Color c1 = Color.LIGHT_GRAY;
|
|
static Color c2 = Color.DARK_GRAY;
|
|
static boolean player = true;
|
|
|
|
public static void main(String[] args) {
|
|
setup(800, 800, "Chess", 1, new Main());
|
|
setInputs(new Input());
|
|
showFrames(true);
|
|
setBackground();
|
|
setFigures();
|
|
startGame();
|
|
}
|
|
|
|
static void setBackground() {
|
|
int[] pos = new int[]{ 350, 250, 150, 50, -50, -150, -250, -350 };
|
|
Color[][] colors = new Color[][] {
|
|
{c1, c2},
|
|
{c2, c1}
|
|
};
|
|
for (int y = 0; y < grid.length; y++) {
|
|
for (int x = 0; x < grid.length; x++) {
|
|
grid[x][y] = new Texture(colors[y % 2][x % 2], new Vector2(pos[x], pos[y]), new Vector2(100, 100));
|
|
getScene().addTexture(grid[x][y]);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void setFigures() {
|
|
Types[] order = new Types[]{ Types.ROOK, Types.BISHOP, Types.KNIGHT, Types.KING, Types.QUEEN, Types.KNIGHT, Types.BISHOP, Types.ROOK };
|
|
//Player 1
|
|
for (int x = 0; x < 8; x++) player1.add(new Figure(x, 7, 1, order[x]));
|
|
for (int x = 0; x < 8; x++) player1.add(new Figure(x, 6, 1, Types.PAWN));
|
|
|
|
//Player 2
|
|
for (int x = 0; x < 8; x++) player2.add(new Figure(x, 0, 2, order[x]));
|
|
for (int x = 0; x < 8; x++) player2.add(new Figure(x, 1, 2, Types.PAWN));
|
|
|
|
for (Figure p1 : player1) getScene().addGameObject(p1);
|
|
for (Figure p2 : player2) getScene().addGameObject(p2);
|
|
}
|
|
|
|
enum Types {
|
|
KING(0),
|
|
QUEEN(1),
|
|
BISHOP(2),
|
|
KNIGHT(3),
|
|
ROOK(4),
|
|
PAWN(5);
|
|
|
|
private final int id;
|
|
Types(int id) { this.id = id; }
|
|
public int getID() { return id; }
|
|
}
|
|
|
|
static class Figure extends GameObject {
|
|
private final int player;
|
|
private final Types type;
|
|
|
|
public Figure(int x, int y, int player, Types type) {
|
|
super(grid[x][y].getPosition().copy(), new Vector2(95, 95), figures.getTexture(type.getID(), player - 1));
|
|
this.player = player;
|
|
this.type = type;
|
|
}
|
|
|
|
public int getPlayer() { return player; }
|
|
public Types getType() { return type; }
|
|
}
|
|
|
|
static class Input extends Inputs {
|
|
private Figure moved;
|
|
private Vector2 started;
|
|
|
|
@Override
|
|
public void mouseDragged(MouseEvent e) {
|
|
if (moved == null) {
|
|
if (player) {
|
|
for (Figure p1 : player1) {
|
|
if (p1.getScreenRect().contains(e.getX(), e.getY())) moved = p1;
|
|
}
|
|
}else {
|
|
for (Figure p2 : player2) {
|
|
if (p2.getScreenRect().contains(e.getX(), e.getY())) moved = p2;
|
|
}
|
|
}
|
|
if (moved != null) {
|
|
moved.setLayer(getLayer("Foreground"));
|
|
started = moved.getPosition().copy();
|
|
}
|
|
}
|
|
else moved.setPosition(InputManager.getMousePos());
|
|
}
|
|
|
|
@Override
|
|
public void mouseReleased(MouseEvent e) {
|
|
if (moved == null) return;
|
|
moved.setLayer(getLayer("Default"));
|
|
for (Texture[] textures : grid) {
|
|
for (int y = 0; y < grid.length; y++) {
|
|
if (textures[y].getScreenRect().contains(e.getX(), e.getY())) {
|
|
Figure found = null;
|
|
if (!checkMove(started.copy(), textures[y].getPosition().copy(), moved)) moved.setPosition(started);
|
|
else {
|
|
moved.setPosition(textures[y].getPosition().copy());
|
|
for (Figure p1 : player1) {
|
|
if (p1.equals(moved)) continue;
|
|
if (p1.getPosition().equals(moved.getPosition())) {
|
|
if (moved.getPlayer() == 1) moved.setPosition(started);
|
|
else found = p1;
|
|
}
|
|
}
|
|
for (Figure p2 : player2) {
|
|
if (p2.equals(moved)) continue;
|
|
if (p2.getPosition().equals(moved.getPosition())) {
|
|
if (moved.getPlayer() == 2) moved.setPosition(started);
|
|
else found = p2;
|
|
}
|
|
}
|
|
if (found != null) {
|
|
if (found.getType().equals(Types.KING)) stopGame();
|
|
player1.remove(found);
|
|
player2.remove(found);
|
|
getScene().removeGameObject(found);
|
|
}
|
|
player = !player;
|
|
}
|
|
moved = null;
|
|
started = null;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (moved == null) return;
|
|
moved.setPosition(started);
|
|
moved.setLayer(getLayer("Default"));
|
|
moved = null;
|
|
started = null;
|
|
}
|
|
}
|
|
|
|
static boolean checkMove(Vector2 original, Vector2 now, Figure figure) {
|
|
Vector2 offset = now.copy().subtract(original).divide(100, 100);
|
|
if (offset.x == 0 && offset.y == 0) return false;
|
|
if (isMateAt(figure.getPlayer(), now)) return false;
|
|
if (!checkLine(original, now) && figure.getType() != Types.KNIGHT) return false;
|
|
switch (figure.getType()) {
|
|
case KING:
|
|
return !((offset.x > 1) || (offset.y > 1));
|
|
case QUEEN:
|
|
return ((offset.x == offset.y || offset.x == -offset.y) || (offset.x == 0 || offset.y == 0));
|
|
case BISHOP:
|
|
return (offset.x == offset.y || offset.x == -offset.y);
|
|
case KNIGHT:
|
|
if ((offset.y == 2 || offset.y == -2) && (offset.x == 1 || offset.x == -1)) return true;
|
|
else if ((offset.y == 1 || offset.y == -1) && (offset.x == 2 || offset.x == -2)) return true;
|
|
break;
|
|
case ROOK:
|
|
return (offset.x == 0 || offset.y == 0);
|
|
case PAWN:
|
|
Vector2 yet = original.copy().add(offset.copy().multiply(100, 100));
|
|
if (offset.x == 0 && (isEnemyAt(figure.getPlayer(), yet) || isMateAt(figure.getPlayer(), yet))) return false;
|
|
if (figure.getPlayer() == 1) {
|
|
if (offset.y < 0) return false;
|
|
if ((offset.y == 2 && offset.x == 0) && original.y == -250) return true;
|
|
}else {
|
|
if (offset.y > 0) return false;
|
|
if ((offset.y == -2 && offset.x == 0) && original.y == 250) return true;
|
|
}
|
|
if ((offset.y == 1 || offset.y == -1) && offset.x == 0) return true;
|
|
if (isEnemyAt(figure.getPlayer(), yet) && offset.y != 0) return true;
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static boolean isEnemyAt(int player, Vector2 pos) {
|
|
if (player == 1) {
|
|
for (Figure other : player2) {
|
|
if (other.getPosition().equals(pos)) return true;
|
|
}
|
|
}else {
|
|
for (Figure other : player1) {
|
|
if (other.getPosition().equals(pos)) return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static boolean isMateAt(int player, Vector2 pos) {
|
|
if (player == 2) {
|
|
for (Figure other : player2) {
|
|
if (other.getPosition().equals(pos)) return true;
|
|
}
|
|
}else {
|
|
for (Figure other : player1) {
|
|
if (other.getPosition().equals(pos)) return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static boolean checkLine(Vector2 start, Vector2 end) {
|
|
Rectangle s = new Rectangle(start.convert().x, start.convert().y, 90, 90);
|
|
Rectangle e = new Rectangle(end.convert().x, end.convert().y, 90, 90);
|
|
Line2D line = new Line2D.Float(start.x, start.y, end.x, end.y);
|
|
for (Figure p1 : player1) {
|
|
if (s.contains(p1.getPosition().convert()) || e.contains(p1.getPosition().convert())) continue;
|
|
GameObject temp = p1.copy();
|
|
temp.setSize(5, 5);
|
|
Rectangle other = temp.getRectangle();
|
|
if (line.intersects(other)) return false;
|
|
}
|
|
for (Figure p2 : player2) {
|
|
if (s.contains(p2.getPosition().convert()) || e.contains(p2.getPosition().convert())) continue;
|
|
GameObject temp = p2.copy();
|
|
temp.setSize(5, 5);
|
|
Rectangle other = temp.getRectangle();
|
|
if (line.intersects(other)) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
}
|