Tag Archives: MVC

Django & Angular overview

Angular is what HTML would have been if it had been designed for building web applications”

What problem does Angular solve?

It separates your javascript models, views and controllers – just like Django does for your server-side code.

It does so using “two-way data-binding”: whenever the model changes, the view changes as well – and vice versa.

Pros and Cons of Angular

Angular has a rich ecosystem of modules, eg. Ionic for mobile app development.

However, Angular 2 (to be released in 2015) will not be easily backwards compatible. Angular 1 may not be supported for much longer (18 months?).

Plenty of alternatives exist – check them out at ToDo MVC.

One that is gaining popularity is React – “a javascript library for building user interfaces”. Mark Finger has written a helpful package called django-react to make this easy to use in Django.

A quick Angular demo

Eg. see the code snippets on the Angular home page.

What tools make it easier to use with Django?

Server-side:

  • Django-angular – lots of useful utilities to help the two work together, especially around forms and template sharing; there is also support for ‘three-way’ data-binding (ie. the server detects when the client’s model changes – and the server can modify values on the client side without the client needing to poll).
  • Django REST framework or TastyPie – since your Django app’s API is now its main feature
  • Django-compressor or django-pipeline – because you will have dozens of little js files defining your Angular components

Client-side:

  • Grunt or gulp – to automate javascript necessities like minification, compilation, unit testing, linting, etc
  • Npm or bower – like pip install for your javascript packages
  • Angular has lots of modules you can add, eg. ngDialog and AngularUI
  • Don’t use the default angular router; ui-router is better.

And Yeoman – a “generator ecosystem” – although there is no django + angular generator yet.

What practices make it easier to use with Django?

This section derived from the excellent Thinkster tutorial Build Web Applications with Django and AngularJS.

Angular directory structure (in the project directory root):

  • /static/javascripts/<ng_app_name>.config.js
  • /static/javascripts/<ng_app_name>.js
  • /static/javascripts/<ng_app_name>.routes.js
  • /static/javascripts/<ng_module_name>/<ng_module_name>.module.js
  • /static/javascripts/<ng_module_name>/controllers/<controller_name>.controller.js, …
  • /static/javascripts/<ng_module_name>/directives/<directive_name>.directive.js, …
  • /static/javascripts/<ng_module_name>/services/<service_name>.service.js, …
  • /static/templates/<ng_module_name>/<ng_template_name>.html, …
  • /templates/<django_template_name>.html, …
  • /templates/javascripts.html

urls.py

urlpatterns = patterns(
    '',
    url(r'^admin/', include(admin.site.urls)),
    url(r'^api/v1/', include(router.urls)),
    # pass everything else through to Angular
    url('^.*$', IndexView.as_view(), name='index'),
)

views.py

from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.generic.base import TemplateView
from django.utils.decorators import method_decorator

class IndexView(TemplateView):
    template_name = 'index.html'

    @method_decorator(ensure_csrf_cookie)
    def dispatch(self, *args, **kwargs):
       return super(IndexView,self).dispatch(*args,**kwargs)

Testing frameworks

There are many javascript testing frameworks available, eg. mocha and jasmine.

What problems have people had?

Please let me know!

Resources – Tutorials

What is this post anyway?

These are some questions for and notes from the SyDjango meetup on Angular in January 2015.

  

Controlling character movement with Box2D

So – the next challenge is a nice way to move the player’s character with Box2D. I would like the user to touch a spot in the game, and have the character try to move to that location (noting that the place on the screen may be different if the world scrolls).  The character should move at constant speed while on the ground, and follow normal physics while falling. I also like the little bounce the character gets with Box2D on landing on the ground after a fall.

For now, I am just representing the character as a ball, but ignoring its rotation for drawing.  I realise now this representation actually matters, since a ball rolls along the ground differently to how a box slides. If I need more realism, I expect to replace the ball representation with a small ball for the legs and a custom shape for the body, with a (wheel?) joint holding the two together, like a car.

Here are some alternatives:

  1. Apply an impulse to the character every update (1/60th of a second)
    I was using code like this in GameElement:

    -(void) applyImpulseToVelocity:(Point3D)targetVelocity {
        b2Vec2 vel = self.body->GetLinearVelocity();
        float dvx = targetVelocity.x - vel.x;
        float dvy = targetVelocity.y - vel.y;
        float mass = self.body->GetMass();
        self.body->ApplyLinearImpulse( b2Vec2(mass * dvx,mass * dvy),
                   self.body->GetWorldCenter() );
    }

    The target velocity is basically proportional to the distance between the character’s current location and the touch location (modified so that the character can’t fly).
    The problem is, this doesn’t look realistic at all: when the character is falling, gravity has very little effect on it – it just drifts down slowly.

  2. Use a mouse joint
    This is inspired by Ray Wenderlich’s breakout tutorial. According to the Box2D manual, a mouse joint attempts to drive a point on the body to the target. It required a bit of a rewrite of GameElement and GameModel, because the mouse joint needs to know the world and the ground body, which I was hoping to isolate from the GameElement.
    Quite an interesting effect: the character speeds to the touched location and then spins around it at a small radius as if on a rope.  Gravity does act on it at this point, if not while it speeds along. Not the game play I was after.
    Also, the manual advises “Many users have tried to adapt the mouse joint for game play. Users often want to achieve precise positioning and instantaneous response. The mouse joint doesn’t work very well in that context. You may wish to consider using kinematic bodies instead.” Hmmm… kinematic bodies, the manual says, do not respond to forces, and do not collide with static or other kinematic bodies. You normally move them by setting their velocity.  I don’t think I’ll pursue this option: I definitely want forces to apply in some situations, and want them to collide with static bodies.

  3. Apply an impulse to the character every update (1/60th of a second), but only when in contact with the ground or a platform
    This approach most closely matches the description of what I want. It felt like a hack but in fact, humans can only propel themselves when on the ground, so it is (somewhat) realistic. With the contact listener already working, this was not too hard to implement. The main work was changing the ground to a GameElement (it was previously just a part of the GameModel), and setting user data for the ground, platforms and ladders as well as animals. The contact listener needs the user data to send a begin/end contact message to the object.
    This is virtually the same as option 1 above, but is only applied if a flag is set on the character’s GameElement saying that it is in contact with the ground, a platform or a ladder.  In fact all these are subclasses of the Platform class, so the test is very simple.
    Great news – this works pretty well!

Nonetheless I expect this is not the end of the story…

  

Cocos2D, Box2D and MVC

As I indicated in my last post, I am going to write my kids’ game in Cocos2D. After implementing the simple bear animation tutorial from Ray Wenderlich, I had a few questions:

  1. How do you use automatic reference counting (ARC) with Cocos2D? The approach I’ve taken is to follow this blog by Steffen Itterheim.
  2. How do you write code with Cocos2D (and maybe with Box2D) in an MVC (model-view-controller)-compliant way?  The approach I’ve taken is to follow this blog and its sequel by Bartek Wilczyński.
  3. How do you add Box2D to the project once you’ve already started it (and continue to use ARC)?  The approach I’ve taken is to make it a static library by following this blog by Red Glasses. This is a pretty involved procedure but does the job. I imagine you can do point (1) above using this approach too – it would be nice to be consistent – but I have not tried this.

I’ve done all this and got it all running, and I thought others may find it helpful, so I have put the result on github at https://github.com/RacingTadpole/Cocos2D-Box2D-MVC-example. You are welcome to download it as a starting point for your own projects, or just to poke holes in it (but please tell me what they are!). The frame rate seems to be only 20-30 frames per second on the simulator, but on a real device it is close to 60, and I have read elsewhere that this stat should be ignored on the simulator anyway. Edit – the project on GitHub was compiled using a slightly older version of XCode, and the latest XCode complains when I try to run it on a device (ld: file is universal (2 slices) but does not contain a(n) armv7s slice: …./libbox2d-lib.a for architecture armv7s ). For now I am solving this by setting “Build Active Architecture Only” to “Yes” in the target’s build settings (see this stackoverflow question), but in the long run it looks like I’ll need to redo step 3 above using the latest XCode.

The game as it stands (called Zambazi) simply involves a host of monkeys and bears falling from the sky onto a grassy foreground, and bouncing like rubber balls. When you touch anywhere, all the animals are hit with random forces.  It’s not much, but my kids find it surprisingly engrossing! They decided you win if you can make all the bears run off the screen before the monkeys… Maybe I’m not so far from the App Store after all? :-)

All images are from Ray & Vicki Wenderlich’s sites – thank you both for making these freely available!

Here’s the basic structure/flow:

GameController

When PLAY is pressed, a GameController is initialized.  The gameController has a GameView and a GameModel, each of which is initialized. The gameController also schedules the updates.

GameView

The gameView has a delegate (actually the gameController) which currently does nothing, because it doesn’t need to know which sprite you’ve touched. This delegate may be useful if you do need to know – see Bartok’s blog for his vision here. In fact I’m planning instead to remove this delegate and simply register the controller with Cocos2D as a touch delegate, as described here.

The view creates the necessary layers:

GameLayer

The gameLayer is in charge of all the sprites. It knows nothing about the view or the controller, but does have a reference to the model. It also registers itself as an observer of notifications from the model. The notifications are:

  • Model initialization – this is so that the gameLayer can get a reference to the model in the first place.
  • Revise game elements – this is so that it can set up the sprites that correspond to the model.

The gameLayer starts by loading in all the sprites for the game, and setting up their actions (CCAction).  I am sure there is a much better way to do this – but this does the job for now.

It also keeps track of which actions are running. This seems an unfortunate complication, but as far as I know, you need to do this so that you can stop the action later. If you can get away with stopping all actions on a sprite – and maybe you can – then you could remove this stuff and use stopAllActions instead.

The gameLayer does not know about Box2D – I see that as a model-level thing.  The gameElements provide their own velocity, where, rotation etc methods.  I have defined a Point3D structure to pass around points – this was when I was thinking the model may have a 3D world even if the view is only 2D.  However, with Box2D, the third dimension is irrelevant – so it would be simpler to just use CGPoint for example.  I am leaving Point3D nonetheless so that if you want to use this code with a 3D model (without Box2D), it shouldn’t be too hard to adapt it.

The other trick is that gameLayer has an NSDictionary (called sprites), with the gameElements as keys and the sprites as the objects. The complication is that NSDictionary copies its keys before it uses them, so that the key winds up being a different object to what you requested.  The solution (implemented in my code) is to override copyWithZone: to return self, without copying, as described in this stack overflow post.  I am assured this is good practice if the object is immutable. All this may be too tricky by half, but it seemed sensible at the time, and works fine.

GameModel

The game model is the Box2D world, and an array of the game elements. When createGameObjects is called (by the Controller – this could equally well be part of the initialization), it sets up some default game elements. It has an update: method which uses Box2D to update the physics; optionally each element may have its own additional update behaviour (I have adopted Bartok’s “Updatable” protocol).

GameElement

The gameElements are the models of the platforms, the enemies, etc.  They basically have a Box2D body and a name.  The name is used by the gameLayer to work out what sprite to show. The gameElement uses Box2D to provide where, velocity and rotation methods, so the body variable itself is kept private (i.e. in a class extension).

I am subclassing GameElement (e.g. Animal) to provide different behaviour for different models.

Technical note – so that subclasses can still access the body variable, I have declared body in a class extension header file called GameElements_Private.h.  Then GameElements.m and Animal.m both import GameElements_Private.h instead of GameElements.h, so that they can refer to body.

Further ideas

As I start to turn this into a functioning game, I have found two further issues, one conceptual, one practical:

  • It’s nice to cleanly separate the model from the view – but the image you are using is a particular size, and I’m finding the model sometimes needs to know this size (so you don’t have to scale the image). I’m solving this with another delegate pattern.  I’ve introduced a NaturalSizeProtocol, which the GameLayer and the GameView follow.  The GameModel then has a naturalSizeDelegate.  When a gameElement needs to know its natural size (i.e. the size the view wants to make it), it asks its naturalSizeDelegate.  This returns the size in model co-ordinates (as a Point3D).  This feels like a contortion of MVC, so I’d love to hear if anyone has a better solution to this.  It has left me wondering if MVC is more trouble than it’s worth after all for image-intensive games.
  • Getting a background image to repeat in Cocos2D is hard.  I have only managed it so far by loading the background image multiple times, which doesn’t seem right.

That’s it for now.  Please let me know if you find this useful, or have any suggestions.

Edit – I have just come across Steffen Itterheim’s excellent post on exactly this subject, which inspired him to write KoboldTouch. Together with problems I am having getting Lua to compile in my Cocos2D/Box2D project, I am starting to wish I had used Kobold2D…