Sunday, 27 April 2014

Corona and the Model-View-Presenter pattern (Part 4)

Hi, and welcome to part 4 of my seven part introduction to Model View Presenter.

First up, the answers to the exercises from Part 3.

1) The background in this case is purely part of the view - it is purely decorative. It doesn't interfere with or even affect the game logic, or the model at all. If it was an 'active' background - say there were obstacles to bounce off, it would have some information about those in the model.

2) Changing the bat height (e.g. thickness) is also view only. In some games - say if there was a second bat half way down the screen - it could have a thickness in the model.

This time, we're going to add something to the game - the ball. The games a bit dull at the moment ... okay, it's very dull.

However, it's just going to be a ball - no actual ball movement (that's in part 5). So this involves changes to the model (the ball data) and the view (the ball representation), there is no 'game logic' for the ball (at the moment).

First to the model. The model needs data representing the various bits of the ball. This involves one new line, as we are doing it all in one go, in model.lua

function model.initialise()
model.bat = { x = 160, y = 440, width = 60 } 
model.bat.dx = 0 
model.bat.speed = 5
model.ball = { x = 100,y = 100, dx = 1,dy = 1,speed = 10, radius = 10 }

So our ball has a position, a vector, a speed, and a radius in the model.

Our view (in view.lua) needs to take this information and render it on the display. So we add this to the 'initialise' function, at the end

view.ballObject = display.newCircle(1,1,12) -- create a ball object (part 4)
view.ballObject:setFillColor( 0,1,1 ) -- make it cyan
view.ballObject.strokeWidth = 2
view.ballObject:setStrokeColor( 0,0,0 )

creating a circle with a border representing the ball. This means it is created when the view is initialised (if you were using composer it would create it response to the 'create' event)

In the update routine, it needs to update the relevant parts of the view from the model, i.e.

function view.update(model)
view.batObject.x = model.bat.x -- update the view from the model.
view.batObject.y = model.bat.y
view.batObject.width = model.bat.width

view.ballObject.x = model.ball.x -- update the ball (part 4)
view.ballObject.y = model.ball.y
view.ballObject.radius = model.ball.radius

Running this will give you an app that looks something like this. As with the last time, though I've added something.

The completed code for part 4 is at

That's the exercise for today, add a score to the game.

Q: What do you add to the view and model ? What is the data that represents the score ? What is the visible thing that represents the score ? Where does each go ?

Q: What, if anything, happens in the presenter ?

A note on Physics

One of the problems with developing games using this structure, or similar structures, is that it is often running counter to the way Corona likes things - everything stuck together.

The Physics engine, for example, operates directly on the display objects, the view. This means that - pretty much - you can't use the Physics Engine a great deal.

One of the concepts of MVP, or indeed any system which separates the model and the view, is that you can replace the view with anything you like, pretty much. Suppose you wanted to have a vector representation, or a Retro look or whatever, or even display it on an external LED panel, you can do all these without changing anything other than a view. You could change it to a first perspective 3D game, and again, you'd change nothing other than the view.

Another advantage, especially if you use more Object Orientated programming, is that you can test things in isolation, even without any view at all. Everything isn't glued together.

It's really a case of pays your money and takes your choice :)

No comments:

Post a Comment