waechtertroll

Members
  • Content Count

    25
  • Joined

  • Last visited

About waechtertroll

  • Rank
    Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I'm not really sure what the requirements for your visualisation are, and if your fiddle is in any way related to what you have to visualise, but might I make a scientific question: what information is the user meant to get from the graphs? I'm speaking as a bioinformatics/data visuals guy, and I fell like it is absolutely ridiculous (no offense, just figure of speech) to think any living entity will ever be able to process those 2e6 data points and their high-freq changes in real time. Before you get lost in this task you should probably research how your users interact with the graphs. Maybe they will just zoom in to a certain range to keep an eye on it, and so you'll be able to start with a closer view need to update far less points. Maybe there are other usage patterns you can use to your advantage. In case you really need to visualise all that data I think you won't get around doing a draw-a-line approach; but drawing lines between known coordinates ain't that hard. The harder part is to draw pleasant looking axes, but really there is no need to. In web you have the possibility of drawing the coordinate system and the data independently. So you could have a graph library of your choice drawing the axis, descriptions, and whatever doesn't need to be redrawn constantly as beautiful as you like, and then render a transparent canvas on top of it which does only render datapoints with simple lines. Maybe even Pixi.graphics.lineTo(x, y) will be enough? Then you only need to take care that viewport changes propagate to both elements. To speed up the whole thing you might want to do object pooling; that is not creating new point coordinates every time you update, but reuse existing point objects - cost of allocation and all the stuff you already know. Perhaps you could even abuse Pixi's already optimised particle system to do that? Using WebGL directly might be good, too - for example scaling the input coordinates to canvas coordinates can be done by a fragment shader instead of JS for even more pure speed.
  2. An interesting topic. I've had good experiences with using immutable data structures for games in the past (ClojureScript). Would you mind sharing some details of your benchmarking @mattstyles? I didn't do anything very fancy with lots of graphics, though. I think it *should* be possible to apply something like redux to keep track of the state. My advice is, you don't subscribe rendering to every game state change directly - as was done in the fiddle - but separate state changes from drawing and draw periodically with animation frames. Maybe also keep the sheer number of state changes low by grouping smaller changes per dispatch together. Immutability plus js being single-threaded will help you, as you'll always have a valid snapshot when rendering (or dispatching a bigger change). You might even have mutable elements like particle effects and physics on their own, as you only need to push them a time-tick event; so they won't trigger dispatches either; although I can imagine that could cause some major headache from the FP point of view...
  3. A bit of playing around showed that in your situation it should be better to just add `e.preventDefault()` to your keyboard handler; as this leaves the rest of the page intact (maybe your game is embedded in another webpage?). In the example the canvas is blue. Click it once to enter the game. Pressing up/down send a message to the console and no scrolling is triggered. Pressing left/right will leave a message on the console and still trigger scrolling.
  4. You might want to do the following: - Add `tabindex = 1` to your canvas element so it can be focused - Store the canvas DOM element in a variable (you might be doing this anyway to init the canvas...) - Attach a listener to window.onfocus. Due to event bubbling it should be called anytime focus inside your page changes. Make it do something in the spirit of `if (document.activeElement !== canvasDOMNode) canvasDOMNode.focus()` - On init, once call `canvasDOMNode.focus()` to be sure to start inside the game canvas This should assure all your input events go to the canvas first. Remember to make them .preventDefault() (and maybe .stopPropagation() ) so they keys won't bubble up and move the page. Be aware that this may break other input elements on the web page. I'm using a similar approach in a complex desktop-app like environment and it works well. If you feel like using existing modules, you might want to check out mousetrap which applies that technique in a very sophisticated way.
  5. Thanks... the Mesh class seems to do exactly what I think I need. Documentation could be a bit better. I'll have to play around a bit with dividing stuff into proper coordinates and figuring out how Mesh uses them exactly, but I'll give it a try in the next weeks.
  6. Hello, although I don't have enough spare time to create games at the moment, I'm playing a bit around with code to understand game mechanics. At the moment I'm teaching myself soft body dynamics. I can create an entity consisting just of cordinates (say a sphere) and play around with their shape, wobbling, squishing etc. But I'm at a loss at how to bind a texture to them that actually distorts according to the coord changes; preferrably in a way performant enough to use it in a game, and most preferrably done in Pixijs. Maybe I'll have to cut the texture into a mesh, bind UV coordinates to them and then use something like three.js to render it? I see that e.g. Dragonbone has some way to add meshes to characters - plus it can be used from pixi. Will it distort textures properly when I modify mesh coordinates, or is this information only used when exporting animations? What other approaches can you think of?
  7. Hm, not sure what you mean with firing, that term is commonly used for events. Do you mean the if-branch of your condition won't be evaluated? To be short, it can't. The if-condition is checked only once, that is directly after you set red's initial position. Afterwards you keep modifying the position in the game loop, but never check the position anymore. I believe you think that if-statement gets evaluated every time the position changed (called the watcher pattern). That is not true. It gets only checked when the JS interpreter reaches the line that contains the if-statement. Watching a variable for changes is possible, but the exact mechanics vary with the browser you choose to run the script, and it's not exactly trivial (at least last time I looked, maybe my information is outdated?). To solve your problem at hand, you need to put your if-condition in some place it can be reached. // initialising object red red.position.set(startX, startY) red.moving = true function gameLoop() { if (red.moving && red.position.y > 250) { red.position.x -= 1 } else { red.moving = false console.log("destination reached") } requestAnimationFram(gameLoop) } Now every time the game loop is evaluated, the position is checked, too. To avoid logging "destination reached" every time, you need to stop checking the position once it has reached the 250px position. Of course, if you want to restrain a number of objects that way, you might not want to do type that for all objects function moveElement(el, dx, dy) { if (!el.moving) return el.position.x += dx el.position.y += dy if ( el.position.x < (el.boundaries.minx || -Infinity) || (el.boundaries.maxx || Infinity) < el.position.x || el.position.y < (el.boundaries.miny || -Infinity) || (el.boundaries.maxy || Infinity) < el.position.y ) { console.log("Boundaries reached") el.moving = false } } red.position.set(...) red.moving = true red.boundaries.miny = 250 function gameLoop() { moveElement(red, -1, 0) requestAnimationFrame(gameLoop) } Of course, this is simplified and not exactly optimised, but not knowing about your project it's as close as I can get. It also seems like you're pretty new to JS or programming in general, so I kept my examples quite simple and I also advise you to check out some of the great JS learning guides linked in the main forum. If I happen do be wrong, no offense meant!
  8. To sort elements, if z-position is not enought, try depth-sorting your elements by giving them proper z-indices. In CSS, objects on top of each other are sorted by z-index: <number>, from low number = below to highest number = on top. To pass on your events you might want to create an event listener that does nothing but pass the event on, and add that listener to all elements that might ever appear above those elements which are meant to receive clicks. You might want to search the web for the term event bubbling for some background information.
  9. Why not just add your own move method to the camera which also updates everything else you need and use that method instead of directly moving the camera? myCamera.doMoveCamera = function(self, x, y) { calculateGameGrid(x, y); self.setPosition(x, y); } And in your code never call "myCamera.setPosition(...)", but alwas "myCamera.doMoveCamera(...)". I'm not sure how you're going to call the function, so I included a "self" If that's too simplistic for you needs, you might also have a read on variable watching in various browsers, like e. g. this article.
  10. @Permith I think your oppinion about functional programs having dirty intermediate states comes from the fact that you're using basic JavaScript Objects as variables. If you write things like player = player.setPos(100, 200), first the object's x will be set, then its y, then the same object with modified fields will be re-assigned to the player variable. Inbetween it will be in a dirty state, so async events, like input, might get either version (player before call, player with new x/old y, new y/old x, new x and new y). In a functional language, first a new position object will be created, this will be attached to a copy of the player object, and then this new object will completely replace the player object. As even asynchronous calls will not find a global state to just pull some data "from exactly now", they will never be able to receive any intermediate, dirty objects. In a more relaxed approach, when global variables can be changed atomically, you'll still have valid objects, either from before or after the update, but never inbetween (think update locks the object until it's done, though that's not true, the concept applies). To get this behaviour in JS, you'll need to use implementations of real immutable data, like Mori.js or immutable.js. FP and ECS pattern Years ago I implemented a platform game on Java using the ECS pattern. A basic entity did just provide position, an update, and a render interface, as well as a list of components and sub-entities (like, Player has a Weapon). Whenever a component was added, I had it added to the list and registered at a system (maybe it could fall, so it got a Gravity component that registered to the physics system, or some entity should be the player figure, so it got a PlayerControl component that registered with the input system, you get the point). Each time step the systems processed an update of their registered components, then the entities combined all update instructions from their components to update their positions. It looked very tedious in the beginning, but once the basic skeleton and all the first entities were finished, I was amazed at how easy I could introduce complex behaviour of anything by simply adding or removing some components from it. Some time ago I began to learn functional programming, and for about two years I've only been writing OOP-style when forced at gunpoint, for some of the reasons MattStyles mentioned, and some more. For web games, I don't write JavaScript when I can avoid it, but write in ClojureScript and transpile to JS.I'll give you some basic points of my way of writing FP games (though writing pure JS/ES6, your experiences may be far different), which works well, though it may be inherently terrible. My game loop models all game events as input queues, and it maps updates of the game world to them in reactive-fp style. That means, anything that requires any change to the game world starts an iteration of the game loop; be it a small change like "increase score", or a big update like "time step". So things like input or logic updates can be done immediately, without waiting for the next drawing loop to finish, while all rendering and global time updates will still have a consistent, finalised state (now, if we could easily delegate rendering to another thread in JS, we could have insanely fast and responsive games...) FP doesn't mean you don't have a state. Every game loop iteration just receives the current world state, swaps out some values and returns an updated version. The point is, no one else does swap out values, especially no arbitrary keypress or anything Yes, time is just a game event User input, entity hit, level solved etc. doesn't do anything on its own, but just put another message to the event queue One advantage: if objects moved so fast that collision locations can't be detected correctly, we still have the previous (input) state availiable and can move the objects back in time for fractions of the delta time until we get a clean situation to solve and output that state Basic data in CLJS is organised in maps. That allows to swap single elements for freshly created ones with constant/linear time access (depending on implementation of the maps). The thought behind it might be similar to your tuple/triple idea. Once again I call out the words "Mori.js" and "immutable.js" Some of the ways I created to update entities and all of their components in the past: Chain all systems, make them act on all entities, but only if they have attributes that system acts on. Bit of slow-ish Group entities by classes, make systems act on their relevant entities. Great until an entity has too much components and you can't decide where to group it Factory style: genereate functions for entities that receive themselves as argument and return updated versions of themselves, chain all those functions on update. Put each entity's functions in a list/array inside itself. Actually working quite well Chain all systems, but make the function calls multi-methods; applying different methods based on the registered components. Very similar to the first version, but more elegant to implement, don't know if that's possible in JS After all, I agree - combining the Components with the immutable data set is the greatest challenge, and there is no canonical way to do that; as always it depends on what you're trying to achieve. I'm not sure if it's of any help, but at least you'll know that it's quite possible to create FP/ECS games ;-)
  11. I thought: Better late than never. Inky cricket's solution works well for square elements. Here is a solution for rectangles of any shape. The corner collision is not 100% perfect at extreme cases that way; the correct/best solution would be to step back time and advance in smaller steps until the corner collision is solved by one of the two unseparated cases, but it works. Again, depending on your axis orientation you might want to swap 'top' and 'bottom'. The solution uses the separation axis theorem (which is a fancy way of looking at the borders, at least for rectangles) to check for simple collisions: if two axes were separated before the collision but are no longer separated after collision, then movement among them caused the collision. For collision around corners (both axes were separated before collision) the simple detection might not be enough, so the objects' relative velocity is compared to their distance before the collision, to see if the collision was caused by the objects' x- or y-movement. function unseparated(x1, d1, x2, d2) { // test for normal axis separation return (x1 <= x2 && x2 <= x1 + d1) || (x2 <= x1 && x1 <= x2 + d2); }; function collision(a, b) { if (unseparated(a.x, a.width, b.x, b.width) && unseparated(a.y, a.height, b.y, b.height)) { // collision vx = (b.x - b.prev_x) - (a.x - a.prev_x); // relative x-velocity vy = (b.y - b.prev_y) - (a.y - a.prev_y); // relative y-velocity if (unseparated(a.prev_x, a.width, b.prev_x, b.width)) { // x-dir overlapped before -> collision in y-direction return (vy > 0) ? 'top' : 'bottom'; } else if (unseparated(a.prev_y, a.height, b.prev_y, b.height)) { // y overlapped before -> collision in return (vy > 0) ? 'left' : 'right'; } else { // diagonal-ish collision near corners dx = b.prev_x - a.prev_x; // x-distance before collision dy = b.prev_y - a.prev_y; // y-distance before collision if (Math.abs(vx) >= Math.abs(dx) && // x-speed was enough to collide dx * dy > 0){ // x-velocity was in x-direction return (vx > 0) ? 'right' : 'left'; } else { // x-speed was not enough to collide => y-collision return (vy > 0) ? 'top' : 'bottom'; } } } };
  12. Well, the most easy solution is to let Phaser auto-scale it to use as much screen space as possible, by adding the following to your gamestate's preload function: this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL; this.scale.pageAlignHorizontally = true; this.scale.pageAlignVertically = true; You can always read up on the Phaser ScaleManager documentation, experiment with other scaleMode constants and find which suits your needs most.
  13. Ah, I SOLVED it. I didn't mention that, but it appeared as root of the problem: I applied scaling and translation to the same Container, so both transforms would influence each other. To achieve my goal, I had to do the following Create a Renderer Create a "root" Container, add it to the Renderer, apply scaling Create a "stage" Container, add it to the "root", apply (now auto-scaled) translation Add graphics into the "stage"
  14. Hello, I'm trying to get a coordinate system with (0,0) at the center of the screen. If I understood the API documentation correctly, adding a Container, applying PIXI.Container.setTransform(x, y, scaleX, scaleY, rotation, skewX, skeyY, pivotX, pivotY) and then adding Sprites as children to that Container should apply the transformation to all of them, right? So I created a Container, set x to width/2 and y to height/2, and added Sprites. Problem is, they still appear with (0,0) at top-left corner. Also modifying Container.x/y or Container.position.x/y would not add translations to children Sprites. Of course I could solve the problem by adding the width/2 and height/2 offsets to every sprite I create, but I really think display parameters should be seperated from the model data. What am I doing wrong? Is there a better solution?
  15. Many good points have been mentioned already. If you have a language that compiles to JS without knowing JS, you might run into big problems debugging; you can never be sure, who's to blame for bugs - you, your X to JS compiler, JS, or the library you used. So even if you don't like JS (and there's lot of reasons to dislike it, especially if you're familiar with other languages), you need to know it first. Something that has not been mentioned yet is ClojureScript. I do the terribly evil deed of writing games in ClojureScript, and it does work really well for me. The reasons behind this choice are as follows: JS's take on var, this, and even inheritance/prototyping is very confusing to beginning developers; it took me longer than in any other language to be able to securely do basic OOP due to these quirks. I could only really understand them once I got serious with functional programming. I think, JS pretends to be OO, while it happily mixes FP and OOP concepts. Another thing that makes JS development tricky is, how quickly one can get lost in the depths of callbacks creating callbacks that mutate objects and create callbacks and so on, commonly refered to as "callback hell". Here ClojureScript really shines. I can write a game loop that keeps an immutable game state and reacts to callback events once and in a controlled way, updating game state predictably (and even with the possibility to go back in time/undo for free). Live developing running games using browser-REPL gives you the ability to 1) immediately test and modify behavior (like you could from the browser console in plain JS, too), while 2) you still have a compiling-like step after each line of code you send to the game, detecting syntax errors. The CLJS syntax is (arguably) simpler than pure JS's (and really much simpler than Java's), and you can do the same task in much less lines of codes; plus if you really need to create a native desktop/Android application of your project, you only need to modify the input/output routines of your web game and compile it to (Android-)Java. There's also downsides, of course. Purely functional programming may sound quite esotheric to OOP/procedural programmers at first; compiling CLJS apps pulls in the whole goog codebase (although optimization removes much of it in production), and thus web loading times are longer than pure JS games. Very complex games may run less performant due to an additional layer of function calls wrapping native library methods (though that never was notably at my projects yet). At the end of the day, you should not go and find "the best language" and "the best toolkit". Choose a language and toolkit that allow you to reach your goal in reasonable time with the least headache. Look at tutorials for the type of app/game you want to create and decide which one is best to follow for you. You learn programming by everything you create, and hitting walls and problems in one scenario helps you understand why other languages/toolkit do it differently. Programming itself does not depend on specific languages (although there's "industry standards" - but you could just compile to, say JS, when your're done, right? ). You will change preferred languages. You will change preferred toolkits. You will change project setups, programming paradigms, application targets and so on. Just stay curious and try. That's just my biased two pence