UNPKG

shaku

Version:

A simple and effective JavaScript game development framework that knows its place!

199 lines (160 loc) 7.89 kB
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Shaku</title> <meta name="description" content="Shaku - a simple and easy-to-use javascript library for videogame programming."> <meta name="author" content="Ronen Ness"> <link href="css/style.css" rel="stylesheet" type="text/css" media="all"> </head> <body> <div class="noselect"> <button class="view-code-btn" onclick="showSampleCode();">View Code</button> <h1 class="demo-title">Shaku Gfx Demo: Render Targets</h1> <p>This demo demonstrate how to use render targets, which are special textures you can draw on and later draw on screen.<br/> The demo is very similar to the sprites demo, but here instead of drawing directly on screen we draw on a texture first and then draw that texture on screen with a tilt.<br /><br /> Use <b>Arrows</b> or <b>WASD</b> to move the player. Collision detection is very basic so don't expect much from it.</p> <span class="credits">Knight image is from: https://opengameart.org/content/knight-sprite</span> <span class="credits">Background image is from: https://lostgarden.home.blog/2006/07/08/more-free-game-graphics/</span> <!-- include shaku --> <script src="js/demos.js"></script> <script src="js/shaku.js"></script> <!-- demo code --> <script> async function runDemo() { // init shaku await Shaku.init(); // screen size let screenX = 800; let screenY = 600; // add canvas to document document.body.appendChild(Shaku.gfx.canvas); Shaku.gfx.setResolution(screenX, screenY, true); // create sprites batch let spritesBatch = new Shaku.gfx.SpriteBatch(); // create render target let renderTarget = await Shaku.assets.createRenderTarget('_my_render_target', 800, 600); // load textures let knight = await Shaku.assets.loadTexture('assets/sprite.png'); let level = await Shaku.assets.loadTexture('assets/level.jpg'); let levelOverlay = await Shaku.assets.loadTexture('assets/level_overlay.png'); let blockMap = await Shaku.assets.loadTexture('assets/level_block.jpg'); // create player sprite let playerSprite = new Shaku.gfx.Sprite(knight); // get the block map pixels data let blockMapPixels = blockMap.getPixelsData(); // for walking animation let walkingAnimation = 0; // sprite starting position and player origin at bottom center playerSprite.position.set(100, 250); playerSprite.origin.set(0.5, 0.95); // walk to position, but only if not marked as blocked in the block map function walkTo(newX, newY) { // get position in blockmap let xBlock = Math.floor((newX / screenX) * blockMap.width); let yBlock = Math.floor((newY / screenY) * blockMap.height); // out of range? if (xBlock < 0 || xBlock > blockMap.width || yBlock < 0 || yBlock > blockMap.height) { if (xBlock < 0) playerSprite.position.x = 1; if (yBlock < 0) playerSprite.position.y = 1; if (xBlock > blockMap.width) playerSprite.position.x = screenX - 1; if (yBlock > blockMap.height) playerSprite.position.y = screenY - 1; return; } // check if blocking for (let i = -1; i <= 1; ++i) { for (let j = -1; j <= 1; ++j) { if (!blockMapPixels[xBlock+i] || !blockMapPixels[xBlock+i][yBlock+j] || blockMapPixels[xBlock+i][yBlock+j].isBlack) { return; } } } // move player playerSprite.position.set(newX, newY); } // do a main loop step. function step() { Shaku.startFrame(); Shaku.gfx.clear(Shaku.utils.Color.cornflowerblue); // set render target Shaku.gfx.setRenderTarget(renderTarget); // draw level background, knight and then level overlay spritesBatch.begin(); spritesBatch.drawRectangle(level, Shaku.gfx.getRenderingRegion()); spritesBatch.drawSprite(playerSprite); spritesBatch.drawRectangle(levelOverlay, Shaku.gfx.getRenderingRegion()); spritesBatch.end(); // clear render target Shaku.gfx.setRenderTarget(null); // now draw entire render target on screen spritesBatch.begin(); spritesBatch.drawQuad(renderTarget, new Shaku.utils.Vector2(screenX / 2, screenY / 2), new Shaku.utils.Vector2(screenX, -screenY), undefined, undefined, Math.sin(Shaku.gameTime.elapsed / 2) / 2); spritesBatch.end(); // walking speed and are we walking this frame? let walkSpeed = Shaku.gameTime.delta * 200; let walking = false; // walk left if (Shaku.input.down('left') || Shaku.input.down('a')) { walking = true; walkTo(playerSprite.position.x - walkSpeed, playerSprite.position.y); playerSprite.size.x = -Math.abs(playerSprite.size.x); } // walk right else if (Shaku.input.down('right') || Shaku.input.down('d')) { walking = true; walkTo(playerSprite.position.x + walkSpeed, playerSprite.position.y); playerSprite.size.x = Math.abs(playerSprite.size.x); } // walk up if (Shaku.input.down('up') || Shaku.input.down('w')) { walking = true; walkTo(playerSprite.position.x, playerSprite.position.y - walkSpeed); } // walk down else if (Shaku.input.down('down') || Shaku.input.down('s')) { walking = true; walkTo(playerSprite.position.x, playerSprite.position.y + walkSpeed); } // do walking animation if (walking) { walkingAnimation += Shaku.gameTime.delta * 15; playerSprite.rotation = Math.sin(walkingAnimation) / 20; } Shaku.endFrame(); Shaku.requestAnimationFrame(step); } step(); } // start demo runDemo(); </script> </div> <!-- code example part --> <div id="sample-code-modal" class="modal"> <div class="modal__overlay jsOverlay"></div> <div class="modal__container"> <p class="noselect">The following is a minimal code example on how to use sprites.</i> </p> <pre><code class="language-js">// create render target let renderTarget = await Shaku.assets.createRenderTarget('_my_render_target', width, height); // part below goes between startFrame() and endFrame() // ------------------------------------------------------- // set render target Shaku.gfx.setRenderTarget(renderTarget); // draw some stuff here... // reset render target Shaku.gfx.setRenderTarget(null); // you can now use 'renderTarget' just like you would with any texture, and it will contain everything you drawn on it. // note: due to WebGL limitation, render targets are flipped upside-down. to correct that, set height to a negative value.</code></pre> <button class="modal__close" onclick="closeModal('sample-code-modal')">&#10005;</button> </div> </div> <link href="prism/prism.css" rel="stylesheet" /> <script src="prism/prism.js"></script> </body> </html>