Upload
georgina-simmons
View
217
Download
0
Tags:
Embed Size (px)
Citation preview
Animation in Minecraft
Movement within Movement
Copyright © 2015 – Curt Hill
Copyright © 2015 – Curt Hill
Introduction• If we created an entity that was a
derivation of EntityCreature it will move– This is part of its inherited behavior– It will move in a semi-random fashion
• If it is modeled with multiple boxes it will move in an unrealistic fashion– It will look like the figure is frozen in a
block of ice and the block is drug around
• Now we set out to fix this
The Modeler
• The derivation of ModelBase contains a render method• In the example this class is
CurtModelEmu
• All the animation work is done in this method or the methods it calls
• The movements we apply here are strictly ornamental– They just make things more realistic
Copyright © 2015 – Curt Hill
The render method
• This is called multiple times a second
• The parent piece is moved by Minecraft
• We use this method to move appendages
• Not so much move as rotate them on the body or to whatever they are attached
Copyright © 2015 – Curt Hill
Angles• There are three angle properties in
ModelRenderer– Recall that each box is an object of this
type
• rotateAngleX, rotateAngleY and rotateAngleZ
• These determine the angles of the box– For the parent this is relative to the
coordinate system– For children this is relative to the parent
and attachment point
Copyright © 2015 – Curt Hill
Interlude on Angles• Most of us are used to measuring
angles in degrees• Java only believes in radians for
measuring angles– Java follows mathematics and science
in this belief
• There are 2π radians in 360°• A good article as to why radians
are superior is:http://www.purplemath.com/modules/radians.htm
Copyright © 2015 – Curt Hill
Table
Copyright © 2015 – Curt Hill
Degrees Radians1 0.0174532925230 0.523598775645 0.785398163457.29577951 160 1.047197551290 1.5707963268120 2.0943951024180 3.1415926536
Angles Again
• Like a good mathematician I will only use radians in code and examples
• If you are stuck in bad practice use this conversion function:
• float degToRad(float deg){return deg*(float)Math.PI/180;}
Copyright © 2015 – Curt Hill
The rotates
• Each of the rotateAngle variables take radians
• They set the box to that angle immediately
• Typically you wish to avoid large angular changes
• Moreover, you also need to be sensitive to motion of the entity
Copyright © 2015 – Curt Hill
Disjointed Action
• An appendage rotating has to occur over a time period
• Thus each call to render moves it some distance but not usually the total distance
• We also need to keep track of progress
• There are several practical techniques that we can use
Copyright © 2015 – Curt Hill
A Counter• We need a counter that tells which
visit to render we are currently in• This is usually an instance variable
of the class– May also be a static local variable of
render
• Each call to render we increment it• We want this value to be in some
range which is usually less than 50– We either divide and keep remainder
or zero it periodicallyCopyright © 2015 – Curt Hill
Selective Actions
• Once the counter is set and in the right range, how do we use it?
• Two good ways:– Use as an index in a constant array to
store the values– Use as the selector in a switch case
• Lets turn the emu’s head in both ways
Copyright © 2015 – Curt Hill
The Counter in Modeler
Copyright © 2015 – Curt Hill
@SideOnly(Side.CLIENT)public class CurtModelEmu extends ModelBase{ public ModelRenderer body; public ModelRenderer leg1; public ModelRenderer leg2; public ModelRenderer neck; public ModelRenderer head;
protected int headCycle=0;
The renderEmu
Copyright © 2015 – Curt Hill
public void renderEmu( CurtEmu ent, float time, float swingSuppress, float par4, float headAngleY, float headAngleX, float par7) { setRotationAngles(time, swingSuppress, par4, headAngleY, headAngleX, par7, ent); body.render(par7); }
Comments• The above two methods will be the
same for both approaches• Notice that we set the angles• Then we render the body• Since the body is the parent, all the
children will also be rendered• The renderEmu routine gets all the
parameters, but I will not use any of them, nor show them here
• Next two versions of renderEmuCopyright © 2015 – Curt Hill
Using a Switch
Copyright © 2015 – Curt Hill
@Overridepublic void setRotationAngles(…){ switch (headCycle++%20) case 3: head.rotateAngleY = .2F; break; case 4: head.rotateAngleY = .4F; break; case 5: head.rotateAngleY = .5f; break;…
Array
Copyright © 2015 – Curt Hill
float turns[] = new float[]{0f, 0f, 0f,.2f,.4f,.5f,.5f,.4f, .2f, 0f,0f,-.2f,-.4f,-.5f,-.5f, -.4f, -.2f, 0f,0f, 0f,0f,0f};…@Overridepublic void setRotationAngles(…){ head.rotateAngleY = turns[headCycle++%20]; }
Comparison
• The switch is much more code• In the array fill in gaps that the
switch does not• Also beware of subscripting errors• Once the basic approach is set, it
is easy to make it faster or slower or make the rotation greater or lesser
Copyright © 2015 – Curt Hill
Motion
• The emu moves its head all the time
• However, you do not want the legs to walk when the emu is standing still
• How do we detect motion?
Copyright © 2015 – Curt Hill
Entities Again• Entities have several properties of
value here• posX, prevPosX and the
corresponding Y and Z items• Comparing current and previous for
X and Z will tell if this item is moving in the plane or not– Changing Y would be a jump
• We can then test the current and previous and only animate if there is motion
Copyright © 2015 – Curt Hill
Head wagging• All the suggestions so far given are
synchronous• All the emus will wag their heads at
the same time– Looks unnatural– Not really a problem with walking
• We can vary this by introducing some randomness
• Insert a random object and cancel occasional ticks before the wag
Copyright © 2015 – Curt Hill
The Final Routines
• In the following screens are the final animations produced in this presentation
Copyright © 2015 – Curt Hill
setRotationAngles
Copyright © 2015 – Curt Hill
@Override public void setRotationAngles(…){ setHeadAngle(); setLegAngles(ent);}
setHeadAngle
Copyright © 2015 – Curt Hill
protected void setHeadAngle(){if(headCycle%20 < 3){ int r = rand.nextInt(10); if(r<6){ headCycle = 0; return; } }head.rotateAngleY = turns[headCycle++%20];}
setLegAngles
Copyright © 2015 – Curt Hill
protected void setLegAngles (Entity ent){if(ent.prevPosX==ent.posX && ent.prevPosZ==ent.posZ){ // no motion leg1.rotateAngleX = 0f; leg2.rotateAngleX = 0f; legCycle = 0; }else { leg1.rotateAngleX = walks[legCycle++%11]; leg2.rotateAngleX = -leg1.rotateAngleX; }}
Concussion
• Now we are ready to create harmless entities
• Helping non-harmless entities to attack or flee must await the next presentation
Copyright © 2015 – Curt Hill