In my code (sample) below I would like to change the sprite's image during the sequence of actions.
spriteActions = [CCRepeatForever actionWithAction:
[CCSequence actions:
[CCShow action],
[CCDelayTime actionWithDuration:1.5],
[CCHide action],
[CCDelayTime actionWithDuration:5.0],
[CCShow action],
[CCDelayTime actionWithDuration:3.0],
// I would like to change the sprite image here before completing the remaining actions.
//I want this line here: sprite = [CCSprite SpriteWithFile:#"newSpriteImage.png"];
[CCMoveTo actionWithDuration:2.0 position:newSpritePos],
[CCHide action],
[CCDelayTime actionWithDuration:2.0],
nil]];
[sprite runAction:spriteActions];
Thanks for the assistance.
You do like this:
[CCRepeatForever actionWithAction:
[CCSequence actions:
[CCShow action],
[CCDelayTime actionWithDuration:1.5],
[CCHide action],
[CCDelayTime actionWithDuration:5.0],
[CCShow action],
[CCDelayTime actionWithDuration:3.0],
// I would like to change the sprite image here before completing the remaining actions.
[CCCallBlockN actionWithBlock:^(CCNode*node){
CCSprite *spritN = (CCSprite*)node;
//[spritN setDisplayFrame:[cache spriteFrameByName:#"newSpriteImage.png"]]
CCTexture2D* tex = [[CCTextureCache sharedTextureCache] addImage:#"newSpriteImage.png"];
CGSize texSize = tex.contentSize;
CGRect texRect = CGRectMake(0, 0, texSize.width, texSize.height);
CCSpriteFrame* frame = [CCSpriteFrame frameWithTexture:tex rect:texRect];
[spritN setDisplayFrame:frame];
}],
[CCMoveTo actionWithDuration:2.0 position:newSpritePos],
[CCHide action],
[CCDelayTime actionWithDuration:2.0],
nil]];
Related
I am using chart.js to create a stacked bar chart and while I have succeed to move and rotate the xaxis labels to be shown on the top of the bars, when I use mouse to move over the bars, the whole chart appears distorted.
this is the normal
and this is what i get after mouse over:
here is the code
this is what i use to rotate xaxis labels:
https://jsfiddle.net/staverist/zhocr17t/96/
animation: {
duration: 1,
onComplete: function() {
var chartInstance = this.chart;
var ctx = chartInstance.ctx;
ctx.textAlign = "left";
ctx.font = "bold 10px Arial";
ctx.fillStyle = "black";
Chart.helpers.each(this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
Chart.helpers.each(meta.data.forEach(function (bar, index) {
ctx.save();
// Translate 0,0 to the point you want the text
ctx.translate(bar._model.x, bar._model.y - 30);
// Rotate context by -90 degrees
ctx.rotate(-0.5 * Math.PI);
// Draw text
//ctx.fillText(value,0,0);
if(bar._datasetIndex==0){
ctx.fillText(bar._model.label, 0, 0);
ctx.restore();
}
}),this)
}),this);
}
This is because you are not restoring the canvas state after rotating it. Instead of restoring it inside the if statement, you should restore it outside, like so :
...
if (bar._datasetIndex == 0) {
ctx.fillText(bar._model.label, 0, 0);
}
ctx.restore(); //<- restore canvas state
...
also, you should better create a plugin (to prevent label flickering), instead of drawing the labels on animation complete.
Here is the working example on JSFiddle
[CCAnimation animationWithFrame:frame
frameCount:2
delay:0.5]
self.abc = [CCSequence actions:
[CCDelayTime actionWithDuration:1],
[CCSpawn actions:
[CCAnimate actionWithAnimation:[CCAnimation animationWithFrame:abc
frameCount:2
delay:0.5]
restoreOriginalFrame:YES],
[CCCallFunc actionWithTarget:self selector:#selector(abc)],
nil],
[CCDelayTime actionWithDuration:0.5],
[CCCallFunc actionWithTarget:self selector:#selector(abc)],
nil
];
I have two surfaces. One is draggable and one is 'full screen' (size: [undefined, undefined]). I'd like to drag the first surface (yellow in my example) right and have the second (green)surface appear. When I click on the green surface, I'd like show the first surface again back in the original starting point (center of screen).
I'd also like the green surface to be non-draggable.
I'm a famo.us novice, and any help is GREATLY appreciated!
fiddle here: http://jsfiddle.net/cjs123456/vfzy4j51/
// the position state
var position = [0, 0];
// create a Sync to listen to mouse events
var sync = new MouseSync();
var renderController = new RenderController();
var mySurface = new Surface({
size: [350, 200],
content: 'drag me right more than 100px to see other surface',
properties: {
backgroundColor: "hsl(" + (5 * 360 / 40) + ", 100%, 50%)",
lineHeight: '200px',
textAlign: 'center',
cursor: 'pointer'
}
});
// Surface provides events that the sync listens to
mySurface.pipe(sync);
// Syncs have `start`, `update` and `end` events. On `update` we increment the position state of the surface based
// on the change in x- and y- displacements
sync.on('update', function(data){
position[0] += data.delta[0];
position[1] += data.delta[1];
console.log(data.position[0]);
if (data.position[0] > 100) {
console.log("FULL");
renderController.show(fullSurface);
}
});
// this modifier reads from the position state to create a translation Transform that is applied to the surface
var positionModifier = new Modifier({
transform : function(){
return Transform.translate(position[0], position[1], 0);
}
});
// a modifier that centers the surface
var centerModifier = new Modifier({
origin : [0.5, 0.5],
align: [0.5, 0.5]
});
var fullSurface = new Surface({
size: [undefined, undefined],
content: 'Click me to show other surface',
properties: {
backgroundColor: "hsl(" + (9 * 360 / 40) + ", 100%, 50%)",
lineHeight: '400px',
textAlign: 'center'
}
});
fullSurface.on("click", function() {
renderController.show(mySurface);
});
renderController.show(mySurface);
var mainContext = Engine.createContext();
var node = mainContext.add(centerModifier).add(positionModifier);
node.add(renderController);
});
There are more than one way to solve this issue.
Control the dragging of the render controller
Create separate render controller and control views
Because your use case here is simple enough, I will show the creating of a separate render controller
Here is the jsFiddle Example of the Code
Create a background render controller
var renderController = new RenderController();
var backRenderController = new RenderController();
Change the node to be the center modifier. Add our draggable to the node. Add the background controller to the node.
var node = mainContext.add(centerModifier)
node.add(positionModifier).add(renderController);
node.add(backRenderController);
Control the draggable render contoller view (Line 42)
renderController.hide();
backRenderController.show(fullSurface);
Clicking on the background will reset the position of the draggable back to the origin, hide the background and show the draggable again.
// Set draggable position back to the origin
position = [0, 0];
// Hide the back render element
backRenderController.hide();
// Show the draggable
renderController.show(mySurface);
Full code:
// the position state
var position = [0, 0];
// create a Sync to listen to mouse events
var sync = new MouseSync();
var renderController = new RenderController();
var backRenderController = new RenderController();
var mySurface = new Surface({
size: [350, 200],
content: 'drag me right more than 100px to see other surface',
properties: {
backgroundColor: "hsl(" + (5 * 360 / 40) + ", 100%, 50%)",
lineHeight: '200px',
textAlign: 'center',
cursor: 'pointer'
}
});
// Surface provides events that the sync listens to
mySurface.pipe(sync);
// Syncs have `start`, `update` and `end` events. On `update` we increment the position state of the surface based
// on the change in x- and y- displacements
sync.on('update', function (data) {
position[0] += data.delta[0];
position[1] += data.delta[1];
console.log(data.position[0]);
if (data.position[0] > 100) {
console.log("FULL");
renderController.hide();
backRenderController.show(fullSurface);
}
//else {
// mySurface.setPosition([0,0,0], {
// curve: Easing.outBack,
// duration: 300
// });
//}
});
// this modifier reads from the position state to create a translation Transform that is applied to the surface
var positionModifier = new Modifier({
transform: function () {
return Transform.translate(position[0], position[1], 0);
}
});
// a modifier that centers the surface
var centerModifier = new Modifier({
origin: [0.5, 0.5],
align: [0.5, 0.5]
});
var fullSurface = new Surface({
size: [undefined, undefined],
content: 'Click me to show other surface',
properties: {
backgroundColor: "hsl(" + (9 * 360 / 40) + ", 100%, 50%)",
lineHeight: '400px',
textAlign: 'center'
}
});
fullSurface.on("click", function () {
// Set draggable position back to the origin
position = [0, 0];
// Hide the back render element
backRenderController.hide();
// Show the draggable
renderController.show(mySurface);
});
//var node = mainContext.add(myModifier);
//node.add(draggable).add(surface);
renderController.show(mySurface);
var mainContext = Engine.createContext();
//mainContext.add(myModifier).add(draggable).add(renderController);
var node = mainContext.add(centerModifier)
node.add(positionModifier).add(renderController);
node.add(backRenderController);
based on how to add walls to a famo.us physics simulation? there is a ball that will bounce off of walls
How do you go about adding a repulsion to the particle so that it will never hit the walls?
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var EventHandler = require('famous/core/EventHandler');
var View = require('famous/core/View');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var PhysicsEngine = require('famous/physics/PhysicsEngine');
var Body = require('famous/physics/bodies/Body');
var Circle = require('famous/physics/bodies/Circle');
var Wall = require('famous/physics/constraints/Wall');
var Repulsion = require('famous/physics/forces/Repulsion');
module.exports = function () {
var context = Engine.createContext();
var contextSize = context.getSize();
var handler = new EventHandler();
var physicsEngine = new PhysicsEngine();
var ball = new Surface ({
size: [200,200],
properties: {
backgroundColor: 'red',
borderRadius: '100px'
}
})
ball.state = new StateModifier({origin:[0.5,0.5]});
ball.particle = new Circle({radius:100});
var replusion = new Repulsion();
ball.particle.applyForce(replusion);
physicsEngine.addBody(ball.particle);
ball.on("click",function(){
ball.particle.setVelocity([1,1,0]);
});
context.add(ball.state).add(ball)
var leftWall = new Wall({normal : [1,0,0], distance : contextSize[0]/2.0, restitution : 0.5});
var rightWall = new Wall({normal : [-1,0,0], distance : contextSize[0]/2.0, restitution : 0.5});
var topWall = new Wall({normal : [0,1,0], distance : contextSize[1]/2.0, restitution : 0.5});
var bottomWall = new Wall({normal : [0,-1,0], distance : contextSize[1]/2.0, restitution : 0.5});
physicsEngine.attach( leftWall, [ball.particle]);
physicsEngine.attach( rightWall, [ball.particle]);
physicsEngine.attach( topWall, [ball.particle]);
physicsEngine.attach( bottomWall,[ball.particle]);
Engine.on('prerender', function(){
ball.state.setTransform(ball.particle.getTransform())
});
};
My first thought is to add repulsion to the ball's particle, but that doesn't seem to be working.
Has anyone done this or is there good documentation for this type of behavior?
I've played around and I think I have a somewhat better idea now.
This code with two balls (particles) in the same physics engine will repel ( one will chase the other around )
var context = Engine.createContext();
var contextSize = context.getSize();
var handler = new EventHandler();
var physicsEngine = new PhysicsEngine();
var ball = new Surface ({
size: [200,200],
properties: {
backgroundColor: 'red',
borderRadius: '100px'
}
})
ball.state = new StateModifier({origin:[0.4,0.3]});
ball.particle = new Circle({radius:100});
var ball2 = new Surface ({
size: [200,200],
properties: {
backgroundColor: 'green',
borderRadius: '100px'
}
})
ball2.state = new StateModifier({origin:[0.3,0.3]});
ball2.particle = new Circle({radius:100});
var leftWall = new Wall({normal : [1,0,0], distance : contextSize[0]/4.0, restitution : 0.3});
var rightWall = new Wall({normal : [-1,0,0], distance : contextSize[0]/4.0, restitution : 0.3});
var topWall = new Wall({normal : [0,1,0], distance : contextSize[1]/4.0, restitution : 0.3});
var bottomWall = new Wall({normal : [0,-1,0], distance : contextSize[1]/4.0, restitution : 0.3});
physicsEngine.attach( leftWall, [ball.particle, ball2.particle]);
physicsEngine.attach( rightWall, [ball.particle, ball2.particle]);
physicsEngine.attach( topWall, [ball.particle, ball2.particle]);
physicsEngine.attach( bottomWall,[ball.particle, ball2.particle]);
physicsEngine.addBody(ball.particle);
physicsEngine.addBody(ball2.particle);
The repulsion has to be added to the PE with a target and source, both of which must already exist in the engine.
var replusion = new Repulsion({strength: 90});
physicsEngine.attach(replusion, [ball2.particle], ball.particle);
ball.on("click",function(){
ball.particle.setVelocity([1,0,0]);
});
ball2.on("click",function(){
ball2.particle.setVelocity([1,1,0]);
});
context.add(ball.state).add(ball)
context.add(ball2.state).add(ball2)
Engine.on('prerender', function(){
ball.state.setTransform(ball.particle.getTransform())
ball2.state.setTransform(ball2.particle.getTransform())
});
I want to ask is it possible to combine ccsequence and a bool??
[self runAction:[CCSequence actions:
myAnimation,
(myBool = YES),
[CCDelayTime actionWithDuration:myTime],
[CCCallFunc actionWithTarget:self selector:#selector(otherAnimation)],
nil]];
But if i do it this way the program breaks down.
Does anybody know a solution??
you was on the right way, you can simply change your action like this
[self runAction:[CCSequence actions:
myAnimation,
//OLD_VERSION(myBool = YES),
[CCCallFunc actionWithTarget:self selector:#selector(yourBoolMethod)],
[CCDelayTime actionWithDuration:myTime],
[CCCallFunc actionWithTarget:self selector:#selector(otherAnimation)],
nil]];
and inside yourBoolMethod set the bool as true
-(void) yourBoolMethod {
myBool = YES:
}