Author: markt Date: Wed Mar 7 09:42:27 2012 New Revision: 1297914 URL: http://svn.apache.org/viewvc?rev=1297914&view=rev Log: Fix line-endings
Modified: tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/filters/SetCharacterEncodingFilter.java tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Direction.java (contents, props changed) tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Location.java (contents, props changed) tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java (contents, props changed) tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/SnakeWebSocketServlet.java (props changed) tomcat/trunk/webapps/examples/websocket/snake.html (contents, props changed) Modified: tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/filters/SetCharacterEncodingFilter.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/filters/SetCharacterEncodingFilter.java?rev=1297914&r1=1297913&r2=1297914&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/filters/SetCharacterEncodingFilter.java (original) +++ tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/filters/SetCharacterEncodingFilter.java Wed Mar 7 09:42:27 2012 @@ -19,6 +19,7 @@ package org.apache.catalina.filters; import java.io.IOException; import java.util.Enumeration; +import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; @@ -55,7 +56,7 @@ import org.apache.tomcat.util.res.String * and <code>User-Agent</code> headers, or a value stashed in the current * user's session.</p> */ -public class SetCharacterEncodingFilter { +public class SetCharacterEncodingFilter implements Filter { private static final Log log = LogFactory.getLog(SetCharacterEncodingFilter.class); @@ -105,6 +106,11 @@ public class SetCharacterEncodingFilter } } + public void destroy() { + // NOOP + } + + /** * Select and set (if specified) the character encoding to be used to * interpret request parameters for this request. Modified: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Direction.java URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Direction.java?rev=1297914&r1=1297913&r2=1297914&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Direction.java (original) +++ tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Direction.java Wed Mar 7 09:42:27 2012 @@ -1,21 +1,21 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package websocket.snake; - -public enum Direction { - NONE, NORTH, SOUTH, EAST, WEST -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package websocket.snake; + +public enum Direction { + NONE, NORTH, SOUTH, EAST, WEST +} Propchange: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Direction.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Location.java URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Location.java?rev=1297914&r1=1297913&r2=1297914&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Location.java (original) +++ tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Location.java Wed Mar 7 09:42:27 2012 @@ -1,65 +1,65 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package websocket.snake; - -public class Location { - - public int x; - public int y; - - public Location(int x, int y) { - this.x = x; - this.y = y; - } - - public Location getAdjacentLocation(Direction direction) { - switch (direction) { - case NORTH: - return new Location(x, y - SnakeWebSocketServlet.GRID_SIZE); - case SOUTH: - return new Location(x, y + SnakeWebSocketServlet.GRID_SIZE); - case EAST: - return new Location(x + SnakeWebSocketServlet.GRID_SIZE, y); - case WEST: - return new Location(x - SnakeWebSocketServlet.GRID_SIZE, y); - case NONE: - // fall through - default: - return this; - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Location location = (Location) o; - - if (x != location.x) return false; - if (y != location.y) return false; - - return true; - } - - @Override - public int hashCode() { - int result = x; - result = 31 * result + y; - return result; - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package websocket.snake; + +public class Location { + + public int x; + public int y; + + public Location(int x, int y) { + this.x = x; + this.y = y; + } + + public Location getAdjacentLocation(Direction direction) { + switch (direction) { + case NORTH: + return new Location(x, y - SnakeWebSocketServlet.GRID_SIZE); + case SOUTH: + return new Location(x, y + SnakeWebSocketServlet.GRID_SIZE); + case EAST: + return new Location(x + SnakeWebSocketServlet.GRID_SIZE, y); + case WEST: + return new Location(x - SnakeWebSocketServlet.GRID_SIZE, y); + case NONE: + // fall through + default: + return this; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Location location = (Location) o; + + if (x != location.x) return false; + if (y != location.y) return false; + + return true; + } + + @Override + public int hashCode() { + int result = x; + result = 31 * result + y; + return result; + } +} Propchange: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Location.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java?rev=1297914&r1=1297913&r2=1297914&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java (original) +++ tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java Wed Mar 7 09:42:27 2012 @@ -1,134 +1,134 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package websocket.snake; - -import java.io.IOException; -import java.nio.CharBuffer; -import java.util.ArrayDeque; -import java.util.Collection; -import java.util.Deque; - -import org.apache.catalina.websocket.WsOutbound; - -public class Snake { - - private static final int DEFAULT_LENGTH = 5; - - private final int id; - private final WsOutbound outbound; - - private Direction direction; - private int length = DEFAULT_LENGTH; - private Location head; - private Deque<Location> tail = new ArrayDeque<Location>(); - private String hexColor; - - public Snake(int id, WsOutbound outbound) { - this.id = id; - this.outbound = outbound; - this.hexColor = SnakeWebSocketServlet.getRandomHexColor(); - resetState(); - } - - private void resetState() { - this.direction = Direction.NONE; - this.head = SnakeWebSocketServlet.getRandomLocation(); - this.tail.clear(); - this.length = DEFAULT_LENGTH; - } - - private synchronized void kill() { - resetState(); - try { - CharBuffer response = CharBuffer.wrap("{'type': 'dead'}"); - outbound.writeTextMessage(response); - } catch (IOException ioe) { - // Ignore - } - } - - private synchronized void reward() { - length++; - try { - CharBuffer response = CharBuffer.wrap("{'type': 'kill'}"); - outbound.writeTextMessage(response); - } catch (IOException ioe) { - // Ignore - } - } - - public synchronized void update(Collection<Snake> snakes) { - Location nextLocation = head.getAdjacentLocation(direction); - if (nextLocation.x >= SnakeWebSocketServlet.PLAYFIELD_WIDTH) { - nextLocation.x = 0; - } - if (nextLocation.y >= SnakeWebSocketServlet.PLAYFIELD_HEIGHT) { - nextLocation.y = 0; - } - if (nextLocation.x < 0) { - nextLocation.x = SnakeWebSocketServlet.PLAYFIELD_WIDTH; - } - if (nextLocation.y < 0) { - nextLocation.y = SnakeWebSocketServlet.PLAYFIELD_HEIGHT; - } - if (direction != Direction.NONE) { - tail.addFirst(head); - if (tail.size() > length) { - tail.removeLast(); - } - head = nextLocation; - } - - for (Snake snake : snakes) { - if (snake.getTail().contains(head)) { - kill(); - if (id != snake.id) { - snake.reward(); - } - } - } - } - - public synchronized Collection<Location> getTail() { - return tail; - } - - public synchronized void setDirection(Direction direction) { - this.direction = direction; - } - - public synchronized String getLocationsJson() { - StringBuilder sb = new StringBuilder(); - sb.append(String.format("{x: %d, y: %d}", - Integer.valueOf(head.x), Integer.valueOf(head.y))); - for (Location location : tail) { - sb.append(','); - sb.append(String.format("{x: %d, y: %d}", - Integer.valueOf(location.x), Integer.valueOf(location.y))); - } - return String.format("{'id':%d,'body':[%s]}", - Integer.valueOf(id), sb.toString()); - } - - public int getId() { - return id; - } - - public String getHexColor() { - return hexColor; - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package websocket.snake; + +import java.io.IOException; +import java.nio.CharBuffer; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; + +import org.apache.catalina.websocket.WsOutbound; + +public class Snake { + + private static final int DEFAULT_LENGTH = 5; + + private final int id; + private final WsOutbound outbound; + + private Direction direction; + private int length = DEFAULT_LENGTH; + private Location head; + private Deque<Location> tail = new ArrayDeque<Location>(); + private String hexColor; + + public Snake(int id, WsOutbound outbound) { + this.id = id; + this.outbound = outbound; + this.hexColor = SnakeWebSocketServlet.getRandomHexColor(); + resetState(); + } + + private void resetState() { + this.direction = Direction.NONE; + this.head = SnakeWebSocketServlet.getRandomLocation(); + this.tail.clear(); + this.length = DEFAULT_LENGTH; + } + + private synchronized void kill() { + resetState(); + try { + CharBuffer response = CharBuffer.wrap("{'type': 'dead'}"); + outbound.writeTextMessage(response); + } catch (IOException ioe) { + // Ignore + } + } + + private synchronized void reward() { + length++; + try { + CharBuffer response = CharBuffer.wrap("{'type': 'kill'}"); + outbound.writeTextMessage(response); + } catch (IOException ioe) { + // Ignore + } + } + + public synchronized void update(Collection<Snake> snakes) { + Location nextLocation = head.getAdjacentLocation(direction); + if (nextLocation.x >= SnakeWebSocketServlet.PLAYFIELD_WIDTH) { + nextLocation.x = 0; + } + if (nextLocation.y >= SnakeWebSocketServlet.PLAYFIELD_HEIGHT) { + nextLocation.y = 0; + } + if (nextLocation.x < 0) { + nextLocation.x = SnakeWebSocketServlet.PLAYFIELD_WIDTH; + } + if (nextLocation.y < 0) { + nextLocation.y = SnakeWebSocketServlet.PLAYFIELD_HEIGHT; + } + if (direction != Direction.NONE) { + tail.addFirst(head); + if (tail.size() > length) { + tail.removeLast(); + } + head = nextLocation; + } + + for (Snake snake : snakes) { + if (snake.getTail().contains(head)) { + kill(); + if (id != snake.id) { + snake.reward(); + } + } + } + } + + public synchronized Collection<Location> getTail() { + return tail; + } + + public synchronized void setDirection(Direction direction) { + this.direction = direction; + } + + public synchronized String getLocationsJson() { + StringBuilder sb = new StringBuilder(); + sb.append(String.format("{x: %d, y: %d}", + Integer.valueOf(head.x), Integer.valueOf(head.y))); + for (Location location : tail) { + sb.append(','); + sb.append(String.format("{x: %d, y: %d}", + Integer.valueOf(location.x), Integer.valueOf(location.y))); + } + return String.format("{'id':%d,'body':[%s]}", + Integer.valueOf(id), sb.toString()); + } + + public int getId() { + return id; + } + + public String getHexColor() { + return hexColor; + } +} Propchange: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/SnakeWebSocketServlet.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/webapps/examples/websocket/snake.html URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/websocket/snake.html?rev=1297914&r1=1297913&r2=1297914&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/websocket/snake.html (original) +++ tomcat/trunk/webapps/examples/websocket/snake.html Wed Mar 7 09:42:27 2012 @@ -1,254 +1,254 @@ -<!-- - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> - <title>Apache Tomcat WebSocket Examples: Multiplayer Snake</title> - <style type="text/css"> - #playground { - width: 640px; - height: 480px; - background-color: #000; - } - - #console-container { - float: left; - margin-left: 15px; - width: 300px; - } - - #console { - border: 1px solid #CCCCCC; - border-right-color: #999999; - border-bottom-color: #999999; - height: 480px; - overflow-y: scroll; - padding-left: 5px; - padding-right: 5px; - width: 100%; - } - - #console p { - padding: 0; - margin: 0; - } - </style> -</head> -<body> - <noscript><h1>Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable - Javascript and reload this page!</h1></noscript> - <div style="float: left"> - <canvas id="playground" width="640" height="480"></canvas> - </div> - <div id="console-container"> - <div id="console"></div> - </div> - <script type="text/javascript"> - - var Game = {}; - - Game.fps = 30; - Game.socket = null; - Game.nextFrame = null; - Game.interval = null; - Game.direction = 'none'; - Game.gridSize = 10; - - function Snake() { - this.snakeBody = []; - this.color = null; - } - - Snake.prototype.draw = function(context) { - for (var id in this.snakeBody) { - context.fillStyle = this.color; - context.fillRect(this.snakeBody[id].x, this.snakeBody[id].y, Game.gridSize, Game.gridSize); - } - }; - - Game.initialize = function() { - this.entities = []; - canvas = document.getElementById('playground'); - if (!canvas.getContext) { - Console.log('Error: 2d canvas not supported by this browser.'); - return; - } - this.context = canvas.getContext('2d'); - window.addEventListener('keydown', function (e) { - var code = e.keyCode; - if (code > 36 && code < 41) { - switch (code) { - case 37: - if (Game.direction != 'east') Game.setDirection('west'); - break; - case 38: - if (Game.direction != 'south') Game.setDirection('north'); - break; - case 39: - if (Game.direction != 'west') Game.setDirection('east'); - break; - case 40: - if (Game.direction != 'north') Game.setDirection('south'); - break; - } - } - }, false); - Game.connect('ws://' + window.location.host + '/examples/websocket/snake'); - }; - - Game.setDirection = function(direction) { - Game.direction = direction; - Game.socket.send(direction); - Console.log('Sent: Direction ' + direction); - }; - - Game.startGameLoop = function() { - if (window.webkitRequestAnimationFrame) { - Game.nextFrame = function () { - webkitRequestAnimationFrame(Game.run); - }; - } else if (window.mozRequestAnimationFrame) { - Game.nextFrame = function () { - mozRequestAnimationFrame(Game.run); - }; - } else { - Game.interval = setInterval(Game.run, 1000 / Game.fps); - } - if (Game.nextFrame != null) { - Game.nextFrame(); - } - }; - - Game.stopGameLoop = function () { - Game.nextFrame = null; - if (Game.interval != null) { - clearInterval(Game.interval); - } - }; - - Game.draw = function() { - this.context.clearRect(0, 0, 640, 480); - for (var id in this.entities) { - this.entities[id].draw(this.context); - } - }; - - Game.addSnake = function(id, color) { - Game.entities[id] = new Snake(); - Game.entities[id].color = color; - }; - - Game.updateSnake = function(id, snakeBody) { - if (typeof Game.entities[id] != "undefined") { - Game.entities[id].snakeBody = snakeBody; - } - }; - - Game.removeSnake = function(id) { - Game.entities[id] = null; - // Force GC. - delete Game.entities[id]; - }; - - Game.run = (function() { - var skipTicks = 1000 / Game.fps, nextGameTick = (new Date).getTime(); - - return function() { - while ((new Date).getTime() > nextGameTick) { - nextGameTick += skipTicks; - } - Game.draw(); - if (Game.nextFrame != null) { - Game.nextFrame(); - } - }; - })(); - - Game.connect = (function(host) { - if ('WebSocket' in window) { - Game.socket = new WebSocket(host); - } else if ('MozWebSocket' in window) { - Game.socket = new MozWebSocket(host); - } else { - Console.log('Error: WebSocket is not supported by this browser.'); - return; - } - - Game.socket.onopen = function () { - // Socket open.. start the game loop. - Console.log('Info: WebSocket connection opened.'); - Console.log('Info: Press an arrow key to begin.'); - Game.startGameLoop(); - setInterval(function() { - // Prevent server read timeout. - Game.socket.send('ping'); - }, 5000); - }; - - Game.socket.onclose = function () { - Console.log('Info: WebSocket closed.'); - Game.stopGameLoop(); - }; - - Game.socket.onmessage = function (message) { - // _Potential_ security hole, consider using json lib to parse data in production. - var packet = eval('(' + message.data + ')'); - switch (packet.type) { - case 'update': - for (var i = 0; i < packet.data.length; i++) { - Game.updateSnake(packet.data[i].id, packet.data[i].body); - } - break; - case 'join': - for (var j = 0; j < packet.data.length; j++) { - Game.addSnake(packet.data[j].id, packet.data[j].color); - } - break; - case 'leave': - Game.removeSnake(packet.id); - break; - case 'dead': - Console.log('Info: Your snake is dead, bad luck!'); - Game.direction = 'none'; - break; - case 'kill': - Console.log('Info: Head shot!'); - break; - } - }; - }); - - var Console = {}; - - Console.log = (function(message) { - var console = document.getElementById('console'); - var p = document.createElement('p'); - p.style.wordWrap = 'break-word'; - p.innerHTML = message; - console.appendChild(p); - while (console.childNodes.length > 25) { - console.removeChild(console.firstChild); - } - console.scrollTop = console.scrollHeight; - }); - - Game.initialize(); - </script> -</body> -</html> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> + <title>Apache Tomcat WebSocket Examples: Multiplayer Snake</title> + <style type="text/css"> + #playground { + width: 640px; + height: 480px; + background-color: #000; + } + + #console-container { + float: left; + margin-left: 15px; + width: 300px; + } + + #console { + border: 1px solid #CCCCCC; + border-right-color: #999999; + border-bottom-color: #999999; + height: 480px; + overflow-y: scroll; + padding-left: 5px; + padding-right: 5px; + width: 100%; + } + + #console p { + padding: 0; + margin: 0; + } + </style> +</head> +<body> + <noscript><h1>Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable + Javascript and reload this page!</h1></noscript> + <div style="float: left"> + <canvas id="playground" width="640" height="480"></canvas> + </div> + <div id="console-container"> + <div id="console"></div> + </div> + <script type="text/javascript"> + + var Game = {}; + + Game.fps = 30; + Game.socket = null; + Game.nextFrame = null; + Game.interval = null; + Game.direction = 'none'; + Game.gridSize = 10; + + function Snake() { + this.snakeBody = []; + this.color = null; + } + + Snake.prototype.draw = function(context) { + for (var id in this.snakeBody) { + context.fillStyle = this.color; + context.fillRect(this.snakeBody[id].x, this.snakeBody[id].y, Game.gridSize, Game.gridSize); + } + }; + + Game.initialize = function() { + this.entities = []; + canvas = document.getElementById('playground'); + if (!canvas.getContext) { + Console.log('Error: 2d canvas not supported by this browser.'); + return; + } + this.context = canvas.getContext('2d'); + window.addEventListener('keydown', function (e) { + var code = e.keyCode; + if (code > 36 && code < 41) { + switch (code) { + case 37: + if (Game.direction != 'east') Game.setDirection('west'); + break; + case 38: + if (Game.direction != 'south') Game.setDirection('north'); + break; + case 39: + if (Game.direction != 'west') Game.setDirection('east'); + break; + case 40: + if (Game.direction != 'north') Game.setDirection('south'); + break; + } + } + }, false); + Game.connect('ws://' + window.location.host + '/examples/websocket/snake'); + }; + + Game.setDirection = function(direction) { + Game.direction = direction; + Game.socket.send(direction); + Console.log('Sent: Direction ' + direction); + }; + + Game.startGameLoop = function() { + if (window.webkitRequestAnimationFrame) { + Game.nextFrame = function () { + webkitRequestAnimationFrame(Game.run); + }; + } else if (window.mozRequestAnimationFrame) { + Game.nextFrame = function () { + mozRequestAnimationFrame(Game.run); + }; + } else { + Game.interval = setInterval(Game.run, 1000 / Game.fps); + } + if (Game.nextFrame != null) { + Game.nextFrame(); + } + }; + + Game.stopGameLoop = function () { + Game.nextFrame = null; + if (Game.interval != null) { + clearInterval(Game.interval); + } + }; + + Game.draw = function() { + this.context.clearRect(0, 0, 640, 480); + for (var id in this.entities) { + this.entities[id].draw(this.context); + } + }; + + Game.addSnake = function(id, color) { + Game.entities[id] = new Snake(); + Game.entities[id].color = color; + }; + + Game.updateSnake = function(id, snakeBody) { + if (typeof Game.entities[id] != "undefined") { + Game.entities[id].snakeBody = snakeBody; + } + }; + + Game.removeSnake = function(id) { + Game.entities[id] = null; + // Force GC. + delete Game.entities[id]; + }; + + Game.run = (function() { + var skipTicks = 1000 / Game.fps, nextGameTick = (new Date).getTime(); + + return function() { + while ((new Date).getTime() > nextGameTick) { + nextGameTick += skipTicks; + } + Game.draw(); + if (Game.nextFrame != null) { + Game.nextFrame(); + } + }; + })(); + + Game.connect = (function(host) { + if ('WebSocket' in window) { + Game.socket = new WebSocket(host); + } else if ('MozWebSocket' in window) { + Game.socket = new MozWebSocket(host); + } else { + Console.log('Error: WebSocket is not supported by this browser.'); + return; + } + + Game.socket.onopen = function () { + // Socket open.. start the game loop. + Console.log('Info: WebSocket connection opened.'); + Console.log('Info: Press an arrow key to begin.'); + Game.startGameLoop(); + setInterval(function() { + // Prevent server read timeout. + Game.socket.send('ping'); + }, 5000); + }; + + Game.socket.onclose = function () { + Console.log('Info: WebSocket closed.'); + Game.stopGameLoop(); + }; + + Game.socket.onmessage = function (message) { + // _Potential_ security hole, consider using json lib to parse data in production. + var packet = eval('(' + message.data + ')'); + switch (packet.type) { + case 'update': + for (var i = 0; i < packet.data.length; i++) { + Game.updateSnake(packet.data[i].id, packet.data[i].body); + } + break; + case 'join': + for (var j = 0; j < packet.data.length; j++) { + Game.addSnake(packet.data[j].id, packet.data[j].color); + } + break; + case 'leave': + Game.removeSnake(packet.id); + break; + case 'dead': + Console.log('Info: Your snake is dead, bad luck!'); + Game.direction = 'none'; + break; + case 'kill': + Console.log('Info: Head shot!'); + break; + } + }; + }); + + var Console = {}; + + Console.log = (function(message) { + var console = document.getElementById('console'); + var p = document.createElement('p'); + p.style.wordWrap = 'break-word'; + p.innerHTML = message; + console.appendChild(p); + while (console.childNodes.length > 25) { + console.removeChild(console.firstChild); + } + console.scrollTop = console.scrollHeight; + }); + + Game.initialize(); + </script> +</body> +</html> Propchange: tomcat/trunk/webapps/examples/websocket/snake.html ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org