Good day to all, I am trying to get an enemy boss ship to appear on screen and attack my ship and also dodge my attacks sometimes. So far I have gotten him to attack my ship but hes stays on the edge of the screen. Here is my code :
#pragma strict
// here are public variables for the enemy ship that can be accessed in the inspector
var health:int = 2;
var explosion:GameObject;
var expOrb:GameObject;
var enemyBullet:GameObject;
var expDrop:int = 3;
var hitSound:AudioClip;
var fireRate:float = 2.0;
//heres the private variable counter to keep track of time for fire rate.
private var counter:float = 0.0;
function Update () {
//here we make counter count based on time for the fire rate
counter += Time.deltaTime;
//if the ship goes too far left, we destroy it.
if(transform.position.x < -12){
Destroy(gameObject);
}
//here we shoot 4 bullets if the counter counts higher than the fire rate.
if(counter > fireRate){
var custom1 = Instantiate(enemyBullet, transform.position - Vector3(0.5,0.1,0), Quaternion.Euler(-90,0,0));
var custom2 = Instantiate(enemyBullet, transform.position - Vector3(0.5,0.1,0), Quaternion.Euler(-90,0,0));
var custom3 = Instantiate(enemyBullet, transform.position- Vector3(0.5,0.1,0), Quaternion.Euler(-90,0,0));
var custom4 = Instantiate(enemyBullet, transform.position- Vector3(0.5,0.1,0), Quaternion.Euler(-90,0,0));
//to make the bullets spread, we add extra z velocity to each one to they all move on their own path.
custom1.rigidbody.velocity.z = 3;
custom2.rigidbody.velocity.z = 1;
custom3.rigidbody.velocity.z = -1;
custom4.rigidbody.velocity.z = -3;
counter = 0.0;
}
//end of function update
}
//if a bullet hits the ship, the bullets sends us the hit message to trigger this function to bring down the ships health
function hit () {
health -= 1;
if(health != 0){
if(audio.enabled == true){
audio.PlayOneShot(hitSound);
}
}
if(health <= 0){
onDeath();
}
}
//if health is 0, then this function is triggered to spawn some orbs, spawn the explosion animation object, and destroy itself
function onDeath () {
Instantiate(expOrb,transform.position,Quaternion.Euler(-90,0,0));
expDrop -= 1;
if(expDrop <= 0){
Instantiate(explosion,transform.position,Quaternion.Euler(-90,Random.Range(-180,180),0));
Destroy(gameObject);
}
if(expDrop > 0){
onDeath();
}
}
How do i add the movement aspect to it?
There are many ways to move an object, you can try:
Transform.translate (http://docs.unity3d.com/ScriptReference/Transform.Translate.html)
Modifying transform.position (http://answers.unity3d.com/questions/188998/transformposition.html)
Adding force to it (http://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html)
And many other ways that I may have not known yet.
For a boss in this kind of game, the movement you may want is either random movement or following the player. Both are not hard to achieve.
Random movement: just do a Random.Range(-1, 1) * bossSpeed *
time.deltaTime and apply it to the boss' x position.
Following the player: get the player's x position then make the boss adjust to the position.
Then how to make the boss dodge the player's bullet sometimes? You can make the boss detect if a player's bullet is incoming by adding a collider thats stands in front of it. If a player's bullet collide with it, then random another number (eg. from 0 to 1). Afterwards, you just need to move the boss away if the random number is 1 and don't move the boss when the random number is 0.
Related
the gif will better explain what I'm trying to do.
Bow aim.
as you can see I can't get the arrow to follow the aim. The problem is I have the Bow and Arrow separate so the bow spawns the arrow and that's the problem I can't get the calculation of the hspeed and vspeed and gravity of the arrow to match the bow draw event of the doted aim. I will post the doted aim code and the arrow gravity/movement code the spawn code for the arrow is simple on the release of the button it spawns the arrow at the x,y position of the bow. If you need any other code I will post it. Sorry if it's not well explained.
Arrow Code:
End Step
///Check if parent still exists
if (parent != noone)
if (!instance_exists(parent))
{
parent = noone;
}
///Gravity
if (grav != 0)
{
hsp += lengthdir_x(grav, grav_dir);
vsp += lengthdir_y(grav, grav_dir);
}
///Increase gravity over time, up until a maximum amount
grav = min(grav+grav_add, grav_max);
///Limit speed
hsp = clamp(hsp, -hsp_max, hsp_max);
vsp = clamp(vsp, -vsp_max, vsp_max);
///Calculate directional speed
var sp = point_distance(0, 0, hsp, vsp);
direction = point_direction(0, 0, hsp, vsp);
Bow:
DrawEvent:
var _f_x = x;
var _f_y = y;
var _f_spd_x = draw_aim_circle_max * dcos(controler_angle)
var _f_spd_y = draw_aim_circle_max *-dsin(controler_angle)
while (!instance_place(_f_x,_f_y,objAimCircleKiller))
{
draw_sprite(sprAimCircleSmall,0,_f_x,_f_y+1);
_f_x += _f_spd_x
_f_spd_y += grav_aimCircle
_f_y += _f_spd_y;
}
Do you have some code in Arrow to slowdown the horizontal speed? It seems to stop faster than it should. Try to use a different variable to manage the horizontal speed instead of the grav var.
When calculate the x speed of the arrow, define an explicit value max speed. The arrow speed should be max speed when the sin angle is 90° and close to 0 when sin angle is 0. Then just use the arcsin function to get a value from 0/1 and multiply for the max speed.
var maxHorSpeed = 10;
var aimAngle = lengthdir_y(bow.x,bow.y,target.x,target.y);
arrow.horizontalSpeed = clamp( sin(aimAngle)*maxHorSpeed,0.2, maxHorSpeed);
I want to code an object that, when the left mouse button it pressed on it, starts moving towards (x,y) point and when it reaches the (x,y) point it stops moving.
I order to object when it's clicked by the left mouse button. The object moves towards (x,y) with 75 px/s speed but it doesn't stop at (x,y) point, it keeps moving on.
You can use something like this:
Create Event:
moving = false;
moving_speed = 4;
target_x = 0;
target_y = 0;
Global Mouse Left Pressed Event:
target_x = mouse_x;
target_y = mouse_y;
moving = true;
sprite_index = spr_walk; // Start animation
image_speed = 0.5; // Animation speed
Step Event:
if moving and point_distance(x, y, target_x, target_y) > moving_speed
{
dir = point_direction(x, y, target_x, target_y);
x += lengthdir_x(moving_speed, dir);
y += lengthdir_y(moving_speed, dir);
}
else
{
moving = false;
x = target_x;
y = target_y;
image_speed = 0; // Stop animation
sprite_index = spr_stay;
}
I've tried on this and this, but I found they only work for mouse events. I would like to drop some pictures on the canvas and let the user to
"touch" on it to drag and drop. But it seems that the picture doesn't receive user's touch event, only the canvas receives the event.
Any suggestion or plugin?
ps: I develop the application on Phonegap and Android system.
you also need to take care of MSPointer events, that are events from Microsoft to manage touch (it was introduced with Win8 and WinPhone 8).
The steps needed, each frame:
detect mouse, touch and MSPointer events
check the cursor position colliding the images
move the image
For the first point:
function getCursorPositions (event, canvas) {
var element = canvas, offsetX = 0, offsetY = 0, positions = [];
if (element.offsetParent) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
// Add padding and border style widths to offset
/*offsetX += stylePaddingLeft;
offsetY += stylePaddingTop;
offsetX += styleBorderLeft;
offsetY += styleBorderTop;*/
var touch = event;
//if multi-touch, get all the positions
if (event.targetTouches) { // or changedTouches
var touchPoints = (typeof event.targetTouches !== 'undefined') ? event.targetTouches : [event];
for (var i = 0; i < touchPoints.length; i++) {
touch = touchPoints[i];
positions.push({touch.pageX - offsetX, touch.pageY - offsetY});
}
}
else {
positions.push({touch.pageX - offsetX}, {touch.pageY - offsetY});
}
//return positions for mouse or fingers
return positions;
}
For the second point, you have at least 2 ways to detect the collision:
you can check whether the mouse position is inside the bounding box of your item :
function pointIsInRegion (point, targetRegion, threshold) {
return point.x >= (targetRegion.position.x - threshold) &&
point.y >= (targetRegion.position.y - threshold) &&
point.x <= (targetRegion.position.x + targetRegion.dimension.width + threshold) &&
point.y <= (targetRegion.position.y + targetRegion.dimension.height + threshold);
}
Or you can be more accurate by checking the pixels collision.
To achieve this second method, you have to render your items in a temporary canvas and check if there is at least pixels from your 2 items that collide (it can be accelerated by using masks).
For the third point (move the image), all you have to do is to move your image from "currentCursorPosition - previousCursorPosition". That's ths easiest part.
Anyway, I suggest you to use a framework. The code is already done and It will help you to go faster.
cgSceneGraph, (I'm the designer of this framework) will do the Job for you in just few lines.
Have a look at the "planner 2D" and "collision" examples (http://gwennaelbuchet.github.com/cgSceneGraph/examples.html)
Hope this can help you.
G'day All,
My little game has 5 bouncing balls and 1 player. Initially I wrote the code for the bouncing balls first and each ball has a collision detection method:
foreach (Bouncer bouncer in Game.Components) //For each bouncer component in the game...
{
if (bouncer != this)// Don't collide with myself
{
if (bouncer.collisionRectangle.Intersects(this.collisionRectangle))
{
// How far apart of the positions of the top right hand corners of the sprites when they hit?
int deltaX = Math.Abs((int)this.position.X - (int)bouncer.position.X);
int deltaY = Math.Abs((int)this.position.Y - (int)bouncer.position.Y);
// This is the width and height of a sprite so when two sprites touch this is how far the corners are from each other.
int targetWidth = 80;
int targetHeight = 80;
// The following determins the type of collision (vert hit vs horiz hit)
// Because the app is driven by a game based timer the actual amount of sprite overlap when the collision detection occurs is variable.
// This bit of simple logic has a 10 pixel tollerance for a hit.
// If target - delta is > 10 it will be interpreted as overlap in the non-colliding axis.
// If both if statements are triggered it is interpreted as a corner collision resulting in both sprites rebounding back along the original paths.
if (targetWidth - deltaX < 10) // The hit is a side on hit.
{
this.velocity.X *= -1;
}
if (targetHeight - deltaY < 10) // The hit is a vertical hit
{
this.velocity.Y *= -1;
}
this.numberOfCollisions = this.numberOfCollisions + 1;
}
}
}
base.Update(gameTime);
}
Then I added my player component and the wheels fell off. The app compiles OK but when I run it I get an InvalidCastException and the message:
Unable to cast object of type 'Bounce2.Player' to type 'Bounce2.Bouncer'.
I don't want to include the player object in this collision detector.
Is there a way I can enumerate my way through the Bouncer objects and exclude any other objects?
Thanks,
Andrew.
You can use this:
foreach (Bouncer bouncer in Game.Components.OfType<Bouncer>())
Note that you can store the Bouncer instances in other list too.
I have made the game, "Breakout". A small fun side-project.
Now, I usually do not make games, so collision-handling is not something I normally think about.
I have a paddle, a ball and some bricks.
For now, when there is a collision (I draw rectangles around each of the objects mentioned), I simply change the Y value of the ball to -Y.
This works fine, EXCEPT if the ball hits a brick from the side (either East or West). The side-effect is not pretty and ruins the gameplay.
I think I can safely assume that instead of the above technique, I need to change the X value to -X when this happens.
So far I have: if (ballRect.IntersectsWith(brickRect))
ballRect and brickRect being rectangles around each object.
Now, what if I created a rectangle around the eastern border of the brick, the western border, etc? I guess the width would be about a pixel.
If collision happens with western or eastern rectangle, then the balls X value should be -X.
And vice versa.
What about the corners though? Should I just randomly choose which rectangle to control of x corner?
Or perhaps should I make a rectangle around each corner? the rectangle being 1*1 in side.
If there is a collision => -x AND -y values of the ball?
Please share your thoughts.
Here is the process so far:
foreach (var brick in Bricks)
{
if (brick.IsAlive)
{
var brickRect = new Rectangle(brick.X, brick.Y, BrickWidth, BrickHeight);
if (ballRect.IntersectsWith(brickRect)) //Ball has hit brick. lets find out which side of the brick
{
var brickRectNorth = new Rectangle(brick.X, brick.Y + BrickHeight, BrickWidth, 1);
var brickRectSouth = new Rectangle(brick.X, brick.Y, BrickWidth, 1);
var brickRectEast = new Rectangle(brick.X, brick.Y, 1, BrickHeight);
var brickRectWest = new Rectangle(brick.X + BrickWidth, brick.Y, 1, BrickHeight);
if (ballRect.IntersectsWith(brickRectNorth) || ballRect.IntersectsWith(brickRectSouth))
{
//STUFF that makes ball.y = -ball.y
}
if (ballRect.IntersectsWith(brickRectWest) || ballRect.IntersectsWith(brickRectEast))
{
//STUFF that makes ball.x = -ball.x
}
}
}
}
Rather than looking for rectangle intersections, I'd intersect the actual edges. At the corner, your ball is touching two edges simultaneously, so its motion vector should be affected by both.
I would keep the single rectangle for collision detection, since that reduces the number of rectangles you need to test in your outer loop, but then once a collision with a brick has been detected, go into an inner loop to detect which edge it was that was hit. If you just test each edge and adjust the vector accordingly for each one, the corner will come for free (as long as you don't break out of the loop when you find the first intersecting edge).
Edit: In response to your updated question:
Actually, this is how I would do it (given your code, this appears to be C# 3.0, so that's what I've assumed below):
foreach(var brick in Bricks) {
if(brick.IsAlive) {
var brickRect = new Rectangle(brick.X, brick.Y, BrickWidth, BrickHeight);
if(ballRect.IntersectsWith(brickRect)) {
// Ball has hit brick. Now let's adjust the ball's vector accordingly
// Convenience variables. Compiler will probably inline.
var brickLeft = brick.X;
var brickRight = brick.X + BrickWidth;
var brickTop = brick.Y;
var brickBottom = brick.Y + BrickHeight;
var ballLeft = ball.X - ball.Radius;
var ballRight = ball.X + ball.Radius;
var ballTop = ball.Y - ball.Radius;
var ballBottom = ball.Y + ball.Radius;
// Test which vector(s) we need to flip
bool flipX = (ballRight >= brickLeft || ballLeft <= brickRight);
bool flipY = (ballTop >= brickBottom || ballBottom <= brickTop);
// Flip the vectors (there are probably ways to optimize this,
// too, but without seeing your code I can't tell).
if(flipY) {
// Stuff that makes ball.y = -ball.y
}
if(flipX) {
// Stuff that makes ball.x = -ball.x
}
}
}
}
Basically, the point is that since you already know the ball actually intersects the brick, you can simplify to a simple box test, which is much faster. Also, there's no need to create extra rectangles for the edges -- just use the edges of the rectangle you already have.