Code cleanup in Window class and improved comments in other classes.
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
### **7not7**
|
||||
### *A 7x7 clone written in java*
|
||||
|
||||
This page should be viewed on [Github](https://github.com/id101010/7not7)
|
||||
|
||||
---
|
||||
|
||||
### Summary
|
||||
|
||||
7x7 is a concentration game which challenges you to connect 4 or more blocks of the same color on the game field.
|
||||
To make things harder each round n blocks of random colors get thrown upon the field and the number n increases with each level.
|
||||
You can choose the field size to be eighter 7x7, 8x8, 9x9 or 10x10.
|
||||
You can choose the field size to be either 7x7, 8x8, 9x9 or 10x10.
|
||||
|
||||

|
||||
|
||||
@@ -15,6 +17,7 @@ You can choose the field size to be eighter 7x7, 8x8, 9x9 or 10x10.
|
||||
|
||||
The goal is to clear as much lines as possible by stacking blocks of the same color in any direction.
|
||||
So you can eighter build up blocks vertically, horizontally or diagonal.
|
||||
To move blocks click on the block you want to move, hold the mouse and release it on the target position.
|
||||
|
||||
### Tools and how to get them
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ public class FieldCanvas extends JPanel{
|
||||
static final int borderTop = 5;
|
||||
static final int borderBottom = 5;
|
||||
|
||||
//Colors to use to paint the blocks. Chosen with a color scheme designer
|
||||
public static final Color[] colors = {
|
||||
new Color(0xD66436),
|
||||
new Color(0x486F70),
|
||||
@@ -34,11 +35,11 @@ public class FieldCanvas extends JPanel{
|
||||
|
||||
|
||||
private Game game;
|
||||
private Point src;
|
||||
private Point dst;
|
||||
private List<Point> path;
|
||||
private List<Point> blockedFields;
|
||||
private boolean freeMoveMode = false;
|
||||
private Point src; //Position of the Block that the user wants to move (can be null)
|
||||
private Point dst; //Destination Position (can be null)
|
||||
private List<Point> path; //Path that visualizes src->dst (can be null)
|
||||
private List<Point> blockedFields; //Fields that should be marked as blocked (can be null)
|
||||
private boolean freeMoveMode = false; //Whether or not we're in free moving mode
|
||||
|
||||
/**
|
||||
* Constructor of FieldCanvas
|
||||
@@ -53,9 +54,9 @@ public class FieldCanvas extends JPanel{
|
||||
super.mousePressed(e);
|
||||
|
||||
Point p = FieldCanvas.this.getClickPoint(e.getPoint());
|
||||
if(p==null || game.getField()[p.x][p.y]==0) { //invalid click
|
||||
if(p==null || game.getField()[p.x][p.y]==0) { //invalid click (outside of bounds or on empty position)
|
||||
src = null;
|
||||
} else {
|
||||
} else { //valid click
|
||||
src = p;
|
||||
if(freeMoveMode) {
|
||||
blockedFields = game.getReachablePoints(src);
|
||||
@@ -69,24 +70,26 @@ public class FieldCanvas extends JPanel{
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
super.mouseDragged(e);
|
||||
if(src!=null) {
|
||||
if(src!=null) { //we have a valid point that the users wants to move
|
||||
Point lastDst = dst;
|
||||
dst = FieldCanvas.this.getClickPoint(e.getPoint());
|
||||
if(lastDst!=dst && dst!=null) { //hovered field changed
|
||||
if(freeMoveMode) {
|
||||
//Check if the target position is empty and we could not move the block there in normal mode
|
||||
if(!game.canMove(src, dst) && game.getField()[dst.x][dst.y]==0) {
|
||||
//Create fake path with only src and dst
|
||||
path = new ArrayList<Point>();
|
||||
path.add(src);
|
||||
path.add(dst);
|
||||
} else {
|
||||
path= null;
|
||||
}
|
||||
} else {
|
||||
path= game.getPath(src, dst);
|
||||
} else { //not in freemove mode
|
||||
path= game.getPath(src, dst); //calculate path from src to dst (pathfinding)
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}else {
|
||||
} else { //no valid src
|
||||
dst = null;
|
||||
path = null;
|
||||
}
|
||||
@@ -96,13 +99,13 @@ public class FieldCanvas extends JPanel{
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
super.mouseReleased(e);
|
||||
dst = FieldCanvas.this.getClickPoint(e.getPoint());
|
||||
path = null;
|
||||
path = null; //do no longer paint path
|
||||
if(freeMoveMode) {
|
||||
if(!game.canMove(src, dst)) {
|
||||
if(!game.canMove(src, dst)) { //if we couldn't move there in normal mode
|
||||
game.doFreeMove(src, dst);
|
||||
}
|
||||
} else {
|
||||
if(dst != null && src!=null && !src.equals(dst)) {
|
||||
} else { //not in freemove mode
|
||||
if(dst != null && src!=null && !src.equals(dst)) { //src and dst are valid
|
||||
System.out.println("Moving from "+src.toString()+ " to "+dst.toString());
|
||||
game.doMove(src, dst);
|
||||
}
|
||||
@@ -147,11 +150,11 @@ public class FieldCanvas extends JPanel{
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the position in which a click event has happened.
|
||||
* Maps a mouse position to game coordinates
|
||||
*
|
||||
* @author timo
|
||||
* @param globalPos
|
||||
* @return Position of clickevent
|
||||
* @param globalPos Position of clickevent
|
||||
* @return point in game coordinates
|
||||
*/
|
||||
private Point getClickPoint(Point globalPos) {
|
||||
int total = Math.min(this.getHeight()-borderTop-borderBottom,FieldCanvas.this.getWidth()-borderLeft-borderRight);
|
||||
@@ -169,6 +172,8 @@ public class FieldCanvas extends JPanel{
|
||||
*/
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
if(game==null) return;
|
||||
|
||||
//Draw field (background and lines)
|
||||
if(freeMoveMode) {
|
||||
@@ -180,21 +185,20 @@ public class FieldCanvas extends JPanel{
|
||||
g.translate(borderLeft, borderTop);
|
||||
int total = Math.min(this.getHeight()-borderTop-borderBottom,FieldCanvas.this.getWidth()-borderLeft-borderRight);
|
||||
int space = total/game.getSize();
|
||||
total = space*game.getSize();
|
||||
|
||||
g.setClip(0, 0, total-4,total-4);
|
||||
g.fillRect(0, 0, total-4,total-4);
|
||||
g.setClip(0, 0, total+1,total+1);
|
||||
g.fillRect(0, 0, total,total);
|
||||
|
||||
g.setColor(Color.white);
|
||||
|
||||
for(int i=0; i<=game.getSize(); i++) {
|
||||
g.drawLine(0,i*space,total-2,i*space);
|
||||
g.drawLine(i*space,0,i*space,total-2);
|
||||
g.drawLine(0,i*space,total,i*space);
|
||||
g.drawLine(i*space,0,i*space,total);
|
||||
}
|
||||
|
||||
if(game==null) return;
|
||||
|
||||
//Draw blocks
|
||||
|
||||
//Draw blocks
|
||||
for(int x=0; x<game.getSize(); x++) {
|
||||
for(int y=0; y<game.getSize(); y++) {
|
||||
int colorCode = game.getField()[x][y];
|
||||
@@ -205,8 +209,7 @@ public class FieldCanvas extends JPanel{
|
||||
}
|
||||
}
|
||||
|
||||
//Draw blocked fields
|
||||
|
||||
//Draw blocked fields
|
||||
if(blockedFields!=null) {
|
||||
g.setColor(Color.darkGray);
|
||||
for(int i=0; i<blockedFields.size(); i++) {
|
||||
|
||||
@@ -16,7 +16,7 @@ public class Game {
|
||||
*
|
||||
*/
|
||||
public interface UpdateListener {
|
||||
public void gameUpdate();
|
||||
public void gameUpdated();
|
||||
}
|
||||
|
||||
// Constants
|
||||
@@ -173,7 +173,7 @@ public class Game {
|
||||
*/
|
||||
private void emitUpdateEvent(){
|
||||
for(UpdateListener e: updateListeners) {
|
||||
e.gameUpdate();
|
||||
e.gameUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,6 +326,8 @@ public class Game {
|
||||
|
||||
// Populate game field
|
||||
this.populateField();
|
||||
|
||||
emitUpdateEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,15 @@ import java.util.List;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class NextMovesCanvas extends JPanel {
|
||||
/**
|
||||
* Class which renders the Blocks that will be placed next on the field
|
||||
* @author timo
|
||||
*
|
||||
*/
|
||||
public class NextMovesCanvas extends JPanel implements Game.UpdateListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Game game;
|
||||
|
||||
static final int borderLeft = 1;
|
||||
@@ -16,19 +24,17 @@ public class NextMovesCanvas extends JPanel {
|
||||
|
||||
public NextMovesCanvas(Game g) {
|
||||
this.game = g;
|
||||
g.addUpdateListener(new Game.UpdateListener() {
|
||||
@Override
|
||||
public void gameUpdate() {
|
||||
NextMovesCanvas.this.repaint();
|
||||
}
|
||||
});
|
||||
g.addUpdateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gameUpdated() {
|
||||
NextMovesCanvas.this.repaint();
|
||||
}
|
||||
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
|
||||
g.setColor(Color.lightGray);
|
||||
int height = getHeight() - borderTop-borderBottom;
|
||||
|
||||
|
||||
@@ -2,25 +2,28 @@ package ch.bfh.sevennotseven;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.HeadlessException;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
* Window class, places gui elements and listeners.
|
||||
* Window class, contains the welcome screen and the game itself
|
||||
*
|
||||
* @author timo
|
||||
*/
|
||||
public class Window extends JFrame implements ActionListener{
|
||||
public class Window extends JFrame implements ActionListener, Game.UpdateListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Game game;
|
||||
@@ -29,6 +32,7 @@ public class Window extends JFrame implements ActionListener{
|
||||
|
||||
private JButton buttonUndo;
|
||||
private JButton buttonFreeMove;
|
||||
private JButton buttonReset;
|
||||
private JLabel labelScore;
|
||||
private JLabel labelLinesLeft;
|
||||
private JLabel labelLevel;
|
||||
@@ -43,16 +47,27 @@ public class Window extends JFrame implements ActionListener{
|
||||
*/
|
||||
public Window(String title) throws HeadlessException {
|
||||
super(title);
|
||||
|
||||
this.addWindowListener(new WindowAdapter(){
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e){
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
game = new Game();
|
||||
game.addUpdateListener(this); //register for game updates
|
||||
|
||||
initMainLayout();
|
||||
}
|
||||
|
||||
private void initMainLayout() {
|
||||
mainPanel = new JPanel();
|
||||
cardLayout = new CardLayout();
|
||||
mainPanel.setLayout(cardLayout);
|
||||
initWelcomeLayout();
|
||||
initGameLayout();
|
||||
this.setContentPane(mainPanel);
|
||||
this.setSize(800,600);
|
||||
this.setVisible(true);
|
||||
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
}
|
||||
|
||||
private void initGameLayout() {
|
||||
|
||||
moves = new NextMovesCanvas(game);
|
||||
field = new FieldCanvas(game);
|
||||
|
||||
@@ -62,16 +77,23 @@ public class Window extends JFrame implements ActionListener{
|
||||
buttonFreeMove.setEnabled(false);
|
||||
buttonFreeMove.addActionListener(this);
|
||||
buttonFreeMove.setActionCommand("freemove");
|
||||
|
||||
buttonUndo = new JButton("Undo (0)");
|
||||
buttonUndo.setEnabled(false);
|
||||
buttonUndo.addActionListener(this);
|
||||
buttonUndo.setActionCommand("undo");
|
||||
|
||||
buttonReset = new JButton("Reset");
|
||||
buttonReset.addActionListener(this);
|
||||
buttonReset.setActionCommand("reset");
|
||||
|
||||
|
||||
labelScore= new JLabel("Score: 0");
|
||||
labelLinesLeft = new JLabel("Lines Left: 40");
|
||||
labelLevel = new JLabel("Level: 1");
|
||||
|
||||
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
|
||||
topPanel.add(buttonReset);
|
||||
topPanel.add(buttonFreeMove);
|
||||
topPanel.add(buttonUndo);
|
||||
topPanel.add(labelScore);
|
||||
@@ -84,50 +106,43 @@ public class Window extends JFrame implements ActionListener{
|
||||
buttonFreeMove.setText("Free Move ("+game.getAvailFreeMoves()+")");
|
||||
buttonUndo.setText("Undo ("+game.getAvailUndo()+")");
|
||||
|
||||
game.addUpdateListener(new Game.UpdateListener() {
|
||||
|
||||
@Override
|
||||
public void gameUpdate() {
|
||||
labelScore.setText("Score: "+game.getScore());
|
||||
buttonFreeMove.setEnabled(game.getAvailFreeMoves()>0);
|
||||
buttonUndo.setEnabled(game.getAvailUndo()>0);
|
||||
buttonFreeMove.setText("Free Move ("+game.getAvailFreeMoves()+")");
|
||||
buttonUndo.setText("Undo ("+game.getAvailUndo()+")");
|
||||
labelLinesLeft.setText("Lines Left: "+game.getLinesLeft());
|
||||
labelLevel.setText("Level: "+game.getLevel());
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
JPanel gamePanel = new JPanel();
|
||||
gamePanel.setLayout(new BorderLayout());
|
||||
gamePanel.add(topPanel, BorderLayout.NORTH);
|
||||
gamePanel.add(field);
|
||||
mainPanel.add(gamePanel);
|
||||
}
|
||||
|
||||
private void initWelcomeLayout() {
|
||||
JPanel welcomePanel = new JPanel();
|
||||
welcomePanel.setLayout(new BoxLayout(welcomePanel, BoxLayout.Y_AXIS));
|
||||
|
||||
JButton btnInstr = new JButton("Instructions & More");
|
||||
btnInstr.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
btnInstr.setActionCommand("github");
|
||||
btnInstr.addActionListener(this);
|
||||
|
||||
welcomePanel.add(Box.createRigidArea(new Dimension(0,5)));
|
||||
welcomePanel.add(btnInstr);
|
||||
welcomePanel.add(Box.createRigidArea(new Dimension(0,10)));
|
||||
|
||||
int sizes [] = {7,8,9,10};
|
||||
for(int i=0; i<sizes.length; i++) {
|
||||
JButton btn = new JButton(sizes[i]+"x"+sizes[i]);
|
||||
btn.addActionListener(this);
|
||||
btn.setActionCommand(Integer.toString(sizes[i]));
|
||||
btn.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
|
||||
welcomePanel.add(btn);
|
||||
welcomePanel.add(Box.createRigidArea(new Dimension(0,5)));
|
||||
}
|
||||
|
||||
JPanel gamePanel = new JPanel();
|
||||
gamePanel.setLayout(new BorderLayout());
|
||||
gamePanel.add(topPanel, BorderLayout.NORTH);
|
||||
gamePanel.add(field);
|
||||
|
||||
mainPanel = new JPanel();
|
||||
cardLayout = new CardLayout();
|
||||
mainPanel.setLayout(cardLayout);
|
||||
mainPanel.add(welcomePanel);
|
||||
mainPanel.add(gamePanel);
|
||||
|
||||
this.setContentPane(mainPanel);
|
||||
|
||||
this.setSize(470,460);
|
||||
this.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Action listener callback, determines which function to call.
|
||||
* Action listener callback: gets called when a button was pressed
|
||||
* The method will either start a game or forward an action to the game
|
||||
*
|
||||
* @author timo
|
||||
* @param e ActionEvent
|
||||
@@ -139,6 +154,17 @@ public class Window extends JFrame implements ActionListener{
|
||||
field.doUndo();
|
||||
} else if (command.equals("freemove")) {
|
||||
field.toggleFreeMove();
|
||||
} else if(command.equals("github")) {
|
||||
if(Desktop.isDesktopSupported()) {
|
||||
final String url = "https://github.com/id101010/7not7/blob/master/README.md";
|
||||
try {
|
||||
Desktop.getDesktop().browse(new URI(url));
|
||||
} catch(Exception ex) {
|
||||
System.out.println("Couldn't open link: "+url+" "+ex.toString());
|
||||
}
|
||||
}
|
||||
} else if(command.equals("reset")) {
|
||||
cardLayout.first(mainPanel);
|
||||
} else {
|
||||
int size = Integer.parseInt(command);
|
||||
cardLayout.last(mainPanel);
|
||||
@@ -146,6 +172,21 @@ public class Window extends JFrame implements ActionListener{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* GameUpdateListener: gets called when the games was updated (e.g. user made a move)
|
||||
*/
|
||||
@Override
|
||||
public void gameUpdated() {
|
||||
labelScore.setText("Score: "+game.getScore());
|
||||
buttonFreeMove.setEnabled(game.getAvailFreeMoves()>0);
|
||||
buttonUndo.setEnabled(game.getAvailUndo()>0);
|
||||
buttonFreeMove.setText("Free Move ("+game.getAvailFreeMoves()+")");
|
||||
buttonUndo.setText("Undo ("+game.getAvailUndo()+")");
|
||||
labelLinesLeft.setText("Lines Left: "+game.getLinesLeft());
|
||||
labelLevel.setText("Level: "+game.getLevel());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method
|
||||
|
||||
Reference in New Issue
Block a user