当前位置: 首页 > 知识库问答 >
问题:

在Angular JS的这个小游戏中,如何将对象同步到控制器作用域?

蔺昊穹
2023-03-14

我做了一个简单的双人游戏,把我所有的代码都塞进了应用程序。js。要玩它,你只需在屏幕上配对卡片:每次你这样做时,卡片对象就会打印到控制台上,其中包含游戏变量,如移动次数、游戏计时器等。这些游戏变量应该显示在屏幕的右下方,但我似乎无法将它们通过卡片翻转器控制器的$范围。我应该怎么做?我应该在控制器内移动我的函数和对象吗?这是我第一次使用Angular JS,所以请随时提出更好的实践或更有效的方法。这是我的应用程序。js公司:

var app = angular.module('memoApp', []);

app.filter('shuffle', function() {
  return function(array) {
    var counter = array.length, temp, index;
    while (counter--) {
        index = (Math.random() * counter) | 0;
        temp = array[counter];
        array[counter] = array[index];
        array[index] = temp;
    } return array;
  }
});

app.directive('card', function() {
  return function(scope, element) {
    element.bind('click', function(e) {
      e.preventDefault();
      revealCard($(this).children('a'));
      console.log(card);
    });
  }
});

function CardFlipper($scope) {
    $scope.deck = [
      1, 2, 3, 4, 5, 6, 7, 8, 9,
      1, 2, 3, 4, 5, 6, 7, 8, 9
    ];
    $scope.card = card;
 };

 /* Gaming */

var card = {
  count: 0,
  pair: 0,
  moves: 0,
  timer: 0
};

var timer = setInterval(function(){
  card.timer++;
}, 1000);

var revealCard = function(picked) {
  if (card.count!=1) {
    // First move: store data
    card.pair = picked.data('pair');
    card.count = 1;
    turnCard('wipe');
    turnCard('flip', picked, card.pair);
  } else {
    // Second move: compare
    if (picked.data('pair')==card.pair) {
      if (!picked.hasClass('flip')) {
        turnCard('win', picked, picked.data('pair'));
      } else {
        turnCard('wipe');
      }
    } else {
      turnCard('flip', picked, picked.data('pair'));
    }
    card.count = 2;
    card.moves++;
  }
};

var turnCard = function(outcome, picked, pair) {
  switch (outcome) {
    case 'flip':
      picked.toggleClass('flip').html(pair);
      break;
    case 'win':
      picked.addClass('flip').html(card.pair);
      $('ul#game .flip').addClass('win');
      break;
    case 'wipe':
      $('ul#game li').find('a').removeClass('flip').html('');
      break;
  }
};

共有1个答案

苏运良
2023-03-14

我相信你太依赖jQuery来实现你的游戏了。仅使用Angular将jQuery事件绑定到DOM元素。

你的游戏对于刚接触Angular的人来说是一个很好的例子,所以我写了自己的版本。

看看这个JSFIDLE。

Js代码:

angular.module('CardFlipperApp', [])
/* Card model */
.factory('Card', function() {
    function Card (number) {
        this.visible = false;
        this.cleared = false;
        this.number = number;
    };
    Card.prototype.show = function() {
        this.visible = true;   
    };
    Card.prototype.hide = function() {
        this.visible = false;   
    };
    Card.prototype.clear = function() {
        this.cleared = true;   
    };
    return Card;
})
/* Deck model */
.factory('Deck', function(Card) {
    function shuffle(array) {
        var counter = array.length, temp, index;
        while (counter--) {
            index = (Math.random() * counter) | 0;
            temp = array[counter];
            array[counter] = array[index];
            array[index] = temp;
        }
        return array;
    }

    function Deck (numberOfCards) {
        var array = [];
        for (var i = 1; i <= numberOfCards; i++) {
            array.push(new Card(i));  
            array.push(new Card(i));
        }
        this.cards = shuffle(array);
    };

    Deck.prototype.hideAllBut = function(card) {
        for (var i = 0; i < this.cards.length; i++) {
            if (this.cards[i] !== card) {
                this.cards[i].hide(); 
            }
        }
    };

    Deck.prototype.allCleared = function() {
        for (var i = 0; i < this.cards.length; i++) {
            if (!this.cards[i].cleared) {
                return false;
            }
        }
        return true;
    };

    return Deck;
})
.controller('CardFlipperCtrl', function($scope, $timeout, Deck) {
    var timeoutHandle = null;

    function nextTick(){
        $scope.timer++;
        timeoutHandle = $timeout(nextTick,1000);
    }

    function startTimer() {
        timeoutHandle = $timeout(nextTick, 1000);
    }

    function stopTimer() {
        if (timeoutHandle) {
            $timeout.cancel(timeoutHandle);
            timeoutHandle = null;
        }
    }

    $scope.init = function() {
        $scope.deck = new Deck(9);
        stopTimer();
        $scope.moves = 0
        $scope.timer = 0;
        $scope.done = false;
    };

    $scope.toggle = function(card) {
        // double click, do nothing
        if ($scope.selectedCard === card) { return; }

        $scope.moves++;
        if ($scope.moves === 1) { // start timer on 1st move
            startTimer();
        }

        if ($scope.selectedCard) {
            if ($scope.selectedCard.number === card.number) {
               $scope.selectedCard.clear();
               card.clear();
               if ($scope.deck.allCleared()) {
                   $scope.done = true;
                   stopTimer();
               }
            } else {
               card.show();
            }
            $scope.selectedCard = null;
        } else {
            card.show();
            $scope.deck.hideAllBut(card);
            $scope.selectedCard = card;   
        }
    };

    $scope.init(); // initial deck creation
});

模板:

<div ng-app="CardFlipperApp">
    <div ng-controller="CardFlipperCtrl">
        <button ng-click="init()">Reset</button>
        Moves: {{moves}} - Time: {{timer}}
        <div ng-if="!done" ng-repeat="card in deck.cards">
            <div class="card" ng-class="{visible: card.visible, cleared: card.cleared, changeLine: ($index % 6 == 0)}" ng-click="toggle(card)">
                <span ng-if="card.visible">{{card.number}}</span>
            </div>
        </div>
        <div ng-if="done" class="done">Done!</div>
    </div>
</div>

注意Card和Deck等“模型”的使用。模型不是Angular特有的东西(jQuery应用程序可以抽象这些实体),但在Angular中,模型可以在IOC内注册为服务并利用DI(Deck依赖Card,控制器依赖Deck)。

我发现最好的方法是在服务中定义一个简单的JS“类”(属性、方法、“静态”函数等),并返回构造函数以在Angular中注册。依赖它的另一个组件只需调用new ModelClass()。

应用程序的实质性功能可以驻留在“模型”(与角度无关的代码)中。这样,您的应用程序更易于阅读、理解和测试。

 类似资料:
  • 问题内容: 我是Angular的新手,正在尝试弄清楚该怎么做… 使用AngularJS,如何注入要在另一个控制器中使用的控制器? 我有以下片段: 执行此操作时,出现错误: 我是否应该尝试在另一个控制器内部使用一个控制器,还是应该将此服务用作服务? 问题答案: 如果您打算掌握已经实例化的另一个组件的控制器,并且如果您遵循的是基于组件/指令的方法,则始终可以遵循某个层次结构的另一个组件中的控制器(一个

  • 问题内容: 因此,我发现了这个名叫法拉利(Ferrari)的家伙创造的这款出色的乒乓球游戏,我的任务是使他成为两名拥有2分但没有高分的玩家。我做了很多尝试,除了当我制作第二组控制运动的代码时,它要么被完全忽略,要么按分配给它的向上按钮,它将一直向上移动,而不会向下移动。 问题答案: 您的代码已被改编为以下两人游戏。该程序已重组为各种功能,类和方法。没有AI时,控件是相同的。 Edit: In de

  • 这个游戏的引导界面是简单的2+2=4,4+4=8,似乎和消除类游戏一样。玩第一次的时候,总是想着这样的加法,可要是这样的话,这个游戏玩起了很困难,其实就是简单的上下左右滑动,相同的会叠加,不要去想加法,我觉得可以修改为仅仅靠重力感应来玩的游戏。

  • 玩家通过“AD”键或者“←→”操控前进中的滑雪者,努力避开路上的树,尽量捡到路上的小旗。 如果碰到树,则得分减50,如果捡到小旗子,则得分加10。 逐步实现: Step1:定义精灵类

  • 问题内容: 我使用Angular组件(this的第一个示例)。当我在组件中绑定对象时,可以在模板中访问它,但不能在控制器中访问它。 js: 的HTML: 模板html(在这里有效): 错误: ReferenceError:未定义英雄 Plunker:https://plnkr.co/edit/U9CJLs6jgrlsZH6tUdr0 问题答案: 您将在上下文中获得价值 虽然以上行不通。因为它不会在

  • 本文向大家介绍Java控制台实现猜拳游戏小游戏,包括了Java控制台实现猜拳游戏小游戏的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Java猜拳游戏的具体代码,供大家参考,具体内容如下 先来看一下效果图:  首先我们创建一个Person类,这个类有name和score两个属性,有play这个方法,源代码如下: 接下来是主程序入口: 源代码下载:Java猜拳游戏 以上就是本文的全部内