Frage

I'm a beginner programmer and I'm building a game. Whenever the player clicks on the gold image, he should get 1 gold. So I have the following HTML piece of code:

<li id="gold">Gold: 0</li>

That's the starting gold, and through JQuery I update that with:

$('#gold-image').click(function() {
    gold++;
    $('#gold').replaceWith('<li id="gold">Gold: ' + gold + '</li>');
});

But I don't feel that's the best way to update how much gold the player has. Is there a way that I can write in the HTML to update the variable whenever it's being changed or something like that without having to replace that whole item?

Later in the game there will be many functions running at the same time and increasing the gold number, so I think replacing HTML code is not the optimal way.

War es hilfreich?

Lösung

Try this with your existing div <div id="gold">Gold: 0</div>:

$('#gold-image').click(function() {
    gold++;
    $('#gold').html('Gold: ' + gold);
});

Although the above code would work. I would NOT use jQuery for something like this. There are other frameworks which would be way better for such applications. For example you can take a look at AngularJS or Ember.

The same functionality can be achieved using the two-way binding with AngularJS.

1) the markup:

<div controller="GameCtrl">
  <img src="/path/to/img.png" ng-click="goldClicked()">
  <div>Gold {{ gold }}</div>  
</div>

2) the javascript code

app.controller('GameCtrl', function($scope) {
  $scope.gold = 0;
  $scope.goldClicked = function() {
    $scope.gold += 1;
  };
});

The code is very very simple and you do not need to deal with selectors. Every time you change the gold (or any other variable) it will automatically be updated in the DOM. You will automatically get modular code and dependency injection. In addition you will write everything declaratively and your code will be much easier to read and easy to change in future.

UPDATE: Here is a working AngularJS fiddle: http://jsfiddle.net/absolutemystery/7WgYK/

Andere Tipps

Or, using a div only around the number (e.g., <div id="gold">0</div>),

$('#gold-image').click(function() {
    $('#gold').html(++gold);
});

You could user Ember.js for this kind of thing. Ember.js its a MVC javascript library.

In this case:

<li id="gold">Gold: {{YourController.goldAmmount}}</li>

and them in your controler you only have to call the function updateAmmount():

var YourController= Em.ArrayController.create({
   goldAmmount : 0,

   updateAmmount : function(){
      this.goldAmmount++;
   }

})

If you can add a <span> element it would make it a little cleaner:

HTML:

<li>Gold: <span id="gold">0</span></li>

JAVASCRIPT:

$('#gold-image').click(function() {
    gold++;
    $('#gold').text(gold);
});

You can use custom events for that. Everytime gold value updates, you can trigger an event, passing an argument, for example:

$('#gold-image').click(function() {
    gold++;
    jQuery.event.trigger({type: "onGoldUpdate",val:gold});
});

After that, you can be always listening to that event and do whatever you want with this information, like this:

jQuery(document).on("onGoldUpdate", function(e){  
    var goldValue = e.val;
    jQuery('.gold .value').html(goldValue);
});

And on HTML part, you can put a span around the value:

<li id="gold">Gold: <span class="value">0</span></li>

You could use a simple MVVM solution for your needs, for example Knockout.js. You can create a model and bind it's values to a place in your html and anytime you update a value in the model the rendered html is automatically updated without your interference. Quick example of how you could use it here...

<html>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<script>
function PlayerModel() {

    // the player score
    this.playerGold = ko.observable(0);

    // The increase gold function to add 1 to the player score
    this.increaseGold = function() {
        var oldScore = parseInt(this.playerGold());
        this.playerGold(++oldScore);
    };
}

var model = new PlayerModel();

$( document ).ready(function() {
    ko.applyBindings(model);
});

</script>
</head>
<body>Gold : <strong data-bind="text: playerGold"></strong></li>
<button onclick="javascript:model.increaseGold()">Standard JS - Increase gold</button>
<button data-bind="click: increaseGold">KO Data bound -Increase gold</button>


</body>
</html> 

Its as easy as that. You can add more variables easily to your player model then if you want. I like this approach because it keeps things easy but also affords you a lot of control over the implementation etc. Ember is another great alternative though.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top