Skip to content

Commit

Permalink
Merge branch 'master' into fix-wh-overriding
Browse files Browse the repository at this point in the history
  • Loading branch information
Caley Brock authored and Caley Brock committed Aug 5, 2016
2 parents 4b82fa9 + ac651a7 commit 1fef5fb
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 13 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
language: node_js
node_js: 4
12 changes: 12 additions & 0 deletions examples/mouseEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

var asterisk;
var ghost;
var draggedSprite;

function setup() {
createCanvas(800, 400);
Expand Down Expand Up @@ -34,18 +35,29 @@ function setup() {
asterisk.onMousePressed = function() {
this.changeAnimation('transform');
this.animation.goToFrame(this.animation.getLastFrame());
if (draggedSprite == null) {
draggedSprite = this;
}
};

asterisk.onMouseReleased = function() {
this.changeAnimation('transform');
this.animation.goToFrame(0);
if (draggedSprite == this) {
draggedSprite = null;
}
};

}

function draw() {
background(255, 255, 255);

if (draggedSprite != null) {
draggedSprite.position.x = mouseX;
draggedSprite.position.y = mouseY;
}

//if a sprite is mouseActive true I can check if the mouse is over its collider
//and if the button is pressed
if(ghost.mouseIsOver)
Expand Down
90 changes: 78 additions & 12 deletions lib/p5.play.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ var round = p5.prototype.round;
* @type {Group}
*/

defineLazyP5Property('allSprites', function() { return new Group(); });
defineLazyP5Property('allSprites', function() {
return new Group();
});

p5.prototype.spriteUpdate = true;

Expand Down Expand Up @@ -1011,6 +1013,48 @@ function Sprite(pInst, _x, _y, _w, _h) {
*/
this.mouseIsPressed = false;

/*
* Width of the sprite's current image.
* If no images or animations are set it's the width of the
* placeholder rectangle.
* Used internally to make calculations and draw the sprite.
*
* @private
* @property _internalWidth
* @type {Number}
* @default 100
*/
this._internalWidth = _w;

/*
* Height of the sprite's current image.
* If no images or animations are set it's the height of the
* placeholder rectangle.
* Used internally to make calculations and draw the sprite.
*
* @private
* @property _internalHeight
* @type {Number}
* @default 100
*/
this._internalHeight = _h;

/*
* _internalWidth and _internalHeight are used for all p5.play
* calculations, but width and height can be extended. For example,
* you may want users to always get and set a scaled width:
Object.defineProperty(this, 'width', {
enumerable: true,
configurable: true,
get: function() {
return this._internalWidth * this.scale;
},
set: function(value) {
this._internalWidth = value / this.scale;
}
});
*/

/**
* Width of the sprite's current image.
* If no images or animations are set it's the width of the
Expand All @@ -1020,6 +1064,17 @@ function Sprite(pInst, _x, _y, _w, _h) {
* @type {Number}
* @default 100
*/
Object.defineProperty(this, 'width', {
enumerable: true,
configurable: true,
get: function() {
return this._internalWidth;
},
set: function(value) {
this._internalWidth = value;
}
});

if(_w === undefined)
this.width = 100;
else
Expand All @@ -1034,6 +1089,17 @@ function Sprite(pInst, _x, _y, _w, _h) {
* @type {Number}
* @default 100
*/
Object.defineProperty(this, 'height', {
enumerable: true,
configurable: true,
get: function() {
return this._internalHeight;
},
set: function(value) {
this._internalHeight = value;
}
});

if(_h === undefined)
this.height = 100;
else
Expand All @@ -1048,7 +1114,7 @@ function Sprite(pInst, _x, _y, _w, _h) {
* @type {Number}
* @default 100
*/
this.originalWidth = this.width;
this.originalWidth = this._internalWidth;

/**
* Unscaled height of the sprite
Expand All @@ -1059,7 +1125,7 @@ function Sprite(pInst, _x, _y, _w, _h) {
* @type {Number}
* @default 100
*/
this.originalHeight = this.height;
this.originalHeight = this._internalHeight;

/**
* True if the sprite has been removed.
Expand Down Expand Up @@ -1223,11 +1289,11 @@ function Sprite(pInst, _x, _y, _w, _h) {
}
else if(this.colliderType === 'image')
{
this.collider.extents.x = this.width * abs(cos(t)) +
this.height * abs(sin(t));
this.collider.extents.x = this._internalWidth * abs(cos(t)) +
this._internalHeight * abs(sin(t));

this.collider.extents.y = this.width * abs(sin(t)) +
this.height * abs(cos(t));
this.collider.extents.y = this._internalWidth * abs(sin(t)) +
this._internalHeight * abs(cos(t));
}
}

Expand Down Expand Up @@ -1289,8 +1355,8 @@ function Sprite(pInst, _x, _y, _w, _h) {
if(animations[currentAnimation] && (animations[currentAnimation].getWidth() !== 1 && animations[currentAnimation].getHeight() !== 1))
{
this.collider = this.getBoundingBox();
this.width = animations[currentAnimation].getWidth()*abs(this._getScaleX());
this.height = animations[currentAnimation].getHeight()*abs(this._getScaleY());
this._internalWidth = animations[currentAnimation].getWidth()*abs(this.scale);
this._internalHeight = animations[currentAnimation].getHeight()*abs(this.scale);
//quadTree.insert(this);
this.colliderType = 'image';
//print("IMAGE COLLIDER ADDED");
Expand All @@ -1302,7 +1368,7 @@ function Sprite(pInst, _x, _y, _w, _h) {
}
else //get the with and height defined at the creation
{
this.collider = new AABB(pInst, this.position, createVector(this.width, this.height));
this.collider = new AABB(pInst, this.position, createVector(this._internalWidth, this._internalHeight));
//quadTree.insert(this);
this.colliderType = 'default';
}
Expand Down Expand Up @@ -1373,7 +1439,7 @@ function Sprite(pInst, _x, _y, _w, _h) {
else
print('Warning: onMousePressed should be a function');

if(mouseWasPressed && !this.mouseIsPressed && this.onMouseReleased !== undefined)
if(mouseWasPressed && !pInst.mouseIsPressed && !this.mouseIsPressed && this.onMouseReleased !== undefined)
if(typeof(this.onMouseReleased) === 'function')
this.onMouseReleased.call(this, this);
else
Expand Down Expand Up @@ -1584,7 +1650,7 @@ function Sprite(pInst, _x, _y, _w, _h) {
{
noStroke();
fill(this.shapeColor);
rect(0, 0, this.width, this.height);
rect(0, 0, this._internalWidth, this._internalHeight);
}
};

Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
"description": "A p5.js library for the creation of games and playthings.",
"dependencies": {},
"devDependencies": {
"eslint": ">=2.5.3 <2.10.0",
"eslint": "^3.1.0",
"http-server": "^0.9.0",
"mocha-phantomjs": "^4.0.1",
"yuidocjs": "^0.10.0"
},
"engines": {
"node" : ">=4.0.0"
},
"scripts": {
"docs": "yuidoc .",
"lint": "eslint lib/** test/unit/** examples/*.js",
Expand Down
163 changes: 163 additions & 0 deletions test/unit/sprite.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,167 @@ describe('Sprite', function() {
expect(sprite.height).to.equal(30);
});
});

describe('mouse events', function() {
var sprite;

beforeEach(function() {
// Create a sprite with centered at 50,50 with size 100,100.
// Its default collider picks up anything from 1,1 to 99,99.
sprite = pInst.createSprite(50, 50, 100, 100);
sprite.onMouseOver = sinon.spy();
sprite.onMouseOut = sinon.spy();
sprite.onMousePressed = sinon.spy();
sprite.onMouseReleased = sinon.spy();
});

function moveMouseTo(x, y) {
pInst.mouseX = x;
pInst.mouseY = y;
sprite.update();
}

function moveMouseOver() {
moveMouseTo(1, 1);
}

function moveMouseOut() {
moveMouseTo(0, 0);
}

function pressMouse() {
pInst.mouseIsPressed = true;
sprite.update();
}

function releaseMouse() {
pInst.mouseIsPressed = false;
sprite.update();
}

it('mouseIsOver property represents whether mouse is over collider', function() {
moveMouseTo(0, 0);
expect(sprite.mouseIsOver).to.be.false;
moveMouseTo(1, 1);
expect(sprite.mouseIsOver).to.be.true;
moveMouseTo(99, 99);
expect(sprite.mouseIsOver).to.be.true;
moveMouseTo(100, 100);
expect(sprite.mouseIsOver).to.be.false;
});

describe('onMouseOver callback', function() {
it('calls onMouseOver when the mouse enters the sprite collider', function() {
moveMouseOut();
expect(sprite.onMouseOver.called).to.be.false;
moveMouseOver();
expect(sprite.onMouseOver.called).to.be.true;
});

it('does not call onMouseOver when the mouse moves within the sprite collider', function() {
moveMouseTo(0, 0);
expect(sprite.onMouseOver.callCount).to.equal(0);
moveMouseTo(1, 1);
expect(sprite.onMouseOver.callCount).to.equal(1);
moveMouseTo(2, 2);
expect(sprite.onMouseOver.callCount).to.equal(1);
});

it('calls onMouseOver again when the mouse leaves and returns', function() {
moveMouseOut();
expect(sprite.onMouseOver.callCount).to.equal(0);
moveMouseOver();
expect(sprite.onMouseOver.callCount).to.equal(1);
moveMouseOut();
expect(sprite.onMouseOver.callCount).to.equal(1);
moveMouseOver();
expect(sprite.onMouseOver.callCount).to.equal(2);
});
});

describe('onMouseOut callback', function() {
it('calls onMouseOut when the mouse leaves the sprite collider', function() {
moveMouseOver();
expect(sprite.onMouseOut.called).to.be.false;
moveMouseOut();
expect(sprite.onMouseOut.called).to.be.true;
});

it('does not call onMouseOut when the mouse moves outside the sprite collider', function() {
moveMouseTo(0, 0);
expect(sprite.onMouseOut.called).to.be.false;
moveMouseTo(0, 1);
expect(sprite.onMouseOut.called).to.be.false;
});

it('calls onMouseOut again when the mouse returns and leaves', function() {
moveMouseOver();
expect(sprite.onMouseOut.callCount).to.equal(0);
moveMouseOut();
expect(sprite.onMouseOut.callCount).to.equal(1);
moveMouseOver();
expect(sprite.onMouseOut.callCount).to.equal(1);
moveMouseOut();
expect(sprite.onMouseOut.callCount).to.equal(2);
});
});

describe('onMousePressed callback', function() {
it('does not call onMousePressed if the mouse was not over the sprite', function() {
expect(sprite.mouseIsOver).to.be.false;
pressMouse();
expect(sprite.onMousePressed.called).to.be.false;
});

it('calls onMousePressed if the mouse was pressed over the sprite', function() {
moveMouseOver();
pressMouse();
expect(sprite.onMousePressed.called).to.be.true;
});

it('calls onMousePressed if the mouse was pressed outside the sprite then dragged over it', function() {
pressMouse();
moveMouseOver();
expect(sprite.onMousePressed.called).to.be.true;
});
});

describe('onMouseReleased callback', function() {
it('does not call onMouseReleased if the mouse was never pressed over the sprite', function() {
expect(sprite.mouseIsOver).to.be.false;
pressMouse();
releaseMouse();
expect(sprite.onMouseReleased.called).to.be.false;
});

it('calls onMouseReleased if the mouse was pressed and released over the sprite', function() {
moveMouseOver();
pressMouse();
releaseMouse();
expect(sprite.onMouseReleased.called).to.be.true;
});

it('calls onMouseReleased if the mouse was pressed, moved over the sprite, and then released', function() {
pressMouse();
moveMouseOver();
releaseMouse();
expect(sprite.onMouseReleased.called).to.be.true;
});

it('does not call onMouseReleased on mouse-out if mouse is still down', function() {
pressMouse();
moveMouseOver();
moveMouseOut();
expect(sprite.onMouseReleased.called).to.be.false;
});

it('does not call onMouseReleased on release if mouse has left sprite', function() {
moveMouseOver();
pressMouse();
moveMouseOut();
releaseMouse();
expect(sprite.onMouseReleased.called).to.be.false;
});
});
});
});

0 comments on commit 1fef5fb

Please sign in to comment.