 It was Thursday evening, when spiff and I got the idea to write an OpenSource game on HTML5, which is progressive in our time, as they say, from scratch and just for fun.
 It was Thursday evening, when spiff and I got the idea to write an OpenSource game on HTML5, which is progressive in our time, as they say, from scratch and just for fun.
function GameModel() { this.setView = function(v) { view = v; }; this.getView = function() { return view; }; this.moveLeft = function() { ... }; this.moveRight = function() { ... }; this.next = function() { // build next/new frame ... view.update(); //update view }; } function HTML5View(canvas) { var model; this.setModel = function(m) { model = m; }; this.getModel = function() { return model; }; var context = canvas.getContext("2d"); this.update = function() { // clear view ... // drawing model to canvas ... }; } function KeyboardController() { var model = null; this.setModel = function(m) { model = m; }; this.getModel = function() { return model; }; this.keydown = function(event) { if (event.keyCode == LEFT_KEY_CODE) { model.moveLeft(); } else if (event.keyCode == RIGHT_KEY_CODE) { model.moveRight(); } }; document.onkeydown = this.keydown; } function Game(model, view, ctrl) { view.setModel(model); ctrl.setModel(model); model.setView(view); this.run = function() { setInterval(model.next, 1000 / DEFAULT_FPS); }; } function main(canvas) { var view = new HTML5View(canvas); var model = new GameModel(); var ctrl = new KeyboardController(); var game = new Game(model, view, ctrl); game.run(); } 
 var generatePlatforms = function() { do { var type = (Math.random() 0.6) ? PLATFORM_TYPE.SOLID : PLATFORM_TYPE.KILLER; var baseline = pCounter > 0 ? platforms[pCounter - 1].y : 0; platforms[pCounter++] = { x: Math.floor(Math.random() * (WIDTH - DEFAULT_PLATFORM_WIDTH)), y: Math.floor(baseline + (Math.random() * (DEFAULT_MAX_PLATFORM_INTERVAL - DEFAULT_MIN_PLATFORM_INTERVAL + 1)) + DEFAULT_MIN_PLATFORM_INTERVAL), w: DEFAULT_PLATFORM_WIDTH, h: DEFAULT_PLATFORM_HEIGHT, type: type }; } while (platforms[pCounter - 1].y < (HEIGHT + DEFAULT_PLATFORM_HEIGHT)); };  var isRollCrossPlatform = function(platform, rollPrev, rollNext) { // we should to check only platforms between prev roll and next roll if (platform.y <= rollPrev.y || platform.y > rollNext.y + rollNext.h) return false; var s1 = { x1: platform.x, y1: platform.y, x2: platform.x + platform.w, y2: platform.y }; var s2 = { x1: rollPrev.x, y1: rollPrev.y + rollPrev.h - worldSpeed, x2: rollNext.x, y2: rollNext.y + rollNext.h }; var s3 = { x1: rollPrev.x + rollPrev.w, y1: rollPrev.y + rollPrev.h - worldSpeed, x2: rollNext.x + rollNext.w, y2: rollNext.y + rollNext.h }; var zn1 = (s2.y2 - s2.y1) * (s1.x2 - s1.x1) - (s2.x2 - s2.x1) * (s1.y2 - s1.y1); var zn2 = (s3.y2 - s3.y1) * (s1.x2 - s1.x1) - (s3.x2 - s3.x1) * (s1.y2 - s1.y1); if (Math.abs(zn1) < Math.EPS && Math.abs(zn2) < Math.EPS) return false; var ch11 = (s2.x2 - s2.x1) * (s1.y1 - s2.y1) - (s2.y2 - s2.y1) * (s1.x1 - s2.x1); var ch21 = (s1.x2 - s1.x1) * (s1.y1 - s2.y1) - (s1.y2 - s1.y1) * (s1.x1 - s2.x1); if ((ch11/zn1 <= 1.0 && ch11/zn1 >= 0.0) && (ch21/zn1 <= 1.0 && ch21/zn1 >= 0.0)) { return true; } var ch12 = (s3.x2 - s3.x1) * (s1.y1 - s3.y1) - (s3.y2 - s3.y1) * (s1.x1 - s3.x1); var ch22 = (s1.x2 - s1.x1) * (s1.y1 - s3.y1) - (s1.y2 - s1.y1) * (s1.x1 - s3.x1); if ((ch12/zn2 <= 1.0 && ch12/zn2 >= 0.0) && (ch22/zn2 <= 1.0 && ch22/zn2 >= 0.0)) { return true; } return false; }; 
 context.fillRect(x, y, width, height) -> context.drawImage(roll, x, y, width, height)  // draw current fps var fps = (frameCounter / totalTime) * 1000.0; context.fillText(fps.toFixed(2) + " fps", 4, HEIGHT - 6); // calc FPS if (frameCounter > FPS_REFRESH_INTERVAL) { frameCounter = 0; totalTime = 0; } frameCounter++; var currentTime = new Date().getTime(); totalTime += (currentTime - lastTime); lastTime = currentTime; 
Source: https://habr.com/ru/post/131366/
All Articles