Curve Sprite Movement COCOS2D - math

I'm trying with no luck to move a sprite position in an simetric curve way with the touch drag. So far I use the following code with no luck
-(BOOL) ccTouchBegan:(UITouch*)touch withEvent:(UIEvent *)event
{
lastTouchLocation = [MultiLayer locationFromTouch:touch];
return YES;
}
-(void) ccTouchMoved:(UITouch*)touch withEvent:(UIEvent *)event
{
CGPoint currentTouchLocation = [MultiLayer locationFromTouch:touch];
moveTo = ccpSub(lastTouchLocation, currentTouchLocation);
lastTouchLocation = currentTouchLocation;
}
-(void) update:(ccTime)delta
{
CCSprite* sprite = [sprites objectAtIndex:1];
if (moveTo.x != 0){
float X = sprite.position.x + moveTo.x;
float Y = sprite.position.y + (pow(X,2));
sprite.position = CGPointMake(X, Y);
}
}
The curve way i'm trying to simulate is in the form y=x^2. Is this posible?
Thanks in advance!

Yes it's possible. You can do it manually as your are trying, but it's better to use a built-in solution. There is a CCJumpTo and CCJumpBy actions in cocos2d engine. They are created for parabolic moves. Use them

Related

Using CSS setProperty for top does not work well when implement GWT drag

I am implementing a GWT application, have a scroll panel, flow panel which contains image, mouse down/move/up to drag the flow panel in scroll panel.
Left part (x direction) works perfectly, however, the same code for top (y direction) does not work well, it seems it shake and move unstable.
Somehow the top value is much larger than left which cause the problem, but no idea how it happens and how to make the Y direction work smoothly.
public void mouseDown(MouseDownEvent event)
{
isMouseDown = true;
event.preventDefault();
xoffset = event.getX();
yoffset = event.getY();
Event.setCapture(panel.getElement());
}
public void mouseMove(MouseMoveEvent event) {
int = event.getX();
int y = event.getY();
float left = panel.getAbsoluteLeft();
float top = panel.getAbsoluteTop();
float offset_XX = x - xoffset;
float offset_YY = y - yoffset;
panel.getElement().getStyle().setProperty("position", "absolute");
float newLeft = left + offset_XX;
if (isMouseDown) {
if (newLeft < scrollPanel.getAbsoluteLeft() ) {
offset_XX = offset_XX - Math.abs(scrollPanel.getAbsoluteLeft() -panel.getAbsoluteLeft());
if (Math.abs(offset_XX) > Math.abs(scrollPanel.getOffsetWidth() - panel.getOffsetWidth())) {
if (offset_XX > 0 )
offset_XX = Math.abs(scrollPanel.getOffsetWidth() - panel.getOffsetWidth());
else
offset_XX = -Math.abs(scrollPanel.getOffsetWidth() - panel.getOffsetWidth());
}
panel.getElement().getStyle().setPropertyPx("left", (int)offset_XX);
}
float newtop = top + offset_YY;
if (newtop < scrollPanel.getAbsoluteTop()) {
offset_YY = offset_YY - Math.abs(scrollPanel.getAbsoluteTop() -panel.getAbsoluteTop());
if (Math.abs(offset_YY) > Math.abs(scrollPanel.getOffsetHeight() - panel.getOffsetHeight())) {
if (offset_YY > 0 )
offset_YY = Math.abs(scrollPanel.getOffsetHeight() - panel.getOffsetHeight());
else
offset_YY = -Math.abs(scrollPanel.getOffsetHeight() - panel.getOffsetHeight());
}
panel.getElement().getStyle().setPropertyPx("top", (int)offset_YY);
}
}
}
Long story short, there're too many computations and DOM calls going on in your drag code. I suggest you to incorporate GWT team's solution for draggable/resizable panels following the implementation of com.google.gwt.logging.client.LoggingPopup. It's very fast, elegant, easy to understand and use. You can get the code here https://github.com/stephenh/google-web-toolkit/blob/master/user/src/com/google/gwt/logging/client/LoggingPopup.java

UIBezierPath colour

I followed this tutorial to create a drawing application. It all works really well at making smooth curves. The problem is that as I draw the line is black, and once I let go it makes the line the colour that I want. The tutorial does not go into line colour, but I have altered it. The only problem is that it's black until touchesEnded runs.
Here is my code:
This first section sets the colour to black.
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder])
{
[self setMultipleTouchEnabled:YES];
path = [UIBezierPath bezierPath];
[path setLineWidth:10.0];
red = 0.0/255.0;
green = 0.0/255.0;
blue = 0.0/255.0;
brush = 10.0;
opacity = 0.8;
toolSelected = 1;
bgImage = 1;
}
return self;
}
Then on touchesEnded this code is ran:
- (void)drawBitmap
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
if (!incrementalImage) // first time; paint background white
{
UIBezierPath *rectpath = [UIBezierPath bezierPathWithRect:self.bounds];
[[UIColor clearColor] setFill];
[rectpath fill];
}
[incrementalImage drawAtPoint:CGPointZero];
UIColor *colour = [UIColor colorWithRed:red green:green blue:blue alpha:opacity];
[colour setStroke];
[path stroke];
incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
I assume that something needs to be ran in the touchesMoved to colourise the bezier path, but I'm just really struggling with it right now.
Can anyone help?
Thanks
It was achieved in the end by adding these two lines to this section
- (void)drawRect:(CGRect)rect
{
[[UIColor redColor]setStroke]; // Added these
[[UIColor redColor]setFill]; // two lines
[incrementalImage drawInRect:rect];
[path stroke];
}

Animating a sprite after a touch?

In a game that I am making whilst using Cocos2d, I have a sprite down the bottom of the screen that stays still. When the screen is tapped, I would like the sprite to move to where the screen was tapped, and then animate through the series of frames, then move to its original position. I know that I will need to use a CCSequence, but I don't yet know how to make it move to the location of the touch. At the moment, I have searched around and I am using this code:
-(void) TouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *Touch = [touches anyObject];
CGPoint location = [Touch locationInView:[Touch view]];
[swat runAction:[CCMoveTo actionWithDuration:3 position:location]];}
I am getting no errors, but the sprite is unresponsive. Any ideas?
First, you have a typo in method's name. It's "ccTouchesBegan", not "TouchesBegan".
-(void)ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
Second, your sprite will not move to where you expect. locationInView returns point in UIKit coordinates, and CCMoveTo uses OpenGL coordinates. You need to convert the point to OpenGL coordinates:
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
Use
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
First make sure you have registered TouchDispatcher:
(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
Then implement :
(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event method
and also confirm you have:
self.isTouchEnabled = YES;
line of code in init() method.

Image Rotate 3D in Flex, but display another image on back of this image?

i want to rotate 3D an Image called img1 in Flex. I want to rotate it around y axis 180 degree. I can do this by using 3D effect already built in Flex but i want to do a bit more different.
I want during rotating, there's another image called img2 appear on back of img1 (in default case, the image appear on the back is img1) and when rotating finish, the image will be img2.
How can i do this ?
Thank you.
If you need no perspective effect, it's quite easy to do. A rough implementation (not tested!):
// Event.ENTER_FRAME event listener
void on_enter_frame(event:Event):void
{
// m_angle is a member of the class/flex component where on_enter_frame is declared
// ANGLE_DELTA is just a constant
m_angle += ANGLE_DELTA;
// Angle clamping to the range [0, PI * 2)
m_angle %= Math.PI * 2;
if (m_angle < 0)
m_angle += Math.PI * 2;
// If we currently look at the front side...
if (m_angle < Math.PI)
{
img1.visible = true;
img2.visible = false;
img1.scaleX = Math.cos(m_angle);
}
else
{
img1.visible = false;
img2.visible = true;
// If you omit negation, the back-side image will be mirrored
img2.scaleX = -Math.cos(m_angle);
}
}
So every frame we increase the rotation angle, clamp it to the range [0, PI * 2). Then depending on the value of the rotation angle, we hide/show the pair of your images, and then perform x-scaling of the visible image.
Thank you, now i found a solution. Please check it here, it's very easy to do.
http://forums.adobe.com/thread/921258

flex: Drag and drop- object centering

In a drag+drop situation using Flex, I am trying to get the object center aligned to the point of drop- somehow, irrespective of the adjustments to height and width, it is always positioning drop point to left top.
here is the code..
imageX = SkinnableContainer(event.currentTarget).mouseX;
imageY = SkinnableContainer(event.currentTarget).mouseY;
// Error checks if imageX/imageY dont satisfy certain conditions- move to a default position
// img.width and img.height are both defined and traced to be 10- idea to center image to drop point
Image(event.dragInitiator).x = imageX-(img.width)/2;
Image(event.dragInitiator).y = imageY-(img.height)/2
The last 2 lines don't seem to have any effect. Any ideas why-must be something straightforward, that I am missing...
You can use the following snippet:
private function on_drag_start(event:MouseEvent):void
{
var drag_source:DragSource = new DragSource();
var drag_initiator:UIComponent = event.currentTarget as UIComponent;
var thumbnail:Image = new Image();
// Thumbnail initialization code goes here
var offset:Point = this.localToGlobal(new Point(0, 0));
offset.x -= event.stageX;
offset.y -= event.stageY;
DragManager.doDrag(drag_initiator, drag_source, event, thumbnail, offset.x + thumbnail.width / 2, offset.y + thumbnail.height / 2, 1.0);
}
Here is one important detail. The snippet uses stage coordinate system.
If you use event.localX and event.localY, this approach will fail in some cases. For example, you click-and-drag a movie clip. If you use localX and localY instead of stage coordinates, localX and localY will define coordinates in currently clicked part of the movie clip, not in the whole movie clip.
Use the xOffset and yOffset properties in the doDrag method of DragManager.
Look here for an example.

Resources