Search

Geek Girl Joy

Artificial Intelligence, Simulations & Software

Tag

Unity3D

SVG Platformer

Can you go from art to program in one or two steps? Well, that’s what today’s post is about.

One of the cool things I remember about web development from years ago was Adobe Flash.

Before you boo me, hear me out!

I’m not saying Flash is a better technologically than HTML5, The Name of Your Favorite JavaScript Framework, CSS, Web Assembly etc… However one place Flash excelled was visual design & layout… an important part of the web!

The problem with many modern tools isn’t that they can’t convey design, it’s that they decouple the design and the development processes!

In practice this means writing code to describe the elements of your software like HTML and later writing more code to style the elements (like CSS, SASS or LESS), none of which is actually visual, though you definitely can get some great results!

Flash Builder (or whatever it was called) was half art studio and half IDE (Integrated Development Environment) where you could draw anything and it was an “object” and you could write code (ActionScript) to control it’s behavior. It wasn’t a mockup or illustration, it was the actual program!

As I recall, once the switch to ActionScript 3 was made the ability to store your code on the objects themselves was depreciated in favor of using references and listeners stored in the main keyframe timeline… I preferred keeping my code on the objects themselves but I digress.

Even with the change to where you stored your code you could still accomplish anything you wanted with the centralized keyframe code and some developers even found this easier to maintain than storing the code on the components.

You would setup your scripts on layered keyframe’s that extended to the last keyframe used in the project, or the last frame that needed that code and by using a sort of “goto keyframe name or id” method you could actually build complex applications quite easily, and more importantly… visually!

That’s why all the games used to be made with Flash, you could basically draw a picture and then turn it into an animation or even a full program in a couple of hours. This meant you were free to experiment & push boundaries.

Now, yes of course there are visual workflows you can use today.There are WYSIWYG editors and CMS App Platforms like WordPress, Drupal & Joomla not to mention the full featured layout capabilities of site builder tools like Wix.

Fundamentally though these tools facilitate laying out HTML elements and applying CSS and maybe some JavaScript via a drag and drop interface. Which is significantly faster than doing visual development via code in my opinion, though I am not arguing it is inherently “better”.

Unlike the aforementioned tools which specialize in “page based” HTML applications, Flash was an element or object that you embed into your page that used Vector Graphics to create lossless re-sizable images, animations and applications.

Inside the Flash movie/app you could draw anything and you were not constrained to HTML elements but you were also not required to code the visual elements.

This made for a wonderfully rapid prototyping experience that I was unable to reproduce until I tried working with Unity 3D which describes itself as “the ultimate game development platform” though I’d go so far as to describe it as “the ultimate app development platform”.

Think about it, at the time of writing this Unity supports 25 Platforms including Desktops (Win/Mac/Linux), the mobile OS’s, and all the major gaming consoles, not to mention the Smart TV’s, Watches etc…. Any platform you want your app on, including the web, well… Unity pretty much supports it right out of the box. Oh, and it’s free until you make $100K a year with it, not too shabby!

The catch? Well, its highly optimized but leans in the 3D gaming direction (though I’ve built 2D apps with Unity) so the applications it produces tend to have a larger size (as far as my tests go) than if you used PhoneGap/Cordova or went native. My guess is this is due to the embedded physics engine and graphics rendering code that gets packaged with the app but i’m only guessing, and there are a few options that let you exclude unnecessary things from the compiled app.

Then again, you may be able to make use of those features in your app so it need not be a negative either.

In any case, the problem as I see it with Unity is that the builder isn’t readily available on Linux, but it will build for Linux ❓ Maybe they should build Unity with Unity so that it can Unity being Unity… 😛

I am aware they kinda released a limited version for Linux… but I could never seem to make it work right and the truth is that it takes some decent (but not outrageous) resources to run the Unity builder application so most micro computers are out and sadly it won’t run on the ARMf architecture so using a Raspberry Pi to do Unity development is just not happening.

Is there another way?

Well, there is a modern Vector Graphic format available for the web called SVG that is basically XML code that can be written in a text editor or it can be drawn using a program like Inkscape (free and what I use) or Adobe Illustrator if you prefer a commercial paid tool.

Since SVG is code, if you place the code inside your HTML (sadly not link to or embed) you don’t just get a static vector image but instead you get elements that are accessible via the DOM (Document Object Model) that you can manipulate using CSS and JavaScript.

That last part should really interest you if you enjoy rapid application prototyping!

Which is the origin of this project, I wanted to know… could I rapid prototype an application by just drawing a picture and writing some code?

Understand that I am not talking about drawing a picture, slicing it then building an app from sliced components or using the sliced images as placeholders or writing code to draw the slices onto a canvas context.

I challenged myself to see if I could only write code that was part of the core functionality and not basic graphic asset creation and certainly not the code to display it, just manipulate it.

I set about creating a very simple “proof of concept” a while back that is basically a “Die Rolling App” that you can view a live example of here: SVG Roller though I never wrote about it. Roller is half image and half app but very basic.

Roller consists mainly of showing and hiding elements in the SVG based on a button click and a random number… good but not all that flashy!

Recently I have been wanting a better SVG application that would be more visual and expand on what I have already done but retain the simplicity of “Draw It then Code it”.

So, I opened up Inkscape and drew this image:


I grouped all the associated assets and gave them id’s like “cloud1”, “player”, “coin2” etc… then saved the image as demo.svg and closed Inkscape.

Why a game? Well, it’s more visual than my SVG Roller and I think it illustrates more of what is possible with an SVG app.

After that I opened demo.svg with a text editor and copied the SVG code into the body tag of my HTML file (remember you can’t link to it you have to include the code in the HTML).

I then wrote a little CSS that helps position the SVG on the page, applied a background color, disabled text highlighting and changed the cursor to the hand icon when the mouse is over a button, minimal CSS.

After that I wrote the JavaScript that turns the image into a playable application.

Game.js

Here is all the code that makes the SVG Platformer game demo work:

var keyEvents = {}; // keyboard state object

// Listen to keyboard outside of game loop to be less "blocky"
var onkeydown = onkeyup = function(key){
  key = key || event; // IE Fix 😦

  if(key.type == 'keydown'){
    keyEvents[key.keyCode] = true;
  }
  else{
    keyEvents[key.keyCode] = false; 
  }
  //console.log(keyEvents);
}


var game = document.getElementById('game'); // A reference to the SVG
if(game){
    game.addEventListener("load",function(){
    ///////////
    // Functions
        
    // Clear Instructions    
    // removes the instructions element
    function ClearInstructions() {
      instructions.remove();
    }

    // Get Position
    // This function gets the current (x,y) cordinates of GetPosition(object)     
    function GetPosition(object){
      var transformlist = object.transform.baseVal;
      var group = transformlist.getItem(0);
      var X = 0;
      var Y = 0;
      if (group.type == SVGTransform.SVG_TRANSFORM_TRANSLATE){
        X = group.matrix.e;
        Y = group.matrix.f;
      }
      return [X, Y];
    }
    
    // Collide
    // A basic box collision detector
    function Collide(element1, element2) {
      var collisionBox1 = element1.getBoundingClientRect();
      var collisionBox2 = element2.getBoundingClientRect();

      return !(collisionBox1.top > collisionBox2.bottom ||
        collisionBox1.right < collisionBox2.left ||
        collisionBox1.bottom < collisionBox2.top ||
        collisionBox1.left > collisionBox2.right);
    }

    // Inside
    // A basic inside box collision detector
    function Inside(element1, element2) {
      var collisionBox1 = element1.getBoundingClientRect();
      var collisionBox2 = element2.getBoundingClientRect();

      return (collisionBox1.top <= collisionBox2.bottom && 
        collisionBox1.bottom >= collisionBox2.top && 
        collisionBox1.left <= collisionBox2.right && 
        collisionBox1.right >= collisionBox2.left);
    }
      
    // Get Bank Total
    // Get the number of diamond or coins the player has
    function GetBankTotal(element){
      var currentValue = element.textContent;
      return parseInt(currentValue);
    }
    
    // Collect 
    // Increment the Coin or a Diamond "player bank"
    function Collect(element){
      element.textContent = GetBankTotal(element) + 1;
    }
      
    
            
    ///////////
    // Game play
    
    // Set the "constants"
    var step = 1;
    var jump = 20;
    var gravity = 1.5;

    // Setup references to the "named" SVG XML elements
    var gameOver = game.getElementById("gameover"); // A hidden "eater/detector" element below the play area to detect player death
    var instructions = game.getElementById('instructions');  // Instructions element
    var gameOverMenu = game.getElementById("gameovermenu");  // Game over screen element
    var player = game.getElementById("player");              // The player element
    var playerCoins = game.getElementById("playercoins");    // The "bank" element showing how many coins the player has collected
    var playerDiamonds = game.getElementById("playerdiamonds");// The "bank" element showing how many diamond the player has collected

    //  Setup references to the "named" SVG XML coin elements
    var coinPieces = ['coin1', 'coin2'];
    var coins = [];
    coinPieces.forEach(element => {
      coins.push(document.getElementById(element));
    });
        
    // Setup references to the "named" SVG XML diamond elements
    var diamondPieces = ['diamond1'];
    var diamond = [];
    diamondPieces.forEach(element => {
      diamond.push(document.getElementById(element));
    });

    // Setup references to the "named" SVG XML ground elements
    var terrainPieces = ['ground1', 'ground2', 'ground3', 'ground4'];
    var terrain = [];
    terrainPieces.forEach(element => {
      terrain.push(document.getElementById(element));
    });

    var winningBankTotal = diamondPieces.length + coinPieces.length;


    // Clear the instructions after 3 seconds
    setTimeout(ClearInstructions, 3000);


    // Redraw Game Loop
    var redrawRate = 30; // microseconds
    var gameLoop = setInterval(function(){
      fall = true; // always try to fall
      allowedToJump = false;// disallow jumping because player might be falling
      allowedToMove = true; // allow moving until the player is dead

      // Check for collisions with ground elements
      terrain.forEach(ground => {
        // If there is a collision with the ground
        if(Collide(player, ground)){
          fall = false; // Stop falling
          allowedToJump = true; // Allow jumping
        }
      });

      // if player fell below the ground
      if(Inside(player, gameOver)){
        fall = false; // stop falling
        allowedToJump = false; // dont allow jumping
        allowedToMove = false; // player is dead stop player movment
        ClearInstructions(); // just in case
        gameOverMenu.style.display = "inline"; // show game over menu
      }


      // if there was no collision between a ground element and
      // the player
      if(fall === true){
        position = GetPosition(player); // get updated player position
        allowedToJump = false; // dont allow jumping
        player.transform.baseVal.getItem(0).setTranslate(position[0], position[1] + gravity); // player falls
      }


      if(allowedToMove === true){
        position = GetPosition(player); // get updated player position
        // keyboard movment
        // left || a
        if (keyEvents[37] === true || keyEvents[65] === true) {
          if(position[0] > -10){
            player.transform.baseVal.getItem(0).setTranslate(position[0] - step, position[1]);
          }
        }
        // right || d
        if (keyEvents[39] === true || keyEvents[68] === true) {
          if(position[0] < 140){
            player.transform.baseVal.getItem(0).setTranslate(position[0] + step, position[1]);
          }
        }
        // up || w || space
        if ((keyEvents[38] === true || keyEvents[87] === true || keyEvents[32] === true) && allowedToJump === true) {
          player.transform.baseVal.getItem(0).setTranslate(position[0], position[1] - jump);    
        }
        // down || s
        if (keyEvents[40] === true || keyEvents[83] === true) {
          //console.log("Down");
        }
      }


      // Item Collection        
      // Collect coins
      coins.forEach(coin => {
        if(Inside(player, coin)){
          coin.remove();
          Collect(playerCoins);
        }
      });

      // Collect diamond
      diamond.forEach(diamond => {
        if(Inside(player, diamond)){
          diamond.remove();
          Collect(playerDiamonds);
        }
      }); 

      // Check for Win
      if((GetBankTotal(playerDiamonds) + GetBankTotal(playerCoins)) == winningBankTotal){
        clearInterval(gameLoop); // stop the game
        fall = false; // stop falling
        allowedToJump = false; // dont allow jumping
        allowedToMove = false; // player won stop player movment
        gameOverMenu.style.display = "inline"; // show game over menu
        // Change Game Over text to You Win
        game.getElementById("gameovermessage").textContent = '  You Win!';
      }

    }, redrawRate); // Game Loop - redraw every 30 microseconds
  }); // game load event listener
} // if game

 

As you can see from the code it supports WASD as well as the arrow keys and spacebar for movment. There is a win condition if you collect the two coins and the single diamond. You lose if you fall into one of the two spike pits.

Overall I am pleased with what I accomplished however the collision detection could be improved and there is quite a bit of room for improving how items are collected and enemies would be nice in addition to a larger/longer level, and maybe even a parallax scrolling  effect on some background elements as the player moves would also be nice, though again, I am happy with how it turned out.

You can Play a Live Demo: Here

You can Get the Code: Here

You can find a list of all my other posts on my Topics and Posts page.

I hope you enjoyed reading about and playing this SVG game prototype.

Your financial support allows me to dedicate time to developing projects like this and while I am publishing them without cost, that isn’t to say they are free. It takes me a lot of time and effort to build and publish projects like this for your enjoyment.

So I ask that if you like my content, please support me on Patreon for as little as $1 or more a month.

Feel free to suggest a project you would like to see built in the comments and if it sounds interesting it might just get built and featured here on my blog for you to enjoy.

 

 

Much Love,

~Joy

Are your GIF’s infected?

Have you ever needed to create a GIF and found the available options for doing so less than stellar?

I mean sure, you could try your luck with an option off download.com and risk a virus! However, if you value your electronic devices as well as your data and would like to just skip the absolute hellish nightmare of dealing with the resulting ransomware you might just decide give one of the more reputable cloud build GIF making services a try instead.

However, fail to use one of those more “reputable” build services and you are back to square one, downloading viruses!

Further, even if you are lucky and do find a service that isn’t a front for a black hat syndicate, anyone with an ounce of sense (28.3495 grams to be exact) 😛 will be left with with more questions and concerns than confidence!

Questions like, do I still own my images? or Are the generated GIF’s mine? Have I given away or extended use rights (redistribution or public display) to the site owners? Have they been tampered with, down-scaled or were any watermarks added? Am I compromising my brand or business by using this service? Am I sure I know what I am getting back is safe for myself and my clients?

Right about now a few of you might be thinking “You can’t get a virus from an image since there is no executable code”… but of course you’d be wrong!

So… Let’s take a trip back to 2002 with this article from PC mag. The first jpeg virus had been identified in the wild and while it was benign (both then and certainly now) it demonstrates that even images can be vectors of attack and a means of passive propagation!

The fact is that even if a GIF acts only as a means of delivering a viral payload, a cargo container on which the malware hitches, the GIF (or image in general) is therefore necessarily used in conjunction with a viewer or player application (executable) and therein lies the problem! The image data must be read to be viewed.

The risk posed here is by a so called “zero-day” attack utilizing as yet undocumented vulnerabilities in the viewer app itself, the codec or libraries used to read the media or even potentially the OS, and if you think you are safe because you’d somehow intuit that the image is seemingly “larger than it should be” (in terms of byte size) well, you’d be wrong again!

Remind me to have a talk with you later about this whole doubting me thing… its weird, it’s becoming a problem and it needs to stop! 😛

Appending raw byte data is a real sloppy & amateur way to infect (or store) data in an image!

There are plenty of methods for hiding data in images that will NOT modify the file size!

Further, I have some future stenographic projects planned so I will be brief here but just to prove the point… consider an image that is only 100x100px.

Like this one:

100x100.png

 

Such an image tends to be only a few bytes to kilobytes in size, the image above is only 0.506 KB (damn small) & you could hardly store any data in that right? Well if you are a clever hacker or computer scientist you can come up with quite a few different ways to encode the data directly into the pixel values themselves while at the same time making such slight modifications to the pixels that no perceivable change has occurred!

Additionally, high definition images are common these days so if anything this example is overly critical and in reality you will commonly deal with larger images. The simple fact is you cannot simply look at file size as and indicator for file infection when the file is an image!

Therefore even in a single static JPEG image that is only 100x100px (like above) could store at minimum 10,000 characters (about double all the characters in this entire post)!

Just when you were thinking “WOW TL;DR!” 😛

If you drop fidelity of the image as a concern you can write data to all color channels and that gives you 30,000 (~6X the length of this post) characters to work with! If instead you use a PNG, so that you can play with the alpha channel too, you get 40,000 (~8X the length of this post) characters (assuming that you didn’t use the alpha channel as a checksum ;-))… I can go on for quite some time on this very deep and fascinating subject but as I said I have some stenographic projects planed for you guys in the future and we will cover this stuff in more detail in those posts, so suffice it to say that just because “it’s an image” does not make it safe!

Now, I’m not trying to scare you… okay maybe a little 😛  but I want you to understand that the fact that you upload and download images to cloud build services is in no way a protection and a professional content creator cannot guess that their content is safe to open.

This is where I found myself when I wanted to animate and publish the Sierpinski triangle animations in my post A Chaos Game.

Sierpinski_triangle

That’s why I used the GIFEncoder PHP class released by László Zsid to animate them myself using PHP rather than risk my system with unknown files! The great thing about GIFEncoder is that you don’t have to wonder if it’s safe,  feel free to read the code yourself over on my GitHub and grab a copy while you  are there! 😉

Plus admit it, its just more impressive and satisfying to copy & paste the code I give you and get a GIF rather than images which you then have to go stitch into a GIF yourself! 😛

I also previewed my latest Patreon App called GIFMaker in my last post A Value Proposition. Well today I am pleased to announce that I have made GIFMaker available over on Patreon for my User and Developer level followers!

Here are some screenshots of GIFMaker :

MAIN VIEW

FILE BROWSER

SETTINGS

 

GIFMAKER GALLERY SIGN IN

GIFMAKER GALLERY

The best part is that you can actually see the code that is responsible for creating the GIF as GIFMaker uses a PHP server back-end (either on your local machine or on your web server) so even my User level followers can modify the core functionality of GIFMaker  (and GIFMaker Gallery) to meet their needs!

If you also would like to modify the GIFMaker GUI you can become a Developer level supporter of mine and get access to the C# Source Code and Unity3D IDE Project along with a commercial reuse license should you want or need that!

  • There are no artificial limits in terms of image dimensional size or byte data placed on the application so if you have the memory and storage, feel free to make GIFs as large as you want!

 

  • GIFMaker will not apply any kind of watermarks or other branding or identifiers to the animations so all you will get back is the images you gave it, simply animated!

 

  • Comes with a Web Interface GIFMaker Gallery enabling the Viewing, Downloading and Deletion of your GIFs.

 

GIFMaker is now available over on Patreon and if it looks & sounds like something you need, consider supporting me over on Patreon so I can bring you more great prototypes and tutorials!

Have a great week!

Much Love,

~Joy

Pathfinder Visual Interface

Meet Pathfinder’s New Look!

What is Pathfinder?

I recently wrote a tutorial where I introduce the Pathfinder neural network and cover how it works and I provided fully functional code as well as a training set to get you and Pathfinder working from scratch!

You can find that over here if you are interested: Pathfinding From Scratch Using a Neural Network

8 Direction Stepping
8 Direction Stepping

Pathfinder is an example of a neural network that is capable of plotting an 8 direction step path from a starting position in a 5×5 grid to an ending position in that grid.

I donated the Pathfinder ANN example to the Official FANN PHP Repo and you automatically obtain a copy over there for free when you download the FANN PHP extension. 😉

Pathfinder on YouTube

If you have been following me for a little while you may have even seen my YouTube Pathfinder demonstration video. Go ahead and give it a play, it’s kinda fun to watch! 🙂

Note: The experience of the Pathfinder Visual Interface (PVI) application differs slightly from this video as this video demonstrates the pathfinder neural network operating rather than the PVI, however it is quite similar. The main difference is that this example is automated to execute a series of paths whereas the PVI allows you to manually set the start and stop positions one at a time.

 

Well, now I am announcing the release of a Visual Interface for Pathfinder!

 

What’s the Pathfinder Visual Interface (PVI)?

The PVI is a front-end GUI application for Pathfinder and it comes with a slightly customized and streamlined version of my Pathfinder Neural Network.

Instead of having to manually run the training process, Pathfinder will automatically generate its mind file (pathfinder_float.net) for you from the available (and modifiable) training data on your web server, however I do provide you with a fully trained version from the start to work with to make it even easier to get started!

Additionally, the customized version of Pathfinder comes with basic single user salted & hashed password security with session handling so you could improve and expand Pathfinder as needed without worrying about unauthorized access to your web server running Pathfinder.

The Pathfinder Visual Interface was created using Unity 3D and utilizes C# under the hood.

The Pathfinder Visual Interface is compiled for Windows, Mac and Linux, both 32 bit (x86) & 64 bit (x64) executables are available.

I may make WebAssembly as well as Android and iOS versions available if there is enough interest.

What’s the Difference?

Unlike the PVI version of Pathfinder, the open source version of Pathfinder runs in a browser and is strictly text based (stylized with CSS) which looks like this:


Testing Pathfinder:

10000
00000
00000
00000
00001

Results:

10000
01000
00100
00010
00001


Completely functional, however not very nice to look at, and you have to interact with Pathfinder directly from the source code. :-/

Now here is the same example as above but using the PVI:

 

 

 

 

 

Clearly it’s easier to test and work with your Pathfinder Neural Network and dare I say more fun too! 😛

 

What’s Required?

The Pathfinder ANN relies on PHP so you will need a web server like XAMPP if you will be running it on your local machine or a web hosting account that grants you administrative access via SSH (Secure Shell) and or any other system or implementation that allows you to install PHP extensions as an administrator.

If you want to get started quickly you can use c9.io for free (not a sponsor) and don’t want to or are unable to install a web server on 127.0.0.1.

Pathfinder also requires the free (but very powerful) FANN (Fast Artificial Neural Network) Library to be installed on the machine that is serving and supporting Pathfinder.

I do recommend using secure connections so if you are running Pathfinder from your website you should be encrypting your traffic using SSL Certificates (HTTPS) to make sure that the data exchanged with Pathfinder (as well as your password and other sensitive data) is not exchanged as plain text.

Note that If you are a Developer level supporter on Patreon and want to modify the PVI app you will also need to obtain a free copy of Unity 3D however it is not needed if you only want to to use or modify the neural network which is written in PHP.

 

What could you actually do with with the PVI?

The PVI exchanges it’s grid data with the Neural Network running on your web server so you are not limited by local resources and as such Pathfinder and the PVI make excellent starting points to build games as well as robotics & IOT projects.

If you are the kind of person asking questions like how can I deploy a neural network to interface with my game or web capable Arduino or Raspberry Pi project, and you also have some basic web server knowledge, this might be the right project for you! 😉

 

What do I actually get?

If you are looking to bypass the development of an extensible web based pathfinder neural network and would like a cross-platform (Win, Mac, Linux) tool to interface with the ANN for testing you should support me over on Patreon at the User level which is perfect for teachers and students looking to study PHP, Unity 3D or pathfinding using neural networks.

User

For only $5 Users Get:

  • Access to the open source customized PHP based Pathfinder UI edition and the closed source Cross-Platform (Win, Mac, Linux) executable of the Pathfinder Visual Interface application.

 

If you also want to be able to modify the PVI application so that it is customized to your project needs you should support me over on Patreon at the Developer level.

For only $25 Developers Get:

  • Access to the open source customized PHP based Pathfinder UI edition and the closed source Unity 3D project used to create the Cross-Platform Pathfinder Visual Interface application that you can freely modify to meet your project needs.
  • Additionally developers receive a commercially permissible reuse license!

Users may use the Pathfinder Visual Interface (as is) in a private or commercial setting but you may not redistribute resell it or reverse engineer or decompile it unless you are a Developer level supporter Patreon.

If you would like to get yourself a copy of the Pathfinder Visual Interface it is available now on Patreon!

Next week I will be releasing another tutorial so please Like, Comment & Share this post with your friends and followers on your social media platforms and don’t forget to click the follow button to get notified when I post something new.

If would like to suggest a topic or project for an upcoming post feel free to contact me.

Much Love,

~Joy

Create a free website or blog at WordPress.com.

Up ↑

%d bloggers like this: