hubert

Members
  • Content Count

    96
  • Joined

  • Last visited

About hubert

  • Rank
    Advanced Member

Contact Methods

  • Twitter
    ttt

Recent Profile Visitors

1108 profile views
  1. That is very true! I had many problems with performance of my game loop since I wanted to have many cool visual effects. I CANNOT UNDERESTIMATE how big performance boost I had after not rendering objects that are offscreen. My advice to you is to use visible false property on sprites or displayObjectContainers. Under the hood this is one of the initial checks the engine makes before rendering and you can simply turn the object on with one line of code (if removed you would have to re-instantianate it agian, as well invisible objects can change position in your game loop). http://www.sevenative.com
  2. Will removing children from sprites have significant impact on rendering speed?
  3. yup. i had a similar situation when wordWrap was set to true. When set to false the space between new lines is ignored. The text is broken by the container or do you do it manually? This is my configuration: var text = new PIXI.Text("Pixi \n it works! :D", { font:"20px Arial", fill:"white", wordWrap : false, dropShadow : true, dropShadowDistance : 2 });also for new line you can you can use htmlentity 10; http://www.sevenative.com 10;
  4. @ Hey! Actually there is another way of creating an array of sprites. This is the code from a recent question about something else. var birdIdle = PIXI.BaseTextureCache[GAME.Assets.BIRD_IDLE];var partTexturebirdIdle0 = new PIXI.Texture(birdIdle, new PIXI.Rectangle(0, 0, 470, 470));var partTexturebirdIdle1 = new PIXI.Texture(birdIdle, new PIXI.Rectangle(470, 0, 470, 470));var partTexturebirdIdle2 = new PIXI.Texture(birdIdle, new PIXI.Rectangle(470 * 2, 0, 470, 470));var partTexturebirdIdle3 = new PIXI.Texture(birdIdle, new PIXI.Rectangle(470 * 3, 0, 470, 470));var partTexturebirdIdle4 = new PIXI.Texture(birdIdle, new PIXI.Rectangle(470 * 4, 0, 470, 470));var partTexturebirdIdle5 = new PIXI.Texture(birdIdle, new PIXI.Rectangle(470 * 5, 0, 470, 470));var partTexturebirdIdle6 = new PIXI.Texture(birdIdle, new PIXI.Rectangle(470 * 6, 0, 470, 470));var partTexturebirdIdle7 = new PIXI.Texture(birdIdle, new PIXI.Rectangle(470 * 7, 0, 470, 470));var partTexturebirdIdle8 = new PIXI.Texture(birdIdle, new PIXI.Rectangle(470 * 8, 0, 470, 470));var texturesBirdIdle = [partTexturebirdIdle0, partTexturebirdIdle1, partTexturebirdIdle2,partTexturebirdIdle3, partTexturebirdIdle4, partTexturebirdIdle5,partTexturebirdIdle6, partTexturebirdIdle7, partTexturebirdIdle8];var birdIdleMC_0 = new PIXI.MovieClip(texturesBirdIdle);birdIdleMC_0.play();this.container.addChild(birdIdleMC_0);The problem is that you can't reuse same spries in different orders with the abouve technique but combining the two elements you get a nifty way to manipulate your sprites animation. I think that this method is even better since the sprite is reduced to only what you need and in my example I was setting a frame. I'm not sure, but I think that frame is not cropping the texture in pixi js memory so I'm going to swich to this method in my project. As for the performance question. From what I have found on the web. set interval or timeout are not affecting the performance like they used to so you can go forward with this technique. Yeah as for other solutions and techniques iIwas digging into this subject for quite a while. You can do clipping which is a technique that is not natively implemented in pixi js, by setting visible = false to sprites that are outside of you view. TRUST ME THIS SPEEDS THE RENDERING A LOT! below you can fine a example map from my game. It has rain (sprite batch), dynamic map movement, plenty of additional sprites, rich interchangable tiles that are prerendered and dynamic sprite transparency when player is behind an object. AND IT ALL RUNS AT 60fps. https://www.youtube.com/watch?v=K8oGU7XEHHU Follow me on my twitter and I'll follow you back, so we can have a private converstion. https://twitter.com/sevenative
  5. YES. Sprites need children. For example my main player sprite has children with info about his health, name etc. for other players to see in myltiplayer game. So when moving my sprite I simply change the position and don't pay attention to metadata about the player contained as children text and graphics. My question to you is will it improve the rendering speed significantly? http://www.sevenative.com
  6. I have been researching this topic by myself. I don't know if this helps but this is how i create a rotating coin like in mario with pixijs var coin; for(var i = 0; i < 10; i++){ var position = i * 46; var frame = new PIXI.Texture(PIXI.BaseTexture.fromImage('assets/images/world/objects/coin.png')); frame.setFrame(new PIXI.Rectangle( (i * 40), 0, 40, 40)); if(i === 0){ coin = new PIXI.Sprite(frame); coin.animation = {}; coin.animation.frameNumber = 10; coin.animation.frames = []; coin.animation.frameCounter = 0; }; coin.animation.frames.push(frame); }; coin._id = 'original player '; // + _sockets.io.engine.id; coin._class = 'player'; coin.entity = true; coin.notMovable = true; coin.anchor = {}; coin.anchor.x = 0.5; coin.anchor.y = 0.5; coin.position = {}; coin.position.x = playerOptions.position.x + 200; coin.position.y = playerOptions.position.y + 150; coin.width = 30; coin.height = 30; coin.collision = {}; coin.collision.mapCollision = false; coin.collision.entityCollision = false; coin.animation.looper = setInterval(function(){ var texture = coin.animation.frames; var counter = coin.animation.frameCounter; coin.setTexture(coin.animation.frames[coin.animation.frameCounter]); coin.animation.frameCounter++; if(coin.animation.frameCounter === coin.animation.frames.length){ coin.animation.frameCounter = 0; }; }, 50); _camera.entityCameras[4].addChild(coin);Animation can be called by interval or by some other method during the game loop. http://www.sevenative.com
  7. hubert

    Render Event Loop

    Well basically what he is refering to is creating a loop for the game. A game loop is a function that performs some actions every iteration it makes. I actually looked at the video and what he is refering to as a a bad design is that everything between request animation frame and animate function is packed into one. What you should actually do is to design actions that have to be done during one iteration over your loop. Usually it is 01. take input. 02. Move player 03. Perform collsion checks. 04. In some cases broadcast the game state to other players 05. render the game stage Designing a good game loop can be quite complicated since ou have to take in account many factors. You should pause and restart the game. How often should you perform collision checks (usually every time but in some cases it is not necessary). How often to check if objects are in viewport in order no to render them (technique called clipping). Broadcasting the game state to other players usually is made every iteration. NPC AI update. For example you should not check if player is in attack range every iteration. .... and many more. Additionally a good design of a loop and how it changes the states of the objects in your game can give you some additional performance boost! Please refer to some of my answers here. http://www.html5gamedevs.com/topic/6691-how-does-pixi-deal-with-items-positioned-off-the-screen/ In case of pii js using requestAnimationFrame is ok because pixi manages render rate at 60fps. What the author of the video means is that in case of having more than 60 FPS you are using resources more than you should since it does not make any difference of r the human eye! Now to some more advanced stuff! NO ONE EVER SAID THAT EVERYTHING SHOULD BE PACKED IN ONE FUNCTION! this means that you can use the webworkers HTML5 api to speed up some of the computations. What I like to do is to start a rendering function separatly from the game logic. This is very useful in case of creating animated option menus. Pausing the game will not pause the rendering loop and you will be able to make a nice animated menu! Collision tests can be moved to a separate function running as a webWorker so you will be able to utilize another CPU thread a side from your main thread. In the post that i have linked I also show that having a counter inside of a loop can give you a firm grip over how often you execute some of its "routines". Last thing: this is an old module that i have written back in the days. Notice that I actually use the requestAnimationFrame method to call the loop again. Either the author meant what I stated previously or he is not aware about the fact that pixi js does not exceed 60 fps framerate by default. _li.define( 'multiverse.game.game_loop', function (renderer, renderGame, reaction, collision, map_watcher, pathwalker, map_backgrounds) { 'use strict'; var init, game_loop, GLOBAL_CNTR = 0, paused, stats; var loop = function(){ GLOBAL_CNTR++; stats.begin(); if(paused){ game_loop = false; return game_loop; }; pathwalker(); collision(); // changes the position fo cameras while moving if(GLOBAL_CNTR % 12 === 0){ map_watcher(); }; if(GLOBAL_CNTR % 5 === 0){ map_backgrounds(); }; renderGame(); if(GLOBAL_CNTR === 100){ GLOBAL_CNTR = 0; }; requestAnimationFrame(loop); stats.end(); }; init = function (action) { if(!game_loop){ // this is generating the stats for the game stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; stats.domElement.style.top = '0px'; stats.domElement.style.zIndex= '1000'; document.body.appendChild( stats.domElement ); paused = false; renderer('pause'); loop(); } if(action === 'pause'){ paused = true; } game_loop = true; return game_loop; }; return init; }, [ 'multiverse.renderer', 'multiverse.renderer.renderGame', 'multiverse.input.reaction', 'multiverse.game.collision', 'multiverse.game.map.map_watcher', 'multiverse.game.pathwalker', 'multiverse.game.map.map_backgrounds' ]);I hope this helps you a little bit! http://www.sevenative.com
  8. Yes you can, redner to texture is what you are looking for, with this you can render many elments (sprites graphics etc) into one texture and use it agian as "one", my sugesstion for you is to use a separate displayObject Container and render everything into it. Then you can move the display object container with one sprite insteda of having a display object container with many dead bodies. Please refer to this in order to see working code examples: Rendering http://www.html5gamedevs.com/topic/6507-display-object-container-to-an-imagesprite/#entry38726 Trimming the element in newer pixi versions http://www.html5gamedevs.com/topic/8613-upgrading-to-pixi-160/#entry51302 I hope this helps you! http://www.sevenative.com https://play.google.com/store/apps/details?id=pl.com.wojciak.kontakt.new_words
  9. If you want to use it with graphics you'll have to pass it with buttonMode = true; A short snippet for graphics; var slot = graphics.drawRect(slotData.X, slotData.Y, _square, slotData.sltHeight); slot.b_id = slotData._id; slot.b_number = slotData.b_number; slot.type = slotData.type; slot.interactive = true; slot.buttonMode = true; slot.hitArea = new PIXI.Rectangle(slotData.X, slotData.Y, _square, slotData.sltHeight);http://www.sevenative.com https://play.google.com/store/apps/details?id=pl.com.wojciak.kontakt.new_words
  10. No do not initialize all views at the same time. My advice... Create a stage -> scene (display objectContainer) and then add views to it. The scene will be a wrapper for all of your elements! A good practice is to call different views every time you need! Here is my code. What you can do is to clear the scene in order to free some memory. THIS IS MY MAIN VIEW ROUTER CLASS _li.define( 'bitwars.views', function ( renderer, scene, loading, mainRouter, main, game, choseName, gamesList, gameRoom ) { //, loading, main, game 'use strict'; var init, view, _renderer, _scene; init = function (data) { console.log('data inside views', data); if(!_renderer){ _renderer = renderer(); }; if(!_scene){ _scene = scene(); }; if(data.clear === true){ for(var ele in _scene.children){ _scene.children[ele].interactive = false; _scene.removeChild(_scene.children[ele]); }; _scene.children = []; }; if(data.view === 'loading'){ view = loading(data.percent); }else if(data.view === 'mainRouter'){ view = mainRouter(); }else if(data.view === 'main'){ view = main(); }else if(data.view === 'game'){ view = game(); }else if(data.view === 'chooseName'){ view = choseName(); }else if(data.view === 'gamesList'){ view = gamesList(); }else if(data.view === 'gameRoom'){ view = gameRoom(data.data); }else if(typeof data.view === 'undefined'){ return view; } _renderer.renderer.render(_renderer.stage); return view; }; return init; }, [ 'bitwars.renderer', 'bitwars.scene', 'bitwars.views.loading', 'bitwars.views.mainRouter', 'bitwars.views.main', 'bitwars.views.game', 'bitwars.views.chooseName', 'bitwars.views.gamesList', 'bitwars.views.gameRoom' ]);AND THIS IS THE SINGLE VIEW CLASS THAT IS CALLED game room: _li.define( 'bitwars.views.gameRoom', function (texture, renderer, scene, audioController, sockets, views) { 'use strict'; var init, _renderer, _scene, _audioController, _sockets, _game, view = 'gameRoom'; init = function (data) { if(typeof data === 'undefined'){ views({ view: 'gamesList', clear: true }); return false; } _game = data; if(!_renderer){ _renderer = renderer(); }; if(!_scene){ _scene = scene(); }; if(!_audioController){ _audioController = audioController(); }; if(!_sockets){ _sockets = sockets(); }; var dim = (Math.sqrt( (_renderer.canvas.height * _renderer.canvas.height) + (_renderer.canvas.width * _renderer.canvas.width) ) )/10; var playButtonTexture = PIXI.Texture.fromImage('assets/images/screens/button1.png'); var playButtonTextureOver = PIXI.Texture.fromImage('assets/images/screens/button2.png'); var playButtonTextureDown = PIXI.Texture.fromImage('assets/images/screens/button3.png'); var back = { position: { x: 0, y: 0 }, dimensions: { height: _renderer.canvas.height, width: _renderer.canvas.width }, asset: 'assets/images/screens/main.png' }; texture(back); var gameName = new PIXI.Text('Game: ' + data, {font : '50px Arial', fill : '#0490FF'}); gameName.anchor.x = 0; gameName.anchor.y = 0; gameName.position.x = (_renderer.canvas.width * 0.05); gameName.position.y = (_renderer.canvas.height * 0.05); gameName.width = (_renderer.canvas.width * 0.2); gameName.height = (_renderer.canvas.height * 0.1); var back = new PIXI.Sprite(playButtonTexture); back.buttonMode = true; back.anchor.x = 0.5; back.anchor.y = 0.5; back.position.x = (_renderer.canvas.width * 0.15); back.position.y = (_renderer.canvas.height * 0.9); back.width = (_renderer.canvas.width * 0.2); back.height = (_renderer.canvas.height * 0.075); back.interactive = true; var backText = new PIXI.Text('Leave', {fill : 'white'}); backText.anchor.x = 0.5; backText.anchor.y = 0.5; backText.position.x = (_renderer.canvas.width * 0.15); backText.position.y = (_renderer.canvas.height * 0.9); backText.width = (_renderer.canvas.width * 0.2); backText.height = (_renderer.canvas.height * 0.1); back.mouseover = function(data) { this.setTexture(playButtonTextureOver); }; back.mouseout = function(data) { this.setTexture(playButtonTexture); }; back.click = function(data){ _sockets.emit('playerLeaveRoom'); }; var test = new PIXI.Sprite(playButtonTexture); test.buttonMode = true; test.anchor.x = 0.5; test.anchor.y = 0.5; test.position.x = (_renderer.canvas.width * 0.5); test.position.y = (_renderer.canvas.height * 0.9); test.width = (_renderer.canvas.width * 0.2); test.height = (_renderer.canvas.height * 0.075); test.interactive = true; test.mouseover = function(data) { this.setTexture(playButtonTextureOver); }; test.mouseout = function(data) { this.setTexture(playButtonTexture); }; test.click = function(data){ _audioController['hud']['click'].play(); if(typeof input.value == 'undefined' || input.value == ''){ }else{ console.log(input.value); _sockets.emit('chatMessage', {message : input.value, room : _game}); }; }; var testText = new PIXI.Text('test', {fill : 'white'}); testText.anchor.x = 0.5; testText.anchor.y = 0.5; testText.position.x = (_renderer.canvas.width * 0.5); testText.position.y = (_renderer.canvas.height * 0.9); testText.width = (_renderer.canvas.width * 0.2); testText.height = (_renderer.canvas.height * 0.1); var element = { type : 'input', id : 'chatTest', position : { x : _renderer.canvas.width/2 - 100, y : (_renderer.canvas.height/10) * 6 }, width: 200, height: 22, backgroundColor : '0xFFFFFF', borderRadius: 5, borderWidth : 1, borderColor : '0x0099CC' }; _sockets.on('chatMessage', function(data){ console.log(data); }); _sockets.on('', function(){ }); var input = PIXI.INPUT.createElement(element); _scene.addChild(input); _scene.addChild(gameName); _scene.addChild(back); _scene.addChild(backText); _scene.addChild(test); _scene.addChild(testText); return view; }; return init; }, [ 'bitwars.renderer.texture', 'bitwars.renderer', 'bitwars.scene', 'bitwars.audio.audioController', 'bitwars.sockets', 'bitwars.views' ]);And based on the mediator pattern I simply just call the view and it is returned by my view router. I have to specify if I want to clear the scene or leave it as it is. views({ view : 'main',clear : true});I hope this will help you. The cleaning of the scene is additioanally unseting the buttons to interactive.false since I know there was some kind of bug there (just to be 100% sure!) http://www.sevenative.com https://play.google.com/store/apps/details?id=pl.com.wojciak.kontakt.new_words
  11. Please do not use any hidden inputs! It is a rabbit hole!!! You wont be able to to use native wrappers like ejecta, completely misses the point of creating this plugin - no DOM elements inside pixi game. Hidden inputs sometimes trigger themselves in mobile browsers! FOR THE LOVE OF GOD DO NOT USE THE HIDDEN INPUTS!!! I BEG YOU!!!
  12. Could you please show us how are you trying to move the mask in your code? Are you moving the sprite or the mask itself? A little snippet would be useful! http://www.sevenative.com https://play.google.com/store/apps/details?id=pl.com.wojciak.kontakt.new_words
  13. great. I started to implement my own Pixi plugin but your seems more smooth! Publish it on git hub! It could gain some traction! +1 for json configuration. i did it the same with my plugin! How are you planning to implement select method and inserting caret between the letters of the word? Additionally I added a value property to the input element. Is it the same in your plugin?
  14. Exactly what I need! How do you instantiate the plugin? Is it going to be done the same way?!
  15. Yeah, I started to play around with it today and i have a working POC but with some bugs, and only input element. The thing is that I am completely allergic to dom in canvas games. Without using pixi there are many libraries doing something like that but in case of pixi everything has to use a normal dom input tag appended to the body element and that sometimes messes up my layout! https://play.google.com/store/apps/details?id=pl.com.wojciak.kontakt.new_words&hl=en http://www.sevenative.com