fighter

    技术2022-07-11  146

    fighter_zzh

    I recently learned a cool technique from Simurai about how to animate PNG sprites with the CSS3 animations' steps() property. The main idea in this technique is to "recreate" some kind of animated GIF but with the tiles of a PNG sprite.

    我最近从Simurai学到了一项很酷的技术,内容涉及如何使用CSS3动画的steps()属性为PNG精灵设置动画。 此技术的主要思想是“重新创建”某种动画GIF,但要带有PNG子画面的图块。

    As with everyone I know, I played to Street Fighter in my childhood and when I saw this ... guess what popped in my head?

    就像我认识的每个人一样,我从小就在《街头霸王》中玩过,当我看到这件事时 ……我脑子里突然冒出了什么?

    Check out this Pen!

    If the pen doesn't render above, click here to see it in action.

    如果笔未在上方渲染, 请单击此处查看其动作。

    让我们创建第一个CSS动作 (Let's Create the First CSS Move)

    We'll start with the punch (see in the sprite bellow it's the third one). First we need to open Photoshop to create the sprite. Make all images the same size (these ones are 70px width and 80px height). There is a good app called Texture Packer which can help in creation of game sprites. Try to find the dimensions of the biggest of your frames and use these dimensions for your grid. At the end you'll get something like this:

    我们将从打Kong开始(请参见下面的精灵,这是第三个)。 首先,我们需要打开Photoshop来创建精灵。 使所有图像大小相同(这些图像的宽度为70px,高度为80px)。 有一个名为Texture Packer的好应用程序,可以帮助创建游戏精灵。 尝试找到最大的框架尺寸,并将这些尺寸用于网格。 最后,您将获得以下内容:

    Then we need to set up a DIV for Ken which will receive our punch move (and all our other future moves):

    然后,我们需要为Ken设置DIV ,该DIV将收到我们的打卡动作(以及所有其他以后的动作):

    /* html */ <div class="ken"></div> /* css */ .ken { width:70px; height:80px; /* exactly the size of an image in our sprite */ background-image:url('../images/sprite.png'); }

    Let's assume vendor prefixes are implicitly working. Now we can declare the punch animation like this:

    假设供应商前缀隐式工作。 现在我们可以这样声明穿Kong动画:

    /* css */ .punch { animation: punch steps(4) 0.15s infinite; } @keyframes punch { from { background-position:0px -160px; } to { background-position:-280px -160px; } }

    What we just did is apply an animation (punch) to a class name (.punch) which basically animates background-position from 0px to -280px (on x axis). This animation will be broken into 4 parts (steps(4) which corresponds to the punch's 4 images), and it will take 0.15 second to perform; then it will start over infinitely.

    我们刚才所做的是将动画(打Kong)应用于类名( .punch ),该类名基本上将background-position从0px为-280px (在x轴上)。 此动画将分为4个部分(对应于打Kong器的4张图像的步骤(4)),并且需要0.15秒的时间来执行; 那么它将无限地重新开始。

    Finally we need a way to add/remove the .punch class name on DIV.ken when another key is pressed.

    最后,我们需要一种在按下另一个键时在DIV.ken上添加/删除.punch类名称的方法。

    /* javascript */ $(document).on('keydown', function(e) { if (e.keyCode === 68) { // 68 is the letter D on the keyboard $('.ken').addClass('punch'); setTimeout(function() { $ken.removeClass('punch'); }, 150); } });

    We used jQuery to addClass('punch') if the letter "D" is pressed and then remove it after a setTimeout (a delay) of 150ms (remember our css animation takes exactly 0.15s wich is the same as 150ms). That's pretty much all you need to know to create a lot more moves.

    如果按下字母“ D”,则使用jQuery来addClass('punch') ,然后在150ms的setTimeout(延迟)后将其删除(请记住,我们CSS动画需要0.15s的时间与150ms相同)。 这就是创建更多动作所需的全部知识。

    使用SASS将其提升到一个新的水平 (Take it to the Next Level with SASS)

    If you pay attention to what we are doing, you'll notice we have some values that never change (width/height of an image in the sprite), and, after you've created some other moves, you'll notice you have a lot of code duplication which will be difficult to read and maintain in the future. SASS can help us DRY all this mess!

    如果您注意我们正在做的事情,您会发现我们有一些永远不变的值(子画面中图像的宽度/高度),并且在创建了其他动作之后,您会注意到很多代码重复,将来将很难阅读和维护。 SASS可以帮助我们干燥所有这些混乱!

    First we need basic @mixins like animation() and keyframes():

    首先,我们需要基本的@mixins例如animation()和keyframes() :

    @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 } }

    We need to store image width / height values and SASS variables exist for this reason:

    为此,我们需要存储图像的宽度/高度值和SASS变量:

    $spriteWidth:70px; $spriteHeight:80px;

    And finally we can mix those together to create a complicated new mixin which will declare moves and handle correct calculation of background positions for us:

    最后,我们可以将它们混合在一起以创建一个复杂的新mixin,它将声明动作并为我们处理正确的背景位置计算:

    @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)); } } }

    Now you can create a new move with a single line of code:

    现在,您可以使用一行代码来创建新动作:

    $spriteWidth:70px; $spriteHeight:80px; /* punch */ @include anim($animName:punch, $steps:3, $animNbr:3, $animParams:.15s infinite); /* kick */ @include anim($animName:kick, $steps:5, $animNbr:7, $animParams:.5s infinite); /* hadoken */ @include anim($animName:hadoken, $steps:4, $animNbr:1, $animParams:.5s infinite); ...

    $animNbr is very important: the calculation is based on this number. In fact it's just the moves count in the sprite. Our first example was the punch, right? And in our sprite it's the move number 3. The kick is number 7, etc.

    $animNbr非常重要:根据此数字进行计算。 实际上,这只是精灵中的动作计数。 我们的第一个例子是一拳,对吗? 在我们的子画面中,它是移动数字3。踢是数字7,依此类推。

    为火球添加碰撞检测 (Add Collision Detection for the Fireball)

    We need a very fast loop for collision detection. It will test the fireball position (offset) every 50 milliseconds, compare it to something else position (here we test the end of the screen). If the fireball's left position is bigger than the window width, then it means the fireball overtaken the screen so we immediately apply an .explode class.

    我们需要一个非常快速的循环来进行碰撞检测。 它将每隔50毫秒测试一次火球位置(偏移),并将其与其他位置进行比较(此处我们测试屏幕的末端)。 如果火球的左侧位置大于窗口宽度,则表示火球超过了屏幕,因此我们立即应用.explode类。

    Here's how I did it; it's not perfect but it works very well:

    这是我的做法; 它并不完美,但效果很好:

    var $fireball = $('<div/>', { class:'fireball' }); $fireball.appendTo($ken); var isFireballColision = function(){ return $fireballPos.left + 75 > $(window).width(); }; var explodeIfColision = setInterval(function(){ $fireballPos = $fireball.offset(); if (isFireballColision()) { $fireball.addClass('explode'); clearInterval(explodeIfColision); setTimeout(function() { $fireball.remove(); }, 500); } }, 50);

    下一步是什么? (What's Next?)

    We could easily add some sound effects, background music, sprite another character, mix this up with web RTC to allow multiple computers to control characters (I don't know something with NodeJS and Socket.io or maybe the cool new Meteor framework); that's what I love with web development: it's almost limitless.

    我们可以很容易地添加一些声音效果,背景音乐,雪碧另一个字符,这混合了网络RTC ,允许多台计算机控制字符(我不知道的东西的NodeJS和Socket.io也许很酷的新流星框架 ); 这就是我对Web开发的热爱:它几乎是无限的。

    翻译自: https://davidwalsh.name/street-fighter

    fighter_zzh

    相关资源:jdk-8u281-windows-x64.exe
    Processed: 0.014, SQL: 9