Haxe / JavaScript Test Shoot'em up 100 lignes de code

02.12.2007 9659 5

Le jeu fonctionne sous Firefox, Opera et IE, mais le rendu sur ce dernier est bien plus médiocre. Je pense que mon code peut être bien plus optimisé, là, je ne me suis pas trop cassé la tête.
Pour faire ce jeu on a besoin de 3 sprites (vous pouvez les enregistrer en cliquant droit dessus ):

La page HTML (index.html) qui contiendra le jeu :

<html>
    <head>
        <title>Haxe JS Game</title>
    </head>
    <link type="text/css" rel="stylesheet" href="game.css"> 
    <body>
        <div id="game">
            <div id="score"></div>
            <div id="ship"></div>
            <div id="gameOver"></div>
        </div>
        <script type="text/javascript" src="game.js"></script>
    </body>
</html>

Le CSS associé (game.css) :

body
{
    background-color    : #EEEEEE;
    margin : 0 0 0 0;
}
#game
{
    font-family            : Arial;
    font-weight            : bold;
    font-size            : 42px;
}
#score
{
    margin                : 20px;    
}
#gameOver
{
    position            : absolute;
    visibility            : hidden;
    text-align            : center;
    border-style        : solid;
    border-width        : 1px;
    border-color        : #333333;
    background-color    : #CCCCCC;
    width                : 200px;
    height                : 100px;
}
#ship
{
    position            : absolute;
    background            : url(ship.gif);
    background-repeat    : no-repeat;
    width                : 64px;
    height                : 46px;
}
.shot
{
    position            : absolute;
    background            : url(shot.gif);
    background-repeat    : no-repeat;
    width                : 16px;
    height                : 24px;
}
.enemy
{
    background            : url(enemy.gif);
    position            : absolute;
    width                : 64px;
    height                : 64px;
}

Le code Haxe (Game.hx):

import js.Dom;
class Game
{
    static var lShots        : List<HtmlDom>;
    static var lEnemies        : List<{ enemy : HtmlDom, count : Int }>;
    
    static var gameDiv        : HtmlDom;
    static var shipDiv        : HtmlDom;
    static var scoreDiv        : HtmlDom;
    static var gameOverDiv    : HtmlDom;
    
    static var score        : Int;
    static var difficulty    : Float;
    static var t1            : haxe.Timer;
    static var t2            : haxe.Timer;
    
    static function main()
    {
           lShots = new List();
           lEnemies = new List();
        
        gameDiv = js.Lib.document.getElementById( "game" );
        shipDiv = js.Lib.document.getElementById( "ship" );
        scoreDiv = js.Lib.document.getElementById( "score" );
        gameOverDiv = js.Lib.document.getElementById( "gameOver" );
        
        shipDiv.style.top = Std.string( js.Lib.window.document.body.clientHeight - shipDiv.offsetHeight );
        
        js.Lib.document.onmousedown = createShot;
        untyped js.Lib.document.onmousemove = mouseMove;
        
        score = 0;
        difficulty = 0;
        scoreDiv.innerHTML = "Score: 0";
        
        t1 = new haxe.Timer( 25 );
        t1.run = moveShip;
        t2 = new haxe.Timer( 1000 );
        t2.run = createEnemy;
    }
    
    static function moveShip()
    {
        difficulty += 0.001;
        for ( i in lShots )
        {
            var iY = Std.parseInt( i.style.top );
            i.style.top = Std.string( iY - 10 );
            if ( iY < 0 )
            {
                gameDiv.removeChild( i );
                lShots.remove( i );
            }
        }
        
        for ( i in lEnemies )
        {
            var iX = Std.parseInt( i.enemy.style.left ) + i.enemy.offsetWidth / 2;
            var iY = Std.parseInt( i.enemy.style.top ) + i.enemy.offsetHeight / 2;
            i.count++;
            i.enemy.style.top = Std.string( Std.parseInt( i.enemy.style.top ) + 1 + difficulty );
            i.enemy.style.left = Std.string( js.Lib.window.document.body.clientWidth / 2 + Math.sin( i.count / 20 ) * ( 100  + difficulty * 100 ) );
            
            if ( iY > Std.parseInt( shipDiv.style.top ) )
            {
                t1.stop();
                t2.stop();
                js.Lib.document.onmousedown = null;
                js.Lib.document.onmousemove = null;
                
                gameOverDiv.innerHTML = "GAME OVER";
                gameOverDiv.style.left = Std.string( js.Lib.window.document.body.clientWidth / 2 - gameOverDiv.offsetWidth / 2 );
                gameOverDiv.style.top = Std.string( js.Lib.window.document.body.clientHeight / 2 - gameOverDiv.offsetHeight / 2 );
                gameOverDiv.style.visibility = "visible";
            }
            
            for ( j in lShots )
            {
                var jX = Std.parseInt( j.style.left ) + j.offsetWidth / 2;
                var jY = Std.parseInt( j.style.top );
                
                if ( Math.abs( iX - jX ) < 20 && Math.abs( iY - jY ) < 20 )
                {
                    gameDiv.removeChild( i.enemy );
                    lEnemies.remove( i );
                    score++;
                    scoreDiv.innerHTML = "Score: " + score;
                }
            }
        }
    }
    
    static function createEnemy()
    {
        var enemy = shipDiv.cloneNode( false );
        enemy.style.top = "0";
        enemy.id = "enemy" + Std.string( lEnemies.length );
        enemy.className = "enemy";
        gameDiv.appendChild( enemy );
        lEnemies.add( { enemy : enemy, count : 0 } );
        enemy.style.left = Std.string( js.Lib.window.document.body.clientWidth / 2 - enemy.offsetWidth / 2  );
    }
    
    static function createShot( e )
    {
        var shot = shipDiv.cloneNode( false );
        shot.id = "shot" + Std.string( lShots.length );
        shot.className = "shot";
        gameDiv.appendChild( shot );
        lShots.add( shot );
        shot.style.left = Std.string( Std.parseInt( shipDiv.style.left ) + shipDiv.offsetWidth / 2  - shot.offsetWidth / 2 );
    }
    
    static function mouseMove( e )
    {
        var x = if ( js.Lib.isIE ) untyped event.x; else e.clientX; // <-- IE (???)
        shipDiv.style.left = Std.string( x - shipDiv.offsetWidth / 2 );
    }
}

Le fichier build.hxml permettant de compiler notre code Haxe en javascript (game.js) associé à la page HTML:

-js game.js
-main Game

Vous obtenez donc un petit jeu entierement javascript et comptatible Firefox, Opera et IE avec du code Haxe !!! Une alternative au SWF ?!
Attention, vous allez rencontrer des problemes si vous désactivez votre cache sous IE (on ne gere pas de prechargement...)
Si vous avez des suggestions d'ameliorations, n’hésitez pas.

Commentaires

02.12.2007 à 21:34 shaun

very very cool! Haxe rock!

03.12.2007 à 01:02 tonypee

I love it! thats very amazing. Thats for the great example! I'll have to look into Haxe js more. It seems like it will help to ease the pain of writing js v.cool

03.12.2007 à 17:37 ali_o_kan

Et Safari 3.0.4 (523.12)
Bien sympa tout ça, ça donne envie de si mettre

03.12.2007 à 19:22 Michal

Hi all !
Happy that it helps some of you having another look at JS
And another way, thanks this try, I've installed all these "strange" browsers like Opera and Safari, and yes , it works on all now.

05.12.2007 à 18:56 Pasteurized

On peut donc voir que nos nuits de coding ne donne pas que des bugs

Laisser un commentaire

http://
×