CodePen

HTML

            
              <div class="stage">
  <div class="ken stance"></div>
</div>





<div class="commands">
  <h1>Control Ken with ur keyboard</h1>

    Punch: <button id="a">a</button><br>
    Kick: <button id="z">z</button><br>
    Reverse kick: <button id="e">e</button><br>
    <br>
    Tatsumaki: <button id="q">q</button><br>
    Hadoken: <button id="s">s</button><br>
    Shoryuken: <button id="d">d</button><br>
    <br>
    Jump: &nbsp;&nbsp;&nbsp;<button id="up">▲</button><br>
    Walk: <button id="left">◀</button><button id="right">►</button><br>
    Kneel: &nbsp;&nbsp;<button id="down">▼</button>
</div>

            
          
!
via HTML Inspector

CSS

            
              /* 
fork this demo on github: 
https://github.com/jkneb/street-fighter-css
*/

/* 
A little more explanations on how it works 
http://front-back.com/animate-png-sprites-with-css3-animations
*/

/* 
 * mixins 
*/
@mixin transform($params) { 
    -webkit-transform:$params;
       -moz-transform:$params;
        -ms-transform:$params;
            transform:$params;
}
@mixin transition($params) { 
    -webkit-transition:$params;
       -moz-transition:$params;
        -ms-transition:$params;
            transition:$params;
}
@mixin animation($params) { 
    -webkit-animation:$params;
       -moz-animation:$params;
        -ms-animation:$params;
            animation:$params;
}
@mixin keyframes($name) { 
    @-webkit-keyframes $name { @content }
    @-moz-keyframes $name { @content }
    @-ms-keyframes $name { @content }
    @keyframes $name { @content }
}
@mixin anim($animName, $steps, $animNbr, $animParams){
    .#{$animName} { 
        @content;
        @include animation($animName steps($steps) $animParams); 
    }
    @include keyframes($animName) {
        from { background-position:0px (-$spriteHeight * ($animNbr - 1)); }
          to { background-position:-($spriteWidth * $steps) (-$spriteHeight * ($animNbr - 1)); }
    }
}

/* element who's going to receive this class will be mirrored */
.flip { @include transform(scaleX(-1)); }

/* sprite tile dimensions */
$spriteWidth:70px;
$spriteHeight:80px;

/* ken */
.ken { 
    position:absolute; bottom:112px; margin-left:150px;
    width:$spriteWidth; height:$spriteHeight; 
    background-image:url('http://front-back.com/wp-content/uploads/2013/01/ken.png'); 
  
  /* other sprites preloading */
  &:before { 
    content:'';
    background: url('http://front-back.com/wp-content/uploads/2013/01/ken-tatsumaki-senpuu-kyaku.png') no-repeat; 
  }
  &:after { 
    content:'';
    background: url('http://front-back.com/wp-content/uploads/2013/01/ken-shoryuken.png') no-repeat;
  }
}

/* ken's fireball */
@include anim($animName:fireball, $steps:2, $animNbr:5, $animParams:.15s infinite) {
    @extend .ken;
    position:absolute; left:100%; bottom:0px;
    margin-left:0; /* default margin-left */
    background-position:140px 320px; /* default background position */
    @include transition(margin 8s linear); 
    &:before { left:25px; right:25px; }
    &.moving { margin-left:4000px; } /* triggering the movement with this class */
}
/* ken's fireball impact explosion */
@include anim($animName:explode, $steps:4, $animNbr:6, $animParams:.5s 1);
/* stance */
@include anim($animName:stance, $steps:4, $animNbr:2, $animParams:.5s infinite);
/* hadoken - must be declared AFTER .stance */
@include anim($animName:hadoken, $steps:4, $animNbr:1, $animParams:.5s infinite);
/* punch */
@include anim($animName:punch, $steps:3, $animNbr:3, $animParams:.15s infinite);
/* walking */
@include anim($animName:walk, $steps:5, $animNbr:4, $animParams:.5s infinite);
/* kick */
@include anim($animName:kick, $steps:5, $animNbr:7, $animParams:.5s infinite);
/* reverse kick */
@include anim($animName:reversekick, $steps:5, $animNbr:8, $animParams:.5s infinite);
/* kneel down */
@include anim($animName:kneel, $steps:1, $animNbr:10, $animParams:.2s infinite);
/* jump */
@include anim($animName:jump, $steps:7, $animNbr:9, $animParams:1s infinite) {
    @include transition(bottom .5s cubic-bezier(0.990, 0.005, 0.000, 0.420));
    bottom:225px;
    &.down { bottom:112px; }
}
/* shoryuken */
@include anim($animName:shoryuken, $steps:7, $animNbr:1, $animParams:1s infinite) {
    height:110px;
    background-image:url('http://front-back.com/wp-content/uploads/2013/01/ken-shoryuken.png');
    @include transition(bottom .5s cubic-bezier(0.990, 0.005, 0.000, 0.420));
    bottom:225px;
    &.down { bottom:112px; }
}
/* tatsumaki senpuu kyaku */
@include anim($animName:tatsumaki, $steps:13, $animNbr:1, $animParams:2s infinite) {
    height:110px;
    background-image:url('http://front-back.com/wp-content/uploads/2013/01/ken-tatsumaki-senpuu-kyaku.png');
    @include transition(bottom .2s cubic-bezier(0.990, 0.005, 0.000, 0.420));
    bottom:132px;
    &.down { bottom:112px; }
}

.commands {
  h1 { margin-top:0; font-size:14px; }
  margin-left:450px;
  font-size:12px; padding:15px; 
  i { padding:0px 4px; font-style:normal; font-weight:bold; outline:1px solid pink; }
  button + button { white-space:nowrap; }
  
}

.stage {
  position:absolute; top:0; width:450px; height:330px;
  background:url('http://front-back.com/wp-content/uploads/2013/01/sf2-bg.jpg') no-repeat 0px -100px;
  background-size:contain;
  float:left; margin-right:20px; 
}
body { margin:0px; padding:0; }

            
          
!
? ?
? ?
Must be a valid URL.
+ add another resource
via CSS Lint

JS

            
              var $ken = $('.ken');
var $kenPos, $fireballPos;

var punch = function(){
  $ken.addClass('punch'); 
  setTimeout(function() { $ken.removeClass('punch'); }, 150);
};
var kick = function(){
  $ken.addClass('kick');
  setTimeout(function() { $ken.removeClass('kick'); }, 500);
};
var rkick = function(){
  $ken.addClass('reversekick');
  setTimeout(function() { $ken.removeClass('reversekick'); }, 500); 
};
var tatsumaki = function(){
  $ken.addClass('tatsumaki');
  setTimeout(function() { $ken.addClass('down'); }, 1500); 
  setTimeout(function() { $ken.removeClass('tatsumaki down'); }, 2000);
};
var hadoken = function(){
  $ken.addClass('hadoken'); 
  setTimeout(function() { $ken.removeClass('hadoken'); }, 500); 
  setTimeout(function() {
      var $fireball = $('<div/>', { class:'fireball' });
      $fireball.appendTo($ken);
              
      var isFireballColision = function(){ 
          return $fireballPos.left + 75 > $(window).width() ? true : false;
      };
  
      var explodeIfColision = setInterval(function(){
                  
          $fireballPos = $fireball.offset();
          //console.log('fireballInterval:',$fireballPos.left);
  
          if (isFireballColision()) {
              $fireball.addClass('explode').removeClass('moving').css('marginLeft','+=22px'); 
              clearInterval(explodeIfColision);
              setTimeout(function() { $fireball.remove(); }, 500); 
          }
  
      }, 50);
  
      setTimeout(function() { $fireball.addClass('moving'); }, 20);
              
      setTimeout(function() { 
          $fireball.remove(); 
          clearInterval(explodeIfColision);
      }, 3020);
  
  }, (250));
};
var shoryuken = function(){
  $ken.addClass('shoryuken');
  setTimeout(function() { $ken.addClass('down'); }, 500); 
  setTimeout(function() { $ken.removeClass('shoryuken down'); }, 1000);
};
var jump = function(){
  $ken.addClass('jump');
  setTimeout(function() { $ken.addClass('down'); }, 500); 
  setTimeout(function() { $ken.removeClass('jump down'); }, 1000); 
};
var kneel = function(){
  $ken.addClass('kneel');
};
var walkLeft = function(){
  $ken.addClass('walk').css({ marginLeft:'-=10px' });
};
var walkRight = function(){
  $ken.addClass('walk').css({ marginLeft:'+=10px' });
};

// on click events
$('#a').click(punch);
$('#z').click(kick);
$('#e').click(rkick);
$('#q').click(tatsumaki);
$('#s').click(hadoken);
$('#d').click(shoryuken);
$('#up').click(jump);
$('#down').on('mousedown mouseup', function(e){
    if (e.type == 'mousedown') { kneel(); }
    else { $ken.removeClass('kneel'); }
});
$('#left').on('mousedown mouseup', function(e){
    if (e.type == 'mousedown') { walkLeft(); }
    else { $ken.removeClass('walk'); }
});
$('#right').on('mousedown mouseup', function(e){
    if (e.type == 'mousedown') { walkRight(); }
    else { $ken.removeClass('walk'); }
});

// on keydown events
$(document).on('keydown keyup', function(e) {
    if (e.type == 'keydown') { 
        
        // s - hadoken
        if (e.keyCode == 83 
            && !$ken.hasClass('tatsumaki') 
            && !$ken.hasClass('shoryuken') 
            && !$ken.hasClass('hadoken') 
            && !$ken.hasClass('punch') 
            && !$ken.hasClass('kick') 
            && !$ken.hasClass('reversekick')
        ) { 
            hadoken();
        }

        // d - shoryuken
        if (e.keyCode == 68 
            && !$ken.hasClass('tatsumaki')
            && !$ken.hasClass('shoryuken') 
            && !$ken.hasClass('hadoken') 
            && !$ken.hasClass('punch') 
            && !$ken.hasClass('kick') 
            && !$ken.hasClass('reversekick')
            && !$ken.hasClass('jump')
        ) { 
            shoryuken();
        }

        // q - tatsumaki senpuu kyaku
        if (e.keyCode == 81 
            && !$ken.hasClass('tatsumaki') 
            && !$ken.hasClass('shoryuken') 
            && !$ken.hasClass('hadoken') 
            && !$ken.hasClass('punch') 
            && !$ken.hasClass('kick') 
            && !$ken.hasClass('reversekick')
            && !$ken.hasClass('jump')
        ) { 
            tatsumaki();
        }

        // a - punch
        if (e.keyCode == 65 
            && !$ken.hasClass('punch') 
            && !$ken.hasClass('hadoken') 
            && !$ken.hasClass('shoryuken') 
            && !$ken.hasClass('tatsumaki') 
        ) { 
            punch(); 
        }

        // e - kick
        if (e.keyCode == 90 
            && !$ken.hasClass('kick') 
            && !$ken.hasClass('hadoken') 
            && !$ken.hasClass('shoryuken') 
            && !$ken.hasClass('tatsumaki')
        ) { 
            kick(); 
        }

        // r - reverse kick
        if (e.keyCode == 69 
            && !$ken.hasClass('reversekick') 
            && !$ken.hasClass('kick') 
            && !$ken.hasClass('hadoken') 
            && !$ken.hasClass('shoryuken') 
            && !$ken.hasClass('tatsumaki')
        ) { 
            rkick();
        }

        // up - jump
        if (e.keyCode == 38 
            && !$ken.hasClass('jump') 
            && !$ken.hasClass('reversekick') 
            && !$ken.hasClass('kick') 
            && !$ken.hasClass('hadoken') 
            && !$ken.hasClass('shoryuken') 
            && !$ken.hasClass('tatsumaki')
        ) { 
            jump();
        }

        // down - kneel
        if (e.keyCode == 40 
            && !$ken.hasClass('kneel') 
            && !$ken.hasClass('jump') 
            && !$ken.hasClass('reversekick') 
            && !$ken.hasClass('kick') 
            && !$ken.hasClass('hadoken') 
            && !$ken.hasClass('shoryuken') 
            && !$ken.hasClass('tatsumaki')
        ) { 
            kneel();
        }
    
    
        // ← flip 
        //if (e.keyCode == 37) $ken.addClass('flip');
        // → unflip 
        //if (e.keyCode == 39) $ken.removeClass('flip');
        // ←← →→ walking
        if (e.keyCode == 37) { walkLeft(); }
        if (e.keyCode == 39) { walkRight(); }
    }
    else { // keyup
        $ken.removeClass('walk kneel');
    }
    return false;
    //console.log(e.keyCode);
});

            
          
!
Must be a valid URL.
+ add another resource
via JS Hint
Loading ..................