Java Script
(function() { var Camera = function(context, settings) { settings = settings || {}; this.distance = 1000.0; this.lookat = [0,0]; this.context = context; this.fieldOfView = Math.tan(Math.PI / 4.0).toFixed(6); //0.9999999 라서 거의 1입니다. this.viewport = { left: 0, right: 0, top: 0, bottom: 0, width: 0, height: 0, scale: [1.0, 1.0] }; this.updateViewport(); }; Camera.prototype = { begin: function() { this.context.save(); this.applyScale(); this.applyTranslation(); }, end: function() { this.context.restore(); }, applyScale: function() { this.context.scale(this.viewport.scale[0], this.viewport.scale[1]); }, applyTranslation: function() { this.context.translate(-this.viewport.left, -this.viewport.top); }, updateViewport: function() { this.aspectRatio = this.context.canvas.width / this.context.canvas.height; this.viewport.width = this.distance * this.fieldOfView; this.viewport.height = this.viewport.width / this.aspectRatio; this.viewport.left = this.lookat[0] - (this.viewport.width / 2.0); this.viewport.top = this.lookat[1] - (this.viewport.height / 2.0); this.viewport.right = this.viewport.left + this.viewport.width; this.viewport.bottom = this.viewport.top + this.viewport.height; this.viewport.scale[0] = this.context.canvas.width / this.viewport.width; this.viewport.scale[1] = this.context.canvas.height / this.viewport.height; }, zoomTo: function(z) { this.distance = z; this.updateViewport(); }, moveTo: function(x, y) { this.lookat[0] = x; this.lookat[1] = y; this.updateViewport(); }, screenToWorld: function(x, y, obj) { obj = obj || {}; obj.x = (x / this.viewport.scale[0]) + this.viewport.left; obj.y = (y / this.viewport.scale[1]) + this.viewport.top; return obj; }, worldToScreen: function(x, y, obj) { obj = obj || {}; obj.x = (x - this.viewport.left) * (this.viewport.scale[0]); obj.y = (y - this.viewport.top) * (this.viewport.scale[1]); return obj; } }; this.Camera = Camera; }).call(this); // ========================================= 객체 생성 관련 // This file is for crap not relevant to this discussion var findRequestAnimationFrame = function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element){ window.setTimeout(callback, 1000 / 30); }; }; var Wall = function(x, y, width, height) { this.x = x; this.y = y; this.width = width; this.height = height; }; Wall.prototype = { draw: function(context) { context.beginPath(); context.moveTo(this.x, this.y); context.lineTo(this.x + this.width, this.y); context.lineTo(this.x + this.width, this.y + this.height); context.lineTo(this.x, this.y + this.height); context.lineTo(this.x, this.y); context.stroke(); } }; var Sprite = function(x, y, width, height, colour) { this.x = x; this.y = y; this.velx = Math.random() * 2.0 - 1.0; this.vely = Math.random() * 2.0 - 1.0; this.width = width; this.height = height; this.colour = colour; }; Sprite.prototype = { tick: function() { this.x += this.velx; this.y += this.vely; }, draw: function(context) { context.fillStyle = this.colour; context.fillRect(this.x, this.y, this.width, this.height); } }; var ObjectPool = function(wall, numObjects) { this.objects = []; this.wall = wall; this.numObjects = numObjects; this.createObjects(); }; ObjectPool.prototype = { createObjects: function() { for(var i = 0; i < this.numObjects; i++) { var width = Math.random() * 50.0 + 10.0; var height = Math.random() * 50.0 + 10.0; var x = this.wall.x + (Math.random() * (this.wall.width - width)); var y = this.wall.y + (Math.random() * (this.wall.height - height)); this.objects.push(new Sprite(x, y, width, height, '#000')); } }, tick: function() { this.objects.forEach(function(item) { item.tick(); }); this.collide(); }, draw: function(context) { this.objects.forEach(function(item) { item.draw(context); }); }, collide: function() { for(var i =0; i < this.objects.length; i++){ this.collideWalls(this.objects[i]); for(var j = i ; j < this.objects.length; j++) { var obj1 = this.objects[i]; var obj2 = this.objects[j]; this.collideObjects(obj1, obj2); } } }, collideObjects: function(one, two) { if(one.x + one.width < two.x) return; if(two.x + two.width < one.x) return; if(one.y + one.height < two.y) return; if(two.y + two.height < one.y) return; var tx = one.velx; var ty = one.vely; one.velx = two.velx; one.vely = two.vely; two.velx = tx; two.vely = ty; }, collideWalls: function(obj) { if(obj.x < this.wall.x || obj.x + obj.width > this.wall.x + this.wall.width) obj.velx = -obj.velx; if(obj.y < this.wall.y || obj.y + obj.height > this.wall.y + this.wall.height) obj.vely = -obj.vely; } }; // ========================================= 객체 생성 관련 // start the game when page is loaded $(document).ready(function() { var canvas = document.getElementById('target'); var context = canvas.getContext('2d'); var camera = new Camera(context); var renderFrame = findRequestAnimationFrame(); var objects = []; var updateScene = function() { objects.forEach(function(item) { if(item.tick) item.tick(); }); }; var drawScene = function() { context.clearRect(0, 0, canvas.width, canvas.height); camera.begin(); objects.forEach(function(item) { if(item.draw) item.draw(context); }); camera.end(); }; var tick = function() { updateScene(); drawScene(); renderFrame(tick); }; var wall = new Wall(-300, -300, 600, 600); objects.push(wall); objects.push(new ObjectPool(wall, 10)); renderFrame(tick); });