blob: b71077c63a46771def4b35763d749b121f3cbf8c [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Apache Tomcat WebSocket Examples: Multiplayer Snake</title>
<style type="text/css"><![CDATA[
#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>
<div class="noscript"><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable
Javascript and reload this page!</h2></div>
<div style="float: left">
<canvas id="playground" width="640" height="480"/>
</div>
<div id="console-container">
<div id="console"/>
</div>
<script type="application/javascript"><![CDATA[
"use strict";
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 = [];
var 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);
if (window.location.protocol == 'http:') {
Game.connect('ws://' + window.location.host + '/examples/websocket/snake');
} else {
Game.connect('wss://' + 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) {
var packet = JSON.parse(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();
document.addEventListener("DOMContentLoaded", function() {
// Remove elements with "noscript" class - <noscript> is not allowed in XHTML
var noscripts = document.getElementsByClassName("noscript");
for (var i = 0; i < noscripts.length; i++) {
noscripts[i].parentNode.removeChild(noscripts[i]);
}
}, false);
]]></script>
</body>
</html>