Space Invaders Tutorial
In this tutorial, we will create a space invaders clone. This tutorial will primarily be focused on creating more game elements through code, and using other APIs that MelonJS provides, that the platformer tutorial does not cover.
Introduction
To work through this tutorial, you need the following:
- The melonJS boilerplate, that we will use as default template project for our tutorial.
-
The tutorial image assets, to be uncompressed into the boilerplate data directory. So when you unzip, you should have:
data/img/player.png data/img/ships.png js/game.js etc
- The melonJS library. If you downloaded the boilerplate, you will already have this. It should be copied under the /lib directory. You can copy the development version, as the boilerplate provides a minification task.
- The melonJS documentation for more details
Testing/debugging :
Your best bet is to use a local web server, as for example detailed in the melonJS boilerplate README, by using the `grunt connect` tool, and that will allow you to test your game in your browser using the http://localhost:8000 url.
If you just want to use the filesystem, the problem is you'll run into "cross-origin request" security errors. With Chrome, you need to use the "--disable-web-security" parameter or better "--allow-file-access-from-files" when launching the browser. This must be done in order to test any local content, else the browser will complain when trying to load assets through XHR. Though this method is not recommended. As long as you have the option enabled, you're adding security vulnerabilities to your session.
 For this tutorial there are some files that we will not need. You can delete the file screens/title.js, and remove the entire js/entities folder. Then update the index.html file to no longer include those, and remove the references of TitleScreen from the game.js file.
var game = { // Run on page load. "onload" : function () { // Initialize the video. if (!me.video.init(640, 480, {wrapper : "screen", scale : 'auto'})) { alert("Your browser does not support HTML5 canvas."); return; } // add "#debug" to the URL to enable the debug Panel if (document.location.hash === "#debug") { window.onReady(function () { me.plugin.register.defer(this, me.debug.Panel, "debug", me.input.KEY.V); }); } // Initialize the audio. me.audio.init("mp3,ogg"); // Set a callback to run when loading is complete. me.loader.onload = this.loaded.bind(this); // Load the resources. me.loader.preload(game.resources); // Initialize melonJS and display a loading screen. me.state.change(me.state.LOADING); }, // Run on game resources loaded. "loaded" : function () { // set the "Play/Ingame" Screen Object this.playScreen = new game.PlayScreen(); me.state.set(me.state.PLAY, this.playScreen); // start the game me.state.change(me.state.PLAY); } };
Game.js is where the game is bootstrapped. index.html calls the game.onload function after loading all the js files in the window ready event. The me.video.init bit creates the canvas tag and gets the video setup.
Lines 12-16 are for using the debug panel.
Then we intialize the audio engine, telling it what formats we are supporting for this game.
We set a callback on me.loader to our loaded function, and then tell what assets it needs to load, via an array.
The final step of this process is setting the state of the game to loading.
"loaded" : function () { this.playScreen = new game.PlayScreen(); me.state.set(me.state.PLAY, this.playScreen); // start the game me.state.change(me.state.PLAY); }
The loaded function then sets up the playscreen and tells the game to use that screen object for the play state.
Then the game state is set to PLAY.
Back to space invaders
The first thing to add is images to the resources.js file.
game.resources = [ { name: "player", type: "image", src: "data/img/player.png" }, { name: "ships", type: "image", src: "data/img/ships.png" } ];
This variable is the one passed to me.loader.preload in game.js
The structure for an asset is :
| name | The name of the asset you wish to use in your game. A string key. |
| type | The type of the asset. Valid types are: audio, binary, image, json, tmx, tsx. Binary is a good solution for loading raw text, or any other format not listed. TMX & TSX are for tiled file formats. Whether it be the xml or json format. |
| src | The path to the asset, relative from index.html. For audio you need specify the folder instead of direct path. |
Open js/screens/play.js and empty the code from the two methods: onResetEvent and onDestroyEvent. Then save, and then open the game in your web browser.
There is not much to see yet. Let's change that.
First thing is to create a player entity.
Add a new file under the js folder, and call it player.js. Be sure to add it in the index.html file.
game.Player = me.Sprite.extend({ init: function () { var image = me.loader.getImage("player"); this._super(me.Sprite, "init", [me.game.viewport.width / 2 - image.width / 2, me.game.viewport.height - image.height - 20, { image: image }]); } });
So what we're doing is adding a function to the window.game object that extends me.Sprite. It sets up an init method that grabs the player image.
For the x coordinate, we simply grab the dead center, and subtract half the ship, so it can be positioned in the center. And then set its y property to be 20 pixels above the bottom. Then finally pass the image instance to it.
Calling this._super is how we reference a parent classes' method. In this case, we're calling the me.Sprite contrusctor.
Let's setup the player in the entity pool. Open game.js and add the following at the top of the loaded method:
me.pool.register("player", game.Player);
Now open up js/screens/play.js, and edit the onResetEvent method so it looks like this:
game.PlayScreen = me.ScreenObject.extend({ /** * action to perform on state change */ onResetEvent: function() { me.game.world.addChild(me.pool.pull("player")); }, /** * action to perform when leaving this screen (state change) */ onDestroyEvent: function() { } });
The onResetEvent is called when this state is loaded. So when invoking
me.state.change(me.state.PLAY);
In the game.js file, onResetEvent is then called.
Yay, the ship is on the bottom of the screen!
But we can still see the loading bar, that's not cool. The reason for this is that MelonJS does not want to do any operations that it doesn't have to. Sometimes you'll have a background image that gets redrawn, so it covers the original loading bar. However, we don't have a background image for this game, so what we will do is add a color layer.
me.game.world.addChild(new me.ColorLayer("background", "#000000", 0));
Add that in the play screen, above the line where we added the player. The first parameter is simply the name for the layer, so it's easy to fetch from the game world later if you need to.
The second parameter is the color to draw in hex.
The last is the z index. We want it to draw first, so we set it at zero. The z-index can also be passed with addChild:
me.game.world.addChild(new me.ColorLayer("background", "#000000"), 0);
Now the pesky loading bar should be gone. Time to add in an enemy. Create a new file under the js folder called enemy.js, and add it to the index.html file.
Since enemies will have to collide with things like the player's laser, it should extend me.Entity as opposed to me.Sprite, so lets get that going:
game.Enemy = me.Entity.extend({ init: function (x, y) { this._super(me.Entity, "init", [x, y, { image: "ships", width: 32, height: 32 }]); } });
With the enemy, we will need to place them in different spots, so x & y will be added to its constructor, and then passed along to the me.Entity's constructor. The third parameter in the array is a hash of settings. The settings specifies the image as "ships", referencing our game.resources array. The width and height are set to 32x32.
In game.js, add the enemy to the entity pool:
me.pool.register("enemy", game.Enemy);
Back in play.js, add an enemy to the game world. Your play.js should now look like:
game.PlayScreen = me.ScreenObject.extend({ /** * action to perform on state change */ onResetEvent: function() { me.game.world.addChild(new me.ColorLayer("background", "#000000", 0)); me.game.world.addChild(me.pool.pull("player")); me.game.world.addChild(me.pool.pull("enemy")); }, /** * action to perform when leaving this screen (state change) */ onDestroyEvent: function() { } });
You can put the enemy at any x & y to try it out. Save & refresh the page in your browser.
You'll likely notice that the ship is constantly changing how it looks. If you open the ships.png file under data/img, you can see that it is a sprite sheet containing 4 different ships. me.Entity for its renderable uses the me.AnimationSheet class. Since we didn't add and set any animations on the renderable property, it is just looping through each & every frame. Let's fix that.
Add a new method to our enemy:
chooseShipImage: function () { var frame = ~~(Math.random() * 3); this.renderable.addAnimation("idle", [frame], 1); this.renderable.setCurrentAnimation("idle"); }
The first line simply randomizes which frame we want. The ship is 32x32, the image is 64x64, so we have 4 frames. ~~ is a shortcut for Math.floor when the number is 0 or positive. On negative numbers, it works like Math.ceil.
The second line is accessing the animation sheet instance (this.renderable), and uses the addAnimation function to add a new idle frame. So we simply specify the index that was generated at random.
With the final line, we set the current animation to idle.
Now call the function at the bottom of the constructor, like so:
game.Enemy = me.Entity.extend({ init: function (x, y) { this._super(me.Entity, "init", [x, y, { image: "ships", width: 32, height: 32 }]); this.chooseShipImage(); }, chooseShipImage: function () { var frame = ~~(Math.random() * 3); this.renderable.addAnimation("idle", [frame], 1); this.renderable.setCurrentAnimation("idle"); }, });
Now refresh the page, and our ship should only pop up as one of them. Try refreshing it multiple times to see it change.
Applying Movement
Now that we have ships on screen, let's actually get some interaction going.
Back in play.js, lets add some keybindings:
game.PlayScreen = me.ScreenObject.extend({ /** * action to perform on state change */ onResetEvent: function() { me.game.world.addChild(new me.ColorLayer("background", "#000000", 0)); me.game.world.addChild(new game.Player(), 1); me.game.world.addChild(new game.Enemy(50, 50), 2); me.input.bindKey(me.input.KEY.LEFT, "left"); me.input.bindKey(me.input.KEY.RIGHT, "right"); me.input.bindKey(me.input.KEY.A, "left"); me.input.bindKey(me.input.KEY.D, "right"); }, /** * action to perform when leaving this screen (state change) */ onDestroyEvent: function() { me.input.unbindKey(me.input.KEY.LEFT); me.input.unbindKey(me.input.KEY.RIGHT); me.input.unbindKey(me.input.KEY.A); me.input.unbindKey(me.input.KEY.D); } });
The method calls here are pretty straight forward. We bind a keypress to an action name. Multiple keys can be assigned to a single action name.
It's typically a good game design practice to offer multiple key bindings. Even a better practice make it configurable. You always need to keep in mind people who are left handed or who have different layouts.
You might also noticed i added the z index option to the addChild calls. It's a pretty good practice, because that way you ensure your draw order.
The onDestroyEvent removes the events when changing state. Not something we actually need, because we only have the play state after loading. But a good practice to keep in mind.
Now that we have bindings, let's implement player movement. Add the following update function to the player class:
Then add a velx property to the player in its init method, as well as the furthest x position it can go on screen (maxX):
init: function () { var image = me.loader.getImage("player"); this._super(me.Sprite, "init", [me.game.viewport.width / 2 - image.width / 2, me.game.viewport.height - image.height - 20, image]); this.velx = 450; this.maxX = me.game.viewport.width - this.width; },
Then modify the update method to check for the key events, and move the player accordingly.
update: function (time) { this._super(me.Sprite, "update", [time]); if (me.input.isKeyPressed("left")) { this.pos.x -= this.velx * time / 1000; } if (me.input.isKeyPressed("right")) { this.pos.x += this.velx * time / 1000; } this.pos.x = this.pos.x.clamp(0, this.maxX); return true; }
Update functions of our game objects will always receive a delta time (in milliseconds). It's important to pass it along to our parent's class update.
this._super(me.Sprite, "update", [time]);
After that, it's a matter of checking if the left action is currently pressed. Using the velocity value set earlier, we simply subtract the velocity value, multiplied by the delta in seconds.
if (me.input.isKeyPressed("left")) { this.pos.x -= this.velx * time / 1000; }
To move right, we check for the right action, and add the velocity value to our x position.
if (me.input.isKeyPressed("right")) { this.pos.x += this.velx * time / 1000; }
We then use clamp to ensure the x value does not go outside the screen.
this.pos.x = this.pos.x.clamp(0, this.maxX);
The return value tells melon whether a re-draw is required. This can be useful to dictate for when an animation sheet needs to animate on a given frame. However, this is a single sprite, so we can just tell it to redraw.
return true;
Save the file & refresh your browser. Try using A/D or the Left & Right arrow keys to move.
Enemy movement
A defining characteristic of space invaders is that all the ships move in one direction, shift down and then go in the other direction. They all move together. We could take the velocity logic that we used for the player, and apply it to the enemy class. But we can better leverage MelonJS to do this for us. Time to use our own subclass of me.Container
Objects inside a container are relative to its parent. So when we move the container, all objects inside shift with it. This applies to rotation & scale operations as well. So let's create one.
Create a new file: js/enemy_manager.js, and add it to the index.html.
game.EnemyManager = me.Container.extend({ init: function () { this.COLS = 9; this.ROWS = 4; this._super(me.Container, "init", [0, 32, this.COLS * 64 - 32, this.ROWS * 64 - 32]); } });
Essentially what we're setting up here is the start position and the base width. Starting the container 32 pixels down, and at 0 left (or x).
We're allotting 64 pixels per ship width & height wise. Then subtracting 32 pixels because the last row & column does not require the side padding.
For adding enemies to our container, we need another method:
createEnemies: function () { for (var i = 0; i < this.COLS; i++) { for (var j = 0; j < this.ROWS; j++) { this.addChild(me.pool.pull("enemy", i * 64, j * 64)); } } }
Generating 9 columns, and 4 rows: 36 ships.
Now in play.js, remove the addChild for the enemy, and set a property to an enemy manager.
For movement, let's keep it simple and have the container move once per second. For this, we can use a melonjs timer.
Add these two methods to the enemy_screen.js
onActivateEvent: function () { var _this = this; this.timer = me.timer.setInterval(function () { _this.pos.x += _this.vel; }, 1000); }, onDeactivateEvent: function () { me.timer.clearInterval(this.timer); }
And then set the vel property in the init method to 16:
this.vel = 16;
onActivateEvent is called (if it's defined) when the object is added to the game world. This goes for any object you pass to addChild on a container. Likewise, onDeactivateEvent is called when the object is removed from the game world.
Using the MelonJS version of setInterval (which is built into the game loop, it does not use window.setInterval), we can then increment the x position.
Save and refresh the browser. The enemy ships now all move together, however they just kinda drift off screen, and don't move down. So let's improve the code adjusting the container position.
First we need to add a rectangle property to track the size of the container:
this.childBounds = this.getBounds().clone();
This takes the current defaults bounds and clones it to a new instance of me.Rect
Then lets re-implement the addChild method to update this new rectangle:
addChild: function (child, z) { this._super(me.Container, "addChild", [child, z]); this.resizeChildBounds(); }
Then add the removeChildNow counterpart:
removeChildNow: function (child) { this._super(me.Container, "removeChildNow", [child]); this.resizeChildBounds(); }
The reason for extending removeChildNow instead of removeChild, is removeChild is called after the current frame finishes. removeChildNow is the method that actually removes the object, and we want to resize the bounds after the object has been removed.
Now add the resizeChildBounds method to the enemy_manager:
resizeChildBounds: function () { this.childBounds.pos.set(Infinity, Infinity); this.childBounds.resize(-Infinity, -Infinity); for (var i = this.children.length, child; i--, (child = this.children[i]);) { if (child.isRenderable) { this.childBounds.union(child); } } }
What this does is uses the union method of me.Rect to determine the minimum bounds that contains all the children. This will determine the width & height values of our container.
onActivateEvent: function () { var _this = this; this.timer = me.timer.setInterval(function () { var bounds = _this.childBounds; var right = _this.pos.x + bounds.right; var left = _this.pos.x; if ((_this.vel > 0 && (right + _this.vel) >= me.game.viewport.width) || (_this.vel < 0 && (left + _this.vel) <= 0)) { _this.vel *= -1; _this.pos.y += 16; if (_this.vel > 0) { _this.vel += 5; } else { _this.vel -= 5; } } else { _this.pos.x += _this.vel; } }, 1000); }
That's a fair bit of code, so let's break it down.
Using the child bounds, we setup the left & right values to world coordinates.
var bounds = _this.childBounds; var right = _this.pos.x + bounds.right; var left = _this.pos.x;
The first part of the if checks if the container is moving right, and the right edge + velocity is outside the viewport.
(_this.vel > 0 && (right + _this.vel) >= me.game.viewport.width)
The second part checks if the container is moving left, and its left bounds is less than zero.
(_this.vel < 0 && (left + _this.vel) <= 0)
In the block, we reverse the velocity, move down by 16 pixels and then increase the velocity.
_this.vel *= -1; _this.pos.y += 16; if (_this.vel > 0) { _this.vel += 5; } else { _this.vel -= 5; }
Then the last bit, we increment the velocity if the container hasn't moved left or right
else { _this.pos.x += _this.vel; }
Save and refresh this time, it will now move back and forth across the screen, closer to our player.
Adding Lasers, pew pew!
Time to get some actual “game” in this game.
First thing to do is open up your play.js file, and add a new keybind & unbind:
me.input.bindKey(me.input.KEY.SPACE, "shoot", true);
me.input.unbindKey(me.input.KEY.SPACE);
The reason for the boolean in the bindKey call is to only allow on register per key press. So in order to shoot twice, the player must press the space bar, release it, and then press it again.
Before we wire up the player to shoot, we need a laser. Create a laser.js file, and add the following code to it. As always, be sure to add the laser.js script tag in the index.html file.
game.Laser = me.Entity.extend({ init: function (x, y) { this._super(me.Entity, "init", [x, y, { width: game.Laser.width, height: game.Laser.height }]); this.z = 5; this.body.addShape(new me.Rect(0, 0, this.width, this.height)); this.body.updateBounds(); this.body.setVelocity(0, 300); this.body.collisionType = me.collision.types.PROJECTILE_OBJECT; this.renderable = new (me.Renderable.extend({ init: function () { this._super(me.Renderable, "init", [0, 0, game.Laser.width, game.Laser.height]); }, destroy: function () {}, draw: function (renderer) { var color = renderer.globalColor.toHex(); renderer.setColor('#5EFF7E'); renderer.fillRect(0, 0, this.width, this.height); renderer.setColor(color); } })); this.alwaysUpdate = true; }, update: function (time) { this.body.vel.y -= this.body.accel.y * time / 1000; if (this.pos.y + this.height <= 0) { me.game.world.removeChild(this); } this.body.update(); me.collision.check(this); return true; } }); game.Laser.width = 5; game.Laser.height = 28;
So lets go through it. At the bottom, we have set two properties of width & height for the laser, so it can easily be re-used.
game.Laser.width = 5; game.Laser.height = 28;
Traditional stuff here. Setup the x & y position from its parameters, and a width+height properties. A bit different from our other objects, we have set the z index on the object manually. This is an alternative to passing the z index in the addChild call.
this._super(me.Entity, "init", [x, y, { width: game.Laser.width, height: game.Laser.height }]); this.z = 5;
These next methods for setting up a collision body.
this.body.addShape(new me.Rect(0, 0, this.width, this.height)); this.body.updateBounds(); this.body.setVelocity(0, 300); this.body.collisionType = me.collision.types.PROJECTILE_OBJECT;
The first adds a shape. While me.Entity creates a body for you, it does not assume a default shape. When creating an object in tiled, you are creating a shape, so that is provided as the default. We're not using tiled, so we shall create a rectangle.
this.body.addShape(new me.Rect(0, 0, this.width, this.height));
updateBounds() re-calculates the AABB bounds based off the shape we added.
this.body.updateBounds();
Now we set a velocity. Velocity is a vector, and we want the laser to move up. So set a velocity of 30. Note that velocity should never be negative to dictate direction.
this.body.setVelocity(0, 300);
Then we set a collision type. This is useful in collision callbacks.
this.body.collisionType = me.collision.types.PROJECTILE_OBJECT;
This is a fairly meaty bit of the code. me.Renderable is the base drawing class in melon. It gives the minimum setup required to be a valid drawing object in the game world.
this.renderable = new (me.Renderable.extend({ init: function () { this._super(me.Renderable, "init", [0, 0, game.Laser.width, game.Laser.height]); }, draw: function (renderer) { var color = renderer.globalColor.toHex(); renderer.setColor('#5EFF7E'); renderer.fillRect(0, 0, this.width, this.height); renderer.setColor(color); } }));
The init is pretty traditional, we set the x & y to zero, as this is going to be relative to the laser entity. Use the same width & height as the entity itself.
init: function () { this._super(me.Renderable, "init", [0, 0, game.Laser.width, game.Laser.height]); },
Then we implement the draw method. The classes we've used so far have provided a working draw method for our purposes, now we're going to use the renderer to draw something by hand.
draw: function (renderer) { var color = renderer.globalColor.toHex(); renderer.setColor('#5EFF7E'); renderer.fillRect(0, 0, this.width, this.height); renderer.setColor(color); }
The renderer can be either me.CanvasRenderer or me.WebGLRenderer, depending on your settings in me.video.init. The renderer provides basic drawing operations.
draw: function (renderer)
So we first get a reference of the original color. globalColor is an instance of me.Color.
var color = renderer.globalColor.toHex();
Set the color to a nice laser green.
renderer.setColor('#5EFF7E');
Then use a fill rect number. Again, 0, 0 is relative. Then use the width & height to dictate the size of the rect we're filling
renderer.fillRect(0, 0, this.width, this.height);
Then set the color back. This is important so our other draw calls will not be effected by the colour change.
renderer.setColor(color);
The final step for our Laser's init method:
init: function (x, y) { // ... this.alwaysUpdate = true; }
The alwaysUpdate property is to be avoided as much as possible. It will update an object when it is outside the viewport. The reason to use it in this game is because we don't want to remove the laser until it is offscreen. If we wait until it's offscreen, and alwaysUpdate is false, it will never get removed.
Speaking of the update method.
update: function (time) { this.body.vel.y -= this.body.accel.y * time / 1000; if (this.pos.y + this.height <= 0) { me.game.world.removeChild(this); } this.body.update(); me.collision.check(this); return true; }
The first bit is how we will move the laser. The ship was just moved by manipulating the position directly. Since this has a collision body, we will manipulate the y velocity, by subtracting the y acceleration.
this.body.vel.y -= this.body.accel.y * time / 1000;
If the position of the laser plus the height (so the bottom of the laser) is less than zero, we can remove the laser from the game world. Again, this will function now work because alwaysUpdate is set to true.
if (this.pos.y + this.height <= 0) { me.game.world.removeChild(this); }
The body update is very important, this applies the velocity we set for this frame.
this.body.update();
Then we tell MelonJS to check collisions against this object with me.collision.check(this).
me.collision.check(this);
The next step for this feature, is to add the laser to the entity pool. Add the following code to game.js, same as the Player & Enemy objects.
me.pool.register("laser", game.Laser);
Then back in the player.js file, add the laser shooting in the update method:
if (me.input.isKeyPressed("shoot")) { me.game.world.addChild(me.pool.pull("laser", this.pos.x + (this.width / 2 - game.Laser.width / 2), this.pos.y - game.Laser.height)) }
Reload the game, and try shooting. You should see the lasers fire. However they don't collide with anything.
Collisions
First lets give our Enemy a physics body. Append this to the init method in enemy.js
this.body.addShape(new me.Rect(0, 0, 32, 32)); this.body.setVelocity(0, 0); this.body.collisionType = me.collision.types.ENEMY_OBJECT;
Then add an update method so we can update the body:
update: function (time) { this._super(me.Entity, "update", [time]); this.body.update(); return true; }
Now lets add a collision handler to the laser.js file.
onCollision: function (res, other) { if (other.body.collisionType === me.collision.types.ENEMY_OBJECT) { me.game.world.removeChild(this); game.playScreen.enemyManager.removeChild(other); return false; } }
The res parameter that we are not using, is simply the collision result. So it contains details on how much overlap there was, where the collision was, etc.
Since we set the collision type on the Enemy's body to be an ENEMY_OBJECT, we can check for that type on the object the laser collided with.
if (other.body.collisionType === me.collision.types.ENEMY_OBJECT) {
Then we remove the enemy from the laser, along with the enemy from the enemyManager container.
me.game.world.removeChild(this); game.playScreen.enemyManager.removeChild(other);
The return false in this case isn't strictly necessary, but it's important to point out. When you return false from a collision handler in MelonJS, the object will pass through. If you return true, it will do a hard stop.
Save the changes, and reload your browser. You should now be able to take out the enemy ships.
Next step, is adding the win & loss conditions.
Win & Loss Conditions
The final step to this game is to actually add conditions for winning & losing. The conditions themselves will be pretty straight forward. When the ships get within range of the player, the player loses. When the player destroys all the enemy ships, they win.
So what happens when the game ends? A lot of the time you want to display a screen of some sort that the player lost or won. To keep this simple and show you another little trick, we'll just reset the game. So it starts over.
First, we'll do the loss condition
The pseudo code for this will be:
if enemy manager overlaps player then end game else continue end
The PlayScreen is our current game state. It holds the reference to the player, and it has the ability to reset the state. So let's add the logic for checking a lose condition there.
checkIfLoss: function (y) { if (y >= this.player.pos.y) { this.reset(); } },
Add that above the onResetEvent method. It accepts a Y value, and checks if it has surpassed the player. Then calls its reset method. The reset will wipe out every object from the game world, and reload the state. So it re-invokes onResetEvent, re-populating the enemies and player.
To call it, simply add it to our interval in the enemy manager:
this.timer = me.timer.setInterval(function () { var bounds = _this.childBounds; var right = _this.pos.x + bounds.right; var left = _this.pos.x; if ((_this.vel > 0 && (right + _this.vel) >= me.game.viewport.width) || (_this.vel < 0 && (left + _this.vel) <= 0)) { _this.vel *= -1; _this.pos.y += 16; if (_this.vel > 0) { _this.vel += 5; } else { _this.vel -= 5; } } else { _this.pos.x += _this.vel; } game.playScreen.checkIfLoss(_this.pos.y + _this.childBounds.bottom); }, 1000);
Since we're checking in the checkIfLoss method if the passed number is greater than the Y position of the player, we need to pass the bottom edge of the container. So we use the bounds.bottom and add the y position to it.
Save and refresh the browser. Let the enemies move around for a minute, and watch the game reset.
The Win Condition
Likewise, we'll just have the game reset once the player wins. Since we want to cause the win once all the ships are gone, we can check the length of the children on enemy manager.
First add this boolean to the bottom of the createEnemies method:
this.createdEnemies = true;
Add the following update method to the enemy manager:
update: function (time) { if (this.children.length === 0 && this.createdEnemies) { game.playScreen.reset(); } this._super(me.Container, "update", [time]); }
This is pretty simple. Children is an array, so we check its length to be zero, and ensure it has created enemies first. Without the boolean check, the game could keep resetting itself because it has no children yet.
Save and refresh the browser. Try to take out all the ships in time, and see the game reset.
Challenges
We left some parts out of this tutorial, so you could explore them yourself. This is an important part of programming and game development.
If you get stuck on any of the challenges or parts of the tutorial, please search for the problem, or ask us the question on our forum: https://groups.google.com/forum/#!forum/melonjs
Challenge #1
Add a proper win & loss screen
- These screens can be made by adding additional ScreenObjects to the game, register them in game.js, and then changing state. For what states to use for the win & screen, look at the states available: http://melonjs.github.io/docs/me.state.html
- The win and loss screen can contain a sprite, or text, or both. Whatever you wish really. Be sure to look at me.Font and me.Sprite. To display a me.Font object, use an instance of me.Renderable that contains an instance of me.Font, and implement the draw function to invoke me.Font#draw.
- Adjust the checkIfLoss method to show your new loss screen instead.
- Adjust the if block in the update method on EnemyManager, to change state to your win screneobject.
- Even more bonus, add a menu screen that tells the player how to play.
Challenge #2
Add a UI
- Add an enemy counter, and enemy velocity to the top right/left corner of the screen. These properties can be retrieved via: game.playScreen.enemyManager.children.length game.playScreen.enemyManager.vel
- Again look at me.Font, and implement a renderable for drawing text. Try to only use one class that extends renderable that can be used for both UI pieces.
- Add a score element. Keep track of the score on the play screen. Update it each time an enemy is killed. Remember that enemies are removed from the collision handler on the laser.
Challenge #3
Add the concept of levels
- After you defeat a wave, instead of refreshing the same wave, do a new wave the starts faster. The main logic here will be keeping wave count on the game.js, and increase it after each win. Then use that count in the enemy manager to configure the velocity.
- Have each wave progress faster too (+ 8 each Y increment over + 5 for example). Play with the numbers a bit until it feels right.


Introduction
Keywords
Comments
Identifiers
Basic Data Types
Constants
Variables
Basic Arrays
Expressions
Program Flow
Functions
Custom Types


JavaScript is disabled on your browser.
Skip navigation links
Overview
Package
Class
Use
Tree
Deprecated
Index
Help
Prev Letter
Next Letter
Frames
No Frames
All Classes
A
B
C
D
E
F
G
H
I
L
M
P
R
S
T
U
V
W
X
T
TabManager
- Class in
gamePlayer
TabManager(Store)
- Constructor for class gamePlayer.
TabManager
TabsList
- Class in
editor
TabsList()
- Constructor for class editor.
TabsList
TabsList(String[])
- Constructor for class editor.
TabsList
TabsListController
- Class in
editor
TabsListController(DataController)
- Constructor for class editor.
TabsListController
testAddedXMLCorrectly()
- Method in class gameEngineTests.
MapManagerTest
testFrom()
- Method in class gamedata.xml.
TestXML
TestObjectHolder
- Class in
gamedata.xml
TestObjectHolder()
- Constructor for class gamedata.xml.
TestObjectHolder
testTo()
- Method in class gamedata.xml.
TestXML
TestXML
- Class in
gamedata.xml
TestXML()
- Constructor for class gamedata.xml.
TestXML
TimerCondition
- Class in
conditions
TimerCondition(int)
- Constructor for class conditions.
TimerCondition
Tower
- Class in
units
Tower(String, double, double, String, Point, int, int, int)
- Constructor for class units.
Tower
Tower(Tower)
- Constructor for class units.
Tower
Tower()
- Constructor for class units.
Tower
TowersData
- Class in
editor.tabData
TowersData()
- Constructor for class editor.tabData.
TowersData
TowersTab
- Class in
editor.tabs
TowersTab()
- Constructor for class editor.tabs.
TowersTab
toXML(Object, String, String, String)
- Method in class gamedata.xml.
XMLConverter
Troop
- Class in
units
Troop(String, double, double, String, Point, int, int, int)
- Constructor for class units.
Troop
Troop()
- Constructor for class units.
Troop
Troop(Troop)
- Constructor for class units.
Troop
TroopsData
- Class in
editor.tabData
TroopsData()
- Constructor for class editor.tabData.
TroopsData
TroopsTab
- Class in
editor.tabs
TroopsTab()
- Constructor for class editor.tabs.
TroopsTab
A
B
C
D
E
F
G
H
I
L
M
P
R
S
T
U
V
W
X
Skip navigation links
Overview
Package
Class
Use
Tree
Deprecated
Index
Help
Prev Letter
Next Letter
Frames
No Frames
All Classes


{% block head %}
Click a post's timestamp to get the url
This may take awhile for posts with a large number of comments


My dear friend Alexandra plays in a new band and I instantly fell in love with it as it is the case with nearly everything she creates or co-creates.
So I just had to share it. Think this band could be my oh-my-zsh of Dada-Pop. Something I instantly fell in love with because it just feels good and makes life easier. In some way it’s exactly as oh-my-zsh <3


Shuffle
Evaluate
Actual Pattern
About
{{$index+1}}
×
Evaluation
You were away by
{{score}}
deviation
×
About
Some Description of the application


| Interface | Description |
|---|---|
| ExperimentFragment.OnFragmentInteractionListener |
| Class | Description |
|---|---|
| Answer |
This class represents an Answer object
|
| AnswerActivity |
This class represents an activity where the user can see all answers to a given question
|
| AnswerCustomList |
This class represents a custom list for answer objects
|
| AnswerTest | |
| Binomial_Trial |
This class represents a binomial trial object
Has a value of pass or fail
|
| BinomialActivity |
This class represents an activity that shows the given binomial trials for an experiment
|
| Count_Trial |
This class represents a count trial object
Increment and decrements only
|
| CountActivity |
This class represents an activity that shows the given count trials for an experiment
|
| CurrentExperimentersActivity |
This class represents an activity that will show all non-ignored experimenters for a given trial
The experiment owner can then choose to ignore experimenters to hide their results from the experiment
|
| ExampleInstrumentedTest |
Instrumented test, which will execute on an Android device.
|
| ExampleUnitTest |
Example local unit test, which will execute on the development machine (host).
|
| Experiment |
This class represents a Experiment object
|
| ExperimentCustomList |
This class is a custom list for experiments
|
| ExperimentFragment |
This class represents a dialog fragment for experiments
|
| Histogram |
This class allows the user to display a bar-graph of the frequency a trial's associated data is repeated.
|
| MainActivity |
This class represents an activity that will show all published experiments and act as the main activity to reach other features
|
| MainActivityTest |
This class is to test the MainActivity
|
| MapActivity |
This class represents a map activity where the user can view
|
| Measurement_Trial |
This class represents a measurement trial object
|
| MeasurementActivity |
This class represents an activity that shows the given measurement trials for an experiment
|
| MeasurementCustomList |
This class represents a custom list for measurement trial objects
|
| MeasurementFragment |
This class represents a dialog fragment for measurement trials
|
| MyExperimentActivity |
This class represents an activity that will show all the user's experiments
|
| MyExperimentActivityTest |
This class is to test the MyExperimentActivity
|
| NNICActivity |
This class represents an activity that shows the given NNIC trials for an experiment
|
| NNICCustomList |
This class represents a custom list to hold all trials of NNIC type
|
| NNICFragment |
This class represents a dialog fragment for NNIC trials
|
| Non_Negative_Integer_Counts_Trial |
This class represents a NNIC Trial object
|
| PickQRType |
This class lets the user choose whether to create a QR code for a trial result or to advertise an experiment
|
| PickQRTypeTest |
this class is to test the PickQRType class
|
| PickScanType |
This class lets the user choose to register a barcode, scan a barcode for a trial result, or
scan a QR code (either for a trial result or to advertise an experiment
|
| PickScanTypeTest |
this class is to test the PickQRType class
|
| Profile |
This class represents an activity that will show the user's profile
|
| ProfileTest | |
| QRGenerate |
This class allows a user to generate a QR code and save it to their photo gallery
|
| QRGenerateTest |
this class is to test the QRGenerate class
|
| QRScanner |
This class allows users to scan a printed QR code and will read out the text of the QR code back to the user
|
| QRScannerTest |
Tests the QRScanner class
|
| Question |
This class represents a quesiton object
|
| QuestionActivity |
This class represents a question activity, where all questions for a given experiment are displayed
|
| QuestionCustomList |
This class represents a custom list that holds question objects
|
| QuestionTest | |
| SearchProfile |
This class represents an activity that allows
the user to search for other user's profiles
|
| SearchQuestionActivity |
This class represents a search activity for all profiles
|
| SelectedProfile |
This class represents an activity which shows the selected profile
|
| StatsActivity |
This class is an activity which displays the statistics and gives the user the ability to display histograms relative to
four trial types an experiment may have
|
| WelcomeActivity |
This class represents the welcome screen where the user is prompted with their hardware id
|


You're all set to use MPTCP on this device! See multipath-tcp.org for more information!
n"; } else { echo "NO!
n"; echo "ttYour OS Platform is"+get_platform()+"
n"; // Detect operating system switch (get_platform()) { case OS_WINDOWS: echo "NO, sorry, but MPTCP is currently unavailable on Windows! Check again at another time!
n"; break; case OS_MAC: echo "YES, via a MPTCP-capable virtual machine!
n"; break; case OS_LINUX: echo "YES, via compiling a MPTCP-capable kernel, or via the MPTCP apt-repository!
n"; break; case OS_BSD: echo "YES, via a FreeBSD kernel patch!
n"; break; case OS_ANDROID: echo "MAYBE, via a patch for select Android devices!
n"; break; case OS_IPHONE: echo "YES, by upgrading to iOS 7! See this article for more information!
n"; break; default: echo "MAYBE, you are using an unknown platform, so check How to Install MPTCP for further information!
n"; break; } } ?>


ANZ consumer confidence hits new lows
by Houses and HolesThere’s no stopping it:
Confidence was down again last week, falling 1.1%. The weakness was predominantly due to the economic conditions component of the index.
• Current economic conditions fell by 2.6%, while future economic conditions were more downbeat, falling 4.9%. Both these subindices are near their multiyear lows.
• In contrast, financial conditions were upbeat, with current financial conditions gaining 0.3% and future financial conditions gaining 0.2%.
• The ‘Time to buy a household item’ gained 0.4% after falling 3.9% in the previous reading. The four-week moving average of inflation expectations declined by 0.1ppt to 3.9% as the weekly reading fell to 3.8%, its lowest level since the end of June.
ANZ Head of Australian Economics, David Plank, commented:
There are 830 words left in this subscriber-only article.


THE GAME -------------------------------------------------------------- GRADE: B+
Filmmaking itself is a bit of a game. Directors, actors, screenwriters, and editors play it with their audiences all the time. You use diversionary tactics, you pluck at heartstrings, you appeal to the emotion, the intellect, and the libido of your audience. When the movie is complete, the studio marketing department plays the game, as well. The object of the game is to get butts in theater seats. On a slightly more high-flown level, the object is to engage, stimulate, and please your audience to the extent that they feel gratified by the experience -- and tell their friends about the little game you're playing so that they can buy tickets, too. And the filmmakers find out whether they've won when the box office receipts start coming in.
David Fincher is hardly the first director to exploit his own uncanny gamesmanship, but he's done it as compellingly as anyone since Hitchcock. Granted, his debut feature, ALIEN3, took a swan dive at the box office that mirrored the film's almost ritual sacrifice of an SF cinema icon. (Fincher says the film is less than he wanted it to be, and blames studio interference.) But who would have thought that SE7EN, an unremittingly pessimistic serial killer film -- in which the serial killer plays a self-righteously depraved game with two big-city detectives and wins -- would score more than $100 million at the domestic box office, with or without Brad Pitt on board?
Well, maybe Fincher knew it. Keep in mind that this man cut his teeth as a director of music videos, including the iconic "Express Yourself" for Madonna. This makes him a salesman of the highest rank, a heavy-rotation participant in perhaps the savviest media blitz ever to impact the pop music business. Salesmanship is a big part of the filmmaking game, and a component of its trickiest gambit -- figuring out a way to make art shake hands with commerce.
As I write, it's hard to tell how solid a commercial hit THE GAME may or may not be, although the general reaction of the audience on opening night was one of near-euphoria, with laughter, gasps, and even screaming throughout and widespread applause at the ending credits. In fact, I hardly know where to start criticizing it, because the pay-off is so terrific.
Michael Douglas, the quintessential white man in trouble, plays Nicholas Van Orton, a wealthy, steely, and entirely troubled gazillionaire. (You may recognize a little bit of your boss in him.) He perches atop a megacorporation headquartered in San Francisco, and works his employees ragged -- but not, he believes, unfairly or without good reason. He's devoted to the bottom line, and puts a sourly positive spin on his firing of an underperforming executive (Armin Mueller-Stahl) -- more time to go sailing, Van Orton assures him. He regards his ex-wife (Anna Katerina), who clearly remains worried about his soul, coldy. He lives in the long shadow of his father, who committed suicide by jumping from the roof of the family home.
He's visited by his estranged brother, Conrad (Sean Penn), who offers him an unusual birthday present -- a gift certificate for a personalized "game" orchestrated by a high-tech company called Consumer Recreation Services, or CRS for short. "They make your life fun," he promises. Resistant to the idea but intrigued at the same time, Nicholas eventually finds himself at the CRS offices, submitting to a battery of psychological tests and a physical exam that will help the company tailor a game just for him. Soon, Nicholas arrives at home to find a clown dummy splayed across his driveway, just as his father was found. Nicholas finds a key in the clown's mouth, and suddenly starts receiving some very strange television programming.
And so the game is afoot. The movie seems to take some cues from John Frankenheimer's sinister SECONDS, but without that film's chilly sensibility. The general mood is closer kin to Martin Scorsese's one-night-in-New-York farce AFTER HOURS, with more sinister overtones but with the same general trajectory. Nicholas bonds with Christine (Deborah Kara Unger, seen earlier this year in Crash), a wrong-place-at-the-wrong-time waitress who dumps drinks all over his expensive suit and then helps him escape after he finds himself, mysteriously, trespassing at CRS offices after hours. Lost credit cards, Swiss bank accounts, a crypt in Mexico and a first edition of TO KILL A MOCKINGBIRD will all figure into the picture as the game plays itself out. Justly paranoid, Van Orton's task is to figure out what the hell is going on, and whether or not he's still just playing.
The screenplay, by the folks who brought you THE NET (with an apparent polish by SE7EN screenwriter Andrew Kevin Walker), is effective but irritatingly simplistic. It relies on cyber-paranoia, the suspicion that anybody with the right technological tools can manipulate your televisioned, cell-phoned world to such an extent that you can't tell what's "real" anymore. What's more interesting is the sobering suggestion, left over from SE7EN, that a human life is really a sort of Rube Goldberg device -- that by setting up the right combinations of pulleys and levers, you can manipulate a person into just about anything.
With the exception of a few choice lines that are accented by Douglas's deliciously dry delivery, the dialogue is mostly banal -- which makes it more and more difficult to figure out just what the hell is really happening. Some skillful misdirection by Fincher compounds the confusion, and Unger's smartly reserved performance drives us to second-guess whether or not she's really involved in what looks more and more like a truly sinister scheme. Douglas is fine, exuding that combination of privilege and haplessness for which he's so well known. Penn is only on-screen for a few minutes, but his performance veers effectively from relative serenity to hysteria.
From a technical standpoint, the film is expertly gorgeous. Fincher remains one of the few directors in Hollywood with a visual style that pushes the bounds of what we think of as "the movies." Van Orton's repeated flashbacks to the life and death of his father are presented as Super-8 home movies -- efficiently and beautifully, the flashbacks are signalled not by dissolves or slow pans, but by the abrupt change in the quality, color, and grain of the film itself. Fincher retains an aesthetic fascination with photography, with what it means to take a picture. Cinematographer Harris Savides photographs an incriminating a pile of Polaroids with the same sort of up-close, shallow-field inserts that made up a good portion of the chilling opening credits to SE7EN. Jim Haygood's film editing is virtuosic and world class, tapping into the rhythm of the characters and the story instead of relying on MTV-style hypermontage. Compared to what's playing elsewhere in the multiplex, this sort of breathtaking craftsmanship nearly qualifies as avant garde.
For all that, THE GAME is almost breezily entertaining. You can take that as a compliment, but it's also a problem. For too long -- about the first three-quarters of the film -- Fincher can't manage to escalate this particular game to the level of tension or exhilaration achieved by the best Hollywood movies, say a BREAKDOWN or a FACE/OFF. Meandering from situation to situation, the script takes pains to remain absolutely ambiguous, since the climax will its depend on being able to jerk our perceptions this way and that. The end result of this is that there's no sense of revelation for the audience, no moment when you feel things click together just right -- just twist after twist. Normally, I'm not a fan of this school of storytelling, which seems sorta lazy to me -- THE USUAL SUSPECTS fell back on a similar one-twist gimmick in 1995, and Joe Eszterhas has used it repeatedly, to my great irritation (JAGGED EDGE, BASIC INSTINCT, and SLIVER). But THE GAME is a little more playful in its convolutions than those films.
In a critical scene, Nicholas is left alone in a room, and he starts investigating his surroundings. To his surprise, the whole room is prefab -- the books on the bookshelves are fake, the refrigerator is empty, and the picture frames hold cutouts from magazine pages. It's as though he's just started taking apart the movie set. In another scene, he stands and squints into the shafts of light pouring out from a projection booth, confused and impatient with the film he's being made to watch.
It occurred to me in retrospect -- Michael Douglas and this character are both part of a literal game, one that has been crafted by Fincher and his cronies at considerable expense, and one whose object is to confound you, the moviegoer. It's a slight diversion, but it is certainly entertaining.  -------------------------------------------------------------- Directed by David Fincher Written by John D. Brancato, Michael Ferris, and Andrew Kevin Walker Cinematography by Harris Savides Edited by Jim Haygood Music by Howard Shore Starring Michael Douglas, Deborah Kara Unger, and Sean Penn USA, 1997
DEEP FOCUS (Movie Reviews) http://www.panix.com/~bfrazer/flicker/ "Oh my GOD! They killed Kenny!"
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Penang’s Swettenham Pier Cruise Terminal expansion to start in early 2020
by BY OPALYN MOKGEORGE TOWN, Nov 18 — The RM155 million Swettenham Pier Cruise Terminal (SPCT) expansion will start in three months, its project partner Royal Caribbean announced today.
Royal Caribbean’s Asia-Pacific managing director Angie Stephen said the expansion plans have been approved and construction partners identified.
“The concessionaire was also identified and now we are tying up loose strings so we can expect construction to start in two to three months,” she said during a press conference on board the Quantum of the Seas that made a one-day stop at SPCT here.
She said the construction work will take about 12 months to complete.
“Once completed, it will be able to handle two Oasis size ships on the outer berths and accommodate two more ships on the inner berths,” she said.
The expansion project is a joint venture between Penang Port Sdn Bhd (60 per cent) and Royal Caribbean Cruises Ltd (40 per cent).
The expansion is to allow the terminal to cater to up to 1.7 million passengers a year and accommodate up to 12,000 passengers at any one time.
Stephen said Penang and Singapore were the two highly rated destinations by most of the cruise liners’ customers.
She said it is time for Penang to grow and improve its land experience to cater to visitors from cruise liners docking here.
“Penang needs to create experiences for visitors in the outskirts of the state rather than let all activities be concentrated in the city,” she said.
She said it is time for Penang to create new experiences and spread out the visitors to all around the state, outside the city, for different experiences, especially for those who have been to Penang before.
Royal Caribbean will be increasing its calls to Malaysia from 43 calls to 55 for the next season.
She said Malaysia is a destination of choice for the region’s growing cruise market.
“We will be bringing a total of 430,000 tourists to Malaysia in the next two years,” she said.
She said Royal Caribbean is committed to bringing in newer and better ships for longer deployments to Malaysia.


Is Monopoly Good or Bad?
Monopoly is nearly always seen as something undesirable. Courts have wrestled with monopoly for ages, sometimes defining it as: "the power to control prices and exclude competition", "restraining trade", or "unfair and anti-competitive behavior." Should monopolistic practices be condemned and outlawed? Let's look at anti-competitive behavior and practices, but let's not confine ourselves to what's traditionally seen as monopoly.
The marriage contract is essentially a monopoly document. It represents a legally sanctioned collusive agreement between two parties to exclude competitors and restrain trade. It closes the market to competition, or at least it is supposed to. This collusion has benefits as well as costs. Because I have exclusive rights to her affections and property rights to a stream of highly valued domestic services, I place a higher value on my spouse, making me willing to share with her a greater percentage of my wealth. My spouse receives a comparable set of benefits from this collusive arrangement.
This monopolistic arrangement has a cost side and perhaps some inefficiencies as well. Neither one of us is as attentive as we were before we made our contractual arrangement. For my part, I don't open the car door for her as often, don't use breath fresheners and colognes as frequently, am not as nearly considerate and gentlemanly as before our marriage some 42 years earlier. The reason is simply that before marriage I was competing against other men and therefore could ill afford to act as a monopolist.
Read the Old Testament's Book of Deuteronomy, Chapter 5, where God gave Moses the Ten Commandments. The first commandment, and presumably the most important is, "Thou Shalt have none other gods before me." The second is, "Thou shalt not make thee any graven image, or any likeness of any thing that is in heaven above. . . ." Then there's, "Thou shalt not bow down thyself unto them, nor serve them: for I the Lord thy God am a jealous God. . . ." If a corporation made a similar decree regarding its services, it would find itself in the sights of the U.S. Department of Justice for gross violations of the anti-trust provisions of the Sherman and Clayton Acts. The Ten Commandments decree exclusive dealing and mandate neither substitutes for nor competition with God.
In order for one to condemn all monopolistic practices as evil, at least for consistency, he would have to also condemn marriage and the basic tenets of Christianity. I neither condemn marriage, the monopolistic tenets of Christianity, nor do I condemn business and labor union monopolies. The only moral argument that can be used to condemn and outlaw monopoly is when it is created through fraud, threats, intimidation and coercion.
Our nation has a number of government-sponsored, created or protected monopolies and collusions in restraint of trade. One of the more egregious examples is the U.S. Postal Service. The federal Private Express Statutes, Sec. 310.2 "Unlawful carriage of letters," says, "(a) It is generally unlawful under the Private Express Statutes for any person other than the Postal Service in any manner to send or carry a letter on a post route or in any manner to cause or assist such activity. Violation may result in injunction, fine or imprisonment or both and payment of postage lost as a result of the illegal activity." The Private Express Statutes have the full effect of saying, "Thou shalt have none other deliverers of first-class mail before the USPS and we shall visit great pain on he who disobeys this commandment."
The U.S. Postal Service is a government-owned monopoly; how ever, there are numerous privately-owned monopolies and collusions in restraint of trade. In fact, nearly every federal agency is an enforcer of monopolistic collusive agreements. Until relatively recently, the Civil Aviation Bureau (CAB) and the Interstate Commerce Commission (ICC) enforced price-fixing agreements in the airline and trucking industries. Deregulation brought an end to those collusive agreements.
Thriving monopolistic agreements, at the federal level, are enforced by agencies such as the U.S. Department of Labor, National Labor Relations Board, Department of Agriculture, Federal Communications Commission, Department of Education, and Department of Commerce. The rule of thumb to determine whether an effective collusion exists is to see whether there are: mandated minimum prices, license to practice provisions and other restrictions on entry and finally whether there are techniques to enforce compliance among the colluding members - such as revocation of license or permit to practice, fines and imprisonment and other sanctions.
The free market, including free international trade, is the most effective protection against monopolistic abuses. In fact, in a free and open market, monopolistic companies can retain their monopoly power only if they do not fully exploit it; otherwise other companies will enter.
Walter E. Williams
Ideas on Liberty, April 2002


OUTSIDE PROVIDENCE A film review by Steve Rhodes Copyright 1999 Steve Rhodes RATING (0 TO ****): *
"Retard!"
"Homo!"
If those crude bits of offensive language are all it takes to make you laugh, you may find bits of Michael Corrente's OUTSIDE PROVIDENCE funny. Most of this laughless comedy, written by the director and by THERE'S SOMETHING ABOUT MARY's Peter and Bobby Farrelly, only sporadically even attempts to be funny. In the dead spots between the would-be jokes that fall like stones, the story has a semi-serious set of sob stories.
As the obnoxious and clichéd father known as "Old Man Dunphy," Alec Baldwin delivers a starkly abysmal performance. A dad who calls his older son "dildo" for unexplained reasons, he's not exactly warmly loved. His younger son is a "cripple," so you can guess how shamelessly the movie will exploit the boy and his handicap. Old Man Dunphy wants you to feel sorry for him, and the story gives him such stereotypically boorish behavior that there's no chance that you will.
His older son, Timothy Dunphy (Shawn Hatosy), is called Dunph by his friends, who include a guy called Drugs and one called Mousy. Dunph, who is poor and not especially bright, lives with his father outside of Providence, Rhode Island. After he gets into trouble, he is sent off to an expensive boarding school -- where the money comes from isn't explained -- called "Cornwall Academy for Boys." Girls are there too. Don't ask; the movie never bothers to explain.
Leaving home is probably good for him even if the school has a forbidden activities list that seems endless. All of the rules are broken anyway. At least away from home he can avoid his dad and his beer-drinking buddies' poker games full of anti-Semitic, homophobic and generally offensive language and behavior. You'd want to leave home too, if you had a dad like that.
Dunph is a high school senior who believes that Arizona is on the coast -- at least after the Alamo. You don't want to try to follow his logic. Like most of the movie, it isn't worth your time. In fact, if the Farrelly brothers weren't associated with the movie, it would have undoubtedly never been green-lighted for production.
Always on the outlook for redeeming features to pathetic movies, your trusty critic found two this time. Although Richard Crudo (AMERICAN BUFFALO) films the interior scenes with a cheap-looking ugliness, the outside sequences happen mainly in a gorgeous, New England autumn in which the trees are bursting with their radiant fall colors.
OUTSIDE PROVIDENCE runs 1:42, but will feel much longer. It is rated R for drug usage, sexual references and language and would be acceptable for older teenagers.
Email<EMAIL_ADDRESS>Web: http://www.InternetReviews.com
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Hear we offer web Design and
Development at Low Prices!
Drop us an email or message us
On Social Media to fined out more!
Follow us on social media to stay
Up to date with all the latest projects
And Deals!
Hear are some testimonials
from Customers that have had
Websites
Developed and designed
By Us!
At Dragon Dev studios we design and develop quality websites at a low price.
If you wish to have a second website developed and you recoment us to a freind
we will do it for free!
And if your website is 2 pages
or less we will also design and develop it for free!
As i need to build up a portfolio, My first Three
customers will have there websites
developed and designed compleately for free. If you wish to hire me please contact
Me Via Social Media or via Email, I would love to hear from you!
-Alex
Come and follow us on Social media to keep up to date
With what we are doing, What projects we are working on
Special offers
Ect. We have Twitter, Facebook And instergram!
-The Social Media Team
Hear are some Testimonials from customers
- No Testimonials Yet.


public enum EasingFunction extends java.lang.Enum<EasingFunction>
| Enum Constant and Description |
|---|
BACK_EASE_IN |
BACK_EASE_IN_OUT |
BACK_EASE_OUT |
BOUNCE_EASE_IN |
BOUNCE_EASE_IN_OUT |
BOUNCE_EASE_OUT |
EASE_IN |
EASE_IN_OUT |
EASE_OUT |
ELASTIC_EASE_IN |
ELASTIC_EASE_IN_OUT |
ELASTIC_EASE_OUT |
LINEAR |
STRONG_EASE_IN |
STRONG_EASE_IN_OUT |
STRONG_EASE_OUT |
| Modifier and Type | Method and Description |
|---|---|
static EasingFunction |
fromValue(java.lang.String str)
Retrieve an enumeration literal for a string.
|
java.lang.String |
toString()
Retrieve a string from the enumeration literal.
|
static EasingFunction |
valueOf(java.lang.String name)
Returns the enum constant of this type with the specified name.
|
static EasingFunction[] |
values()
Returns an array containing the constants of this enum type, in
the order they are declared.
|
public static final EasingFunction LINEAR
public static final EasingFunction EASE_IN
public static final EasingFunction EASE_OUT
public static final EasingFunction EASE_IN_OUT
public static final EasingFunction BACK_EASE_IN
public static final EasingFunction BACK_EASE_OUT
public static final EasingFunction BACK_EASE_IN_OUT
public static final EasingFunction ELASTIC_EASE_IN
public static final EasingFunction ELASTIC_EASE_OUT
public static final EasingFunction ELASTIC_EASE_IN_OUT
public static final EasingFunction BOUNCE_EASE_IN
public static final EasingFunction BOUNCE_EASE_OUT
public static final EasingFunction BOUNCE_EASE_IN_OUT
public static final EasingFunction STRONG_EASE_IN
public static final EasingFunction STRONG_EASE_OUT
public static final EasingFunction STRONG_EASE_IN_OUT
public static EasingFunction[] values()
for (EasingFunction c : EasingFunction.values()) System.out.println(c);
public static EasingFunction valueOf(java.lang.String name)
name
- the name of the enum constant to be returned.java.lang.IllegalArgumentException
- if this enum type has no constant
with the specified namejava.lang.NullPointerException
- if the argument is nullpublic java.lang.String toString()
toString
in class java.lang.Enum<EasingFunction>
public static EasingFunction fromValue(java.lang.String str)
str
- The string (as used by kineticjs)


Progresio is the tool to show your customers what they want to see. Progresio uses an intelligent and intuitive way to show customers the progress of their order, and when they can expect it to be complete.
Progression allows customers to plan in advance and make sure everything goes to plan
Progresio has been designed for the user. Everything you, the creator, could want to do will take only a few clicks - it's even easier for your viewers!
Anyone can create a progress bar without even signing up (however you can sign up to keep track of all your bars) - to get started enter the details and click go!


Routines for performing empirical calibration of observational study estimates. By using a set of negative control hypotheses we can estimate the empirical null distribution of a particular observational study setup. This empirical null distribution can be used to compute a calibrated p-value, which reflects the probability of observing an estimated effect size when the null hypothesis is true taking both random and systematic error into account. A similar approach can be used to calibrate confidence intervals, using both negative and positive controls.
| Version: | 1.4.0 |
| Imports: | ggplot2 (≥ 2.0.0), gridExtra, methods |
| Suggests: | knitr, rmarkdown |
| Published: | 2018-11-24 |
| Author: | Martijn Schuemie [aut, cre], Marc Suchard [aut] |
| Maintainer: | Martijn Schuemie <schuemie at ohdsi.org> |
| BugReports: | https://github.com/OHDSI/EmpiricalCalibration/issues |
| License: | Apache License 2.0 |
| URL: | https://ohdsi.github.io/EmpiricalCalibration, https://github.com/OHDSI/EmpiricalCalibration |
| NeedsCompilation: | no |
| Citation: | EmpiricalCalibration citation info |
| Materials: | README NEWS |
| CRAN checks: | EmpiricalCalibration results |
| Reference manual: | EmpiricalCalibration.pdf |
| Vignettes: |
Empirical calibration of confidence intervals Empirical calibration of p-values |
| Package source: | EmpiricalCalibration_1.4.0.tar.gz |
| Windows binaries: | r-devel: EmpiricalCalibration_1.4.0.zip, r-release: EmpiricalCalibration_1.4.0.zip, r-oldrel: EmpiricalCalibration_1.4.0.zip |
| OS X binaries: | r-release: EmpiricalCalibration_1.4.0.tgz, r-oldrel: EmpiricalCalibration_1.4.0.tgz |
| Old sources: | EmpiricalCalibration archive |
Please use the canonical form https://CRAN.R-project.org/package=EmpiricalCalibration to link to this page.


Class JsonSchemaOptions
Defines options associated with JSON Schema.
Inheritance
Inherited Members
Namespace: Manatee.Json.Schema
Assembly: Manatee.Json.dll
Syntax
public class JsonSchemaOptions
Constructors
| Improve this Doc View SourceJsonSchemaOptions()
Creates a new instance of the JsonSchemaOptions class.
Declaration
public JsonSchemaOptions()
JsonSchemaOptions(JsonSchemaOptions)
Creates a new instance of the JsonSchemaOptions class.
Declaration
public JsonSchemaOptions(JsonSchemaOptions source)
Parameters
| Type | Name | Description |
|---|---|---|
| JsonSchemaOptions | source |
Properties
| Improve this Doc View SourceAllowUnknownFormats
Gets or sets whether unknown string formats are permitted. If disabled and an unknown format is found, the system will throw a JsonSerializationException while loading the schema. The default is true.
Declaration
public bool AllowUnknownFormats { get; set; }
Property Value
| Type | Description |
|---|---|
| System.Boolean |
Default
Default options used by schema.
Declaration
public static JsonSchemaOptions Default { get; }
Property Value
| Type | Description |
|---|---|
| JsonSchemaOptions |
DefaultBaseUri
Defines a default base URI for root schemas that use a relative URI for their $id
. The default is manatee://json-schema/
.
Declaration
public Uri DefaultBaseUri { get; set; }
Property Value
| Type | Description |
|---|---|
| System.Uri |
DefaultProcessingVersion
Gets or sets a default draft version to use in case a schema can be determined to support multiple drafts. Default is latest to earliest.
Declaration
public List<JsonSchemaVersion> DefaultProcessingVersion { get; set; }
Property Value
| Type | Description |
|---|---|
| System.Collections.Generic.List<JsonSchemaVersion> |
Download
Gets and sets a method used to download online schema.
Declaration
public static Func<string, string> Download { get; set; }
Property Value
| Type | Description |
|---|---|
| System.Func<System.String, System.String> |
LogMetaSchemaValidation
Gets or sets whether meta-schema validation is enabled. Default is false.
Declaration
public bool LogMetaSchemaValidation { get; set; }
Property Value
| Type | Description |
|---|---|
| System.Boolean |
Remarks
A schema is validated against the meta-schemas the first time it is used to validate an instance. This is done to determine the specific draft that the schema supports. Logging for this can be quite verbose, but if you want this to be logged, you can enable this feature.
OutputFormat
Gets or sets the output verbosity. The default is Flag.
Declaration
public SchemaValidationOutputFormat OutputFormat { get; set; }
Property Value
| Type | Description |
|---|---|
| SchemaValidationOutputFormat |
RefResolution
Determines whether siblings of $ref
keywords are processed. This also affects how $ref
is resolved
when adjacent to an $id
keyword when a specific draft cannot be identified. The default is
ProcessSiblingKeywords to be consistent with the latest draft, 2019-09.
Declaration
public RefResolutionStrategy RefResolution { get; set; }
Property Value
| Type | Description |
|---|---|
| RefResolutionStrategy |
Remarks
As of draft 2019-09, keywords are allowed to be adjacent to $ref
. This means that an
adjacent $id
keyword will now change the base URI whereas in prior drafts it would not
since adjacent keywords were to be ignored.
When Manatee.Json cannot determine the draft a particular schema is using (determined via
the $schema
keyword or the selection of keywords being used), this option will
determine the behavior for resolving URIs.
ValidateFormatKeyword
Gets or sets whether the "format" schema keyword should be validated. The default is true.
Declaration
public bool ValidateFormatKeyword { get; set; }
Property Value
| Type | Description |
|---|---|
| System.Boolean |
Methods
| Improve this Doc View SourceIgnoreErrorsForChildren(JsonPointer)
Ignores error and annotation collection for children of specific schema locations.
Declaration
public void IgnoreErrorsForChildren(JsonPointer location)
Parameters
| Type | Name | Description |
|---|---|---|
| JsonPointer | location |
Remarks
This may help improve performance. There may be cases where it would be sufficient to only
report on the immediate error rather than all child errors. An example of this may be a keyword
like oneOf
at a specific location, where the client may only want a single error that says,
"4 of the 10 subschemas passed validation, but only 1 was expected."
IgnoreErrorsForChildren<T>()
Ignores error and annotation collection for children of specific keywords.
Declaration
public void IgnoreErrorsForChildren<T>()
where T : IJsonSchemaKeyword
Type Parameters
| Name | Description |
|---|---|
| T | The keyword type to ignore. |
Remarks
This may help improve performance. There may be cases where it would be sufficient to only
report on the immediate error rather than all child errors. An example of this may be a keyword
like oneOf
, where the client may only want a single error that says, "4 of the 10 subschemas
passed validation, but only 1 was expected."
ShouldReportChildErrors(IJsonSchemaKeyword, SchemaValidationContext)
Checks whether child errors and annotations should be reported. Should be called during validation.
Declaration
public bool ShouldReportChildErrors(IJsonSchemaKeyword keyword, SchemaValidationContext context)
Parameters
| Type | Name | Description |
|---|---|---|
| IJsonSchemaKeyword | keyword | The keyword currently executing validation. |
| SchemaValidationContext | context | The validation context. |
Returns
| Type | Description |
|---|---|
| System.Boolean |
|


PBWorks Unofficial Offline Editor
Loading . . .
You have not configured your info
Can't use PBwork addon in this web page.
Help


Lata Mangeshkar’s Official Spokesperson Updates Her Fans On The Singer’s Health Condition, Says She Is Doing Good
The legendary singer, Lata Mangeshkar, was rushed to Breach Candy hospital on Monday.
by IANSMelody queen Lata Mangeshkar is on her way to recovery after being hospitalised for viral chest congestion and is “doing good” on Saturday.
An official spokesperson said on Saturday: “Lata didi (Lata Mangeshkar) is doing good today.”
The legendary singer, Lata Mangeshkar, was rushed to Breach Candy hospital on Monday.
Since then, many fans and Bollywood celebrities such as Shabana Azmi and Hema Malini have been praying for her speedy recovery.
The iconic singer, who turned 90 on September 28, became a recipient of India’s highest civilian honour Bharat Ratna in 2001. She has recorded songs in over 36 Indian languages.
Born on September 28, 1929, Lata Mangeshkar has also been honoured with Dadasaheb Phalke Award and France’s highest civilian award, Officer of the Legion of Honour, besides numerous national and international awards.
In 1974, the Guinness Book of Records ranked her as the most recorded artiste in history. She had reportedly sung over 25,000 songs between 1948 and 1974.
Lata Mangeshkar, who has been active on social media despite her advancing age, on Sunday wished actress Padmini Kolhapure good luck for the upcoming film “Panipat“.


The One Where 'Friends' Get Old: Cast From the Famous Sitcom 25 Years Later
16 Nov 2019, 17:45
We might not believe it, but 25 years ago the first episode of the super-popular TV show "Friends" was released. Rachel, Ross, Chandler, Joey, Phoebe, and Monica became the favourite characters of millions of viewers.
A story about friendship, love, relationships, and people who became a family in New York turned into the most successful television project of the 1990s.
The celebrated sitcom began on 22 September 1994 and ran for 236 episodes, ending in 2004. The sitcom’s first episode was watched by 22 million people, while the average number of viewers of the first season was 24 million. The final episode of the tenth and last season was viewed by more than 52 million people, which at the time was the fourth-highest viewership in the history of television.
Jennifer Aniston, Courteney Cox, Lisa Kudrow, Matt LeBlanc, Matthew Perry, and David Schwimmer all became some of the highest-paid actors and actresses in TV history.
The cast of the television show "Friends" appeared at the 54th annual Emmy Awards in Los Angeles on 22 September 2002. From left: Matthew Perry, David Schwimmer, Matt LeBlanc, Lisa Kudrow, Jennifer Aniston, and Courteney Cox. The show was nominated for the Award for Outstanding Comedy Series. © REUTERS / Adrees Latif
Jennifer Aniston joined Instagram, posting a photo of a reunion of the Friends sitcom cast. © Photo: Instagram / @jenniferaniston
Actresses Courteney Cox, left, and Jennifer Aniston from the television series "Friends" at the 9th annual Screen Actors Guild Awards in Los Angeles on 9 March 2003. Aniston guest-starred in the season finale of Cox's new FX Networks show "Dirt", the network said. © AP Photo / Chris Pizzello
Actresses Courteney Cox, left, and Jennifer Aniston addressed the audience during the 46th AFI Life Achievement Award gala ceremony honouring actor/director George Clooney at the Dolby Theatre on 7 June 2018, in Los Angeles. © AP Photo / Chris Pizzello
Jennifer Aniston at WE Day California at The Forum on Thursday, 19 April 2018, in Inglewood, California. © AP Photo / Richard Shotwell
Courteney Cox attended Chanel and NRDC Host Dinner to Celebrate Our Majestic Oceans on 2 June 2018, in Malibu, California. © AP Photo / Richard Shotwell
"Friends" cast member Courteney Cox, left, gives fellow cast member Matthew Perry a kiss backstage as Lisa Kudrow looks on after the actors won the award for Outstanding Ensemble Performance in a Comedy Series at the 2nd Annual Screen Actors Guild Awards, on 24 February 1996, in Santa Monica, California. © AP Photo / Chris Pizzello
Actor Matthew Perry participated in the BUILD Speaker Series to discuss the mini-series "The Kennedys After Camelot" at AOL Studios on 30 March 2017, in New York. © AP Photo / Evan Agostini
(L-R) Jennifer Aniston, David Schwimmer, and Lisa Kudrow from the television series "Friends" hold their People's Choice Award for Favourite Television Comedy Series backstage at the 27th Annual People's Choice Awards on 7 January 2001 in Pasadena, California. © AFP 2019 / Scott Nelson
Lisa Kudrow at Audi Celebrates the 71st Creative Arts Emmy Awards at the Microsoft Theatre on 14 September 2019 in Los Angeles, California. © AFP 2019 / Vivien Killilea
Actors Matt LeBlanc (L) with a broken arm and David Schwimmer (R), the stars of "Friends", arrived for the 48th Annual Emmy Awards on 8 September 1996 in Pasadena, California. © AFP 2019 / Vince Bucci
Actor Matt LeBlanc attended the 2017 PaleyLive LA Summer Season Premiere Screening and Conversation for Showtime's "Episodes" at the Paley Centre for Media on 16 August 2017 in Beverly Hills, California. © AFP 2019 / Alberto E. Rodriguez
Jennifer Aniston (L) and David Schwimmer from the television series "Friends" at the 27th Annual People's Choice Awards on 7 January 2001 in Pasadena. Aniston was nominated for the Favourite Female Television Performer category at the awards. © AFP 2019 / Lucy Nicholson
David Schwimmer spoke during “David Schwimmer: In Conversation” at the Vulture Festival at Milk Studios on 21 May 2016 in New York City. © AFP 2019 / Bryan Bedder
The cast of the television comedy "Friends" (From L-R): Matthew Perry, Lisa Kudrow, Jennifer Aniston, and David Schwimmer pose with their award at the 26th People's Choice Awards in Pasadena, California on 9 January 2000. The show won the Favourite Television Comedy Series Award. © AFP 2019 / Lucy Nicholson
(L-R) Courteney Cox, winner of the “Artists Inspiration Award”, Jennifer Aniston, and Lisa Kudrow attended the SAG-AFTRA Foundation's 4th Annual Patron of the Artists Awards at the Wallis Annenberg Centre for the Performing Arts on 7 November 2019 in Beverly Hills, California. © AFP 2019 / Gregg Deguire