<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>LibCanvas :: ping-pong</title> <link href="/styles.css" rel="stylesheet" /> <script src="/lib/atom.js"></script> <script src="/lib/libcanvas.js"></script> </head> <body> <canvas></canvas> <!-- Game engine --> <script src="js/init.js"></script> <script src="js/controller.js"></script> <script src="js/field.js"></script> <script src="js/unit.js"></script> <script src="js/ball.js"></script> </body> </html>
LibCanvas.extract
in order to be able to use global names. By default, all classes are stored in their namespaces: LibCanvas.Shapes.Circle
. After extract
they can be used in abbreviated form: Circle
LibCanvas.extract(); window.Pong = {}; atom.dom(function () { new Pong.Controller('canvas'); });
<!DOCTYPE html> <title>LibCanvas :: ping-pong</title> <script src="js/load.ls"></script>
LibCanvas
object and game elements. I will create all game classes using atom.Class
, where initialize
is a constructor. Pong.Controller = atom.Class({ initialize: function (canvas) { this.libcanvas = new LibCanvas(canvas, { preloadImages: { elems : 'im/elems.png' } }) .listenKeyboard([ 'aup', 'adown', 'w', 's' ]) .addEvent('ready', this.start.bind(this)) .start(); }, start: function () { var libcanvas = this.libcanvas; [...] } });
LibCanvas
that we will use the keyboard and it is necessary to avoid default actions for the 'aup', 'adown', 'w' and 's' keys. This will allow for convenient management and, for example, the browser window will not move with arrows. Pong.Field = atom.Class({ Implements: [ Drawable ], width : 800, height: 500, [...] });
Pong.Controller = atom.Class({ [...] start: function () { var libcanvas = this.libcanvas; var field = new Pond.Field(); libcanvas.size( field, true ); libcanvas.addElement( field ); [...] } });
libcanvas
is not there yet, so you need to wait for the libcanvasSet
event and only then wield with libcanvas
Pong.Ball = atom.Class({ Implements: [ Drawable ], impulse: null, initialize: function (controller) { this.impulse = new Point( Number.random(325, 375), Number.random(325, 375) ); this.addEvent('libcanvasSet', function () { this.image = this.libcanvas.getImage('elems').sprite( 23, 0, 26, 26 ); }); }, move: function (time) { this.shape.move( this.impulse.clone().mul(time / 1000) ); }, update: function (time) { this.move(time); var from = this.shape.from, to = this.shape.to; // if ( (this.impulse.y < 0 && from.y < 0) || (this.impulse.y > 0 && to.y > this.field.height) ) this.impulse.y *= -1; }, appendTo: function (field) { this.shape = new Rectangle( 40, field.height / 2, 24, 24 ); this.field = field; return this; }, draw: function () { this.libcanvas.ctx.drawImage(this.image, this.shape); } });
addFunc
Pong.Controller = atom.Class({ [...] start: function () { [...] ball = new Pong.Ball(); libcanvas [...] .addElement( ball.appendTo( field ) ) .addFunc(function (time) { ball.update( time ); libcanvas.update(); }); } });
Pong.Unit = atom.Class({ Implements: [ Drawable ], size: { width: 20, height: 100, padding: 20 }, speed: new Point( 0, 300 ), score: 0, controls: function (up, down) { this.addEvent('libcanvasSet', function () { var lc = this.libcanvas.addFunc(function (time) { if (lc.getKey(up)) { this.move( -time ); } else if (lc.getKey(down)) { this.move( time ); } }.bind(this)); }); return this; }, appendTo: function (field, number) { var s = this.size; this.field = field; this.number = number; this.shape = new Rectangle({ // field.width, field.height from: [ (number == 2 ? field.width - s.width - s.padding : s.padding), (field.height - s.height) / 2 ], size: s }); return this; }, fitToField: function () { var shape = this.shape; var top = shape.from.y, bottom = shape.to.y - this.field.height; if (top < 0) shape.move(new Point(0, -top)); if (bottom > 0) shape.move(new Point(0, -bottom)); }, move: function (time) { this.shape.move( this.speed.clone().mul( time / 1000 ) ); this.fitToField(); }, draw: function() { this.libcanvas.ctx.drawImage( this.libcanvas.getImage('elems').sprite(0,0,20,100), this.shape ); } });
Pong.Field = atom.Class({ [...] createUnits: function (libcanvas) { this.unit = new Pong.Unit() .controls('w', 's') .appendTo( this, 1 ); this.enemy = new Pong.Unit() .controls('aup', 'adown') .appendTo( this, 2 ); libcanvas .addElement( this.unit ) .addElement( this.enemy ); }, [...]
Pong.Controller = atom.Class({ [...], start: function () { [...], field.createUnits( libcanvas ); } });
Pong.Ball = atom.Class({ [...] checkCollisions: function () { var coll = this.field.collidesUnits( this ), isOut = this.field.isOut( this.shape ); if ( (( coll < 0 || isOut < 0 ) && this.impulse.x < 0) || (( coll > 0 || isOut > 0 ) && this.impulse.x > 0) ) this.impulse.x *= -1; }, update: function (time) { [...] this.checkCollisions(); }, [...] });
Pong.Field = atom.Class({ [...] collidesUnits: function (ball) { return this.unit .collides(ball) ? -1 : this.enemy.collides(ball) ? 1 : 0; }, isOut: function (shape) { if (shape.from.x < 0) { this.enemy.score++; return -1; } else if (shape.to.x > this.width) { this.unit.score++; return 1; } return 0; }, [...]
Rectangle().intersect
, to check the intersection of two rectangles. Pong.Unit = atom.Class({ [...] collides: function (ball) { return ball.shape.intersect(this.shape); }, });
ctx.text
- it allows you to draw text more closely to css, specify indents, a rectangle into which you want to output text and some additional features. Pong.Field = atom.Class({ [...] drawScore: function (unit, align) { this.libcanvas.ctx.text({ text: unit.score, size: 32, padding: [0, 70], color: 'white', align: align }); return this; }, draw: function () { this .drawScore( this.unit , 'left' ) .drawScore( this.enemy, 'right' ); } });
Source: https://habr.com/ru/post/119420/
All Articles