JS MVC game dynamic objects? - javascript

I'm having trouble wrapping my head around how to represent a class/object as an image or div on the browser screen. The div would have attributes, and methods. Say I'm making a game where enemy spaceships appear randomly, moving around.
So do I JQuery.append a div tag with every instance creation? How do I connect/bind the div to the class?
Or is there a MVC frame that'll be more efficient?
thanks.

First of all, MVC's not necessarily a perfect fit for a game, but understanding it could help you get a better handle on OOP and something similar could make sense.
Assume CSS as appropriate setting background images, making .spaceObject elements absolute and defaulting at 0,0 and making body an actual set width/height box, etc...
JS doesn't have classes. It uses function constructors instead. I do not recommend attempting to emulate classes. There's nothing wrong with constructors and they actually have some nifty advantages when you get deeper into prototypes and the like.
function BuildSpaceDiv(divID){
var $_spaceDiv = $('<div id="'+divID+'" class="spaceObject" />').appendTo('body');
this.move = function(x,y){
$_spaceDiv.animate({ top:x, left:y });
}
}
Without using the new keyword it works just like a function. You use the new keyword to create an object/instance (not class/object, that's diagram and thing built, object and instance are the interchangeable terms).
var deathSun = new BuildSpaceDiv('death_sun');
You can make as many as you want or add new args to set starting coords, etc... I'm fond of using options objects with my JS constructors. Note that it still fires like a function so building an instance can have side effects if you want and that the $_spaceDiv var is unique to every instance and persistent.

Related

JavaScript to jQuery for KendoUI

I've been using KendoUI and have been using they're command functions. However to call JS I must call named jS functions. No huge deal. When I use the "This" key word it brings back the entire grid and I mus find a value of a child from a sibling of the same parent elements and i wound up doing this ugly thing. The question I have is how can I turn this "thing" into something jqueryable readable and comprehensible
function AddRole(e) {
var $ParentNode = e.target.parentNode.parentNode.children[1].children[0].getAttribute("value", 0);
}
Sorry, but you have other problems.
If you rely on such a structure e.target.parentNode.parentNode.children[1].children[0], your Markup and JS do not scale at all.
Use the oppurtunity to create scalable and consistent code. Or at least, set some id, class or html5 data attribute on the children[0] element in order to identify it properly.

Multiple Classes in SVG

I'm very new to SVG (using D3.js to call everything). Recently, I just came into a huge limitation with a project I am working on. I want to be able to make "g" classes for each category of data I am working with. Unfortunately, I am getting my data from an XML file that only connects data in one way (ex: person1 ---> person2, but not person2 ---> person1). What I would like to be able to do is to put each shape generated from my data in the root class AND the class it is connecting with. If I could add this shape to two or more classes (such as g class = person1 and person2), that would be the fastest solution I believe...But is something like this possible? Can I set an SVG shape to two or more classes? Or will it overwrite it as I define new ones.
I really hope someone can understand what I am asking. It is kind of hard to verbalize my problem without giving away every detail of my final project.
Yes, you can set multiple classes. For example,
<g class="person1 person2">
Or, in D3:
g.attr("class", "person1 person2");
One more note: If you're calling a function from within a file:
.attr("class",function(d) { return d.person1+" "+ d.person2;} )

Compound Javascript Elements

I've got this page I'm doing some tests in Javascript and jQuery: JS Tests
I've got a few questions on how to create, not sure if this is right term, but compound controls via Javascript. In something like Flash, you'd create the Object class, have the getters and setters, draw your images, etc. In JS, it seems to be a very different thought process. My main question is How do you create multiple elements with getters and setters to be rendered, filtered, and interacted with in Javascript?
The main code regarding this example sits with:
var html = (function(){
// var FRAG = $(document.createDocumentFragment());
htmlBox = $(document.createElement("div"));
var eTitle = $(document.createElement("h4"));
var ePrice = $(document.createElement("p"));
// set class first
htmlBox.addClass("box")
htmlBox.css({
backgroundColor : color
})
// set text values
eTitle.text(title);
ePrice.text("$" + price);
htmlBox.append(eTitle)
htmlBox.append(ePrice)
return htmlBox;
})();
... inside the Box() class. If someone could take a look at the source and let me know what isn't quite right, that'd be great.
EDIT
Here's the final result for this example. Some logistics to work out, but what I'm after.
http://geerswitch.in/tests/obj/
As for the jQuery creating nodes, the built in JS version works fine for this, and some research on Google shows that the non-jquery way is faster in most cases anyway (and looks worse, imo)
You're doing it almost right. You've created a Box class to represent your higher-order UI element, you're instantiating it for each element, and your main program is manipulating the elements through its interface. The only thing you're missing is the split between the public interface and the private implementation. There's nothing to prevent me from doing myBox.price += 10 right now, even though the Box interface clearly implies that price should be set at construction and never modified.
JavaScript doesn't have visibility modifiers like "private" and "public", but you can create the same effect yourself. Check out Douglas Crockford's explanation for the details. Crockford is an opinionated genius when it comes to JavaScript, and he's the brains behind JSLint and JSON.

Never store intermediate program state in DOM?

I managed to run into this funny bug the other day where too quick modifications of the DOM caused the entire internet explorer to crash. So i was thinking, why am i even setting these values if i'm going to change them later anyway? (the modifications are very unpredictable so completely avoiding the scenario is impossible)
Some background, my website is more like a game/application and has alot of custom elements etc. Performance is key and moving around and modifying objects should be fast, smooth and without flicker. In one iteration tons of objects can have their state modified.
The objects in my application right now follows something similar to this pattern. domElement is the actual element used in the DOM, created with document.createElement or getElementById.
function SetWidth(w) {
this.width = w;
this.domElement.style.width = w + "px";
}
Obiously an object has more styles than just width but just to simplify things. This works pretty well right now but what if i for some reason set the width of one object twice inside one "program loop". This will mean the DOM will be modified twice but it's only the second state that should be displayed. In most new browsers this doesn't make a difference because the page is not rendered until all user javascript has completed. But in some browsers you can get updates unpredictably anytime. And even if there is no visible change, does it impact the performance?
Another problem is that some elements depend on being attached to the DOM before you can set/get some properties on them which you can easier avoid with the pattern below.
What i was thinking of doing instead was going back to the old-school render-loop pattern.
So the above object would look like this:
function SetWidth(w) {
this.width = w;
this.stateChanged = true;
}
function Render() {
if(this.stateChanged)
this.domElement.style.width = this.width + "px";
}
Once the "program-loop" is done you loop through every object only to "render" them (or use some more sophisticated structure keeping track of all modified objects).
To me this seems like defeating the whole purpose of having the DOM as you are basically reinventing what is already in place but sometimes it feels like it doesn't work properly so you have to roll your own version.
Has anyone used something similar and is it worth it? What are the pros and cons? What else do i have to think of? Adding and removing objects and managing z-index also should be taken into consideration.
One of the things to watch out for is that if you request the value of property that is dependant on the layout, the browser will recalculate the layout to get the value, which may take a significant amount of time. So "this.style.width = '80px'" will be quick but "this.style.width = '80px'; var wid = this.clientWidth;" will take much, much longer. Of course, if you use the setWidth/render pattern above, you won't be able to get the value of
clientWidth until after the render phase.
The setWidth/render pattern is a reasonable one for your use case, but I'd create a sub object to hold the pending layout values rather than storing them directly on the 'this' object. If you empty/recreate the sub object at the end of the render step, you won't need to store a separate stateChanged variable, the presence of the property in the sub object can serve that purpose.

Override "private" function in JavaScript

I'm monkey-patching some of the jQuery's Draggable code*.
The goal is to avoid modifying the original source files and patch dynamically one of the internal functions.
The function _generatePosition is declared like this:
(function($) {
$.widget("ui.draggable", $.ui.mouse, {
...
_generatePosition: function(event) {
...
}
}
})(jQuery);
Is it possible to achieve the dynamic replacement of it?
*So it calculates the snapping grid relative to the top of parent element and not relative to the top of element being dragged. See here for more details.
You can manipulate individual instances:
.draggable().data("draggable")._generatePosition = function() {};
Or modify the prototype, affecting all instances:
$.ui.draggable.prototype._generatePosition = function() {};
You can actually modify these, but only on a per-element basic as far as I know. But you could easily create your own $.fn.draggable wrapper, and just call the original wrapper and run this: draggableElement.data('draggable')._generatePosition = fn
As Jörn Zaefferer pointed out, you could also modify the draggable prototype, by using $.ui.draggable.prototype._generatePosition = fn
Edit for below comments: It seems you can edit these (after the last widget re-write), but I would still steer clear. Here's an example of the base method, you can modify from there if you wish, but keep in mind this can and probably will break in a future release. Also any "inheritors" of the widget won't pick up these changes, not sure if that's an issue.
As for the reason, to deny you access isn't the reason really (not in this case). In library cases like this it's more to be clean than deny you access, or because the library may want to change architecture later, and still break as few people as possible when they do so...letting you only access the "public" members of their code gives the authors more flexibility in changing anything that's "private".
Case in point: jQuery UI 1.8 moved a lot of code into the position utility, allowing a lot of private code cleanup that you didn't see happen, since it was all private before this allowed a fairly big optimization/code reduction without breaking people left and right.

Categories

Resources