• Content Count

  • Joined

  • Last visited

  • Days Won


SebastianNette last won the day on November 1 2014

SebastianNette had the most liked content!

About SebastianNette

  • Rank
    Advanced Member

Profile Information

  • Gender
  • Location

Recent Profile Visitors

2733 profile views
  1. Trailer looks pretty good. Nice work. Maybe my mind is just corrupted, but the only thing that comes to mind when I see those thumbs is:
  2. If you need to call methods with arguments, then you could use apply for that. command[val].apply(this,, 1)); //... processCommands("shoot", "first argument of the shoot method"); If you want to use a different context per function, you could bind the methods first: command = { rain: this.startRain.bind(this), //in the current file jump: this.player.jumpUp.bind(this.player), //jumpUp is in player.js shoot: this.singleBullet.bind(this.singleBullet, this.player)//needs an argument }; commad[val](); There are dozens of ways to get that kind of stuff done. Also I would move the command object outside of the processCommands method, or else it will be recreated everytime you use that method. However, I would just remove that processCommands function and just call the methods directly when needed. I don't see the benefit of using this.processCommands("jump") over this.player.jumpUp();
  3. As sapptime said, it should be: command[val](); However, if you call the functions like that, then they are called in a different context. So you might want to change that to: command[val].call(this);
  4. Thanks for the input, mattstyles. I generally tend to avoid DOM in my pixi projects. Mainly because on my other not-so-good-laptop it seems to get less fps if DOM elements overlay the canvas and for styling reasons. It's not only about screen resizing, but also about the idea of coding something once and having it work on all screen sizes out of the box. I haven't seen that PIXI/React framework yet, so I am not entirely sure how it works. About the framework I am working on, the 3 core concepts are: 1. Being able to easily position / display / size elements based on the screen size. 2. Being able to de-couple logic, views and data. 3. And to abstract away event listeners. I'm not using any angular code, I just mimic its behaviour, so hopefully there won't be any performance issues. All elements that are listened on, either by $watch or inside an expression, are pushed to a linear graph and the time it takes to loop through a few items for dirty checking, should be negligible low. At around 10,000 listeners, the dirty checking takes about 1ms for me. I can't imagine a game that actually needs that many properties, so I would assume that in most cases this will take around 0.1ms to 0.5ms. Most devs probably need close to that time with their own event listeners based on how heavy their UI is. There is still a lot room for improvement, I just quickly coded this up in the past week.
  5. Note: This is still work in progress Hi folks, I haven't done much with pixi lately, most of my work resolves around MEAN stack and I usually don't have enough time for anything not work related. A few weeks ago, when I had more time, I started working on my new game. My game looked ace on my laptop, but literally looked terrible for anyone who didn't use anything close to my screen resolution. On smaller devices, my content barely fit, if at all. On bigger devices, I had a lot empty spaces or the fonts were too small. I tried fixing most of the issues, but this bloated my files with a lot UI related code. But that wasn't the only issue. Most of my UI is way too repetitive to code. Character inventories, which display an array of items, friendslists, which display an array of ingame friends, ingame stores, that display an array of cash shop items, skillbars, that, well.. display an array of skills. Eventually I ended up telling myself to screw this. So I was thinking on. Why is it, that I can easily create a website that fits any screen resolution, manipulate content in a few lines of code, but when it comes to pixi (or canvas for that matter), it often takes me at least a day to add a new component to my game? And the answer is obviously that there are just better tools for that task in the DOM world. What I am currently doing - and I have literally no idea, if this is worth it at all or not - is to mimic the behaviour of angular and bootstrap for pixi. I have a simple demo here: Small Screen | Medium Screen | Large Screen Here is a short overview of how RedHawk is supposed to work: Scenes instead of Controllers Unlike Angular, RedHawk is using scenes. Scenes consist of the following methods: init (called before preload), preload (loads the assets), create (called after preload), update (called pre render), render (called after the scene is rendered to canvas) and shutdown (called when the scene changes). Took inspiration from phaser when I decided for those methods. Every scene comes with a $scope, which holds all scene related methods and is also used to dynamically update objects. You can inject different modules/components to your scene by simply adding those as arguments to the scene methods. Some of those predefined modules are: $timeout, $interval, $raf; Start / stop timeouts, intervals and animation frames. Unlike the window methods, those timers are cleared when the scene changes. $http: Handles ajax requests (also bound to the scene. requests are aborted if not done before changing the scene) $q: Also bound to the current scene, something that acts similiar to Q / Promises. $scene: used to change scene. $layout: Holds the device class, screen width / height and several other methods. Example: RedHawk .addScene("Shop", { init: function ($scope) { $scope.something = 123; }, //... }) .boot("Shop"); Services Services can be injected to any scene and are generally used to separate data from logic. Example: Demo: RedHawk .addService(function ItemService($http) { // request $http module function getInfo(id) { return $http.json("./items/" + id + ".json"); } return { // expose public methods getInfo: getInfo } }) .addScene("Shop", { init: function ($scope, ItemService) { // request item service ItemService.getInfo(1).then(function (response) { $scope.item =; }); }, create: function ($scope) { var item = $scope.$hawk("Text", {text: "Name: {{}}\nPrice: {{item.price}}", show: "item", style: {fill: "#fff"}}); $scope.$add(item); } }); Factories Factories are pretty similiar to services, but with one difference. Factories return an instance everytime they are called. Example: RedHawk .addFactory("Monster", function () { = 100; }); RedHawk config: RedHawk .config({ ticker: {fps: true}, // rendering loop, fps: true populates $scope.fps with the current fps renderer: "auto", // can be a PIXI renderer or auto | webgl | canvas options: { ... }, // renderer options target: document.body, // element to append the renderer view to boot: "StartScene" // tells redhawk which scene to boot }); Booting RedHawk: RedHawk.boot("Scene"); // unless already specified in config Watching a scope property: Demo: RedHawk .addScene(function SomeScene($scope) { $scope.watchMe = 0; $scope.$watch("watchMe", function (newValue, oldValue) { console.log("watchMe changed: ", newValue, oldValue); }); this.render = function (elapsed, time) { $scope.watchMe = time; }; }); Bootstrap But how do we copy bootstrap? If you ever used bootstrap, then you know quite a few of the most convenient bootstrap classes. 1. Device class The $layout component, which is responsible for screen resizes / detection, knows about the following classes: xs - screens that are less than 768px wide (usually phones) sm - screens between 768px and 991px (tablets / phones) md - screen between 992px and 1199px (tablets / desktop) lg - screen that are 1200px or wider (desktop / smart tv / etc) Order is xs -> sm -> md -> lg 2. Columns The bootstrap grid consists of 12 columns. Each column therefor takes up 1/12 of the parents width. One of the major advantages is that you can define different column sizes for different device classes. For instance: col-md-6 would be 50% of the width in bootstrap. We use something similiar, which I will explain at hawk objects 3. Rows Unlike Bootstrap, we not only use columns, but also rows. So our grid is actually 12x12. 4. Visibility classes hidden-xs, hidden-sm, hidden-md, hidden-lg: only hides the object on the specified device class. visible-xs, visible-sm, visible-md, visible-lg: only shows the object on the specified device class. visible-*-up: only shows the object on * and up e.g. visible-sm-up: visible on sm, md, lg visible-*-down: only shows the object on * and down e.g. visible-sm-down: visible on xs, sm same for hidden-*-up and hidden-*-down Hawk Objects So, now with all this fancy stuff, how would we use it? Simple, we need to call $scope.$hawk (or the shortcut $hawk for that matter) on any PIXI object. Example: Demo: RedHawk. .addScene("Profile", { init: function ($scope) { $scope.player = { name: "Desu", level: 9001 }; }, create: function ($scope, $hawk) { var name = new PIXI.Text("", {fill: "#fff", font: "10pt Arial"}); $scope.$hawk(name, {text: "{{}}"}); // magic: every expression needs to be written as {{exp}} $scope.$add(name); // another way to do this : note $hawk and $scope.$hawk act exactly the same var level = $hawk("Text", { text: "Level: {{player.level}}", style: {fill: "#fff", font: "10pt Arial"}, y: 10 }); $scope.$add(level); } }); Whenever $ changes it's value, name gets updated automatically. Same for level when $scope.player.level changes. RedHawk property list: var sprite = $hawk(new PIXI.Sprite(), { classes: "visible-sm-up xs-3x3 right", // {String} shortcut for visibility, grid and position classes visibility: "hidden-lg hidden-xs", // {String} List of all visbility classes grid: "md-6 xs-12 lg-4x4", // {String} List of grid classes *-(cols)x(rows) or *-(cols), show: "player.level > 1", // {String} expression that determines whether or not this element should be displayed repeat: "friend in friends", // {String} Iterates over an array. possible values: "value in scope.var", "(key, value) in scope.var", "value in [1,2,3]" bounds: { width: "25%", height: 100 }, // {Object} widths/height can either be % or a number, defines their width/height without scaling width: "25%", // object width, can either be a number or a percentage height: "50%", // object height, can either be a number or a percentage x: "10%", // object x, can either be a number or a percentage y: 100, // object y, can either be a number or a percentage position: "top right" // {String} positions the element at (left|center|right) (top|middle|bottom) }); Any other property of the object works as well. E.g.: texture (for sprites), text (for texts), or anything else. So, to get back to the example that I posted earlier. If you look at the source code, here is what happens: var desu = { /* StartScene: create */ create: function($scope, $hawk) { /* PIXI.Text * * text and font update based on the properties of * $scope.$device - provided by $layout * $scope.$width - provided by $layout * $scope.$height - provided by $layout * $scope.fps - provided by $ticker * * Every time any of those change, the text gets automatically updated * if the fps are lower than 10, a leading 0 is displayed: {{fps < 10 ? '0' + fps : fps}} * the font size changes according to the $device class: {{font[$device]}}px arial (fonts is defined in init */ var debug = $hawk("Text", { text: "FPS: {{fps < 10 ? '0' + fps : fps}}\nDevice: {{$device}}\nScreen: {{$width}} x {{$height}}\nTap to add an fps indicator.\nTap 4 times to change the scene.", style: {fill: "#fff"}, font: "{{font[$device]}}px arial" }); // add the text to the stage $scope.$add(debug); /* PIXI.Container * * Outer container for our fps indicator sprites * Container is fixed to bottom center * Container is 50% of the parents width and 25% of the parents height * since the stage is the parent, the width equals 50% of $width ($layout) * and 25% of $height ($layout) */ var itemContainer = $hawk("Container", { bounds: { width: "50%", height: "25%" }, position: "bottom center" }); /* PIXI.Sprite * * Creates automatically a Sprite (repeat) for each element in $scope.items (repeat: "item in items") * Sets the texture of that Sprite to "./img/fps-{{Math.min(3, fps / 15 | 0)}}.png" (gets updated when $scope.fps changes) * basically 0-14 fps red, 15-29 orange, 30-44 yellow, otherwise green * Each sprite gets stretched to grid: "xs-4x12" * Grid: 4 cols and 12 rows, so width: 33.33% and height 100% of the parent * The parent is the Container, which means we get 33.33% of 50% of $layout.width and 100% of 25% of $layout.height * Each Sprite is positioned at $index * this.width ($index is the index in the repeat object) and this.width is the Sprite's width */ var items = $hawk("Sprite", { image: "./img/fps-{{Math.min(3, fps / 15 | 0)}}.png", grid: "xs-4x12", repeat: "item in items", x: "{{$index * this.width}}" }); itemContainer.addChild(items); // outer container is added to the stage $scope.$add(itemContainer); } } Well, that's enough for now.. Didn't plan to write so much, and to display so many examples, but instead I just wanted to ask for opinions. Maybe some of you also use angular / bootstrap or you have suggestions for me. I intentionally keep the redhawk.js minified, since it is still work in progress. I just thought showing a minimalistic demo would make my intention clearer. And generally, would anyone use a framework like this? It is intended to mainly handle UI and to allow you to quickly push out a game state/scene. I'm pretty sure that this would work well with Phaser or any other game engine, so while RedHawk solves all your UI nightmares, an actual game engine could hook in to render the game. My goal is to be able to render a huge amount of hawk objects in preferable less than 1ms, so that the remaining time in the rendering loop can be used to render the game. When playing some of the most successful games in app stores, I realized that those games are at least 50% fancy UI, the games usually are minimalistic. Which lead me to my decision to focus on UI first, before finishing my game. Anyways, would like to hear some thoughts on this. Cheers
  6. You don't need a physics library for that. Simple trigonometry is enough. function move(object, distance) { object.x = object.x + distance * Math.cos(object.rotation); object.y = object.y + distance * Math.sin(object.rotation); }
  7. Art and Audio can be (and usually is by default) copyrighted, game ideas and mechanics however are free to use by anyone and rightly so. You can waste your money on a patent, but you won't be able to enforce it in court. And trying to sue some shady dev who is sitting in a country on the other side of the planet takes a lot effort, time and money. The one thing that got games to where they are today is the constant copying of ideas. Imagine the people creating the first FPS would have the sole monopoly on that genre. GG. The chances that someone creates a blatant 1:1 copy of your game is very slim, especially before you release your game. So the only advice I can give is to start promoting your game as early as you have something to show on any media you have access to. You might even find people who want to back up your game or you could start a kickstarter. Often games are rejected by publishers, even when they are really good, just because the dev didn't have any promotion material or no one ever heard of that game before. And if you mess up the marketing, then you will miss out on some great deals. Many games even start promoting as early as 1-1.5 years before the actual release.
  8. That would work but it feels pretty lame to add an extra Container just to scale a single sprite. Thanks though, guess I'll have to do that in the end.
  9. Yea, that was just my lazyness, lol. I remembered that Containers didn't have an anchor property back then, so I wanted to use a Sprite instead. That whole pivot thing seems way too inconvenient :/ So basically, if the size of the object can change, I have to re-set the pivot every frame since it works in absolute pixel. meh.
  10. I think you are misunderstanding the PIXI.Text object. It sure creates a canvas when you create a new object, which makes sense, since you are creating a new Texture. When you update the text then it just sets a dirty flag. And in the next rendering loop, it redraws the text once. All optimization lies in your responsibility. For instance, when you re-use some text te.g. you have a user list and next to every user name is a "Add as Friend" text, you could do something like: var addAsFriend = new PIXI.Text("Add as Friend"); var button1 = new PIXI.Sprite(addAsFriend.texture); var button2 = new PIXI.Sprite(addAsFriend.texture); var button3 = new PIXI.Sprite(addAsFriend.texture); ... You could as well take that texture and use it as a baseTexture and divide it into multiple frames. var manyTexts = new PIXI.Text("Add as Friend\nRemove Friend\nIgnore"); and then just set a frame per line. It sure is not meant to constantly change huge texts. But do you really need to do that? What are you using it for? If you are worried about the amount of textures/canvas, you could always use a Bitmap text or write a shader to act like a Bitmap text.
  11. Hi Guys, I'm pretty confused by anchors in v3. For instance, I have a Sprite and set the anchor to (0.5, 0.5) and place that Sprite in the middle of the canvas. Now I add some children to that Sprite. How comes that those children when set to position (0,0) are not in the top left corner of the parent Sprite but instead in the center of it? I also have a second Sprite with the same anchor (0.5, 0.5) and then I am trying to scale it. But the Sprite doesn't scale from the center. So I take that the anchor just determines where the texture is drawn but does not affect any transforms? How would I scale a Sprite from the center?
  12. Well, the error is pretty clear. The image is tainted and you don't have the permission to access the image data. You need to fix the serverside CORS headers when serving the image e.g. Access-Control-Allow-Origin "*"
  13. Hey Rick, is there a way to 1. preview posts and 2. to disable the wysiwyg editor? I can't find those options anymore. I would also be happy if there is a way to reduce the lineHeight for messages. This kinda gives the facebook vibe. No double checking, type it and send it, feels so spammy xD
  14. Hey Ivan, thanks for the feedback. This topic is quite old. I was really busy with uni and work (freelancing) in the past year. Pretty much got a 50-60 hour work week. My renderer works differently. It automatically culls the frustum and just needs to draw 1 single quad. It's pretty much the fastest I came up with. The map itself is a simple texture. Each pixel represents 1 tile. The red channel is the x and the green channel is the y for the tile position in the spritesheet. The blue channel can either be 0 or 1, where 1 means that the tile is animated. Animated tiles animate over y, y+1, y+2 and y+3. I have no intention to support depths. Anything that can overlap the character, like the character standing behind a tree, shall just be a simple sprite in a spritebatch traveling with the character. Here is an example (not too optimized) and ignore the fog of war around the cursor LOL! I was just experimenting. This is the spritesheet for the demo. The first water tile can be animated and then loops over those 4 water tiles.
  15. The performance is actually pretty good, all the texture lookups should be cached by the gpu and the rest is just some simple math. Another approach would be to pre-render 9 chunks at half the viewport width and height and move / redraw them as needed. Not sure yet which would be faster. But the cost of drawing several quads should be greater than drawing the map in one go. I'm still experimenting on this. I want a really fast background shader that ignores all depth. As few quads as possible. My isometric renderer is inspired by Toji's 2d renderer for LTTP. Just that I go 2.5d instead of 2d. I think no one can complain about the rendering speed Thanks xerver, that makes sense. I need 3 textures (the map image, the hit test tile and the spritesheet). Is there an example somewhere that shows how I would send more than 1 texture to my shader? For my fog of war shader, I basically just disable the colorMask and enable the stencil buffer, then I draw a batch of white circle textures to all onscreen units, enable the color mask again and draw a fullscreen half transparent black quad and disable the stencil buffer again. gl.enable(gl.STENCIL_TEST); gl.stencilFunc(gl.ALWAYS, 0x1, 0xffffffff); gl.stencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE); gl.colorMask(false, false, false, false); /* draw units / gl.colorMask(true, true, true, true); gl.depthMask(true); gl.stencilFunc(gl.NOTEQUAL, 1, 1); gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); /* draw quad (0.0, 0.0, 0.0, 0.5) */ gl.disable(gl.STENCIL_TEST); The shader for the fog would then just discard all pixel in the buffer drawn by the circle batch. How would I go about this? I don't want to use a PIXI.Graphics object, especially because I don't want it to calculate the circles as a polygon each frame but instead just batching those circle textures, like a ParticleContainer would do. Is there a way for PIXI, to mask a Sprite by a ParticleContainer?