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

12.02.2007 9965 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.

Comments

12.02.2007 at 21:34 shaun

very very cool! Haxe rock!

12.03.2007 at 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

12.03.2007 at 17:37 ali_o_kan

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

12.03.2007 at 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.

12.05.2007 at 18:56 Pasteurized

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

Write a comment

http://
×