Jerorx

Members
  • Content count

    25
  • Joined

  • Last visited

About Jerorx

  • Rank
    Member

Contact Methods

  • Website URL
    www.dynetisgames.com
  • Twitter
    jerome_renaux

Profile Information

  • Gender
  • Location
    Belgium

Recent Profile Visitors

384 profile views
  1. Thanks for the pointer to Incheon, didn't know it, looks quite interesting! @kabuto178 Keyboard-controlled movements would typically fall in the "fast-paced games" category, in which case the server would send the player coordinates multiple times per second, and the client would interpolate the sprite's position in-between. This is often done by not rendering the last update, but the one-before-last; this keeps the rendering slightly in the past but allows to cope with latency. Actually, this conversation made me think that I should make another tutorial similar to this one but for keyboard-controlled multiplayer games. That would be a good testing bed and would be useful for the discussion. I'll try to post that relatively soon!
  2. Thanks Eric, I'm sure it could be useful for some projects as well. Maybe more for 3D than 2D projects, where they could be used as textures for environment objects. In any case, that 's a very nice collection and a great contribution, good job!
  3. @kabuto178 The problem would rather be the type and movements and the pace of the action, rather than the real-time aspect. You can have a look at Phaser Quest, which is the multiplayer online game I was referring to in my previous message. Similarly to BrowserQuest, it is designed to be an MMO-like, and the solution I discussed works well for this game. @FakeWizard Good points. Actually, having a tween execute the movement from point A to point B is some form of movement prediction: you assume that the player will follow the indicated trajectory until the end and render it accordingly. The trick is then to make sure that the timing of this rendering is correct! Did you know that Blizzard's World of Warcraft uses TCP? It's true that UDP is often recommended for online games, but UDP and TCP both have pros and cons, and some AAA MMO's do use TCP apparently. I don't have a reference available here but I can try to post one later. Indeed, to handle very big loads and scale well, eventually the back-end architecture has to change, even from the hardware point of view. Thanks for the pointer to SocketCluster. I still have some margin before any of my projects gather enough traffic that such improvements are necessary, so I admit I haven't looked into much of that yet, but you are right: eventually, any serious MMO project will have to resort to that.
  4. @kabuto178 : I invite you to have a look at the source code, and more particularly at client.js, which processes the messages from the server, and game.js, which contains the Phaser code. When a new player connects, the server sends the message 'newplayer' to all clients, along with the id and coordinates of the new player. This is handled in client.js by Client.socket.on('newplayer',function(data){ Game.addNewPlayer(data.id,data.x,data.y); }); In game.js, Game.addNewPlayer() is defined : Game.addNewPlayer = function(id,x,y){ Game.playerMap[id] = game.add.sprite(x,y,'sprite'); }; So it boils down to using Phaser's game.add.sprite, using the coordinates sent by the server. (Game.playerMap is a map to organize the sprites by id). Similar methods are used to update the position upon receiving a 'move' event from the server. In client.js: Client.socket.on('move',function(data){ Game.movePlayer(data.id,data.x,data.y); }); And in game.js: Game.movePlayer = function(id,x,y){ var player = Game.playerMap[id]; var distance = Phaser.Math.distance(player.x,player.y,x,y); var tween = game.add.tween(player); var duration = distance*10; tween.to({x:x,y:y}, duration); tween.start(); }; Where a basic tween is used to move the sprite. Let me know if this is helpful or not. @FakeWizard: this is a good point indeed. Actually, I had to solve that problem for a game I just finished, which I will release in a few days. I'm also currently writing an article with a section precisely about this, which should come out at the same time. Both will be published on the same website as this tutorial. The first solution I used was the one you mention, by associating timestamps to movements. But it turned out to be a bit problematic, because timestamps are not universal, they can vary wildly from one machine to another (if you can, open a browser on two different computers side by side, and in the console type console.log(Date.now()); you should see different values). It worked as long as I was testing on my machine, but once online it broke down. I ended up simplifying this, and instead of using the timestamps, I only used the latency of the clients, which is the key factor here. Once you keep track of the latency, you can use it as follows: Player A sends message telling server that he's moving to pos.x , pos.y (In my implementation, since the environment is fixed, A doesn't have to wait the response from the server to move ; it moves immediately, and will be adjusted only if the server replies that the move was illegal, which can happen only by attempting to cheat. It makes the game more responsive but doesn't change your point.) Server receives the message X ms later. The server has an estimate of X (= latency of player A) and stores it along the move request. Server broadcasts the information to all connected clients; to each, it sends the information that A has moved, along with the latency X of A, + the latency Y, Z, etc. of each receiving client Player B receives the message K ms later. If we consider that X was the latency of player A, and Y is the latency of player B, K = X + Y. The values of X and Y are estimated by the server and sent along the movement messages, so they are known by the client when he has to update position. Now, the position update is likely not instantaneous, to be smooth you are likely to use a tween or something. The duration of the tween can be adjusted to compensate for the delay K. If K is 150ms and the tween is supposed to last 400ms, the tween will end up lasting only 250ms, to make sure that on the screens of the two players, A's sprite arrives at his destination roughly at the same time. Typically, such changes in tween duration are not very perceptible; either the tween lasts a long time, and a difference of 150ms will be no difference, either it is short, and the tween will happen too fast anyway for a human observer to really perceive the difference. Let me know what you think of this solution, I'm interested in feedbacks. Out of experience, it worked pretty well for my game in any case. Now if you make a fast-paced game such as an FPS or a MOBA, where very fast, short movements happen a lot, this solution might not be the best one (although with 200ms latency, players will be screwed no matter what in that kind of games). Dedicated solutions exist for this kind of games, but it's always relatively tricky and ad hoc. If you use Twitter, I invite you to follow me to get notified when I release the article about this problem, it should interest you. If not, I'll notify you through here.
  5. Hi, I've been working on multiplayer online experiences with Phaser, Node.js and Socket.io recently. I thought that it might be interesting to make a tutorial detailing how to make a very basic multiplayer game with these tools, so here it is : How to make a multiplayer online game with Phaser, Socket.io and Node.js . As I said, the game (which can be played here) is very very basic: you click on the small map and your character moves to where you clicked. The movements of the other players (if any) are displayed in real-time. No animations or collisions or whatever, the focus is on the networking aspect. Feedback is more than welcome, as this is my first tutorial ever. If you find it interesting and would like me to make follow-up tutorials on some aspects, don't hesitate to ask! Jérôme
  6. Ok I made some progresses based on what was mentioned here, but here is where I'm stuck now. The end goal is to be able to offer to the players very, very big maps, and to do so efficiently. That's why I try to draw only the relevant parts of the maps (or "chunks" in the procedural terminology). The big problem about performance are the layers; very big layers, even with no tiles, will make the game extremely slow. Therefore, it is NOT an option to start with a huge layer and draw to it (using putTile() for example) as the game goes. I have to start with a small layer, and then expand it gradually. But I don't seem to find any way to change the size of the render area of a layer after creation. If I create a layer of size 20 tiles * 20 tiles, I can putTile() wherever in that area; but if I try to putTile() outside of these coordinates (at 21,21 for example), it obviously doesn't work, no matter how I mess with the layer properties (I tried resize(), I tried to change the dimensions of the layer.data object which holds the tiles, etc. but to no avail). (NB: I would also need to do the opposite, that is shrink the layer to remove the parts that the player has visited and left, in order to keep as small layer size at all time. I guess if you can do one you can do both.) I may not be doing it the right way, and I suspect I would need to dig into the underlying Pixi stuff, but I'm not familiar with this at all so any hints would be appreciated.
  7. Hi, I'm creating a tilemap from a map made in Tiled. When I import it and create a layer in Phaser, the whole layer is created. I'm dealing with a medium-sized map, but I guess on huge maps, this might become costly, performance-wise? Isn't there a way to create a small part of the layer, for example the region around the player, and to create other parts as the player explores the map, in order not to ever create the full map, or only in the rare cases when the player explores it all?
  8. Hi, I'm finished with a small 2D MMO-like project using Phaser, and I now need an original map for the game. The explorable world consists in one ~300 tiles * ~100 tiles map to explore, but I would like to have a new map of similar dimensions. A tileset is already available, and I need someone interested in drawing the map using that tileset in Tiled. The main requirement is to have a small amount of creativity so that the environment that is drawn is interesting enough (that's why I don't do it myself, I don't qualify). There are close to no restrictions about the content of the map, apart from trying to leverage all the decor elements that the tileset offers and having some variety. So if you enjoy making maps, that would be a moderate amount of work with lots of freedom. I need the map in tmx format, but I don't actually require experience with Tiled; it's a pretty easy tool and there is no hurry, so if you feel like it you can take the time to learn on the go, as long as the result is nice. As my project has no commercial views, I would be looking for this for a free collaboration. In addition you'll be free to reuse the map, as is or modified, for whatever other projects you want. Full credit will be given on the page of the game. The game is about finished and is testable online, I can provide the URL if you are interested (that will also give an idea of what kind of map to make). The fact that the project is already close to finished and will see the light of day in the coming weeks might make contributing to it a bit more interesting! For more information or if you are interested, you can contact me at jerome.renaux@gmail.com . Thanks!
  9. I was not familiar with postUpdate() and how to use it, I looked into it and indeed it solved the problem! Thanks!
  10. Hi, Consider the following code: mySprite.addChild(game.add.sprite(0, 5, 'shadow')); This has the effect of adding a shadow to a sprite. The cool thing is that the shadow will follow the parent sprite extremely smoothly, without any apparent lag. My question is, how could I emulate such a smooth "tracking" behavior without using addChild() ? I tried something as follow: // In create() : var player = game.add.sprite(100, 100, 'player')); var shadow= game.add.sprite(100, 105, 'shadow')); // In update() : shadow.x = player.x shadow.y = player.y + 5 That is, manually associating the coordinates of both sprites in the update loop. It works, but it's much less smooth, and you can see the shadow always lagging a bit behind. Visually speaking, it's not satisfactory at all. What sorcery takes place under the hood that makes it work fine with addChild(), but not when doing it manually in the update loop (I didn't find anything conclusive in the code, but I guessed I didn't look right)? Is it possible to reproduce? Thanks for your tips. NB: I need this because I'm in a situation where the parent sprite (e.g. the player) should be rendered below some sprites, while child sprite (e.g. the shadow) should be rendered on top of them. If I put the parent and child sprites in different groups, the rendering is ok, but the following behavior becomes laggy. If I add the child to the parent using addChild, the following behavior is ok but then I can't figure how to render parent and child on two completely different levels.
  11. I don't see anything obviously wrong at first glance, but here are two tips: - Try to inspect all the objects of which you try to access the property 'x'; apparently one of these objects is undefined. - For development purposes, it's usually better to use the non-minified version of a library, so that the error messages point to meaningful lines of code (as you say, with a minified file, line 24 doesn't mean much). Hopefully this will help you track down the issue.
  12. Hi people, I'm extending the Sprite class with a class named "Being", which I further extend with two child classes, "Monster" and "Player". But it doesn't work. Here is first the code for my classes. function Being(x,y,key){ Phaser.Sprite.call(this, game, x,y,key); game.add.existing(this); } Being.prototype = Object.create(Phaser.Sprite.prototype); Being.prototype.constructor = Being; function Player(x,y,key){ Being.call(x,y,key); } Player.prototype = Object.create(Being.prototype); Player.prototype.constructor = Player; function Monster(x,y,key){ Being.call(x,y,key); } Monster.prototype = Object.create(Being.prototype); Monster.prototype.constructor = Monster; ("game" is the Phaser.Game instance and is a global variable, I didn't forget to pass it as an argument.) I have looked at the examples and forum topics, and it seems to me that it's the proper way to do. Now if I create a new instance of Being, which inherits from Sprite, this works like a charm. var B = new Being(300,300,'player'); But if I try to make a new instance of Player, which inherits from Being which itself inherits from Sprite, the it doesn't work. The code is: var P = new Player(200,200,'player'); And in the console I get the following error: "phaser.js:15246 Uncaught TypeError: this.onTextureUpdate is not a function". This error makes the entire game crash. I'm really puzzled by the fact that it works for Being, but not for Player, which seems to indicate that all this code is mostly correct, except that I must be doing something wrong with the "second-level" inheritance. Any help would be greatly appreciated!
  13. Hi, I'm interested in using the QuadTree class of Phaser to retrieve spatially-indexed objects based on their spatial coordinates. But it seems I don't quite understand the "retrieve" part. I'm looking at the quadtree example, and I don't understand it well. I would expect that when you click somewhere in the example, only the green rectangles that intersect or are within the big blue rectangle would be selected, based on their spatial coordinates. However, it doesn't seem to be the case at all, and I don't see any "logic" in the way the green rectangles are selected. Depending on where I click, nearby rectangles are selected (which makes sense), but rectangles very far away from the select zone are selected as well, which seems to me to defeat the purpose of spatial-based selection. In other cases (seemingly random to me), almost all rectangles are selected, which renders the whole thing useless. Never do I manage to select only the rectangles that are in the blue selection zone. Can someone explain it to me? My goal being to be able to select only the rectangles in the blue zone, or at least rectangles closeby.
  14. @alex_h: it seems that this callback fires at every frame, not when each intermediate value in the array is reached. It's useful to encapsulate the monitoring of the tween elsewhere than in the update loop, but this would still require me to manually check at every frame the state of advancement of the tween, wouldn't it? What would be great would be, in my example, a callback that fires only three times, that is, when the sprite reaches the three positions (1,2), (1,3),(2,3) . @lumoludo:Last time I used chained tweens, I had a slight interruption between each tween. Meaning that if my sprite has to move five times forward, and I use five chained tweens, the sprite would briefly stop four times, instead of performing one smooth progression. Or maybe I did it wrong? That would be good news, because the only hack I found at the time to solve that issue was to extract all the straight lines of n points in the path and create as many tweens, but it felt overly complex.
  15. Hi, I'm tweening a sprite along a path, through specific x,y coordinates. Let's say I want the sprite to go through the points (1,2), (1,3),(2,3), I'm doing it as follow: tween.to({x: [1,1,2],y:[2,3,3]}, 600,null, false, 0); What I call "intermediate values" in a tween are the different values contained in the arrays provided to the to(). In my case, the intermediate values correspond to the point through which the sprite has to move. The tween works like a charm, but my question is, how to detect when each of those intermediate values are reached? Something like tween.onComplete(), but that fires after each iteration through the value arrays? Or do I need to monitor myself the position of the sprite in the update loop, and detect myself when each point is reached?