Reconnecting
Reconnecting...
Your session has timed out. Reload to continue.
Your session has timed out. Reload to continue.

We are going to make a game where you fling objects at floating shapes until they explode. There will be suggestions for how you can personalise the game and you can experiment with the code to make other changes.

You can launch the project to see it working. In the demo we have used ducks. Here is another example where you fling fish!

Before we begin...

For this project you will need a 3D model. This could be one you have made yourself or one you have found online. Upload the model to your Mixiply assets or have the link to the model handy.

Click 'Create' and choose the 'New project' template.

Global variables

The first thing we need to do is set up a variable at the very top of the code. These are called global variables because they can be used anywhere in your code.

If you make a variable inside a function (called a local variable), it can only be used inside that function.

This will hold the behaviour used by the projectile.
var moveInDirection

Create a global variable in your code.

setup()

Let's start with the setup. The setup is where we get everything organised for the project to do it's thing. It runs once before anything else. This is where you need to load anything that your project needs, such as assets.

To do this, we use this code:
Asset.load("assetUrl", "assetName")

All asset types are loaded in the same way. In the first pair of quotation marks, you need a URL for the asset and in the second pair of quotation marks, you need and a name for your asset.

  • The assetUrl could be a link to an asset you have uploaded to Mixiply or an external URL.
  • The assetName will be what you use to refer to the asset later in your code. So, to make things easier, try to name it something that describes the asset.

Load your 3D model in your code now.

It will look something like this:

start()

The start function is like the initial form your project will take and it gets the project running. This could include things like creating and placing assets, starting movement and setting behaviours, as well as many other things.

The first thing we are going to do is create the targets.

Check out this chunk of code and then we will break it down:

Here we are creating a line of 10 floating spheres that will move when hit and change colour depending on how much health they have.

How? Let's break it down:

First, we set the amount of targets we want to appear. In the example it is 10.
const numberOfTargets = 10;

Then we create two arrays: one that will store our targets and one that will store their health.
targets = [];
targetsHealth = [];

Inside your start() choose how many targets you want and create your targets and targetsHealth arrays.

Next, we run a loop that will make all of our targets and store them in the array.
for(var i = 0; i < length; i++)

Each time it runs through the loop, it creates a variable called target and sets it to the Primitive.sphere() shape and a range of attributes are set.
var target = Primitive.sphere()

The Primitive is the class that is used to create simple 3D shapes and objects. We have used a sphere but you can try one of the other shapes (cube, cylinder, capsule or a quad).

Set the position of the target based on its starting position.
.move( 1.5*i, 0, 2 )

Give the target a name.
.setName("target "+i)

Set kinematic to false.
.setKinematic(false)

This determines whether the object can be affected by forces and collisions. Setting it to false means that it can be.

Set the gravity of the target to false.
.setGravity(false)

This determines whether the object will be effected by gravity or not. Setting it to false means that it won't be.

Set the mass of the target.
.setMass(1)

Higher mass objects push lower mass objects more when they collide. The target has low mass so the projectile will move it around when it gets hit.

Set the drag that will be applied to the target. .setDrag(1)

Drag refers to the resistance an object to movement. The higher the drag, the faster an object will slow down.

Inside your start() function, under the target arrays, add this loop and create the shape you want for your targets.

You could also try changing the forces to see what difference it makes or making your target another 3D model or an image asset.

Once the new target is created, it is added to the targets[] array.
targets[i] = obj;

The target's health is added to the targetsHealth[] array with a value of 1.0.
targetsHealth[i] = 1.0;

Then the target's colour is set based on the value of its health.
target.setColor(1-targetsHealth[i], 0, targetsHealth[i])

Add your targets to the array and set the colour.

There's one other snippet of code that we haven't talked about. This code is setting a movement behaviour which will be used by your 3D model when you fling it at the targets.

This line creates the behaviour.
moveInDirection = Behaviour.create("moveInDirection");

The next line sets the attributes for the behaviour.
moveInDirection.setSpeed(0.25).setDirection( Vector.forward ).start();

You can experiment with these attributes more once we have the projectile set up.

Add these lines into your code.

Try launching your project. You should be able to see your targets.

OnClickDown()

Next we want to be able to fling our projectiles. This will happen when the user clicks or taps the screen, so we need to write a new function called onClickDown().

This function will follow a similar pattern to the targets. We will create an instance of our 3D model, set the attributes, then tell it what to do when it collides with something.

Here is the whole block of code:

Let's break it down again.

We create an instance of our 3D model.
var projectile = Asset.create("DuckModel")

This Asset.create() method has to come after you have loaded it using Asset.load().

Give the projectile a name.
.setName("Projectile")

Set the projectile mass.
.setMass(100)

Note: The projectile has a much greater mass than the target. This means that when they collide, the projectile will push the target because it is heavier.

Set the projectile's position. .setPosition(hitInfo.origin)

Note: hitInfo is the information we get given about the click or tap when the method is called (that's this bit... onClickDown(hitInfo)). So, hitInfo.origin is where the click or tap originated, meaning that the projectile will appear in the place that the user clicked or tapped.

Set the direction that it is facing is set using the .lookAt() function and some of the information from hitInfo.
.lookAt( Vector.add(Vector.multiply(hitInfo.direction, 1), hitInfo.origin))

Create your projectile and set the attributes

Before we tell the projectile what to do when it collides with the targets, we need to give the projectile the moveInDirection behaviour that we created in the setup().

Apply the behaviour to the projectile so it knows where and how to move.
moveInDirection.addObject(projectile);

This goes at the end of the onClickDown() function, after the code for the projectile has finished.

Add this line of code to the end of your onClickDown() funciton.

Launch your project again. You should now be able to fling your 3D model.

Now back to finishing the projectile. We need to tell the projectile what to do when it collides with something using the onCollision() method and the information we are given about the object that was hit (hitObj).

Attach the method to the end of the creation of the projectile. This means that it will only apply to this object.
.onCollision(function(hitObj) {}

Apply a short force to the target that was hit using the .applyImpulse() method.
hitObj.applyImpulse(Vector.subtract(hitObj.position, projectile.position).normalized);

The example uses the current position of the target and the projectile to determine the direction and amount of force that will be applied.

Create a flare effect in the current position of the projectile.
Effect.flare(projectile.position);

Remove the moveInDirection behaviour so the projectile stops moving.
moveInDirection.removeObject(projectile);

Destroy the projectile, removing it from the game.
MixiplyObject.destroy(projectile);

Call a function that tells the target what to do and pass it the hitObj it knows which target to change.
hitTarget(hitObj);

Don't forget to close the function!
});

Add the onCollision() method to your projectile.

Launch your project. The projectiles should now flare and disappear when they hit a target.

hitTarget()

Lastly, we need to tell the targets what to do if they get hit. We will write another function and call it hitTarget(), which is the function that is called at the end of the projectile's onCollision() function.

Firstly, we create the function.
function hitTarget(hitObj) {}

The steps of the function go inside the curly braces ({}).

Now, we need to figure out which target to change.

To do this, we loop through the targets[] array.
for(var i = 0; i < targets.length; i++){}

Inside the loop, we compare each target in the array to the target that got hit.
var target = targets[i]
if(target === hitObj) {}

If we find the matching target, we reduce its health by 0.2 and store it as the variable newHealth.
const newHealth = targetsHealth[i] - 0.2;

Now that we have found the target and reduced its health, we need to do a few other things.

We check if the target's health has reached 0 or less than 0.
if(newHealth <= 0) {}

If the target's health has reached 0 or less, then we need to do a few things:

Remove the target from the targets[] array.
targets.splice(i, 1);

Remove the target's health from the targetsHealth[] array.
targetsHealth.splice(i, 1);

Create an explosion effect in the current position of the target.
Effect.explosion(target.position);

Destroy the target, removing it from the game.
MixiplyObject.destroy(target);

Otherwise, if the target's health is still above 0 we do something different:

We need an else statement which will run if the target's health is still above 0.
else {}

First, we replace the target's current health with the newHealth in the targetsHealth [] array.
targetsHealth[i] = newHealth;

Then, we update the target's colour based on the value of the newHealth.
target.setColor(1-newHealth, 0, newHealth)

Now, experiment!

Try changing things, even if it's just to see what happens!

You could change some of the things that we talked about above:

  • The speed of the projectile (in the start() function).
  • The number of targets and where they spawn.
  • The shape and colour of the targets.
  • You could add an image to the targets by adding .texture("url") to the target attributes (maybe try your friends face).
  • You could load another 3D model to use instead of a shape.
  • The forces that are applied to the objects.
  • What will happen if you add gravity to the targets or the projectiles?
  • What about if you change the mass or drag of the objects?
  • What would happen if you used the applyAcceleration(x, y, z) or applyVelocityChange(x, y, z) functions to targets or the projectiles?
  • What about if you use applyForce(x, y, z)?
  • The onCollision() or hitTarget() functions.
  • Change the effects that are used.
  • What happens if you don't destroy the projectile once it hits a target?
  • Can you make it so a projectile can hit multiple targets?
  • What could the target or the projectile do differently when it gets hit?

Here are some other ideas you could try:

  • The targets move.
  • Projectiles don't shoot straight.
  • Some targets are worth different points.
  • There is a time limit.
  • More targets spawn during the game.
  • You have a limited number of projectiles.

An error has occurred. This application may no longer respond until reloaded. Reload 🗙