10 November 2016

JavaScript Spiderweb Generator now on GitHub

Previously released open source JavaScript application > Spiderweb Generator 

more info [http://flanture.blogspot.rs/2015/02/javascript-spider-web-application.html]

is now also hosted on GitHub

here [https://github.com/pdja/SpiderWebApplication]

There are currently few items on to do list >

TODO:

v 1.1 - image save option [Save SpiderWeb] button, up to six memory slots
v 1.2 - color choosers for web and background
v 1.3 - skew web option
v 1.4 - effects option, custom backrounds, spiders, web holes
v 1.5 - ...

Since it is HTML5 Canvas, there is already option to save image by right click, save as png.
V1.1 will have memory slots inside app so user can temporary preview different spiderwebs.

*_*

20 February 2015

Phaser example: simple RoadMap function

RoadMap function is basically object chain tween movement where different tween points are user defined. This has been previously done in ActionScript on this blog, see here, example here and more code here. This function has been written in 2009 and now Phaser comes along ...

How it works. Click few times on the screen to create some object diamonds. When done with it press spacebar on keyboard to create and start object star animation. Object star will follow road of diamonds in order user created them - that is why it is called RoadMap function.



You can change the object's speed which is actually time between two diamond points.

Here is the JavaScript Phaser code:

Game.js


window.onload = function() {

    var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update});

    function preload () {

        game.load.image('diamond', 'diamond.png');
        game.load.image('star', 'star.png');

    }

    function create () {

        // starting game physics    
        game.physics.startSystem(Phaser.Physics.ARCADE);    
    
        // enabling spacebar keyboard button
        fireButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
        game.input.keyboard.addKeyCapture([Phaser.Keyboard.SPACEBAR]);
    }
    
    // Container Array for all diamonds / path points
    var pointsContainer = new Array();
    
    // If new star / bullet can fire or not
    var canFireBullet = true;

    function update () {
    
        handleClick();
        
        if (fireButton.isDown)
        {
            fireBullet();
        }
    
    }
    
    // Every mouse click sets new object diamond on stage
    function handleClick() {
    
        game.input.mouse.onMouseUp = function (evt) {
        
            var myPointX = game.input.activePointer.x-16;
            var myPointY = game.input.activePointer.y-14;
            
            var d = game.add.sprite(myPointX, myPointY, 'diamond');
            
            // we must remember diamonds positions
            pointsContainer.push([myPointX, myPointY]);

        };            
    }
    
    function fireBullet() {
        
            // if there are points to follow 
            if (pointsContainer.length > 1 && canFireBullet) {
            
                var starCounter = 1;
                
                // set object star speed
                var speed = 500;
                
                // disable new object star creation until last tween is complete
                canFireBullet = false;
            
                // create star on location of first object
                var s = game.add.sprite(pointsContainer[0][0], pointsContainer[0][1], 'star');
                
                // create tweens chain         
                var tween = game.add.tween(s);
                while (starCounter < pointsContainer.length) {
                    tween.to({ x: pointsContainer[starCounter][0], y: pointsContainer[starCounter][1] }, speed);
                    starCounter ++;
                }
                
                // enable new object star creation
                tween._lastChild.onComplete.add(canFire, this);
                tween.start();    
            };
    };
    
    function canFire() {
    
        canFireBullet = true;
    }

};


You will also need some graphics diamond.png and star.png to see this works. Ask questions if you have any. I remember there was another function where star speed was same despite of distances between diamonds.

Now, we can play with it a little bit more. It can be useful to group diamonds together and change alpha to entire group. At start we define new variable:

var diamondsGroup;

We have two new lines inside create function:

diamondsGroup = this.add.group();
diamondsGroup.enableBody = true;

Inside handleClick function instead of adding sprite line we have:

var d = diamondsGroup.create(myPointX, myPointY, 'diamond');

After if line in fireBullet function we set new alpha value, which can be anything, for example, lets subtract half of alpha for every new bullet:

diamondsGroup.alpha -= 0.5;

which makes our diamonds disappear very fast.

*_*

16 February 2015

Using Group.countLiving() to delay Instance creation in Phaser

Few days ago for the first time I decided to check out Phaser, HTML5/JavaScript game engine. My first impressions are very good, I'm pleasantly surprised with all the energy people are investing into this engine.

I have completed two intro tutorials, Making your first Phaser game by PhotonStorm which I'm extending here a little bit and another one Let's make a Game with Phaser video tutorial by Gabe Hollombe from JSConf Asia 2014 which I'll talk about later.

My tools for this time included Notepad++ as code editor, Mongoose free web server and Chrome. I actually started with Firefox but something went wrong while refreshing edited code and I couldn't figured out what is happening so I switched to Chrome to save time and speed things up. Chrome made me no problem.

Tutorial is well explained and easy to understand. Step by step instructions gives nice first time overview of how Phaser actually works. Not too many details but just enough to make things interesting. Here, I'm just going to explain some minor modifications I made with already existing code.





Resources I used here are this background by Louis Vest and free platform graphic by Kenney - thanks good people!

Inside preload function one line is added:

game.load.image('diamond', 'assets/diamond.png');

since there was already diamond.png file, but I also renamed my new images so I don't have to change code.

I have two new variables:

var diamonds;
var diamondok;

This is important. Since I'm going to create a diamond only after all stars are killed I need to do it inside update function and since I want to do this only once I need logical variable diamondok which will block all further attempts to make more diamonds after one I need is created. I don't need infinite diamonds when all stars die (this could be good song :).

Now for the create function also few additions:


// Add a diamonds group
diamonds = game.add.group();
diamonds.enableBody = true;

// set diamondok variable to true
diamondok = true;


For update function first I had to include collision detection:

// Check to see if the player overlaps with diamond, if he does call collectDiamond function game.physics.arcade.overlap(player, diamonds, collectDiamond, null, this);

and finally here I use countLiving method and my condition to create diamond (level exit) is when there are no stars and if diamondok is true, which is set at start.


// check if all stars are dead
if (stars.countLiving() < 1 && diamondok)
{
    // create a diamond at position
    var diamond = diamonds.create(50, 400, 'diamond');
    diamond.scale.setTo(1, 1);
    diamond.body.immovable = true;
    
    // lets lock diamondok to prevent making them forever
    diamondok = false;
}


That's all, we just have one more function:


function collectDiamond (player, diamond) {
    
    // Removes the diamond from the screen
    diamond.kill();

    //  Add and update the score
    score += 30;
    scoreText.text = 'Score: ' + score + '   YOU WON!!!';

}


and this one adds some points to the score and write appropriate message to scoreTest.

Happy to learn that with such small modification change game a lot and it will be really interesting to dive into Phaser's docs further and see more tutorials.

*_*

03 February 2015

JavaScript Spider Web application

First of all I wanna say thank you all, as I'm receiving this award ... OK, not any award but really thank you all for reading all these years and commenting, this is my post number 300! It's kinda interesting to just be around so many years (started back in 2007) and to be able to see how technologies change over time, some old disappear and some new are created and you can see where things are moving and it's in good direction so you feel OK about what you're doing.

For this occasion I prepared JavaScript version of my previously written ActionScript Spider Web application, thing - whatever. It's been almost five years ago when this app was coded, never to late to recycle.

There are five variables you can play with: Circles, Nodes, Distance, Radius and Tension. They are easy to understand if you just try different values.

here is entire code:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <title>SpiderWeb App</title>
    </head>
    <body>
    <style type="text/css">
    p {
        font-family:'Lucida Grande',Tahoma,Verdana,Arial,Sans-serif; 
        font-size:11px; 
        font-weight:700;
        width:50px;
    }
    .styled-button-4 { 
        -webkit-box-shadow:rgba(0,0,0,0.98) 0 1px 0 0; 
        -moz-box-shadow:rgba(0,0,0,0.98) 0 1px 0 0; 
        box-shadow:rgba(0,0,0,0.98) 0 1px 0 0; 
        background-color:#EEE; 
        border-radius:0; 
        -webkit-border-radius:0; 
        -moz-border-radius:0; 
        border:1px solid #999; 
        color:#666; 
        font-family:'Lucida Grande',Tahoma,Verdana,Arial,Sans-serif; 
        font-size:11px; 
        font-weight:700; 
        padding:2px 6px; 
        height:28px 
    } 
    .styled-input { 
        -webkit-box-shadow:rgba(0,0,0,0.98) 0 1px 0 0; 
        -moz-box-shadow:rgba(0,0,0,0.98) 0 1px 0 0; 
        box-shadow:rgba(0,0,0,0.98) 0 1px 0 0; 
        background-color:#EEE; 
        border-radius:0; 
        -webkit-border-radius:0; 
        -moz-border-radius:0; 
        border:1px solid #999; 
        color:#666; 
        font-family:'Lucida Grande',Tahoma,Verdana,Arial,Sans-serif; 
        font-size:11px; 
        font-weight:700; 
        padding:1px 3px; 
        height:20px 
    } 
    </style>
    <div id="menu"  style="width:160px;float:left;">
    <p>
        Circles: <input type="text" class="styled-input" id="circles" value="5"><br>
        Nodes: <input type="text" class="styled-input" id="nodes" value="7"><br>
        Distance: <input type="text" class="styled-input" id="distance" value="0.4"><br>
        Radius: <input type="text" class="styled-input" id="radius" value="20"><br>
        Tension: <input type="text" class="styled-input" id="tension" value="0.25"><br><br><br>
        <input type="button" class="styled-button-4" value="Make SpiderWeb" onClick="initWeb()"/>     
    </p>
    </div>
    <div id="content" style="background-color:#EEEEEE;float:left;">
    <canvas id="myCanvas" width="600" height="500" style="border:1px solid #d3d3d3;">
    Your browser does not support the HTML5 canvas tag.</canvas>
    </div>
        <script>
    
            function Point(x, y) {
              this.x = x;
              this.y = y;
            }
            function drawLine(x1, y1, x2, y2) {
                var c = document.getElementById("myCanvas");
                var ctx = c.getContext("2d");
                ctx.beginPath();
                ctx.moveTo(x1, y1);
                ctx.lineTo(x2, y2);
                ctx.lineWidth = 3;
                ctx.strokeStyle = 'black';
                ctx.stroke();
            }
        
            function drawCurves(a, t) {
                var canvas = document.getElementById('myCanvas');
                var context = canvas.getContext('2d');
                var webx = canvas.width / 2;
                var weby = canvas.height / 2;                
                context.beginPath();
                
                for (var m = 0; m < a.length-1; m++)
                {
                    context.moveTo(a[m].x, a[m].y);
                    var pointOnMedianX = (a[m].x + a[m+1].x)/2;
                    var pointOnMedianY = (a[m].y + a[m+1].y)/2;
                    var controlX = t * webx + (1-t) * pointOnMedianX;
                    var controlY = t * weby + (1-t) * pointOnMedianY;
                    context.quadraticCurveTo(controlX, controlY, a[m+1].x, a[m+1].y);
                }
                context.moveTo(a[a.length-1].x, a[a.length-1].y);
                
                var pointOnMedianX = (a[a.length-1].x + a[0].x)/2;
                var pointOnMedianY = (a[a.length-1].y + a[0].y)/2;
                var controlX = t * webx + (1-t) * pointOnMedianX;
                var controlY = t * weby + (1-t) * pointOnMedianY;                                
                
                context.quadraticCurveTo(controlX, controlY, a[0].x, a[0].y);
                
                context.lineWidth = 2;
                context.strokeStyle = 'black';
                context.stroke();            
            }
            
            function trim(num)
            {
                var nstr = parseInt(num*100);
                return Number(nstr/100);
            }            

            function makeWeb(circles, nodes, distance, radius, tension) {
                var canvas = document.getElementById("myCanvas");
                var webx = canvas.width / 2;
                var weby = canvas.height / 2;
                
                var coords = [];
                var angle;
                var currentRadius = radius;
                var angleStep = 360 / nodes;
                
                for (var i=0; i<circles; i++) 
                {
                    currentRadius += currentRadius * distance;
                    for (var j=0; j<nodes; j++)
                    {
                        angle = angleStep * (j + 1);
                        angle = angle * Math.PI / 180;
                        var z1 = webx + trim(currentRadius * Math.cos(angle));
                        var z2 = weby + trim(currentRadius * Math.sin(angle));
                        
                        var point = new Point(z1, z2);
                        coords.push(point);

                    }
                    drawCurves(coords, tension);
                    if (i == circles-1) 
                    {
                        for (var l=0; l<coords.length; l++)
                        {
                            drawLine(webx, weby, coords[l].x, coords[l].y);
                        }
                    }
                    coords.splice(0, nodes);
                }        
            }
            
            function initWeb() {
                var circlesValue = Number(document.getElementById('circles').value);
                var nodesValue = Number(document.getElementById('nodes').value);
                var distanceValue = Number(document.getElementById('distance').value);                
                var radiusValue = Number(document.getElementById('radius').value);
                var tensionValue = Number(document.getElementById('tension').value);
                var c = document.getElementById("myCanvas");
                var ctx = c.getContext("2d");
                ctx.clearRect (0, 0 , c.width , c.height );
                makeWeb(circlesValue, nodesValue, distanceValue, radiusValue, tensionValue);
            }
            
            makeWeb(5, 7, 0.4, 20, 0.25);

        </script>
    </body>
</html>
        



*_*

31 January 2015

Search Array JavaScript functions port

Eons ago there existed Search Array ActionScript functions post about completely non-efficient code, though mentioned on few places in educational purposes only. That was my starting point for doing same thing again, this time in JavaScript, but with few modifications.

Languages are very similar, there was just few extra ;s and some deleting of type declarations, that's all.

app.js

// JavaScript search array functions port from AS3
// @author: http://flanture.blogspot.com Jan 2015

var a = [1,2,3,5,3];
var b = [2,4,6,8];

// **************************************
// function search finds element in array and displays position if element exists

function search(word, arr) {
 
    var exists = false;

    for(var i=0; i < arr.length; i++){
        if(arr[i]==word){
            window.alert("Element exist on position "+i);
            exists = true;
        };
    };

    if(!(exists)){
        window.alert("Element doesn't exist in array.");
    };

};

// tests for search function 
// search(7, b)
// search(6, b)

// **************************************
// function searchB search element in array and returns Boolean value
 
function searchB(word, arr) {

    var exists = false;

    for(var i=0; i < arr.length; i++) {
        if(arr[i]==word){
            exists = true;
        };
    };
    
    return exists;
};

// tests for searchB function
// window.alert("6 exists in b? "+searchB(6,b));
// window.alert("7 exists in b? "+searchB(7,b));

// ***************************************
// function searchCount returns number of appearances of element in array
 
function searchCount(word, arr) {

    var counter = 0;

    for(var i=0; i < arr.length; i++) {
        if(arr[i]==word){
            counter+=1;
        };
    };
    
    return counter;
};

// tests for searchCount function
// window.alert("number of 3 in a? "+searchCount(3,a));
// window.alert("number of 11 in a? "+searchCount(11,a));

// ****************************************
// function iSection returns intersection array of two arrays
 
function iSection(arr1, arr2) {

    var arr3 = new Array();
    var count = 0;
    
    for(var i=0; i < arr1.length; i++){
        for(var j=0; j < arr2.length; j++){
            if(arr1[i]==arr2[j]){
                arr3[count] = arr1[i];
                count+=1;
            };
        };
    };

    return arr3;
}

// tests for iSection function
// window.alert("intersection of a and b is : "+iSection(a,b));

// *******************************************
// function shuffle simply shuffles given array elements
     
function shuffle(b) {

    var temp = new Array();
    var templen;
    var take;
    while (b.length > 0) {
        take = Math.floor(Math.random()*b.length);
        templen = temp.push(b[take]);
        b.splice(take,1);
    };
    
    return temp;
};
    
// tests for shuffle function
// window.alert("shuffled b is : "+shuffle(b));


There are a lot of ways this code can be improved and porting like this is bad actually since JavaScript built-in functions are not used.

As an example, search function doesn't use built-in JavaScript indexOf method, in this situation:

app2.js
var a = [1,2,3,5,3];
var b = [2,4,6,8];

// **************************************
// function search2 finds element in array and displays position if element exists

function search2(word, arr) {
 
     var n = arr.indexOf(word);

    if(n>-1){
        window.alert("Element exist on position "+n);
    } else {
        window.alert("Element doesn't exist in the given array.");
    };
};

// tests for search function 
// search2(7, b)
// search2(6, b)


Similarly, there are better and much faster options for other functions too.

For second function which searches element in array and returns Boolean value True is element is present and False if element is not there, code is very simple:

searchB2 function:

// function searchB2 search element in array and returns Boolean value
 
function searchB2(word, arr) {

    return arr.indexOf(word)>-1;
    
};

// tests for searchB function
// window.alert("6 exists in b? "+searchB2(6,b));
// window.alert("7 exists in b? "+searchB2(7,b));

One more search array function I mentioned earlier is the one which returns number of appearances of given element in array.

searchCount2 function:

// function searchCount2 returns number of appearances of element in array
 
function searchCount2(word, arr) {

    var counter = 0;    
    var n = arr.indexOf(word);
    while(n>-1){
        counter ++;
        n = arr.indexOf(word, n+1);
    };
    
    return counter;
};

// tests for searchCount2 function
// window.alert("number of 3 in a? "+searchCount2(3,a));
// window.alert("number of 11 in a? "+searchCount2(11,a));


For solution on intersection function I recommend as further reading this post by Peter Scott.

*_*

 

template by blogger templates