-
Notifications
You must be signed in to change notification settings - Fork 0
/
SnakeView.java
207 lines (165 loc) · 5.02 KB
/
SnakeView.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/**
* @author Kamil Gabryjelski
*/
import javax.swing.*;
import java.awt.*;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Observer;
/**
* SnakeView creates and modifies the graphics of game based on data from model.
* Observing changes of model is handled by Observer interface.
* Actions of user are transfered to control.
*/
class SnakeView implements Observer
{
/**
* handles KeyListener
*/
SnakeControl control = null;
/**
* contains data on basis of which the view is created
*/
SnakeModel model = null;
/**
* main frame of program
*/
private JFrame mainFrame;
/**
* field that the snake moves on
*/
private Canvas canvas;
/**
* contains current score
*/
private JLabel labelScore;
/**
* contains manual of key controls
*/
private JLabel labelHelp;
/**
* contains information from labelHelp
*/
private JPanel panelButton = new JPanel();
/**
* width of the field the snake moves on
*/
private static int canvasWidth;
/**
* height of the field the snake moves on
*/
private static int canvasHeight;
/**
* width of the window containing canvas and information (score and manuals)
*/
private static int cpWidth;
/**
* height of the window containing canvas and information (score and manuals)
*/
private static int cpHeight;
/**
* width of a node
*/
private static final int nodeWidth = 10;
/**
* height of a node
*/
private static final int nodeHeight = 10;
/**
* Constructor of SnakeView
* Creates the main frame and places canvas and panels in it
* Sets location of main frame in the middle of the screen
* @param model model which should be used to create view
* @param control handles pressing the keys by user
*/
SnakeView(final SnakeModel model, final SnakeControl control)
{
this.model = model;
this.control = control;
canvasWidth = (model.maxX)*nodeWidth;
canvasHeight =(model.maxY)*nodeHeight;
mainFrame = new JFrame("Snake");
Container cp = mainFrame.getContentPane();
cp.setSize(canvasWidth+10, canvasHeight+10);
labelScore = new JLabel("Score:");
cp.add(labelScore, BorderLayout.NORTH);
canvas = new Canvas();
canvas.setSize(canvasWidth, canvasHeight);
//canvas.setSize(mainFrameWidth-20, mainFrameWidth-20);
cp.add(canvas, BorderLayout.CENTER);
panelButton.setLayout(new GridLayout(0,1));
labelHelp = new JLabel("Press arrows or WSAD to move.", JLabel.CENTER);
panelButton.add(labelHelp);
labelHelp = new JLabel("Press \"+\" or \"-\" to accelerate or decelerate.", JLabel.CENTER);
panelButton.add(labelHelp);
labelHelp = new JLabel("Press ENTER or R to restart.", JLabel.CENTER);
panelButton.add(labelHelp);
labelHelp = new JLabel("Press SPACE or P to pause", JLabel.CENTER);
panelButton.add(labelHelp);
cp.add(panelButton, BorderLayout.SOUTH);
cpWidth = cp.getSize().width;
cpHeight = cp.getSize().height;
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
mainFrame.addKeyListener(control);
mainFrame.pack();
mainFrame.setResizable(true);
mainFrame.setLocation((dim.width-cpWidth)/2, (dim.height-cpHeight)/2);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setVisible(true);
}
/**
* draws background, food and snake
* location of food and snake is based on data from model
* invokes updateScore() method
*/
void repaint()
{
Graphics g = canvas.getGraphics();
//draw background
g.setColor(Color.BLACK);
g.fillRect(0, 0, canvasWidth, canvasHeight);
// draw the snake
g.setColor(Color.WHITE);
LinkedList<SnakeModel.Node> na = model.nodeArray;
Iterator<SnakeModel.Node> it = na.iterator();
while (it.hasNext())
{
SnakeModel.Node n = (SnakeModel.Node) it.next();
drawNode(g, n);
}
// draw the food
g.setColor(Color.RED);
SnakeModel.Node n = model.food;
drawNode(g, n);
updateScore();
}
/**
* draws a rectangular node in a given location specified by argument SnakeModel.Node
* @param g an object which handles drawing a rectangular
* @param n node which is going to be drew
*/
private void drawNode(Graphics g, SnakeModel.Node n)
{
g.fillRect(n.x * nodeWidth, n.y * nodeHeight, nodeWidth - 1, nodeHeight - 1);
}
/**
* sets the text displayed by labelScore to current score
*/
private void updateScore()
{
String s = "Score: " + model.score;
labelScore.setText(s);
}
/**
* method from Observer interface invoked each time a model changes, which is handled by methods setChanged() and notifyObservers() from Observable class
* if game is over, displays a message
* invokes repaint()
*/
public void update(Observable o, Object arg)
{
if (model.failed)
JOptionPane.showMessageDialog(null, "You failed", "Game Over", JOptionPane.INFORMATION_MESSAGE);
repaint();
}
}