zoukankan      html  css  js  c++  java
  • javascript异步编程系列【十】—Jscex+Easeljs制作坦克大战

    一.简介

    为了利用当今和未来的硬件,您可以对代码进行并行化,以将工作分摊在多个处理器上。 往往,并行化需要线程和锁的低级操作,但是Jscex不用,因为javascript这种解释型语言,仅仅需要一个线程来解释它,已其他线程无关,且不冲突!

    二.回顾

    上面介绍了一下Easeljs以及其优势,并且利用Easeljs+Jscex实现了坦克的右移以及开炮,但是还存在许多问题,比如移动不能开炮,开炮不能移动。

    这篇主要利用Jscex并行编程模型搭起游戏的基本框架,并且解决坦克的转弯和开火。

    三.架构设计

    昨天我仔细想了想,不管是任何东西,拆得越细就越好控制。如果使用Easeljs的tick(也就相当于Jscex的while(true)),任何东西都往里面丢,函数冗长,不能灵活控制。Jscex有个很明显的优势,它可以轻松挂起一个while(true),用于监听,然后根据监听的结果做出相应的操作。所以,我把坦克大战拆成以下七个异步任务,游戏的所有元素都在下面七个异步任务当中:

    a.坦克的移动

    b.子弹的生产

    c.子弹的飞行

    d.碰撞检测,比如击中墙壁,击中敌方坦克

    e.宝物的生成,比如增加火力的宝物,增加生命的宝物

    f.统计任务,比如消灭敌军坦克获取积分

    g. GameOver监听,比如老巢被灭,比如自己牺牲并且剩余生命条数为0

    这七个任务同时执行,看似相互独立,其实是相互影响,比如

    碰撞检测到击中敌方坦克,就会触发统计任务,

    击中掉宝坦克,触发宝物的生成

    被敌方坦克消灭老巢,触发GameOver

    四.转弯和开火

    开始打算用rotation属性来旋转图片,实现转弯,并且带有转弯动画,这也算超越了以前的坦克大战。然后rotation旋转图片不会以图片的中心旋转,而会以图片左上角为基准点旋转,这叫我情何以堪!旋转效果如下:

    好吧,我还是用四张图片吧,反正素材就提供了4张图片。

    fiveTank

    我们把转弯与开火拆成三个异步任务:

    a.坦克的移动

    b.子弹的生产

    c.子弹的飞行

    坦克的移动:

    var moveAsync = eval(Jscex.compile("async", function () {
    var i = 0;
    while (true) {
    if (goRight == true) {
    bmpR.visible = true;
    bmpL.visible = false;
    bmpD.visible = false;
    bmpU.visible = false;
    bmpL.x += 1;
    bmpR.x += 1;
    bmpD.x += 1;
    bmpU.x += 1;
    }
    if (goLeft == true) {
    bmpR.visible = false;
    bmpL.visible = true;
    bmpD.visible = false;
    bmpU.visible = false;
    bmpR.x -= 1;
    bmpL.x -= 1;
    bmpD.x -= 1;
    bmpU.x -= 1;
    }
    if (goUp == true) {
    bmpR.visible = false;
    bmpL.visible = false;
    bmpD.visible = false;
    bmpU.visible = true;
    bmpR.y -= 1;
    bmpL.y -= 1;
    bmpD.y -= 1;
    bmpU.y -= 1;
    }
    if (goDown == true) {
    bmpR.visible = false;
    bmpL.visible = false;
    bmpD.visible = true;
    bmpU.visible = false;
    bmpR.y += 1;
    bmpL.y += 1;
    bmpD.y += 1;
    bmpU.y += 1;
    }
    stage.update();
    $await(Jscex.Async.sleep(10));
    }
    }))

    生成子弹:

    var bulletStream = new Array();
    var createBulletAsync = eval(Jscex.compile("async", function () {
    var i = 0;
    while (true) {
    if (shootHeld == true) {
    bulletStream[i] = new Bitmap("image/tankmissile.gif");
    if (bmpD.visible == true) {
    bulletStream[i].direction = "down";
    bulletStream[i].x = bmpR.x + 21;
    bulletStream[i].y = bmpR.y + 60;
    }
    if (bmpL.visible == true) {
    bulletStream[i].direction = "left";
    bulletStream[i].x = bmpR.x ;
    bulletStream[i].y = bmpR.y + 21;
    }
    if (bmpR.visible == true) {
    bulletStream[i].direction = "right";
    bulletStream[i].x = bmpR.x + 60;
    bulletStream[i].y = bmpR.y + 21;
    }
    if (bmpU.visible == true) {
    bulletStream[i].direction = "up";
    bulletStream[i].x = bmpR.x + 21;
    bulletStream[i].y = bmpR.y ;
    }
    stage.addChild(bulletStream[i]);
    i++;
    }
    stage.update();
    $await(Jscex.Async.sleep(200));
    }
    }))

    我们要在生成子弹的时候,告诉子弹的方向,也许以后会扩展一个子弹的速度。

    子弹的飞行:

    var fireAsync = eval(Jscex.compile("async", function () {
    while (true) {
    for (bullet in bulletStream) {
    if (bulletStream[bullet].direction == "up") {
    bulletStream[bullet].y -= 10;
    }
    if (bulletStream[bullet].direction == "down") {
    bulletStream[bullet].y += 10;
    }
    if (bulletStream[bullet].direction == "right") {
    bulletStream[bullet].x += 10;
    }
    if (bulletStream[bullet].direction == "left") {
    bulletStream[bullet].x -= 10;
    }
    }
    stage.update();
    $await(Jscex.Async.sleep(50));
    }
    }))

    元素初始化,并行任务开始:

    function init() {
    canvas = document.getElementById("testCanvas");
    stage = new Stage(canvas);
    bmpR = new Bitmap("image/p1tankR.gif");
    bmpL = new Bitmap("image/p1tankL.gif");
    bmpD = new Bitmap("image/p1tankD.gif");
    bmpU = new Bitmap("image/p1tankU.gif");
    bmpL.visible = false;
    bmpD.visible = false;
    bmpU.visible = false;
    stage.addChild(bmpR);
    stage.addChild(bmpL);
    stage.addChild(bmpD);
    stage.addChild(bmpU);
    Ticker.addListener(stage);
    createBulletAsync().start();
    fireAsync().start();
    moveAsync().start();
    }

     

    五.在线演示

    操作指南:WSAD+J

    未完待续,下篇加入敌方坦克,ohoh··········

    最新的Jscex 库,请上https://github.com/JeffreyZhao/jscex或者http://www.sndacode.com/projects/jscex/wiki下载吧····

    六.同步

    本文已同步更新至:

    HTML5实验室【目录】:   http://www.cnblogs.com/iamzhanglei/archive/2011/11/06/2237870.html

  • 相关阅读:
    js的浅拷贝与深拷贝
    用Nodejs连接MySQL(原文链接)
    HTML5交互性图表库
    GitHub Desktop离线安装包
    docker--Dockerfile--sonarqube
    docker --Nexus仓库
    docker --Dockerfile--一些语法
    zookeeper 四字命令
    docker --swarm创建一个集群
    docker --swarm启动2375端口监听
  • 原文地址:https://www.cnblogs.com/iamzhanglei/p/2176848.html
Copyright © 2011-2022 走看看