docs
[mirrors/Programs.git] / java / pong / pong.java
1 import static java.lang.Math.*;
2 import javax.swing.*;
3 import java.awt.*;
4
5 import java.awt.event.KeyEvent;
6 import java.awt.event.KeyListener;
7 import java.awt.event.MouseEvent;
8 import java.awt.event.MouseMotionListener;
9
10 import java.io.*;
11 import java.net.*;
12
13 /** Class implementing network interface for PongPanel objects */
14 class PongNetwork implements Runnable {
15 BufferedReader br;
16 BufferedWriter bw;
17 Socket sock;
18 String host = "localhost";
19 int port = 1033;
20
21 PongPanel pp = null;
22
23 /** constructor should be given instance of PongPanel to interface with and hostname to connect to */
24 PongNetwork(PongPanel pp, String host) {
25 this.pp = pp;
26 this.host = host;
27 Thread t = new Thread(this);
28 t.start();
29 }
30
31 /** creates new thread which tries to connect to existing server on desired host and if it's not listening it starts own socket server. */
32 public void run() {
33 try {
34 if(!this.startClient(port)) this.startServer(port);
35
36 br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
37 bw = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
38
39 if(pp.right == 0) {
40 send("0.5,-5,-7");
41 send("0.5,-5,-7");
42 }
43
44 String s = "";
45 while (s != null) {
46 s = br.readLine();
47 if (s == null) continue;
48 System.out.println(s);
49 pp.putBall(s);
50 }
51 sock.close();
52 System.out.println("Remote host closed connection :-(");
53 System.out.println("Your score was: "+ pp.score + " against oponent's score: " + pp.score_oponent);
54 System.exit(0);
55 } catch(Exception e) {
56 System.out.println("Something's wrong with connection :-(");
57 }
58 }
59
60 /** start own server */
61 boolean startServer(int port) {
62 pp.right = 1;
63 System.out.println("Starting server on port "+port+" ...");
64 try {
65 ServerSocket ss = new ServerSocket(port);
66 sock = ss.accept();
67 System.out.println("Client connected!");
68 } catch(Exception e) {
69 e.printStackTrace();
70 return false;
71 }
72 return true;
73 }
74
75 /** try to connect to existing server */
76 boolean startClient(int port) {
77 pp.right = 0;
78 System.out.println("Connecting to server "+host+":"+port+" ...");
79 try {
80 sock = new Socket();
81 sock.connect(new InetSocketAddress(host, port), 2000);
82 System.out.println("Connected to server!");
83 } catch (Exception e) {
84 System.out.println("Connection failed!");
85 return false;
86 }
87 return true;
88 }
89
90 /** once connection to another pong instance is estabilished, we can send data using this method */
91 public void send(String s) {
92 try {
93 bw.write(s+"\n"); // zapíšeme předem připravený požadavek
94 bw.flush(); // odeslání z bufferu
95 } catch(Exception e) {
96 }
97 }
98
99 }
100
101 /** Pong Panel is object painted on main pong window (PongFrame) and contains all methods and variables needed to play pong */
102 class PongPanel extends JPanel implements KeyListener, MouseMotionListener {
103 PongNetwork pn;
104
105 int right = 1; //right (1) or left (0)?
106
107 int pad_pos = 50; //0-100;
108 int pad_speed = 10;
109 int pad_thickness = 10;
110 int pad_size = 70;
111
112 public int score = 0;
113 public int score_oponent = 0;
114
115 boolean have_ball = false;
116 int ball_pos_x, ball_pos_y;
117 int ball_mov_x, ball_mov_y;
118 int ball_size = 10;
119
120 /** new round is called when your opponent scored */
121 public void newRound() {
122 if(!have_ball) return;
123 ball_pos_x = getWidth()/2;
124 ball_pos_y = getHeight()/2;
125 ball_mov_x = 7*(right==0?-1:1);
126 ball_mov_y = 3;
127 }
128
129 /** Constructor */
130 public PongPanel(int x, int y, String host) {
131 setSize(x, y);
132 //newRound();
133 addKeyListener(this);
134 addMouseMotionListener(this);
135 pn = new PongNetwork(this, host);
136 }
137
138 /** Repaint game window */
139 public void paint(Graphics g) {
140 //createBufferStrategy(2); //double buffered
141 Graphics2D g2D=(Graphics2D) g; // cast to 2D
142 g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
143 RenderingHints.VALUE_ANTIALIAS_ON);
144
145 g.setColor(Color.WHITE);
146 g.setColor(Color.BLACK);
147 g.fillRect(0,0, getWidth(), getHeight());
148 g.setColor(Color.GREEN);
149
150 if(have_ball) g.fillOval(ball_pos_x-(ball_size/2), ball_pos_y-(ball_size/2), ball_size, ball_size); // draw ball
151
152 g.fillRect(right*(getWidth()-pad_thickness), pad_pos, pad_thickness, pad_size); // draw pad
153 g.drawString("PONG! "+score+":"+score_oponent, 20,20);
154 }
155
156 /** increment score of your oponent */
157 public void oponentScores() {
158 score_oponent++;
159 pn.send("+gotme :-)"); //HEY! do not comment this you cheater! :-P
160 newRound();
161 }
162
163 /** compute next iteration of game and repaint screen */
164 public boolean tick() {
165 if(have_ball) {
166 ball_pos_x += ball_mov_x;
167 ball_pos_y += ball_mov_y;
168 if(ball_pos_y >= getHeight() || ball_pos_y <= 0) ball_mov_y = -ball_mov_y; //bounce
169
170 if(
171 (
172 (right == 1 && ball_pos_x >= (getWidth()-pad_thickness-round(ball_size/2))) ||
173 (right == 0 && ball_pos_x <= pad_thickness+round(ball_size/2))
174 ) &&
175 (
176 ball_pos_y >= pad_pos &&
177 ball_pos_y <= pad_pos + pad_size
178 )
179 ) {
180 ball_mov_x = -ball_mov_x;
181 }
182
183 else if(
184 (right == 1 && ball_pos_x >= getWidth()) ||
185 (right == 0 && ball_pos_x <= 0)
186 ) oponentScores();
187
188 else if(
189 (right == 0 && ball_pos_x >= getWidth()) ||
190 (right == 1 && ball_pos_x <= 0)
191 ) {
192 //send ball over network
193 pn.send(getBall());
194 have_ball = false; super.repaint();
195 //newRound();
196 return false;
197 }
198
199 //putBall(getBall()); //haloooz s roundem
200 }
201
202 super.repaint();
203 return true;
204 }
205
206 /** serialize ball (position and speed) to be sent over TCP/IP socket */
207 public String getBall() {
208 have_ball = false;
209 return(
210 ((float)ball_pos_y / (float)getHeight()) +
211 ","+ball_mov_x +
212 ","+ball_mov_y +
213 ","+right
214
215 );
216
217 }
218
219 /** deserialize ball received through TCP/IP connection */
220 public void putBall(String ball) {
221 if(ball.charAt(0) == '+') {
222 score++;
223 return;
224 }
225 have_ball = true;
226 String[] vars = ball.trim().split(",");
227 System.out.println("Parsing: "+vars[0]+" "+vars[1]+" "+vars[2]);
228 ball_pos_x = (right==1)?pad_thickness+ball_size:getWidth()-(pad_thickness+ball_size);
229 ball_pos_y = (int)round(getHeight()*(new Double(vars[0])));
230 ball_mov_x = new Integer(vars[1]);
231 ball_mov_y = new Integer(vars[2]);
232 System.out.println("Parsed: "+ball_pos_y+" "+ball_mov_x+" "+ball_mov_y);
233 }
234
235 public void keyPressed(KeyEvent evt) {
236 int keyCode = evt.getKeyCode();
237 if(keyCode == KeyEvent.VK_UP && pad_pos >= pad_speed) pad_pos -= pad_speed;
238 if(keyCode == KeyEvent.VK_DOWN && pad_pos <= (100-pad_speed)) pad_pos += pad_speed;
239 super.repaint();
240 }
241
242 public void keyReleased(KeyEvent evt) {
243 }
244
245 public void keyTyped(KeyEvent evt) {
246 }
247 public boolean isFocusTraversable() { return true; }
248
249 public void mouseMoved(MouseEvent e) {
250 pad_pos = e.getY()-(pad_size/2);
251 }
252 public void mouseDragged(MouseEvent e) {
253 }
254
255 }
256
257 /** Main window of game */
258 class PongFrame extends JFrame {
259 PongPanel pp;
260 PongFrame(int x, int y, String host) throws InterruptedException {
261 this.setSize(x,y);
262 this.setTitle("NetPong");
263 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
264
265 pp=new PongPanel(getWidth(),getHeight(),host);
266 this.getContentPane().add(pp);
267
268 this.setVisible(true);
269 }
270
271 /** start game */
272 public void play() throws InterruptedException {
273 while(true) {
274 pp.tick();
275 //if(!pp.tick()) Thread.sleep(2*1000);
276 Thread.sleep(1000/24);
277 }
278 }
279
280 }
281
282 /**
283 * Implementation of classical "PONG" game modified to pass ball over TCP/IP connection.
284 * You need to run two instances (client + server).
285 * Game takes one optional commandline argument specifiing remote host running the server (localhost is default).
286 * If there's no server running on desired hostname, server is started on local machine on port 1033.
287 * Copylefted by: Harvie 2o1o
288 * @author Thomas Harvie Mudrunka (mudruto1)
289 * @version 1.0
290 */
291
292 public class pong {
293 public static void main(String[] args) throws InterruptedException {
294 PongFrame pf = new PongFrame(640,480,args.length>0?args[0]:"127.0.0.1");
295 pf.play();
296 }
297 }
This page took 0.362018 seconds and 4 git commands to generate.