cannot get cc.point and delay to work together - cocos2d-html5

OK think Space Invaders and Galaga. I have an enemy squadron at the top of the screen. They move left and right and down the screen as a group. Every now and then an enemy fighter leaves the group and attack's the player's ship. does a few bezier curves, attempts to attack the player's ship. If the enemy fighter misses he (1) fly off the bottom of the screen, hides, moves to the top of the screen, appears and flys back into its position in the squadron. The problem is the enemy fighter flys back into the position where it left the squadron not where its current position should be.
set variable new_pos
call action function with delay to handle the bezier flight paths e.g.
action ((bezier), (delay 5 seconds), (hide enemy fighter), (delay 1 second), (move enemy fighter to top of screen), (display enemy fighter), (callfunc to get the enemy fighter's new position in the squadron), (bezier back to new position)
CallFunc seems to get called as soon as the parent function is called. Not after the delay. Is what I am expecting possible?
var epos = 0;
if (enemy_fly_out_from == 0)
this.runAction(cc.Sequence.create(cc.DelayTime.create(enemy_fly_out_duration), cc.CallFunc.create(this.reduce_flied_out, this), cc.MoveTo.create(1, cc.p(ship_pos.x-25, -25)), cc.Hide.create(), cc.MoveTo.create(0, cc.p(ship_pos.x-25, 610)), cc.Show.create(), cc.CallFunc.create(this.get_enemy_pos(which_enemy), this), cc.BezierTo.create(5, [cc.p(ship_pos.x-25, 600), cc.p(pos.x, 600), cc.p(epos.x,epos.y)]), cc.CallFunc.create(this.end_fly_out(which_enemy), this)));
else
this.runAction(cc.Sequence.create(cc.DelayTime.create(enemy_fly_out_duration), cc.CallFunc.create(this.reduce_flied_out, this), cc.MoveTo.create(1, cc.p(ship_pos.x+25, -25)), cc.Hide.create(), cc.MoveTo.create(0, cc.p(ship_pos.x+25, 610)), cc.Show.create(), cc.CallFunc.create(this.get_enemy_pos(which_enemy), this), cc.BezierTo.create(5, [cc.p(ship_pos.x+25, 600), cc.p(pos.x-100, 600), cc.p(epos.x, epos.y)]), cc.CallFunc.create(this.end_fly_out(which_enemy), this)));
},
end_fly_out:function(which_enemy)
{
enemies_array[which_enemy].flied_out = 0;
},
get_enemy_pos:function(which_enemy)
{
epos = enemies_array[which_enemy].getPosition();
},
reduce_flied_out:function()
{
enemies_flied_out = 0;
}

I have solved this by (1) create a new sprite based on the enemy fighter that flys out of the squadron (2) hide the enemy fighter (3) show the new sprite (4) the new sprite acts as the enemy fighter (5) hide the sprite (6) display the enemy fighter
Thank you for your time #Sebastian Vansteenkiste. If sprite is not shot by the defender, i.e. the sprite completes its flight, then it flys out of screen via the bottom
cc.MoveTo.create(1, cc.p(ship_pos.x + 25, -25)). It then reappears out of screen at the top of the screen cc.MoveTo.create(1, cc.p(ship_pos.x + 25, 610)). It then flys back into position in the squadron.

Related

How to apply two-finger touch anywhere in the image, such that the point stays at the same location

I have a 2D texture image that is zoomed in/out via 2-finger touch and pinch.
Currently the image is not panned, i.e. the center of the image is always in the middle.
I want the center point between the twoFinger touch to stay between the 2 fingers.
If I pinch exactly in the center of the image, then the center image point will stay between the fingers - good!
But if I pinch near the corner of the image the point will move away, relative to the 2 fingers, because of the zoom.
So I need to apply some pan in addition to the zoom, to make the point appear in the same place.
I basically need to transftorm the camera position such that, for every zoom, the same world coordinate is projected to the same screen coord.
Figures 1-3 illustrate the problem.
Figure1 is the original image.
Currently when I zoom in the camera stays in the same position, so the object between the 2 fingers (the cat's eye on the right) is drifted from being between the 2 fingers, as the image zooms (Figure 2).
I want to pan the camera such that the object between the 2 fingers stays between the 2 fingers even after the zooming the image (Figure 3).
I used the code below, but the object still drifts as the image zooms in/out.
How should I calculate the amount of shift that needs to be applied to the camera?
Thanks
Code to calculate the amount of shift that needs to be applied to the camera
handleTwoFingerTouchMove( p3_inScreenCoord) {
// normalize the screen coord to be in the range of [-1, 1]
// (See method1 in https://stackoverflow.com/questions/13542175/three-js-ray-intersect-fails-by-adding-div/)
let point2dNormalizedX = ( ( p3_inScreenCoord.x - windowOffset.left ) / windowWidth) * 2 - 1;
let point2dNormalizedY = -( ( p3_inScreenCoord.y - windowOffset.top ) / windowHeight) * 2 + 1;
// calc p3 before zoom (in world coords)
let p3_beforeZoom = new THREE_Vector3( point2dNormalizedX, point2dNormalizedY, -1 ).unproject( this.camera );
// Apply zoom
this.dollyInOut( this.getZoomScale(), true );
// calc p3 after zoom (in world coords)
let p3_afterZoom = new THREE_Vector3( point2dNormalizedX, point2dNormalizedY, -1 ).unproject( this.camera );
// calc the required shift in camera position
let deltaX = p3_afterZoom.x - p3_beforeZoom.x;
let deltaZ = p3_afterZoom.z - p3_beforeZoom.z;
// shift in camera position
this.pan( deltaX, deltaZ );
};
I was able to solve my problem. Here is my solution in the hope that it helps others.
When first applying a 2-finger touch (i.e. on touchstart event), the code computes:
the world-coordinate of the object pointed at (e.g. the cat's eye on the right), when starting two-finger touch
centerPoint3d_inWorldCoord0 (Vector3)
the screen-coordinate anchor for zooming via two-finger touch
centerPoint2dBetweenTwoFingerTouch_inScreenCoordNormalized (Vector2)
While zooming in/out via two-finger pinch in/out (on touchmove event)
in the event listener function, immediately after the applying the zoom,
I call the following code:
// Calculate centerPoint3d_inWorldCoord2, which is the new world-coordinate, for
// centerPoint2dBetweenTwoFingerTouch_inScreenCoordNormalized given the new zoom setting.
let centerPoint3d_inWorldCoord2 = new THREE_Vector3( centerPoint2dBetweenTwoFingerTouch_inScreenCoordNormalized.x,
centerPoint2dBetweenTwoFingerTouch_inScreenCoordNormalized.y,
-1 ).unproject( camera );
// compute the shift in world-coordinate between the new vs the original world-coordinate
let delta_inWorldCoords = new THREE_Vector2(centerPoint3d_inWorldCoord2.x - centerPoint3d_inWorldCoord0.x,
centerPoint3d_inWorldCoord2.z - centerPoint3d_inWorldCoord0.z);
// pan the camera, to compensate the shift
pan_usingWorldCoords( delta_inWorldCoords );
The function pan_usingWorldCoords shifts the camera in the x axis (panLeft), and then in the y axis (panUp)
pan_usingWorldCoords( delta_inWorldCoord ) {
panLeft( delta_inWorldCoord.x );
panUp( delta_inWorldCoord.y );
};
The functions panLeft, panUp are similar to the functions that are used in three.js-r114/examples/jsm/controls/OrbitControls.js
Initially the object pointed at was drifting from being between the 2 fingers, as the image zoomed in/out.
I added this.camera.updateProjectionMatrix() at the end of each function.
This updates the projection matrix at the end of panLeft, before using it again in panUp.
With the code above and after updating the projection matrix at the end of panLeft, panUp, the object pointed at (e.g. the eye on the right), when starting two-finger touch, is kept between the 2 fingers, while zooming via two-finger pinch.

JavaFX Dynamically creating objects and checking for collision with main character

I am currently trying to create a dodge-the-asteroid game in which the user controls a spaceship and tries to avoid the asteroids (3 kinds, small medium large). I currently have the animations all working (spaceship moving, asteroids falling). When the user presses start, the animation for randomly inserting asteroids begins:
public void startGame()
{
Timeline asteroids = new Timeline(new KeyFrame(Duration.seconds(.5), e -> displayAsteroid()));
asteroids.setCycleCount(Timeline.INDEFINITE);
asteroids.play();
}
Here is the code for creating the asteroids everytime the Timeline runs:
public void displayAsteroid()
{
// creates an asteroid object (constructor randomly creates one of 3 sizes)
Asteroid asteroid = new Asteroid();
getChildren().add(asteroid);
// randomly generates x coordinate from the board size
Random rand = new Random();
int randomNum = rand.nextInt((int) (getWidth() - asteroid.getWidth()));
//sets the x and y (y is -200 so that the asteroid doesn't just appear at top
// x is set to the random number
asteroid.setY(-200);
asteroid.setX(randomNum);
asteroid.setTranslateY(asteroid.getY());
asteroid.setTranslateX(randomNum);
// animation to move the asteroid down the screen
Timeline timeline = new Timeline();
KeyFrame keyFrame = new KeyFrame(Duration.millis(50), event -> {
// checks if the asteroid leaves the screen or if collision happens
if(asteroid.getY() > getHeight() || spaceShip.intersects(asteroid.getBoundsInParent()))
{
timeline.stop();
getChildren().remove(asteroid);
}
else
{
// getSpeed is the speed of the asteroid (small is fastest, large is slowest)
asteroid.setY(asteroid.getY()+asteroid.getSpeed());
asteroid.setTranslateY(asteroid.getY());
}
});
timeline.setCycleCount(Animation.INDEFINITE);
timeline.getKeyFrames().add(keyFrame);
timeline.play();
}
The spaceship is a pane (bunch of rectangles/ellipses) stacked onto eachother, and the asteroids are also panes with random ellipses stacked ontop of a big ellipse (to make it look like an asteroid).
As of now, the collision does not work, as it will randomly delete one every now and then and I had a bunch disappear as I hit one of them - several times. How can I change this code up so it detects when the asteroid comes into contact with the ship?
Yes, I have looked at other questions, but they were normal objects such as circles, which is why I haven't been able to get mine to work. I can provide additional code (asteroid/spaceship classes) to help you test this out if needed
I feel the logic is wrong behind my code, and any help is greatly appreciated!
Thank you, have a nice day ! :)

Modify x position of Gameobject while playing an animation - Unity

I have a gameobject with an animator controller. The gameobject moves from the bottom of the screen to the top, this movement is being controlled by the animation of th Y axis.
What i am trying to do is to also move it randomly in the X axis While the this animation is moving it in the Y axis
What i did was to set a few animation events in this main animation:
In this events i am calling a script that moves the object between 2 x positions:
public void RandomX ()
{
var pos = transform.position;
pos.x = Mathf.Clamp(transform.position.x, -1.75f, 2.85f);
print(pos.x);
}
But this is not working. Tha animation plays with no modifications in the X axis.
Thanks in advance for any help provided
The animation overwrites the transform position. For your object to be controlled by code, you would have to change the hierarchy.
-object A with script controlling x position
- object B with animation
Now you can move the parent object A by code. The animation controls only the object B.

Processing bat and ball game on vertical axis

This is the code I have at the moment but I want to put the bat on the y axis and have it move up and down vertically rather than horizontally, and have the ball bounce in a left to right motion rather than up and down. Help is needed quickly. Thanks.
int x=250; // Horizontal position of ball
int direction_x=2; // Change in horizontal position each time draw() executed
int y=150; // Vertical position of ball
int direction_y=2; // Change in horizontal position each time draw() executed
int lives=3;
int score=0;
void setup()
{
size(400,400); // Create a window 400x400 pixels
}
void draw()
{
background(255,255,255); // Clear screen to white
fill(0,255,0); // Set fill colour to blue
rect(mouseY-60,380,120,20); // Position rectangle using mouse
fill(0,0,255);
ellipse(x,y,20,20); // Draw blue disk centered on x,y diameter 20
x=x+direction_x; // Update position
if(x<10) direction_x=-direction_x; // Reverse direction if hit boundary
if(x>(width-10)) direction_x=-direction_x;
y=y+direction_y;
if(y<10) direction_y=-direction_y;
// if(y>(height-10)) direction_y=-direction_y;
if(y>(height-10)) // If ball bits bottom of screen then miss..
{
direction_y=-direction_y; // Bounce
lives--; // Reduce lives by one
if(lives==0) exit(); // If lives is zero then quit
}
if((y>(height-30))&&(abs(mouseX-x)<60)) // If ball has bit paddle then..
{
direction_y=-direction_y; // Bounce
score++; // Increase score by one
}
textSize(32);
fill(0,0,255);
text(score, 10, 30); // Display score
text(lives,width-30, 30); // Display lives
}
Since help is needed quickly, you'll have better luck if you ask a specific "I tried X, expected Y, but got Z instead" type question. It's hard to help with general "how do I do this" type questions, other than to offer general tips.
That being said, there are two main approaches that I can think of:
Option One: Break your problem down into smaller steps. Start with a blank sketch and get just the paddle working how you want it to. Then try adding the ball. After that's working, then try adding game logic. This is the better option here.
Option Two: Since you seem to almost have this working going up and down, you could just rotate everything 90 degrees by using the rotate() function. This is a bit of a hack though.
Thanks Kevin, got it working at last, turns out I just had to change co-ordinates of the paddle from (mouseX,0,0,0) to (0, mouseY,0,0) and needed to add in an additional line of code to change the axis parameters. I was doing my age old trick of over complicating things.
int x=250; // Horizontal position of ball
int direction_x=2; // Change in horizontal position each time draw() executed
int y=150; // Vertical position of ball
int direction_y=2; // Change in horizontal position each time dra) executed
int lives=3;
int score=0;
void setup()
{
size(400,400); // Create a window 400x400 pixels
}
void draw()
{
background(255,255,255); // Clear screen to white
fill(0,255,0); // Set fill colour to blue
rect(0,mouseY-60,20,120); // Position rectangle using mouse
fill(0,0,255);
ellipse(x,y,20,20); // Draw blue disk centered on x,y diameter 20
x=x+direction_x; // Update position
if(x<10) direction_x=-direction_x; // Reverse direction if hit boundary
if(x>(width-10)) direction_x=-direction_x;
y=y+direction_y;
if(y<10) direction_y=-direction_y;
// if(y>(height-10)) direction_y=-direction_y;
if(y>(height-10)) // If ball bits bottom of screen then miss..
{
direction_y=-direction_y; // Bounce
lives--; // Reduce lives by one
if(lives==0) exit(); // If lives is zero then quit
}
if(x<10)
{
direction_x=-direction_x; // Bounce
x=30; // Force x to beyond the paddle on a restart
lives--; // Reduce lives by one
if(lives==0) exit(); // If lives is zero then quit
}
if((x<30)&&(abs(mouseY-y)<60)) // If ball has bit paddle then..
{
direction_x=-direction_x; // Bounce
score++; // Increase score by one
}
textSize(32);
fill(0,0,255);
text(score, 10, 30); // Display score
text(lives,width-30, 30); // Display lives
}

Control ball movement by tilting device in Unity3D

I'm using the following script to control a ball but it doesn't do exactly what I want.
Our 3D game will be played in landscape mode with the home button (or bottom) of the device in the right hand. Tilting (not turning) the device to the left should make the ball roll left, tilting to the right should make it roll right. Tilting the device down (top of device going down) should make the ball roll faster and tilting the device upward should slow it down.
I don't want the ball to indefinitely accelerate either.
The code below wants the device held straight as opposed to laying flat and it moves the ball by turning the device not by tiling it.
void FixedUpdate()
{
// Player movement in mobile devices
// Building of force vector
Vector3 movement = new Vector3(-Input.acceleration.x, 0.0f, -Input.acceleration.z);
// Adding force to rigidbody
var move = movement * speed * Time.deltaTime;
rigidbdy.AddForce(move);
}
For your tilting problem you likely just need to choose something other than (-Input.acceleration.x, 0.0f, -Input.acceleration.z);, in the example in the documentation they do (-Input.acceleration.y, 0.0f, Input.acceleration.x); to do tilt controls.
For the max speed issue, just add a check for rigidbdy.velocity.magnitude > maxSpeed in your code and cap the value if it is maxed.
public float maxSpeed;
void FixedUpdate()
{
// Player movement in mobile devices
// Building of force vector
Vector3 movement = new Vector3(-Input.acceleration.y, 0.0f, Input.acceleration.x);
// Adding force to rigidbody
var move = movement * speed * Time.deltaTime;
rigidbdy.AddForce(move);
//Limits the max speed
if(rigidbdy.velocity.magnitude > maxSpeed)
{
rigidbdy.velocity = rigidbdy.velocity.normalized * maxSpeed;
}
}
That will cause the velocity to be capped to whatever value you have set for maxSpeed in the inspector.

Resources