Code cleanup in Window class and improved comments in other classes.

This commit is contained in:
t-moe
2016-06-24 23:29:08 +02:00
parent ef0cdb4764
commit b217734b49
5 changed files with 137 additions and 82 deletions

View File

@@ -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.
![Moving Blocks](https://github.com/id101010/7not7/blob/master/doc/movingBlocks.png)
@@ -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

View File

@@ -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);
@@ -170,6 +173,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) {
g.setColor(Color.gray);
@@ -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
for(int x=0; x<game.getSize(); x++) {
for(int y=0; y<game.getSize(); y++) {
int colorCode = game.getField()[x][y];
@@ -206,7 +210,6 @@ public class FieldCanvas extends JPanel{
}
//Draw blocked fields
if(blockedFields!=null) {
g.setColor(Color.darkGray);
for(int i=0; i<blockedFields.size(); i++) {

View File

@@ -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();
}
/**

View File

@@ -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;

View File

@@ -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;
@@ -44,15 +48,26 @@ 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);
@@ -147,6 +173,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
*