• R/O
  • SSH
  • HTTPS

zenjiro: コミット


コミットメタ情報

リビジョン121 (tree)
日時2007-05-20 10:40:35
作者zenjiro

ログメッセージ

- サーバにプレイヤの現在位置を送るようにしました。
- サーバから他プレイヤの位置を受け取って描画するようにしました。
- フレームを2つ開くと、最初に起動したフレームのキー入力が受け付けられなくなるSwi
ngのバグ(?)のため、やる気がなくなりました。
-- jdk1.5.0_11、jdk1.6.0_01 on Fedora Core 6で発生します。

変更サマリ

差分

Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
--- netkart/trunk/Client.java (revision 120)
+++ netkart/trunk/Client.java (revision 121)
@@ -1,9 +1,7 @@
1-import java.io.IOException;
21 import java.io.InputStream;
32 import java.io.OutputStream;
43 import java.io.PrintWriter;
54 import java.util.Calendar;
6-import java.util.Map;
75 import java.util.Scanner;
86
97 /**
@@ -25,7 +23,7 @@
2523 /**
2624 * 出力ストリーム
2725 */
28- private final OutputStream out;
26+ private final PrintWriter out;
2927
3028 /**
3129 * 識別子
@@ -38,6 +36,21 @@
3836 private String stageID;
3937
4038 /**
39+ * x座標
40+ */
41+ private double x;
42+
43+ /**
44+ * y座標
45+ */
46+ private double y;
47+
48+ /**
49+ * 向き
50+ */
51+ private double direction;
52+
53+ /**
4154 * コンストラクタです。
4255 * @param server サーバ
4356 * @param in 入力ストリーム
@@ -46,38 +59,51 @@
4659 public Client(final Server server, final InputStream in, final OutputStream out) {
4760 this.server = server;
4861 this.in = in;
49- this.out = out;
62+ this.out = new PrintWriter(out);
5063 }
5164
5265 public void run() {
5366 final Scanner scanner = new Scanner(this.in);
54- final PrintWriter writer = new PrintWriter(this.out);
5567 while (scanner.hasNextLine()) {
56- try {
57- final String line = scanner.nextLine();
58- System.out.println("Got " + line);
59- if (line.equals(Const.Network.PUT_PLAYER_NAME)) {
60- this.id = scanner.nextLine();
61- System.out.println("Set id " + this.id);
62- } else if (line.equals(Const.Network.GET_STAGE_LIST)) {
63- for (final Map.Entry<String, Stage> entry : this.server.getStages().entrySet()) {
64- writer.println(Const.Network.PUT_STAGE_ID);
65- writer.println(entry.getKey());
66- }
67- } else if (line.equals(Const.Network.PUT_STAGE_ID)) {
68- this.stageID = scanner.nextLine();
69- System.out.println("Set stage id " + this.stageID);
70- } else if (line.equals(Const.Network.GET_STAGE)) {
71- writer.println(Const.Network.PUT_STAGE_START);
72- this.server.sendStage(this.stageID, writer);
73- writer.println(Const.Network.PUT_STAGE_END);
68+ final String line = scanner.nextLine();
69+ System.out.println("Got " + line);
70+ if (line.equals(Const.Network.PUT_PLAYER_NAME)) {
71+ this.id = scanner.nextLine();
72+ this.server.clientsTable.put(this.id, this);
73+ System.out.println("Set id " + this.id);
74+ } else if (line.equals(Const.Network.GET_PLAYER_NAME)) {
75+ this.out.println(this.id);
76+ } else if (line.equals(Const.Network.GET_PLAYER_LIST)) {
77+ for (final Client client : this.server.clientsTable.values()) {
78+ this.out.print(client.id + "\t");
7479 }
75- writer.flush();
76- } catch (final IOException exception) {
77- exception.printStackTrace();
80+ this.out.println();
81+ } else if (line.equals(Const.Network.GET_STAGE_LIST)) {
82+ for (final String stageName : this.server.stages.keySet()) {
83+ this.out.print(stageName + "\t");
84+ }
85+ this.out.println();
86+ } else if (line.equals(Const.Network.PUT_STAGE_ID)) {
87+ this.stageID = scanner.nextLine();
88+ System.out.println("Set stage id " + this.stageID);
89+ } else if (line.equals(Const.Network.GET_STAGE_ID)) {
90+ this.out.println(this.stageID);
91+ } else if (line.equals(Const.Network.PUT_LOCATION)) {
92+ this.x = Integer.parseInt(scanner.nextLine());
93+ this.y = Integer.parseInt(scanner.nextLine());
94+ this.direction = Integer.parseInt(scanner.nextLine()) / 360.0;
95+ System.out.println("Got location " + this.x + ", " + this.y + ", " + this.direction);
96+ } else if (line.equals(Const.Network.GET_LOCATION)) {
97+ final Client client = this.server.clientsTable.get(scanner.nextLine());
98+ this.out.println((int) client.x);
99+ this.out.println((int) client.y);
100+ this.out.println((int) (client.direction * 360));
101+ this.out.flush();
78102 }
103+ this.out.flush();
79104 }
80105 System.out.println(this.id + " disconnected on " + Calendar.getInstance().getTime());
106+ this.server.clientsTable.remove(this.id);
81107 }
82108
83109 }
--- netkart/trunk/Server.java (revision 120)
+++ netkart/trunk/Server.java (revision 121)
@@ -3,15 +3,14 @@
33 import java.io.FileInputStream;
44 import java.io.FileNotFoundException;
55 import java.io.IOException;
6-import java.io.PrintWriter;
76 import java.net.ServerSocket;
87 import java.net.Socket;
9-import java.util.ArrayList;
108 import java.util.Calendar;
11-import java.util.HashMap;
12-import java.util.List;
139 import java.util.Map;
14-import java.util.Scanner;
10+import java.util.concurrent.ConcurrentHashMap;
11+import java.util.concurrent.Executors;
12+import java.util.concurrent.ScheduledExecutorService;
13+import java.util.concurrent.TimeUnit;
1514
1615 /**
1716 * NetKartのサーバです。
@@ -22,51 +21,19 @@
2221 /**
2322 * ステージの一覧
2423 */
25- private final Map<String, Stage> stages;
26-
27- /**
28- * クライアントの一覧
29- */
30- private final List<Client> clients;
24+ final Map<String, Stage> stages;
3125
3226 /**
33- * ステージを追加します。
34- * @param id ステージの識別子
35- * @param stage ステージ
27+ * プレイヤの識別子とクライアントの対応表
3628 */
37- public void putStage(final String id, final Stage stage) {
38- this.stages.put(id, stage);
39- }
29+ final Map<String, Client> clientsTable;
4030
4131 /**
42- * ステージを送信します。
43- * TODO どんなファイルでも見られてしまうセキュリティホールがあります。
44- * @param id ステージの識別子
45- * @param writer 出力ストリーム
46- * @throws FileNotFoundException ファイル未検出例外
47- */
48- public void sendStage(final String id, final PrintWriter writer) throws FileNotFoundException {
49- final Scanner scanner = new Scanner(new File(id));
50- while (scanner.hasNextLine()) {
51- writer.println(scanner.nextLine());
52- }
53- scanner.close();
54- }
55-
56- /**
57- * クライアントを追加します。
58- * @param client クライアント
59- */
60- public void addPlayer(final Client client) {
61- this.clients.add(client);
62- }
63-
64- /**
6532 * コンストラクタです。
6633 */
6734 public Server() {
68- this.stages = new HashMap<String, Stage>();
69- this.clients = new ArrayList<Client>();
35+ this.stages = new ConcurrentHashMap<String, Stage>();
36+ this.clientsTable = new ConcurrentHashMap<String, Client>();
7037 }
7138
7239 /**
@@ -77,10 +44,11 @@
7744 public static void main(final String[] args) throws FileNotFoundException {
7845 final Server server = new Server();
7946 for (final String arg : args) {
80- server.putStage(arg, (Stage) new XMLDecoder(new FileInputStream(new File(arg))).readObject());
47+ server.stages.put(arg, (Stage) new XMLDecoder(new FileInputStream(new File(arg))).readObject());
8148 }
82-
49+
8350 System.out.println("Server started on " + Calendar.getInstance().getTime());
51+ final ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
8452 while (true) {
8553 try {
8654 final ServerSocket serverSocket = new ServerSocket(Const.Network.PORT);
@@ -89,8 +57,7 @@
8957 final Socket socket = serverSocket.accept();
9058 System.out.println("Accepted connection from " + socket.getInetAddress());
9159 final Client client = new Client(server, socket.getInputStream(), socket.getOutputStream());
92- server.addPlayer(client);
93- new Thread(client).start();
60+ service.schedule(client, 0, TimeUnit.SECONDS);
9461 }
9562 } catch (final IOException exception) {
9663 exception.printStackTrace();
@@ -98,11 +65,4 @@
9865 }
9966 }
10067
101- /**
102- * @return ステージの一覧
103- */
104- public Map<String, Stage> getStages() {
105- return this.stages;
106- }
107-
10868 }
--- netkart/trunk/NetKart2D.java (nonexistent)
+++ netkart/trunk/NetKart2D.java (revision 121)
@@ -0,0 +1,246 @@
1+import java.awt.Color;
2+import java.awt.Graphics;
3+import java.awt.Graphics2D;
4+import java.awt.event.KeyEvent;
5+import java.awt.event.WindowEvent;
6+import java.awt.event.WindowListener;
7+import java.awt.geom.AffineTransform;
8+import java.awt.geom.GeneralPath;
9+import java.beans.XMLDecoder;
10+import java.io.IOException;
11+import java.io.InputStream;
12+import java.io.PrintWriter;
13+import java.net.Socket;
14+import java.net.UnknownHostException;
15+import java.util.Arrays;
16+import java.util.List;
17+import java.util.Map;
18+import java.util.Random;
19+import java.util.Scanner;
20+import java.util.concurrent.ConcurrentHashMap;
21+import java.util.concurrent.Executors;
22+import java.util.concurrent.ScheduledExecutorService;
23+import java.util.concurrent.TimeUnit;
24+
25+import javax.swing.JFrame;
26+import javax.swing.JPanel;
27+import javax.swing.UIManager;
28+import javax.swing.UnsupportedLookAndFeelException;
29+import javax.swing.WindowConstants;
30+
31+/**
32+ * NetKartクライアントの2D実装です。
33+ * @author zenjiro
34+ */
35+public class NetKart2D {
36+
37+ /**
38+ * メインメソッドです。
39+ * @param args コマンドライン引数
40+ * @throws UnsupportedLookAndFeelException
41+ * @throws IllegalAccessException
42+ * @throws InstantiationException
43+ * @throws ClassNotFoundException
44+ * @throws InterruptedException
45+ * @throws IOException
46+ * @throws UnknownHostException
47+ */
48+ public static void main(final String[] args) throws ClassNotFoundException, InstantiationException,
49+ IllegalAccessException, UnsupportedLookAndFeelException, InterruptedException, UnknownHostException, IOException {
50+ final KeyHandler handler = new KeyHandler();
51+ final Player player = new Player();
52+ final Stage stage = new Stage();
53+ final Map<String, Player> players = new ConcurrentHashMap<String, Player>();
54+
55+ final Socket socket = new Socket(Const.Network.SERVER, Const.Network.PORT);
56+ final InputStream in = socket.getInputStream();
57+ final Scanner scanner = new Scanner(in);
58+ final PrintWriter out = new PrintWriter(socket.getOutputStream());
59+ out.println(Const.Network.GET_STAGE_LIST);
60+ out.flush();
61+ final List<String> stageNames = Arrays.asList(scanner.nextLine().split("\t"));
62+ System.out.println(stageNames);
63+ out.println(Const.Network.PUT_STAGE_ID);
64+ out.println(stageNames.get(1));
65+ out.println(Const.Network.GET_STAGE_ID);
66+ out.flush();
67+ final String stageName = scanner.nextLine();
68+ System.out.println("Stage name is " + stageName);
69+ stage.setStage((Stage) new XMLDecoder(NetKart2D.class.getResourceAsStream(stageName)).readObject());
70+ out.println(Const.Network.PUT_PLAYER_NAME);
71+ out.println("test" + new Random().nextInt(100));
72+ out.println(Const.Network.GET_PLAYER_NAME);
73+ out.flush();
74+ final String myName = scanner.nextLine();
75+ System.out.println("My name is " + myName);
76+ out.println(Const.Network.GET_PLAYER_LIST);
77+ out.flush();
78+ for (final String playerName : scanner.nextLine().split("\t")) {
79+ players.put(playerName, new Player());
80+ }
81+ System.out.println("players = " + players);
82+ final CheckPoint startLine = stage.getCheckPoints().get(0);
83+ player.x = startLine.location.getX();
84+ player.y = startLine.location.getY();
85+ player.direction = startLine.angle;
86+ final ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
87+ service.scheduleAtFixedRate(new Runnable() {
88+ public void run() {
89+ out.println(Const.Network.PUT_LOCATION);
90+ out.println((int) player.x);
91+ out.println((int) player.y);
92+ out.println((int) (player.direction * 360));
93+ out.flush();
94+ for (final Map.Entry<String, Player> entry : players.entrySet()) {
95+ final Player player = entry.getValue();
96+ out.println(Const.Network.GET_LOCATION);
97+ out.println(entry.getKey());
98+ out.flush();
99+ player.x = Integer.parseInt(scanner.nextLine());
100+ player.y = Integer.parseInt(scanner.nextLine());
101+ player.direction = Integer.parseInt(scanner.nextLine()) / 360.0;
102+ }
103+ }
104+ }, 0, 1000, TimeUnit.MILLISECONDS);
105+
106+ final JFrame frame = new JFrame("Kart 2D");
107+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
108+ frame.setLocationByPlatform(true);
109+ frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
110+ frame.setSize(640, 480);
111+ frame.addKeyListener(handler);
112+ frame.addWindowListener(new WindowListener() {
113+
114+ public void windowOpened(final WindowEvent e) {
115+ }
116+
117+ public void windowIconified(final WindowEvent e) {
118+ }
119+
120+ public void windowDeiconified(final WindowEvent e) {
121+ }
122+
123+ public void windowDeactivated(final WindowEvent e) {
124+ }
125+
126+ public void windowClosing(final WindowEvent e) {
127+ }
128+
129+ public void windowClosed(final WindowEvent e) {
130+ service.shutdown();
131+ }
132+
133+ public void windowActivated(final WindowEvent e) {
134+ }
135+
136+ });
137+ final JPanel panel = new JPanel() {
138+ @Override
139+ protected void paintComponent(final Graphics g) {
140+ final double x = player.x;
141+ final double y = player.y;
142+ final double direction = player.direction;
143+ final Graphics2D g2 = (Graphics2D) g;
144+ g2.setColor(Color.WHITE);
145+ g2.fillRect(0, 0, this.getWidth(), this.getHeight());
146+ g2.translate(0, this.getHeight());
147+ g2.scale(1, -1);
148+ g2.translate(this.getWidth() / 2, this.getHeight() / 4);
149+ g2.scale(2, 2);
150+ g2.rotate(-direction + Math.PI / 2);
151+ g2.translate(-x, -y);
152+ this.draw(player, stage, g2, x, y, direction);
153+ g2.translate(x, y);
154+ g2.rotate(direction - Math.PI / 2);
155+ g2.scale(.5, .5);
156+ g2.translate(-this.getWidth() / 2, -this.getHeight() / 4);
157+ g2.translate(0, this.getHeight() * 3 / 4);
158+ g2.scale(.25, .25);
159+ this.draw(player, stage, g2, x, y, direction);
160+ g2.scale(4, 4);
161+ g2.translate(0, -this.getHeight() * 3 / 4);
162+ g2.setColor(Color.RED);
163+ g2.translate(100, 20);
164+ g2.rotate(Math.PI - player.speed / 2.4 * Math.PI);
165+ g2.fillPolygon(new int[] { 0, 80, 80, 0 }, new int[] { -4, -2, 2, 4 }, 4);
166+ }
167+
168+ private void draw(final Player player, final Stage stage, final Graphics2D g2, final double x,
169+ final double y, final double direction) {
170+ g2.setColor(new Color(240, 240, 240));
171+ for (final Rail rail : stage.getRails()) {
172+ g2.fill(Util.getShape(rail, true));
173+ }
174+ g2.setColor(Color.BLACK);
175+ for (final Rail rail : stage.getRails()) {
176+ g2.draw(Util.getShape(rail, false));
177+ }
178+ final GeneralPath playerShape = new GeneralPath();
179+ playerShape.moveTo(0, 0);
180+ playerShape.lineTo(-24, -10);
181+ playerShape.lineTo(-24, 10);
182+ playerShape.closePath();
183+ for (final Player enemy : players.values()) {
184+ final AffineTransform playerTransform = new AffineTransform();
185+ playerTransform.translate(enemy.x, enemy.y);
186+ playerTransform.rotate(enemy.direction);
187+ g2.setColor(Color.YELLOW);
188+ g2.fill(playerTransform.createTransformedShape(playerShape));
189+ g2.setColor(Color.BLACK);
190+ g2.draw(playerTransform.createTransformedShape(playerShape));
191+ }
192+ final AffineTransform playerTransform = new AffineTransform();
193+ playerTransform.translate(x, y);
194+ playerTransform.rotate(direction);
195+ g2.setColor(Color.RED);
196+ g2.fill(playerTransform.createTransformedShape(playerShape));
197+ g2.setColor(Color.BLACK);
198+ g2.draw(playerTransform.createTransformedShape(playerShape));
199+ }
200+ };
201+ panel.setFocusable(false);
202+ frame.add(panel);
203+
204+ frame.setVisible(true);
205+
206+ int wait = 1;
207+ long last = System.currentTimeMillis();
208+ while (frame.isShowing()) {
209+ // キー入力を処理する。
210+ if (handler.isPressed(KeyEvent.VK_BACK_SLASH)) {
211+ player.speed += 0.05;
212+ }
213+ if (handler.isPressed(KeyEvent.VK_LEFT)) {
214+ player.handle += .002;
215+ }
216+ if (handler.isPressed(KeyEvent.VK_RIGHT)) {
217+ player.handle -= .002;
218+ }
219+ player.speed *= .98;
220+ player.handle *= .9;
221+ player.speed *= (1 - Math.abs(player.handle) / 2);
222+ // test
223+ player.direction += 0.001;
224+
225+ // プレイヤの位置を変更する。
226+ player.direction += player.handle;
227+ player.x += player.speed * Math.cos(player.direction);
228+ player.y += player.speed * Math.sin(player.direction);
229+
230+ // 再描画する。
231+ panel.repaint();
232+
233+ // 待つ。
234+ final long now = System.currentTimeMillis();
235+ if (now - last < 10) {
236+ wait++;
237+ } else if (now - last > 10) {
238+ wait = Math.max(0, wait - 1);
239+ }
240+ last = now;
241+ Thread.sleep(wait);
242+ System.out.print("Waiting " + wait + "ms at " + now + " \r");
243+ }
244+ }
245+
246+}
--- netkart/trunk/Const.java (revision 120)
+++ netkart/trunk/Const.java (revision 121)
@@ -45,40 +45,65 @@
4545 * @author zenjiro
4646 */
4747 public static class Network {
48+
4849 /**
50+ * サーバのホスト名
51+ */
52+ public static final String SERVER = "zenjiro.dyndns.org";
53+
54+ /**
4955 * サーバが接続を待ち受けるポート番号
5056 */
5157 public static final int PORT = 60143;
5258
5359 /**
54- * プレイヤの識別子を送る文字列
60+ * クライアントがサーバにプレイヤの識別子を送る文字列
61+ * 続いて「playerName」
5562 */
5663 public static final String PUT_PLAYER_NAME = "PUT_PLAYER_NAME";
64+
65+ /**
66+ * クライアントがサーバにプレイヤの識別子を要求する文字列
67+ * 戻り値は「playerName」
68+ */
69+ public static final String GET_PLAYER_NAME = "GET_PLAYER_NAME";
5770
5871 /**
5972 * クライアントがサーバにステージの一覧を要求する文字列
73+ * 戻り値は「stageID1 stageID2 ...」
6074 */
6175 public static final String GET_STAGE_LIST = "GET_STAGE_LIST";
6276
6377 /**
64- * クライアントがサーバにステージを要求する文字列
78+ * クライアントがサーバにステージの識別子を要求する文字列
79+ * 戻り値は「stageID」
6580 */
66- public static final String GET_STAGE = "GET_STAGE";
81+ public static final String GET_STAGE_ID = "GET_STAGE_ID";
6782
6883 /**
69- * ステージの識別子を送る文字列
84+ * クライアントがサーバにステージの識別子を送る文字列
85+ * 続いて「stageID」
7086 */
7187 public static final String PUT_STAGE_ID = "PUT_STAGE_ID";
7288
7389 /**
74- * サーバがクライアントに1つのステージを送る開始文字列
90+ * クライアントがサーバにプレイヤの位置を送る文字列
91+ * 続いて「x座標」「y座標」「向き」
7592 */
76- public static final String PUT_STAGE_START = "PUT_STAGE_START";
93+ public static final String PUT_LOCATION = "PUT_LOCATION";
7794
7895 /**
79- * サーバがクライアントに1つのステージを送る終了文字列
96+ * クライアントがサーバにプレイヤの一覧を要求する文字列
97+ * 戻り値は「playerName1 playerName2 ...」
8098 */
81- public static final String PUT_STAGE_END = "PUT_STAGE_END";
99+ public static final String GET_PLAYER_LIST = "GET_PLAYER_LIST";
100+
101+ /**
102+ * クライアントがサーバにプレイヤの位置を要求する文字列
103+ * 続いて「playerName」
104+ * 戻り値は「x座標」「y座標」「向き」
105+ */
106+ public static final String GET_LOCATION = "GET_LOCATION";
82107 }
83108
84109 /**
--- netkart/trunk/Kart2D.java (revision 120)
+++ netkart/trunk/Kart2D.java (revision 121)
@@ -1,7 +1,6 @@
11 import java.awt.Color;
22 import java.awt.Graphics;
33 import java.awt.Graphics2D;
4-import java.awt.RenderingHints;
54 import java.awt.event.KeyEvent;
65 import java.awt.geom.AffineTransform;
76 import java.awt.geom.GeneralPath;
@@ -59,7 +58,6 @@
5958 final Graphics2D g2 = (Graphics2D) g;
6059 g2.setColor(Color.WHITE);
6160 g2.fillRect(0, 0, getWidth(), getHeight());
62- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
6361 g2.translate(0, this.getHeight());
6462 g2.scale(1, -1);
6563 g2.translate(getWidth() / 2, getHeight() / 4);
旧リポジトリブラウザで表示