diff --git a/game/asset/image/sample/javascript-racer-master/LICENSE b/game/asset/image/sample/javascript-racer-master/LICENSE new file mode 100644 index 0000000..efec39d --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012, 2013, 2014, 2015, 2016 Jake Gordon and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +=============================================================================== + diff --git a/game/asset/image/sample/javascript-racer-master/README.md b/game/asset/image/sample/javascript-racer-master/README.md new file mode 100644 index 0000000..b765bff --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/README.md @@ -0,0 +1,111 @@ +Javascript Pseudo 3D Racer +========================== + +An Outrun-style pseudo-3d racing game in HTML5 and Javascript + + * [play the game](https://jakesgordon.com/games/racer/) + * view the [source](https://github.com/jakesgordon/javascript-racer) + * read about [how it works](https://jakesgordon.com/writing/javascript-racer/) + +Incrementally built up in 4 parts: + + * play the [straight road demo](https://jakesgordon.com/games/racer/v1-straight/) + * play the [curves demo](https://jakesgordon.com/games/racer/v2-curves/) + * play the [hills demo](https://jakesgordon.com/games/racer/v3-hills/) + * play the [final version](https://jakesgordon.com/games/racer/) + +With detailed descriptions of how each part works: + + * read more about [v1 - straight roads](https://jakesgordon.com/writing/javascript-racer-v1-straight/) + * read more about [v2 - curves](https://jakesgordon.com/writing/javascript-racer-v2-curves/) + * read more about [v3 - hills](https://jakesgordon.com/writing/javascript-racer-v3-hills/) + * read more about v4 - final (coming soon) + +A note on performance +===================== + +The performance of this game is **very** machine/browser dependent. It works quite well in modern +browsers, especially those with GPU canvas acceleration, but a bad graphics driver can kill it stone +dead. So your mileage may vary. There are controls provided to change the rendering resolution +and the draw distance to scale to fit your machine. + +Currently supported browsers include: + + * Firefox (v12+) works great, 60fps at high res - Nice! + * Chrome (v19+) works great, 60fps at high res... provided you dont have a bad GPU driver + * IE9 - ok, 30fps at medium res... not great, but at least it works + +The current state of mobile browser performance is pretty dismal. Dont expect this to be playable on +any mobile device. + +>> _NOTE: I havent actually spent anytime optimizing for performance yet. So it might be possible to + make it play well on older browsers, but that's not really what this project is about._ + +A note on code structure +======================== + +This project happens to be implemented in javascript (because its easy for prototyping) but +is not intended to demonstrate javascript techniques or best practices. In fact, in order to +keep it simple to understand it embeds the javascript for each example directly in the HTML +page (horror!) and, even worse, uses global variables and functions (OMG!). + +If I was building a real game I would have much more structure and organization to the +code, but since its just a racing game tech demo, I have elected to [KISS](http://en.wikipedia.org/wiki/KISS_principle). + +FUTURE +====== + +It's quite astounding what it takes to actually [finish](https://jakesgordon.com/writing/defining-finished/) +a game, even a simple one. And this is not a project that I plan on polishing into a finished state. It should +really be considered just how to get started with a pseudo-3d racing game. + +If we were to try to turn it into a real game we would have to consider: + + * car sound fx + * better synchronized music + * full screen mode + * HUD fx (flash on fastest lap, confetti, color coded speedometer, etc) + * more accurate sprite collision + * better car AI (steering, braking etc) + * an actual crash when colliding at high speed + * more bounce when car is off road + * screen shake when off-road or collision + * throw up dirt particles when off road + * more dynamic camera (lower at faster speed, swoop over hills etc) + * automatic resolution & drawDistance detection + * projection based curves ? x,y rotation + * sub-pixel aliasing artifacts on curves + * smarter fog to cover sprites (blue against sky, cover sprites) + * multiple stages, different maps + * a lap map, with current position indicator + * road splits and joins + * day/night cycle + * weather effects + * tunnels, bridges, clouds, walls, buildings + * city, desert, ocean + * add city of seattle and space needle to background + * 'bad guys' - add some competetor drivers to race against as well as the 'traffic' + * different game modes - fastest lap, 1-on-1 racing, collect coins ? shoot bad guys ? + * a whole lot of gameplay tuning + * ... + * ... + +Related Links +============= + + * [Lou's Pseudo-3d Page](http://www.extentofthejam.com/pseudo/) - high level how-to guide + * [Racer 10k](https://github.com/onaluf/RacerJS) - another javascript racing game + +License +======= + +[MIT](http://en.wikipedia.org/wiki/MIT_License) license. + +>> NOTE: the music tracks included in this project are royalty free resources paid for and licensed +from [Lucky Lion Studios](http://luckylionstudios.com/). They are licensed ONLY for use in this +project and should not be reproduced. + +>> NOTE: the sprite graphics are placeholder graphics [borrowed](http://pixel.garoux.net/game/44) from the old +genesis version of outrun and used here as teaching examples. If there are any pixel artists out there who want to +provide original art to turn this into a real game please get in touch! + diff --git a/game/asset/image/sample/javascript-racer-master/Rakefile b/game/asset/image/sample/javascript-racer-master/Rakefile new file mode 100644 index 0000000..c02a1df --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/Rakefile @@ -0,0 +1,36 @@ + +desc 'recreate sprite sheets' +task 'resprite' do + require 'sprite_factory' + + SpriteFactory.run!('images/sprites', :layout => :packed, :output_style => 'images/sprites.js', :margin => 5, :nocomments => true) do |images| + SpriteHelper.javascript_style("SPRITES", images) + end + + SpriteFactory.run!('images/background', :layout => :vertical, :output_style => 'images/background.js', :margin => 5, :nocomments => true) do |images| + SpriteHelper.javascript_style("BACKGROUND", images) + end + +end + +#------------------------------------------------------------------------------ + +module SpriteHelper + + # slightly unusual use of sprite-factory to generate a javascript object structure instead of CSS attributes... + def self.javascript_style(variable, images) + maxname = images.keys.inject(0) {|n,key| [n,key.length].max } + rules = [] + images.each do |name, i| + name = name.upcase + whitespace = ' '*(maxname-name.length) + x = '%4d' % i[:cssx] + y = '%4d' % i[:cssy] + w = '%4d' % i[:cssw] + h = '%4d' % i[:cssh] + rules << " #{name}: #{whitespace}{ x: #{x}, y: #{y}, w: #{w}, h: #{h} }" + end + "var #{variable} = {\n#{rules.join(",\n")}\n};" + end + +end diff --git a/game/asset/image/sample/javascript-racer-master/common.css b/game/asset/image/sample/javascript-racer-master/common.css new file mode 100644 index 0000000..5bb2d2b --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/common.css @@ -0,0 +1,28 @@ + +/****************************************/ +/* common styles used for v1 through v4 */ +/****************************************/ + +body { font-family: Arial, Helvetica, sans-serif; } +#stats { border: 2px solid black; } +#controls { width: 28em; float: left; padding: 1em; font-size: 0.7em; } +#controls th { text-align: right; vertical-align: middle; } +#instructions { clear: left; float: left; width: 17em; padding: 1em; border: 1px solid black; box-shadow: 0 0 5px black; } +#racer { position: relative; z-index: 0; width: 640px; height: 480px; margin-left: 20em; border: 2px solid black; } +#canvas { position: absolute; z-index: 0; width: 640px; height: 480px; z-index: 0; background-color: #72D7EE; } +#mute { background-position: 0px 0px; width: 32px; height: 32px; background: url(images/mute.png); display: inline-block; cursor: pointer; position: absolute; margin-left: 20em; } +#mute.on { background-position: -32px 0px; } + +/**************************************************/ +/* rudimentary heads up display (only used in v4) */ +/**************************************************/ + +#hud { position: absolute; z-index: 1; width: 640px; padding: 5px 0; font-family: Verdana, Geneva, sans-serif; font-size: 0.8em; background-color: rgba(255,0,0,0.4); color: black; border-bottom: 2px solid black; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } +#hud .hud { background-color: rgba(255,255,255,0.6); padding: 5px; border: 1px solid black; margin: 0 5px; transition-property: background-color; transition-duration: 2s; -webkit-transition-property: background-color; -webkit-transition-duration: 2s; } +#hud #speed { float: right; } +#hud #current_lap_time { float: left; } +#hud #last_lap_time { float: left; display: none; } +#hud #fast_lap_time { display: block; width: 12em; margin: 0 auto; text-align: center; transition-property: background-color; transition-duration: 2s; -webkit-transition-property: background-color; -webkit-transition-duration: 2s; } +#hud .value { color: black; font-weight: bold; } +#hud .fastest { background-color: rgba(255,215,0,0.5); } + diff --git a/game/asset/image/sample/javascript-racer-master/common.js b/game/asset/image/sample/javascript-racer-master/common.js new file mode 100644 index 0000000..a0eb697 --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/common.js @@ -0,0 +1,414 @@ +//========================================================================= +// minimalist DOM helpers +//========================================================================= + +var Dom = { + + get: function(id) { return ((id instanceof HTMLElement) || (id === document)) ? id : document.getElementById(id); }, + set: function(id, html) { Dom.get(id).innerHTML = html; }, + on: function(ele, type, fn, capture) { Dom.get(ele).addEventListener(type, fn, capture); }, + un: function(ele, type, fn, capture) { Dom.get(ele).removeEventListener(type, fn, capture); }, + show: function(ele, type) { Dom.get(ele).style.display = (type || 'block'); }, + blur: function(ev) { ev.target.blur(); }, + + addClassName: function(ele, name) { Dom.toggleClassName(ele, name, true); }, + removeClassName: function(ele, name) { Dom.toggleClassName(ele, name, false); }, + toggleClassName: function(ele, name, on) { + ele = Dom.get(ele); + var classes = ele.className.split(' '); + var n = classes.indexOf(name); + on = (typeof on == 'undefined') ? (n < 0) : on; + if (on && (n < 0)) + classes.push(name); + else if (!on && (n >= 0)) + classes.splice(n, 1); + ele.className = classes.join(' '); + }, + + storage: window.localStorage || {} + +} + +//========================================================================= +// general purpose helpers (mostly math) +//========================================================================= + +var Util = { + + timestamp: function() { return new Date().getTime(); }, + toInt: function(obj, def) { if (obj !== null) { var x = parseInt(obj, 10); if (!isNaN(x)) return x; } return Util.toInt(def, 0); }, + toFloat: function(obj, def) { if (obj !== null) { var x = parseFloat(obj); if (!isNaN(x)) return x; } return Util.toFloat(def, 0.0); }, + limit: function(value, min, max) { return Math.max(min, Math.min(value, max)); }, + randomInt: function(min, max) { return Math.round(Util.interpolate(min, max, Math.random())); }, + randomChoice: function(options) { return options[Util.randomInt(0, options.length-1)]; }, + percentRemaining: function(n, total) { return (n%total)/total; }, + accelerate: function(v, accel, dt) { return v + (accel * dt); }, + interpolate: function(a,b,percent) { return a + (b-a)*percent }, + easeIn: function(a,b,percent) { return a + (b-a)*Math.pow(percent,2); }, + easeOut: function(a,b,percent) { return a + (b-a)*(1-Math.pow(1-percent,2)); }, + easeInOut: function(a,b,percent) { return a + (b-a)*((-Math.cos(percent*Math.PI)/2) + 0.5); }, + exponentialFog: function(distance, density) { return 1 / (Math.pow(Math.E, (distance * distance * density))); }, + + increase: function(start, increment, max) { // with looping + var result = start + increment; + while (result >= max) + result -= max; + while (result < 0) + result += max; + return result; + }, + + project: function(p, cameraX, cameraY, cameraZ, cameraDepth, width, height, roadWidth) { + p.camera.x = (p.world.x || 0) - cameraX; + p.camera.y = (p.world.y || 0) - cameraY; + p.camera.z = (p.world.z || 0) - cameraZ; + p.screen.scale = cameraDepth/p.camera.z; + p.screen.x = Math.round((width/2) + (p.screen.scale * p.camera.x * width/2)); + p.screen.y = Math.round((height/2) - (p.screen.scale * p.camera.y * height/2)); + p.screen.w = Math.round( (p.screen.scale * roadWidth * width/2)); + }, + + overlap: function(x1, w1, x2, w2, percent) { + var half = (percent || 1)/2; + var min1 = x1 - (w1*half); + var max1 = x1 + (w1*half); + var min2 = x2 - (w2*half); + var max2 = x2 + (w2*half); + return ! ((max1 < min2) || (min1 > max2)); + } + +} + +//========================================================================= +// POLYFILL for requestAnimationFrame +//========================================================================= + +if (!window.requestAnimationFrame) { // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + window.requestAnimationFrame = window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback, element) { + window.setTimeout(callback, 1000 / 60); + } +} + +//========================================================================= +// GAME LOOP helpers +//========================================================================= + +var Game = { // a modified version of the game loop from my previous boulderdash game - see https://jakesgordon.com/writing/javascript-boulderdash/#gameloop + + run: function(options) { + + Game.loadImages(options.images, function(images) { + + options.ready(images); // tell caller to initialize itself because images are loaded and we're ready to rumble + + Game.setKeyListener(options.keys); + + var canvas = options.canvas, // canvas render target is provided by caller + update = options.update, // method to update game logic is provided by caller + render = options.render, // method to render the game is provided by caller + step = options.step, // fixed frame step (1/fps) is specified by caller + stats = options.stats, // stats instance is provided by caller + now = null, + last = Util.timestamp(), + dt = 0, + gdt = 0; + + function frame() { + now = Util.timestamp(); + dt = Math.min(1, (now - last) / 1000); // using requestAnimationFrame have to be able to handle large delta's caused when it 'hibernates' in a background or non-visible tab + gdt = gdt + dt; + while (gdt > step) { + gdt = gdt - step; + update(step); + } + render(); + stats.update(); + last = now; + requestAnimationFrame(frame, canvas); + } + frame(); // lets get this party started + Game.playMusic(); + }); + }, + + //--------------------------------------------------------------------------- + + loadImages: function(names, callback) { // load multiple images and callback when ALL images have loaded + var result = []; + var count = names.length; + + var onload = function() { + if (--count == 0) + callback(result); + }; + + for(var n = 0 ; n < names.length ; n++) { + var name = names[n]; + result[n] = document.createElement('img'); + Dom.on(result[n], 'load', onload); + result[n].src = "images/" + name + ".png"; + } + }, + + //--------------------------------------------------------------------------- + + setKeyListener: function(keys) { + var onkey = function(keyCode, mode) { + var n, k; + for(n = 0 ; n < keys.length ; n++) { + k = keys[n]; + k.mode = k.mode || 'up'; + if ((k.key == keyCode) || (k.keys && (k.keys.indexOf(keyCode) >= 0))) { + if (k.mode == mode) { + k.action.call(); + } + } + } + }; + Dom.on(document, 'keydown', function(ev) { onkey(ev.keyCode, 'down'); } ); + Dom.on(document, 'keyup', function(ev) { onkey(ev.keyCode, 'up'); } ); + }, + + //--------------------------------------------------------------------------- + + stats: function(parentId, id) { // construct mr.doobs FPS counter - along with friendly good/bad/ok message box + + var result = new Stats(); + result.domElement.id = id || 'stats'; + Dom.get(parentId).appendChild(result.domElement); + + var msg = document.createElement('div'); + msg.style.cssText = "border: 2px solid gray; padding: 5px; margin-top: 5px; text-align: left; font-size: 1.15em; text-align: right;"; + msg.innerHTML = "Your canvas performance is "; + Dom.get(parentId).appendChild(msg); + + var value = document.createElement('span'); + value.innerHTML = "..."; + msg.appendChild(value); + + setInterval(function() { + var fps = result.current(); + var ok = (fps > 50) ? 'good' : (fps < 30) ? 'bad' : 'ok'; + var color = (fps > 50) ? 'green' : (fps < 30) ? 'red' : 'gray'; + value.innerHTML = ok; + value.style.color = color; + msg.style.borderColor = color; + }, 5000); + return result; + }, + + //--------------------------------------------------------------------------- + + playMusic: function() { + var music = Dom.get('music'); + music.loop = true; + music.volume = 0.05; // shhhh! annoying music! + music.muted = (Dom.storage.muted === "true"); + music.play(); + Dom.toggleClassName('mute', 'on', music.muted); + Dom.on('mute', 'click', function() { + Dom.storage.muted = music.muted = !music.muted; + Dom.toggleClassName('mute', 'on', music.muted); + }); + } + +} + +//========================================================================= +// canvas rendering helpers +//========================================================================= + +var Render = { + + polygon: function(ctx, x1, y1, x2, y2, x3, y3, x4, y4, color) { + ctx.fillStyle = color; + ctx.beginPath(); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.lineTo(x3, y3); + ctx.lineTo(x4, y4); + ctx.closePath(); + ctx.fill(); + }, + + //--------------------------------------------------------------------------- + + segment: function(ctx, width, lanes, x1, y1, w1, x2, y2, w2, fog, color) { + + var r1 = Render.rumbleWidth(w1, lanes), + r2 = Render.rumbleWidth(w2, lanes), + l1 = Render.laneMarkerWidth(w1, lanes), + l2 = Render.laneMarkerWidth(w2, lanes), + lanew1, lanew2, lanex1, lanex2, lane; + + ctx.fillStyle = color.grass; + ctx.fillRect(0, y2, width, y1 - y2); + + Render.polygon(ctx, x1-w1-r1, y1, x1-w1, y1, x2-w2, y2, x2-w2-r2, y2, color.rumble); + Render.polygon(ctx, x1+w1+r1, y1, x1+w1, y1, x2+w2, y2, x2+w2+r2, y2, color.rumble); + Render.polygon(ctx, x1-w1, y1, x1+w1, y1, x2+w2, y2, x2-w2, y2, color.road); + + if (color.lane) { + lanew1 = w1*2/lanes; + lanew2 = w2*2/lanes; + lanex1 = x1 - w1 + lanew1; + lanex2 = x2 - w2 + lanew2; + for(lane = 1 ; lane < lanes ; lanex1 += lanew1, lanex2 += lanew2, lane++) + Render.polygon(ctx, lanex1 - l1/2, y1, lanex1 + l1/2, y1, lanex2 + l2/2, y2, lanex2 - l2/2, y2, color.lane); + } + + Render.fog(ctx, 0, y1, width, y2-y1, fog); + }, + + //--------------------------------------------------------------------------- + + background: function(ctx, background, width, height, layer, rotation, offset) { + + rotation = rotation || 0; + offset = offset || 0; + + var imageW = layer.w/2; + var imageH = layer.h; + + var sourceX = layer.x + Math.floor(layer.w * rotation); + var sourceY = layer.y + var sourceW = Math.min(imageW, layer.x+layer.w-sourceX); + var sourceH = imageH; + + var destX = 0; + var destY = offset; + var destW = Math.floor(width * (sourceW/imageW)); + var destH = height; + + ctx.drawImage(background, sourceX, sourceY, sourceW, sourceH, destX, destY, destW, destH); + if (sourceW < imageW) + ctx.drawImage(background, layer.x, sourceY, imageW-sourceW, sourceH, destW-1, destY, width-destW, destH); + }, + + //--------------------------------------------------------------------------- + + sprite: function(ctx, width, height, resolution, roadWidth, sprites, sprite, scale, destX, destY, offsetX, offsetY, clipY) { + + // scale for projection AND relative to roadWidth (for tweakUI) + var destW = (sprite.w * scale * width/2) * (SPRITES.SCALE * roadWidth); + var destH = (sprite.h * scale * width/2) * (SPRITES.SCALE * roadWidth); + + destX = destX + (destW * (offsetX || 0)); + destY = destY + (destH * (offsetY || 0)); + + var clipH = clipY ? Math.max(0, destY+destH-clipY) : 0; + if (clipH < destH) + ctx.drawImage(sprites, sprite.x, sprite.y, sprite.w, sprite.h - (sprite.h*clipH/destH), destX, destY, destW, destH - clipH); + + }, + + //--------------------------------------------------------------------------- + + player: function(ctx, width, height, resolution, roadWidth, sprites, speedPercent, scale, destX, destY, steer, updown) { + + var bounce = (1.5 * Math.random() * speedPercent * resolution) * Util.randomChoice([-1,1]); + var sprite; + if (steer < 0) + sprite = (updown > 0) ? SPRITES.PLAYER_UPHILL_LEFT : SPRITES.PLAYER_LEFT; + else if (steer > 0) + sprite = (updown > 0) ? SPRITES.PLAYER_UPHILL_RIGHT : SPRITES.PLAYER_RIGHT; + else + sprite = (updown > 0) ? SPRITES.PLAYER_UPHILL_STRAIGHT : SPRITES.PLAYER_STRAIGHT; + + Render.sprite(ctx, width, height, resolution, roadWidth, sprites, sprite, scale, destX, destY + bounce, -0.5, -1); + }, + + //--------------------------------------------------------------------------- + + fog: function(ctx, x, y, width, height, fog) { + if (fog < 1) { + ctx.globalAlpha = (1-fog) + ctx.fillStyle = COLORS.FOG; + ctx.fillRect(x, y, width, height); + ctx.globalAlpha = 1; + } + }, + + rumbleWidth: function(projectedRoadWidth, lanes) { return projectedRoadWidth/Math.max(6, 2*lanes); }, + laneMarkerWidth: function(projectedRoadWidth, lanes) { return projectedRoadWidth/Math.max(32, 8*lanes); } + +} + +//============================================================================= +// RACING GAME CONSTANTS +//============================================================================= + +var KEY = { + LEFT: 37, + UP: 38, + RIGHT: 39, + DOWN: 40, + A: 65, + D: 68, + S: 83, + W: 87 +}; + +var COLORS = { + SKY: '#72D7EE', + TREE: '#005108', + FOG: '#005108', + LIGHT: { road: '#6B6B6B', grass: '#10AA10', rumble: '#555555', lane: '#CCCCCC' }, + DARK: { road: '#696969', grass: '#009A00', rumble: '#BBBBBB' }, + START: { road: 'white', grass: 'white', rumble: 'white' }, + FINISH: { road: 'black', grass: 'black', rumble: 'black' } +}; + +var BACKGROUND = { + HILLS: { x: 5, y: 5, w: 1280, h: 480 }, + SKY: { x: 5, y: 495, w: 1280, h: 480 }, + TREES: { x: 5, y: 985, w: 1280, h: 480 } +}; + +var SPRITES = { + PALM_TREE: { x: 5, y: 5, w: 215, h: 540 }, + BILLBOARD08: { x: 230, y: 5, w: 385, h: 265 }, + TREE1: { x: 625, y: 5, w: 360, h: 360 }, + DEAD_TREE1: { x: 5, y: 555, w: 135, h: 332 }, + BILLBOARD09: { x: 150, y: 555, w: 328, h: 282 }, + BOULDER3: { x: 230, y: 280, w: 320, h: 220 }, + COLUMN: { x: 995, y: 5, w: 200, h: 315 }, + BILLBOARD01: { x: 625, y: 375, w: 300, h: 170 }, + BILLBOARD06: { x: 488, y: 555, w: 298, h: 190 }, + BILLBOARD05: { x: 5, y: 897, w: 298, h: 190 }, + BILLBOARD07: { x: 313, y: 897, w: 298, h: 190 }, + BOULDER2: { x: 621, y: 897, w: 298, h: 140 }, + TREE2: { x: 1205, y: 5, w: 282, h: 295 }, + BILLBOARD04: { x: 1205, y: 310, w: 268, h: 170 }, + DEAD_TREE2: { x: 1205, y: 490, w: 150, h: 260 }, + BOULDER1: { x: 1205, y: 760, w: 168, h: 248 }, + BUSH1: { x: 5, y: 1097, w: 240, h: 155 }, + CACTUS: { x: 929, y: 897, w: 235, h: 118 }, + BUSH2: { x: 255, y: 1097, w: 232, h: 152 }, + BILLBOARD03: { x: 5, y: 1262, w: 230, h: 220 }, + BILLBOARD02: { x: 245, y: 1262, w: 215, h: 220 }, + STUMP: { x: 995, y: 330, w: 195, h: 140 }, + SEMI: { x: 1365, y: 490, w: 122, h: 144 }, + TRUCK: { x: 1365, y: 644, w: 100, h: 78 }, + CAR03: { x: 1383, y: 760, w: 88, h: 55 }, + CAR02: { x: 1383, y: 825, w: 80, h: 59 }, + CAR04: { x: 1383, y: 894, w: 80, h: 57 }, + CAR01: { x: 1205, y: 1018, w: 80, h: 56 }, + PLAYER_UPHILL_LEFT: { x: 1383, y: 961, w: 80, h: 45 }, + PLAYER_UPHILL_STRAIGHT: { x: 1295, y: 1018, w: 80, h: 45 }, + PLAYER_UPHILL_RIGHT: { x: 1385, y: 1018, w: 80, h: 45 }, + PLAYER_LEFT: { x: 995, y: 480, w: 80, h: 41 }, + PLAYER_STRAIGHT: { x: 1085, y: 480, w: 80, h: 41 }, + PLAYER_RIGHT: { x: 995, y: 531, w: 80, h: 41 } +}; + +SPRITES.SCALE = 0.3 * (1/SPRITES.PLAYER_STRAIGHT.w) // the reference sprite width should be 1/3rd the (half-)roadWidth + +SPRITES.BILLBOARDS = [SPRITES.BILLBOARD01, SPRITES.BILLBOARD02, SPRITES.BILLBOARD03, SPRITES.BILLBOARD04, SPRITES.BILLBOARD05, SPRITES.BILLBOARD06, SPRITES.BILLBOARD07, SPRITES.BILLBOARD08, SPRITES.BILLBOARD09]; +SPRITES.PLANTS = [SPRITES.TREE1, SPRITES.TREE2, SPRITES.DEAD_TREE1, SPRITES.DEAD_TREE2, SPRITES.PALM_TREE, SPRITES.BUSH1, SPRITES.BUSH2, SPRITES.CACTUS, SPRITES.STUMP, SPRITES.BOULDER1, SPRITES.BOULDER2, SPRITES.BOULDER3]; +SPRITES.CARS = [SPRITES.CAR01, SPRITES.CAR02, SPRITES.CAR03, SPRITES.CAR04, SPRITES.SEMI, SPRITES.TRUCK]; + diff --git a/game/asset/image/sample/javascript-racer-master/images/background.js b/game/asset/image/sample/javascript-racer-master/images/background.js new file mode 100644 index 0000000..cae8fa6 --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/images/background.js @@ -0,0 +1,5 @@ +var BACKGROUND = { + HILLS: { x: 5, y: 5, w: 1280, h: 480 }, + SKY: { x: 5, y: 495, w: 1280, h: 480 }, + TREES: { x: 5, y: 985, w: 1280, h: 480 } +}; diff --git a/game/asset/image/sample/javascript-racer-master/images/background.png b/game/asset/image/sample/javascript-racer-master/images/background.png new file mode 100644 index 0000000..6590b02 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/background.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/background/background.svg b/game/asset/image/sample/javascript-racer-master/images/background/background.svg new file mode 100644 index 0000000..0bbcd8d --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/images/background/background.svg @@ -0,0 +1,1921 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/game/asset/image/sample/javascript-racer-master/images/background/hills.png b/game/asset/image/sample/javascript-racer-master/images/background/hills.png new file mode 100644 index 0000000..f1d2be5 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/background/hills.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/background/sky.png b/game/asset/image/sample/javascript-racer-master/images/background/sky.png new file mode 100644 index 0000000..26c332d Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/background/sky.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/background/trees.png b/game/asset/image/sample/javascript-racer-master/images/background/trees.png new file mode 100644 index 0000000..57fb422 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/background/trees.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/mute.png b/game/asset/image/sample/javascript-racer-master/images/mute.png new file mode 100644 index 0000000..5ee7f91 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/mute.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites.js b/game/asset/image/sample/javascript-racer-master/images/sprites.js new file mode 100644 index 0000000..2cd9324 --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/images/sprites.js @@ -0,0 +1,36 @@ +var SPRITES = { + PALM_TREE: { x: 5, y: 5, w: 215, h: 540 }, + BILLBOARD08: { x: 230, y: 5, w: 385, h: 265 }, + TREE1: { x: 625, y: 5, w: 360, h: 360 }, + DEAD_TREE1: { x: 5, y: 555, w: 135, h: 332 }, + BILLBOARD09: { x: 150, y: 555, w: 328, h: 282 }, + BOULDER3: { x: 230, y: 280, w: 320, h: 220 }, + COLUMN: { x: 995, y: 5, w: 200, h: 315 }, + BILLBOARD01: { x: 625, y: 375, w: 300, h: 170 }, + BILLBOARD06: { x: 488, y: 555, w: 298, h: 190 }, + BILLBOARD05: { x: 5, y: 897, w: 298, h: 190 }, + BILLBOARD07: { x: 313, y: 897, w: 298, h: 190 }, + BOULDER2: { x: 621, y: 897, w: 298, h: 140 }, + TREE2: { x: 1205, y: 5, w: 282, h: 295 }, + BILLBOARD04: { x: 1205, y: 310, w: 268, h: 170 }, + DEAD_TREE2: { x: 1205, y: 490, w: 150, h: 260 }, + BOULDER1: { x: 1205, y: 760, w: 168, h: 248 }, + BUSH1: { x: 5, y: 1097, w: 240, h: 155 }, + CACTUS: { x: 929, y: 897, w: 235, h: 118 }, + BUSH2: { x: 255, y: 1097, w: 232, h: 152 }, + BILLBOARD03: { x: 5, y: 1262, w: 230, h: 220 }, + BILLBOARD02: { x: 245, y: 1262, w: 215, h: 220 }, + STUMP: { x: 995, y: 330, w: 195, h: 140 }, + SEMI: { x: 1365, y: 490, w: 122, h: 144 }, + TRUCK: { x: 1365, y: 644, w: 100, h: 78 }, + CAR03: { x: 1383, y: 760, w: 88, h: 55 }, + CAR02: { x: 1383, y: 825, w: 80, h: 59 }, + CAR04: { x: 1383, y: 894, w: 80, h: 57 }, + CAR01: { x: 1205, y: 1018, w: 80, h: 56 }, + PLAYER_UPHILL_LEFT: { x: 1383, y: 961, w: 80, h: 45 }, + PLAYER_UPHILL_STRAIGHT: { x: 1295, y: 1018, w: 80, h: 45 }, + PLAYER_UPHILL_RIGHT: { x: 1385, y: 1018, w: 80, h: 45 }, + PLAYER_LEFT: { x: 995, y: 480, w: 80, h: 41 }, + PLAYER_STRAIGHT: { x: 1085, y: 480, w: 80, h: 41 }, + PLAYER_RIGHT: { x: 995, y: 531, w: 80, h: 41 } +}; diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites.png b/game/asset/image/sample/javascript-racer-master/images/sprites.png new file mode 100644 index 0000000..0b302ae Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/billboard01.png b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard01.png new file mode 100644 index 0000000..9c100cd Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard01.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/billboard02.png b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard02.png new file mode 100644 index 0000000..1db594e Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard02.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/billboard03.png b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard03.png new file mode 100644 index 0000000..9a43480 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard03.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/billboard04.png b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard04.png new file mode 100644 index 0000000..abfd4b1 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard04.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/billboard05.png b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard05.png new file mode 100644 index 0000000..c470e0d Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard05.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/billboard06.png b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard06.png new file mode 100644 index 0000000..0ba9efb Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard06.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/billboard07.png b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard07.png new file mode 100644 index 0000000..646c95b Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard07.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/billboard08.png b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard08.png new file mode 100644 index 0000000..50f59eb Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard08.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/billboard09.png b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard09.png new file mode 100644 index 0000000..976f6e5 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/billboard09.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/boulder1.png b/game/asset/image/sample/javascript-racer-master/images/sprites/boulder1.png new file mode 100644 index 0000000..fe98901 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/boulder1.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/boulder2.png b/game/asset/image/sample/javascript-racer-master/images/sprites/boulder2.png new file mode 100644 index 0000000..67b62f6 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/boulder2.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/boulder3.png b/game/asset/image/sample/javascript-racer-master/images/sprites/boulder3.png new file mode 100644 index 0000000..637d69a Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/boulder3.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/bush1.png b/game/asset/image/sample/javascript-racer-master/images/sprites/bush1.png new file mode 100644 index 0000000..b22d74d Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/bush1.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/bush2.png b/game/asset/image/sample/javascript-racer-master/images/sprites/bush2.png new file mode 100644 index 0000000..61d4b3c Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/bush2.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/cactus.png b/game/asset/image/sample/javascript-racer-master/images/sprites/cactus.png new file mode 100644 index 0000000..a52df7e Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/cactus.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/car01.png b/game/asset/image/sample/javascript-racer-master/images/sprites/car01.png new file mode 100644 index 0000000..8efdb84 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/car01.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/car02.png b/game/asset/image/sample/javascript-racer-master/images/sprites/car02.png new file mode 100644 index 0000000..54ab5a1 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/car02.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/car03.png b/game/asset/image/sample/javascript-racer-master/images/sprites/car03.png new file mode 100644 index 0000000..dbc629e Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/car03.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/car04.png b/game/asset/image/sample/javascript-racer-master/images/sprites/car04.png new file mode 100644 index 0000000..611b7ab Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/car04.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/column.png b/game/asset/image/sample/javascript-racer-master/images/sprites/column.png new file mode 100644 index 0000000..6b1e058 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/column.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/dead_tree1.png b/game/asset/image/sample/javascript-racer-master/images/sprites/dead_tree1.png new file mode 100644 index 0000000..399c9f6 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/dead_tree1.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/dead_tree2.png b/game/asset/image/sample/javascript-racer-master/images/sprites/dead_tree2.png new file mode 100644 index 0000000..ad7e52e Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/dead_tree2.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/palm_tree.png b/game/asset/image/sample/javascript-racer-master/images/sprites/palm_tree.png new file mode 100644 index 0000000..8044b5c Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/palm_tree.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/player_left.png b/game/asset/image/sample/javascript-racer-master/images/sprites/player_left.png new file mode 100644 index 0000000..457d943 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/player_left.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/player_right.png b/game/asset/image/sample/javascript-racer-master/images/sprites/player_right.png new file mode 100644 index 0000000..ca26b0a Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/player_right.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/player_straight.png b/game/asset/image/sample/javascript-racer-master/images/sprites/player_straight.png new file mode 100644 index 0000000..ef1c8cd Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/player_straight.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/player_uphill_left.png b/game/asset/image/sample/javascript-racer-master/images/sprites/player_uphill_left.png new file mode 100644 index 0000000..8aaa6cf Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/player_uphill_left.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/player_uphill_right.png b/game/asset/image/sample/javascript-racer-master/images/sprites/player_uphill_right.png new file mode 100644 index 0000000..3e3dfdb Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/player_uphill_right.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/player_uphill_straight.png b/game/asset/image/sample/javascript-racer-master/images/sprites/player_uphill_straight.png new file mode 100644 index 0000000..634d7a0 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/player_uphill_straight.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/semi.png b/game/asset/image/sample/javascript-racer-master/images/sprites/semi.png new file mode 100644 index 0000000..f679c1b Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/semi.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/stump.png b/game/asset/image/sample/javascript-racer-master/images/sprites/stump.png new file mode 100644 index 0000000..6319df2 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/stump.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/tree1.png b/game/asset/image/sample/javascript-racer-master/images/sprites/tree1.png new file mode 100644 index 0000000..9544094 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/tree1.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/tree2.png b/game/asset/image/sample/javascript-racer-master/images/sprites/tree2.png new file mode 100644 index 0000000..d3c8a12 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/tree2.png differ diff --git a/game/asset/image/sample/javascript-racer-master/images/sprites/truck.png b/game/asset/image/sample/javascript-racer-master/images/sprites/truck.png new file mode 100644 index 0000000..d72b520 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/images/sprites/truck.png differ diff --git a/game/asset/image/sample/javascript-racer-master/index.html b/game/asset/image/sample/javascript-racer-master/index.html new file mode 100644 index 0000000..e61ae58 --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/index.html @@ -0,0 +1,18 @@ + + + + Javascript Racer + + + + + + + + + diff --git a/game/asset/image/sample/javascript-racer-master/music/racer.mp3 b/game/asset/image/sample/javascript-racer-master/music/racer.mp3 new file mode 100644 index 0000000..15a5c83 Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/music/racer.mp3 differ diff --git a/game/asset/image/sample/javascript-racer-master/music/racer.ogg b/game/asset/image/sample/javascript-racer-master/music/racer.ogg new file mode 100644 index 0000000..d85ddfe Binary files /dev/null and b/game/asset/image/sample/javascript-racer-master/music/racer.ogg differ diff --git a/game/asset/image/sample/javascript-racer-master/stats.js b/game/asset/image/sample/javascript-racer-master/stats.js new file mode 100644 index 0000000..e9fa9c6 --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/stats.js @@ -0,0 +1,143 @@ +/** + * @author mrdoob / http://mrdoob.com/ + */ + +var Stats = function () { + + var startTime = Date.now(), prevTime = startTime; + var ms = 0, msMin = 1000, msMax = 0; + var fps = 0, fpsMin = 1000, fpsMax = 0; + var frames = 0, mode = 0;mode + var container = document.createElement( 'div' ); + container.id = 'stats'; + container.addEventListener( 'mousedown', function ( event ) { event.preventDefault(); setMode( ++ mode % 2 ) }, false ); + container.style.cssText = 'width:80px;opacity:0.9;cursor:pointer'; + + var fpsDiv = document.createElement( 'div' ); + fpsDiv.id = 'fps'; + fpsDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#002'; + container.appendChild( fpsDiv ); + + var fpsText = document.createElement( 'div' ); + fpsText.id = 'fpsText'; + fpsText.style.cssText = 'color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px'; + fpsText.innerHTML = 'FPS'; + fpsDiv.appendChild( fpsText ); + + var fpsGraph = document.createElement( 'div' ); + fpsGraph.id = 'fpsGraph'; + fpsGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0ff'; + fpsDiv.appendChild( fpsGraph ); + + while ( fpsGraph.children.length < 74 ) { + + var bar = document.createElement( 'span' ); + bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#113'; + fpsGraph.appendChild( bar ); + + } + + var msDiv = document.createElement( 'div' ); + msDiv.id = 'ms'; + msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;display:none'; + container.appendChild( msDiv ); + + var msText = document.createElement( 'div' ); + msText.id = 'msText'; + msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px'; + msText.innerHTML = 'MS'; + msDiv.appendChild( msText ); + + var msGraph = document.createElement( 'div' ); + msGraph.id = 'msGraph'; + msGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0f0'; + msDiv.appendChild( msGraph ); + + while ( msGraph.children.length < 74 ) { + + var bar = document.createElement( 'span' ); + bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#131'; + msGraph.appendChild( bar ); + + } + + var setMode = function ( value ) { + + mode = value; + + switch ( mode ) { + + case 0: + fpsDiv.style.display = 'block'; + msDiv.style.display = 'none'; + break; + case 1: + fpsDiv.style.display = 'none'; + msDiv.style.display = 'block'; + break; + } + + } + + var updateGraph = function ( dom, value ) { + + var child = dom.appendChild( dom.firstChild ); + child.style.height = value + 'px'; + + } + + return { + + domElement: container, + + setMode: setMode, + + current: function() { return fps; }, + + begin: function () { + + startTime = Date.now(); + + }, + + end: function () { + + var time = Date.now(); + + ms = time - startTime; + msMin = Math.min( msMin, ms ); + msMax = Math.max( msMax, ms ); + + msText.textContent = ms + ' MS (' + msMin + '-' + msMax + ')'; + updateGraph( msGraph, Math.min( 30, 30 - ( ms / 200 ) * 30 ) ); + + frames ++; + + if ( time > prevTime + 1000 ) { + + fps = Math.round( ( frames * 1000 ) / ( time - prevTime ) ); + fpsMin = Math.min( fpsMin, fps ); + fpsMax = Math.max( fpsMax, fps ); + + fpsText.textContent = fps + ' FPS (' + fpsMin + '-' + fpsMax + ')'; + updateGraph( fpsGraph, Math.min( 30, 30 - ( fps / 100 ) * 30 ) ); + + prevTime = time; + frames = 0; + + } + + return time; + + }, + + update: function () { + + startTime = this.end(); + + } + + } + +}; + diff --git a/game/asset/image/sample/javascript-racer-master/v1.straight.html b/game/asset/image/sample/javascript-racer-master/v1.straight.html new file mode 100644 index 0000000..112a7b0 --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/v1.straight.html @@ -0,0 +1,314 @@ + + + + + Javascript Racer - v1 (straight) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ straight | + curves | + hills | + final +
+ +
+ +
+ +
+

Use the arrow keys to drive the car.

+
+ +
+ + Sorry, this example cannot be run because your browser does not support the <canvas> element + + Loading... +
+ + + + + + + + + + diff --git a/game/asset/image/sample/javascript-racer-master/v2.curves.html b/game/asset/image/sample/javascript-racer-master/v2.curves.html new file mode 100644 index 0000000..0ef0915 --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/v2.curves.html @@ -0,0 +1,387 @@ + + + + + Javascript Racer - v2 (curves) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ straight | + curves | + hills | + final +
+ +
+ +
+ +
+

Use the arrow keys to drive the car.

+
+ +
+ + Sorry, this example cannot be run because your browser does not support the <canvas> element + + Loading... +
+ + + + + + + + + + diff --git a/game/asset/image/sample/javascript-racer-master/v3.hills.html b/game/asset/image/sample/javascript-racer-master/v3.hills.html new file mode 100644 index 0000000..1881035 --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/v3.hills.html @@ -0,0 +1,419 @@ + + + + + Javascript Racer - v3 (hills) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ straight | + curves | + hills | + final +
+ +
+ +
+ +
+

Use the arrow keys to drive the car.

+
+ +
+ + Sorry, this example cannot be run because your browser does not support the <canvas> element + + Loading... +
+ + + + + + + + + diff --git a/game/asset/image/sample/javascript-racer-master/v4.final.html b/game/asset/image/sample/javascript-racer-master/v4.final.html new file mode 100644 index 0000000..81d6935 --- /dev/null +++ b/game/asset/image/sample/javascript-racer-master/v4.final.html @@ -0,0 +1,688 @@ + + + + + Javascript Racer - v4 (final) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ straight | + curves | + hills | + final +
+ +
+ +
+ +
+

Use the arrow keys to drive the car.

+
+ +
+
+ 0 mph + Time: 0.0 + Last Lap: 0.0 + Fastest Lap: 0.0 +
+ + Sorry, this example cannot be run because your browser does not support the <canvas> element + + Loading... +
+ + + + + + + + + + diff --git a/game/data/map/segment.json b/game/data/map/segment.json new file mode 100644 index 0000000..b34da57 --- /dev/null +++ b/game/data/map/segment.json @@ -0,0 +1,82 @@ +[ + { + "enter": 1, + "hold" : 1, + "leave": 90, + "curve": 9, + "height": 80, + "width" : 3000 + }, + { + "enter": 25, + "hold" : 25, + "leave": 25, + "curve": 0, + "height": 0, + "width" : 1000 + }, + { + "enter": 50, + "hold" : 50, + "leave": 50, + "curve": 2, + "height": 0, + "width" : 2000 + }, + { + "enter": 50, + "hold" : 50, + "leave": 50, + "curve": 2, + "height": 20, + "width" : 2000 + }, + { + "enter": 100, + "hold" : 100, + "leave": 100, + "curve": 4, + "height": 40, + "width" : 4000 + }, + { + "enter": 50, + "hold" : 50, + "leave": 50, + "curve": 0, + "height": 0, + "width" : 1000 + }, + { + "enter": 50, + "hold" : 50, + "leave": 50, + "curve": 6, + "height": 60, + "width" : 3000 + }, + { + "enter": 50, + "hold" : 50, + "leave": 50, + "curve": 0, + "height": 60, + "width" : 2000 + }, + { + "enter": 50, + "hold" : 50, + "leave": 50, + "curve": 0, + "height": 20, + "width" : 3000 + }, + { + "enter": 100, + "hold" : 100, + "leave": 100, + "curve": 0, + "height": -280, + "width" : 4000 + } +] diff --git a/game/data/map/sprites.json b/game/data/map/sprites.json new file mode 100644 index 0000000..a41d6d7 --- /dev/null +++ b/game/data/map/sprites.json @@ -0,0 +1,17 @@ +[ + { + "index" : 200, + "texture" : "asset/image/sample/javascript-racer-master/images/sprites/column.png", + "offset" : -0.1 + }, + { + "index" : 200, + "texture" : "asset/image/sample/javascript-racer-master/images/sprites/cactus.png", + "offset" : 4 + }, + { + "index" : 150, + "texture" : "asset/image/sample/javascript-racer-master/images/sprites/stump.png", + "offset" : 0 + } +] diff --git a/game/lib/choro/projection.lua b/game/lib/choro/projection.lua index 27cfea6..5fd3abe 100644 --- a/game/lib/choro/projection.lua +++ b/game/lib/choro/projection.lua @@ -65,11 +65,12 @@ end ---@param cameraDepth number distance from camera to projection plane ---@param resolution table render resolution {width, height} ---@param size table object {width, height} ----@return table,table {x, y, z}, {w, h} +---@return table,table,table {x, y, z}, {x, y}, {w, h} function projection.projectWorldToCam(world, cameraPos, cameraDepth, resolution, size) local relativetocamera = projection.translateToRelativeCamera(world, cameraPos) local scale = cameraDepth / relativetocamera[3]; return + relativetocamera, projection.scalePosToRelativeProjectCamera(relativetocamera, scale, resolution), projection.scaleSizeToRelativeProjectCamera(size, scale, resolution) end diff --git a/game/main.lua b/game/main.lua index ecf44c0..9f34db6 100644 --- a/game/main.lua +++ b/game/main.lua @@ -8,7 +8,7 @@ world = { ["train"] = require("src.world.train")(), }; -current = wm["main_menu"] +current = wm["2_town_square"] function load_world(world_to_load) current = world_to_load diff --git a/game/src/world/2_town_square/component/perspective.lua b/game/src/world/2_town_square/component/perspective.lua new file mode 100644 index 0000000..90812a8 --- /dev/null +++ b/game/src/world/2_town_square/component/perspective.lua @@ -0,0 +1,75 @@ +local components = {} + +components.dict = { + resolution = "perspective.resolution", + lanes = "perspective.lanes", + draw_distance = "perspective.draw_distance", + road_width = "perspective.road_width", + fog_density = "perspective.fog_density", + + field_of_view = "perspective.field_of_view", + camera_height = "perspective.camera_height", + + segment_length = "perspective.segment_length", + segment_count = "perspective.segment_count", + rumble_length = "perspective.rumble_length", + + scroll = "perspective.scroll", + + segment_path = "perspective.segment_path", + segment_sprite_map_path = "perspective.segment_sprite_map_path" +} + +function components.resolution (c, x, y) + c.data = {love.graphics.getDimensions()} +end + +function components.lanes (c, x) + c.data = x +end + +function components.draw_distance (c, x) + c.data = x +end + +function components.road_width (c, x) + c.data = x +end + +function components.fog_density (c, x) + c.data = x +end + +function components.field_of_view (c, x) + c.data = x +end + +function components.camera_height (c, x) + c.data = x +end + +function components.segment_length (c, x) + c.data = x +end + +function components.segment_count (c, x) + c.data = x +end + +function components.rumble_length (c, x) + c.data = x +end + +function components.scroll (c, x) + c.data = x +end + +function components.segment_path (c, x) + c.data = x +end + +function components.segment_sprite_map_path (c, x) + c.data = x +end + +return components diff --git a/game/src/world/2_town_square/init.lua b/game/src/world/2_town_square/init.lua index 8e67a19..4fb747e 100644 --- a/game/src/world/2_town_square/init.lua +++ b/game/src/world/2_town_square/init.lua @@ -5,6 +5,7 @@ local BASE = reap.base_path(...) local world = require("wrapper.Concord.world") local debug_entity = require("src.world.common.template.debug_entity") +local road = require("src.world.2_town_square.template.road") local wm = require("world_map") @@ -16,7 +17,8 @@ end function wrapper:load(_args) wrapper.super.load(self, { - "src/world/common/system/" + "src/world/common/system/", + "src/world/2_town_square/system" }, { { assemblage = debug_entity.assembleDebug, @@ -25,6 +27,10 @@ function wrapper:load(_args) label = "2_town_square" } }, + { + assemblage = road.assemble, + data = road.default_data + }, }) end diff --git a/game/src/world/2_town_square/pseudo3d/render/road.lua b/game/src/world/2_town_square/pseudo3d/render/road.lua new file mode 100644 index 0000000..983524d --- /dev/null +++ b/game/src/world/2_town_square/pseudo3d/render/road.lua @@ -0,0 +1,89 @@ +local ease = require("src.world.2_town_square.pseudo3d.ease") + +local utils = {} + +local function drawQuad(slice, image, quads, x1, y1, x2, y2, w1, w2, h1, h2, sw, sh) + for i = 1, #quads do + local percent = ease.percentRemaining(i, #quads) + local destY = ease.interpolate(y1, y2, percent) + local destX = ease.interpolate(x1, x2, percent) + local destW = ease.interpolate(w1, w2, percent) + local destH = ease.interpolate(h1, h2, percent) + + if (slice == "vertical") then + love.graphics.draw(image,quads[i], + destX, destY, 0, destW / sw, 1 + ) + elseif (slice == "horizontal") then + love.graphics.draw(image,quads[i], + destX, destY, 0, 1, destH / sh + ) + end + end +end + +local function drawSection(texture, key, x1, y1, x2, y2, w1, w2, h1, h2, resolution) + local image = texture[key].image + local quads = texture[key].quads + + local sw, sh = image:getDimensions() + + if (key == "floor") then + drawQuad("vertical", image, quads, + x1, y1, + x2, y2, + w1, w2, + h1, h2, + sw, sh + ) + elseif (key == "ceil") then + drawQuad("vertical", image, quads, + x1, -y1 + resolution[2]/2, + x2, -y2 + resolution[2]/2, + w1, w2, + h1, h2, + sw, sh + ) + elseif (key == "wallL") then + drawQuad("horizontal", image, quads, + x1, -y1 + h1, + x2, -y2 + h2, + w1, w2, + h1, h2, + sw, sh + ) + elseif (key == "wallR") then + drawQuad("horizontal", image, quads, + x1 + w1, -y1, + x2 + w2, -y2, + w1, w2, + h1 + y1, + h2 + y2, + sw, sh + ) + end +end + +function utils.draw(p1screenpos, p2screenpos, p1screensize, p2screensize, texture, resolution, maxy) + local x1 = p1screenpos[1] + local y1 = p1screenpos[2] + local x2 = p2screenpos[1] + local y2 = p2screenpos[2] + + local w1 = p1screensize[1] + local w2 = p2screensize[1] + + local h1 = (y1) + local h2 = (y2) + + local x1e = x1 + w1 + local x2e = x2 + w2 + + drawSection(texture, "wallL", x1 , y1, x2, y2, w1, w2, h1, h2, resolution) + drawSection(texture, "wallR", x1 , y1, x2, y2, w1, w2, h1, h2, resolution) + drawSection(texture, "floor", x1 , y1, x2, y2, w1, w2, h1, h2, resolution) + drawSection(texture, "ceil", x1 , y1, x2, y2, w1, w2, h1, h2, resolution) + +end + +return utils diff --git a/game/src/world/2_town_square/pseudo3d/render/sprite.lua b/game/src/world/2_town_square/pseudo3d/render/sprite.lua new file mode 100644 index 0000000..43409dc --- /dev/null +++ b/game/src/world/2_town_square/pseudo3d/render/sprite.lua @@ -0,0 +1,72 @@ +local projection = require("lib.choro.projection") + +local UV = require("engine.utils.obj3d.texture.uv") +local quadToUV = UV.quadToUV +local imageToUV = UV.imageToUV + +local QuadCache = require("engine.cache.loveapi.quadcache").obj + +local utils = {} + +function utils.drawstatic(segment, roadWidth, resolution) + -- render roadside sprites + local w2 = resolution[1]/2 + for i = 1, #segment.sprites do + local sprite = segment.sprites[i].source; + local spriteoffset = segment.sprites[i].offset; + + local spritePath = segment.sprites[i].data.path; + local spriteType = segment.sprites[i].data.type; + local spriteState = segment.sprites[i].data.state; + + local quad + local img + if (spriteType == "aseprite") then + img = sprite.image + quad = sprite.frame.quad + else + img = sprite + quad = QuadCache:load(spritePath, 0, 0, 1, 1, img:getWidth(), img:getHeight(), spriteType) + end + + local u, v, nu, nv = quadToUV(quad) + + local spriteScale = segment.p1.screen.scale; + local spriteX = segment.p1.screen.pos.x + (spriteScale * spriteoffset * roadWidth * w2); + local spriteY = segment.p1.screen.pos.y; + + local offsetX + if (spriteoffset < 0) then + offsetX = -1 + else + offsetX = 0 + end + local offsetY = -1 + + -- scale for projection AND relative to roadWidth (for tweakUI) + local destW = (img:getWidth() * spriteScale * w2) * (projection.getSpriteScale(resolution[1]/3) * roadWidth); + local destH = (img:getHeight() * spriteScale * w2) * (projection.getSpriteScale(resolution[1]/3) * roadWidth); + + local destX = spriteX + (destW * (offsetX or 0)); + local destY = spriteY + (destH * (offsetY or 0)); + + local clipH = 0; + if (segment.clip) then + clipH = math.max(0, destY+destH-segment.clip) + end + + if (clipH < destH) then + local _nv = nv - (nv * clipH/destH) + + local _destH = destH - clipH + + local _quad = quad + if (_nv ~= nv) then + _quad = QuadCache:load(spritePath, u, v, nu, _nv, img:getWidth(), img:getHeight(), spriteType, spriteState) + end + love.graphics.draw(img, _quad, destX, destY, 0, destW, _destH) + end + end +end + +return utils diff --git a/game/src/world/2_town_square/pseudo3d/render/uv.lua b/game/src/world/2_town_square/pseudo3d/render/uv.lua new file mode 100644 index 0000000..70546b9 --- /dev/null +++ b/game/src/world/2_town_square/pseudo3d/render/uv.lua @@ -0,0 +1,37 @@ +--- get texture UV +---@param x number y +---@param y number x +---@param frameSizeX number size Frame X +---@param frameSizeY number size Frame Y +---@param sw number size Width +---@param sh number size Height +---@return number, number, number, number +local function getUV(x, y, frameSizeX, frameSizeY, sw, sh) + return + x / sw, + y / sh, + (x + 1 * frameSizeX) / sw, + (y + 1 * frameSizeY) / sh +end + +--- get uv from quad +---@param quad love.Quad +local function quadToUV(quad) + local sw, sh = quad:getTextureDimensions() + local x, y, w, h = quad:getViewport() + local u, v, nu, nv = getUV(x, y, w, h, sw, sh) + return u, v, nu, nv +end + +--- get uv from image +---@param image love.Image +local function imageToUV(image) + local u, v, nu, nv = getUV(0, 0, image:getWidth(), image:getHeight(),image:getWidth(), image:getHeight()) + return u, v, nu, nv +end + +return { + getUV = getUV, + imageToUV = imageToUV, + quadToUV = quadToUV +} diff --git a/game/src/world/2_town_square/pseudo3d/roadsegment.lua b/game/src/world/2_town_square/pseudo3d/roadsegment.lua index 2f8a367..a3a2795 100644 --- a/game/src/world/2_town_square/pseudo3d/roadsegment.lua +++ b/game/src/world/2_town_square/pseudo3d/roadsegment.lua @@ -77,9 +77,9 @@ function utils.addQuads(path, slice, w1, w2) local percent = easeFN.percentRemaining(i, sh - 1) local destW = easeFN.interpolate(w1, w2, percent) table.insert(quads, - QuadCache:load_to(string.format("%s %s %s %s %s %s %s", + QuadCache:load_to(string.format("%s_%s_%s_%s_%s_%s_%s", path, 0, i, sw, 1, sw, sh), - path, 0, i, sw, 1, sw, sh) + 0, i, sw, 1, sw, sh) ) end elseif (slice == "horizontal") then @@ -88,9 +88,9 @@ function utils.addQuads(path, slice, w1, w2) local destH = easeFN.interpolate(w1, w2, percent) table.insert(quads, QuadCache:load_to( - string.format("%s %s %s %s %s %s %s", + string.format("%s_%s_%s_%s_%s_%s_%s", path, i, 0, 1, sh, sw, sh), - path, i, 0, 1, sh, sw, sh) + i, 0, 1, sh, sw, sh) ) end end @@ -315,12 +315,6 @@ function utils.loadSpriteMapData(segments, path) end end -local imageData = { - ["car"] = { - path = "asset/image/sample/javascript-racer-master/images/sprites/car01.png" - } -} - function utils.addSprite(segments, index, sprite, offset, key) table.insert(segments[index].sprites, { source= sprite, @@ -329,8 +323,8 @@ function utils.addSprite(segments, index, sprite, offset, key) }) local _sIndex = #segments[index].sprites segments[index].sprites[_sIndex].data = { - path = imageData[key].path, - type = imageData[key].type + path = key, + type = "static" } end diff --git a/game/src/world/2_town_square/system/perspective.lua b/game/src/world/2_town_square/system/perspective.lua new file mode 100644 index 0000000..eeb7b7f --- /dev/null +++ b/game/src/world/2_town_square/system/perspective.lua @@ -0,0 +1,254 @@ +local system_constructor = require("wrapper.Concord.system") + +local roadsegment = require("src.world.2_town_square.pseudo3d.roadsegment") +local perspective = require("src.world.2_town_square.component.perspective") +local projection = require("lib.choro.projection") +local ease = require("src.world.2_town_square.pseudo3d.ease") +local vm = require("lib.vornmath") +local roaddraw = require("src.world.2_town_square.pseudo3d.render.road") + +local system = {} + +system.__index = system + +system.pool = { + pool = { + perspective.dict.camera_height, + perspective.dict.draw_distance, + perspective.dict.field_of_view, + perspective.dict.fog_density, + perspective.dict.lanes, + perspective.dict.resolution, + perspective.dict.road_width, + perspective.dict.rumble_length, + perspective.dict.scroll, + perspective.dict.segment_count, + perspective.dict.segment_length, + perspective.dict.segment_path, + perspective.dict.segment_sprite_map_path + } +} + +system.components = { + [perspective.dict.camera_height] = perspective.camera_height, + [perspective.dict.draw_distance] = perspective.draw_distance, + [perspective.dict.field_of_view] = perspective.field_of_view, + [perspective.dict.fog_density] = perspective.fog_density, + [perspective.dict.lanes] = perspective.lanes, + [perspective.dict.resolution] = perspective.resolution, + [perspective.dict.road_width] = perspective.road_width, + [perspective.dict.rumble_length] = perspective.rumble_length, + [perspective.dict.scroll] = perspective.scroll, + [perspective.dict.segment_count] = perspective.segment_count, + [perspective.dict.segment_length] = perspective.segment_length, + [perspective.dict.segment_path] = perspective.segment_path, + [perspective.dict.segment_sprite_map_path] = perspective.segment_sprite_map_path +} +function system.new() + local new_system = system_constructor.new("perspective", system.pool) + if (new_system) then + for k, v in pairs(system) do + new_system[k] = v + end + return new_system + else + return nil + end +end + +function system:load() + for _, e in ipairs(self.pool) do + local segment_path = e[perspective.dict.segment_path].data + local segment_sprite_map_path = e[perspective.dict.segment_sprite_map_path].data + local segment_length = e[perspective.dict.segment_length].data + local rumble_length = e[perspective.dict.rumble_length].data + local scroll = e[perspective.dict.scroll].data + + local segments, track_length = roadsegment.resetRoad(segment_path, segment_sprite_map_path, segment_length, rumble_length, scroll) + -- entityBuilder.setComponent(e, "segments", segments) + -- entityBuilder.setComponent(e, "track_length", track_length) + + local field_of_view = e[perspective.dict.field_of_view].data + local camera_height = e[perspective.dict.camera_height].data + local camera_depth = projection.distanceCamToProjection(field_of_view) + local player_z = camera_depth * camera_height + + e.player = {} + e.player.pos = {0, scroll, player_z} + + e.segments = segments + e.track_length = track_length + + e.camera_depth = camera_depth + + -- entityBuilder.setComponent(e, "camera_depth", projection.distanceCamToProjection(field_of_view)) + + -- local camera_depth = e.camera_depth.data + -- entityBuilder.setComponent(e, "player_z", projection.getPlayerZ(camera_height, camera_depth)) + + -- entityBuilder.setComponent(e, "prev_frame", 0) + end +end + +function system:update(dt) + for _, e in ipairs(self.pool) do + if love.keyboard.isDown("up") then + e.player.pos[3] = e.player.pos[3] + 1000 * dt + elseif love.keyboard.isDown("down") then + e.player.pos[3] = e.player.pos[3] - 1000 * dt + end + if love.keyboard.isDown("left") then + e.player.pos[1] = e.player.pos[1] + 1 * dt + elseif love.keyboard.isDown("right") then + e.player.pos[1] = e.player.pos[1] - 1 * dt + end + if love.keyboard.isDown("w") then + e.player.pos[2] = e.player.pos[2] + 1000 * dt + elseif love.keyboard.isDown("s") then + e.player.pos[2] = e.player.pos[2] - 1000 * dt + + end + end +end + +local function drawRoad( + zPosition, drawDistance, + segments, + segment_length, track_length, + playerX, cameraHeight, cameraDepth, + resolution, lanes, + playerZ, fogDensity +) + if (zPosition == 0) then + zPosition = 1 + end + local baseSegment = roadsegment.findSegment(zPosition, segments, segment_length); + local basePercent = ease.percentRemaining(zPosition, segment_length); + + local playerSegment = roadsegment.findSegment(zPosition + playerZ, segments, segment_length); + local playerPercent = ease.percentRemaining(zPosition+playerZ, segment_length); + local playerY = ease.interpolate(playerSegment.p1.world.y, playerSegment.p2.world.y, playerPercent); + local maxy = resolution[2]; + + local x = 0; + local dx = - ((baseSegment.curve or 0) * basePercent); + + local n, segment; + for n = 0, drawDistance do + local index = (baseSegment.index + n) % #segments + + if (index >= #segments) then + index = n + 1 + elseif (index <= 0) then + index = #segments - (n + 1) + end + + segment = segments[index]; + local loopPos = 0 + if (segment.index < baseSegment.index) then + loopPos = track_length + end + + local p1Width = segment.p1.world.w + local p2Width = segment.p2.world.w + + local camera1 = vm.vec3({ + (playerX * p1Width) - x, --x + playerY + cameraHeight, --y + zPosition - loopPos --z + }) + + local camera2 = vm.vec3({ + (playerX * p2Width) - x - dx, --x + playerY + cameraHeight, --y + zPosition - loopPos --z + }) + + segment.fog = ease.exponentialFog(n/drawDistance, fogDensity); + segment.clip = maxy + + local p1cam, p1screenpos, p1screensize = projection.projectWorldToCam({ + segment.p1.world.w, + segment.p1.world.y, + segment.p1.world.z + }, camera1, cameraDepth, resolution, { + p1Width, + 1 + }); + local p2cam, p2screenpos, p2screensize = projection.projectWorldToCam({ + segment.p2.world.w, + segment.p2.world.y, + segment.p2.world.z + }, camera2, cameraDepth, resolution, { + p2Width, + 1 + }); + + x = x + dx; + dx = dx + (segment.curve or 0); + + if ((p1cam[3] <= cameraDepth) or -- behind us + (p2screenpos[2] >= p1screenpos[2]) or -- back face cull + (p2screenpos[2] >= maxy)) -- clip by (already rendered) segment + then + else + -- segmentdebugdraw.draw(segment, resolution, maxy) + roaddraw.draw(p1screenpos, p2screenpos, p1screensize, p2screensize, segment.texture, resolution, maxy) + + maxy = p1screenpos[2]; + end + end + + for n = (drawDistance), 0, -1 do + local index = (baseSegment.index + n) % #segments + + if (index >= #segments) then + index = n + 1 + elseif (index <= 0) then + index = #segments - (n + 1) + end + + segment = segments[index]; + + local p1Width = segment.p1.world.w + + -- for i = 1, #segment.sprites do + -- drawstatic.drawstatic( + -- segment, p1Width, resolution) + -- end + + end +end + +function system:draw() + for _, e in ipairs(self.pool) do + local scroll = e.player.pos[2] -- pos[2] + local draw_distance = e[perspective.dict.draw_distance].data + local camera_height = e[perspective.dict.camera_height].data + local resolution = e[perspective.dict.resolution].data + local lanes = e[perspective.dict.lanes].data + local segment_length = e[perspective.dict.segment_length].data + local fogDensity = e[perspective.dict.fog_density].data + + local segments = e.segments + local player_x = e.player.pos[1] -- pos[1] + local camera_depth = e.camera_depth + local track_length = e.track_length + local player_z = e.player.pos[3] -- pos[3] + + love.graphics.push() + drawRoad( + scroll, draw_distance, + segments, + segment_length, track_length, + player_x, camera_height, camera_depth, + resolution, lanes, + player_z, + fogDensity + ) + love.graphics.pop() + love.graphics.print(string.format("%s,%s,%s",player_x, scroll, player_z), 20, 20) + end +end + +return system diff --git a/game/src/world/2_town_square/template/road.lua b/game/src/world/2_town_square/template/road.lua new file mode 100644 index 0000000..fd219dc --- /dev/null +++ b/game/src/world/2_town_square/template/road.lua @@ -0,0 +1,52 @@ +local perspective = require("src.world.2_town_square.component.perspective") + +local template = {} + +template.default_data = { + resolution = {love.graphics.getDimensions()}, -- resolution x, y + lanes = 3, + draw_distance = 300, + road_width = 2000, + + fog_density = 0, + + -- player + player_x = 0, + player_width = 50, + centrifugal = 0.3, + player_speed = 0, + player_max_speed = 5000, + player_accel = 100, + + -- camera + field_of_view = 140, -- field of view + camera_height = 1000, + + -- road segment + segment_length = 200, + segment_count = 500, + rumble_length = 3, + + scroll = 1, + + segment_path = "data/map/segment.json", + segment_sprite_map_path = "data/map/sprites.json", +} + +function template.assemble(e, data) + e:give(perspective.dict.camera_height, data.camera_height) + e:give(perspective.dict.draw_distance, data.draw_distance) + e:give(perspective.dict.field_of_view, data.field_of_view) + e:give(perspective.dict.fog_density, data.fog_density) + e:give(perspective.dict.lanes, data.lanes) + e:give(perspective.dict.resolution, data.resolution.x, data.resolution.y) + e:give(perspective.dict.road_width, data.road_width) + e:give(perspective.dict.rumble_length, data.rumble_length) + e:give(perspective.dict.scroll, data.scroll) + e:give(perspective.dict.segment_count, data.segment_count) + e:give(perspective.dict.segment_length, data.segment_length) + e:give(perspective.dict.segment_path, data.segment_path) + e:give(perspective.dict.segment_sprite_map_path, data.segment_sprite_map_path) +end + +return template diff --git a/game/wrapper/lappy/new/quad.lua b/game/wrapper/lappy/new/quad.lua index 41809c6..5f323f7 100644 --- a/game/wrapper/lappy/new/quad.lua +++ b/game/wrapper/lappy/new/quad.lua @@ -5,7 +5,7 @@ local _cache = cache:extend() --- new function function _cache:new() - _cache.super.new(self, love.image.newQuad, ".quad") + _cache.super.new(self, love.graphics.newQuad, ".quad") self.cache = {} end