General Demo
Created with
PulpCore
// GeneralDemo.java
package simpull2core.demo.general;
import pulpcore.Input;
import pulpcore.animation.Timeline;
import pulpcore.image.Colors;
import pulpcore.image.CoreFont;
import pulpcore.image.CoreImage;
import pulpcore.sprite.FilledSprite;
import pulpcore.sprite.ImageSprite;
import pulpcore.sprite.Label;
import simpull.Circle;
import simpull.Composite;
import simpull.CustomBodyFinisher;
import simpull.Particle;
import simpull.Rectangle;
import simpull.SimpleSpring;
import simpull.VectorForce;
import simpull2core.CustomBodyViewFinisher;
import simpull2core.SimpullFactory;
import simpull2core.SimpullScene2D;
import simpull2core.SimpullToTheCoreComposite;
public class GeneralDemo extends SimpullScene2D {
private Composite star, tumbler;
private Particle pendulum;
public GeneralDemo() {
super(new VectorForce(false, 0f, 3f));
}
@Override
@SuppressWarnings("unchecked")
protected void loadInternal() {
CoreImage rock1 = CoreImage.load("img/rock1.png");
CoreImage rock2 = CoreImage.load("img/rock2.png");
CoreImage branch1 = CoreImage.load("img/branch1.png");
CoreImage branch2 = CoreImage.load("img/branch2.png");
// Add just a plain ole PulpCore image to the scene for the background.
add(new ImageSprite(CoreImage.load("img/bg.jpg"), 0, 0));
{ // set up the branch(es) in the upper right corner
ImageSprite thickBranchImg = new ImageSprite(branch1, 785, 90);
thickBranchImg.angle.set(0.4);
add(SimpullFactory.createRectangle(thickBranchImg, true, 1, 0, 1), thickBranchImg, true);
ImageSprite thickBranchImg2 = new ImageSprite(branch1, 746, 79);
thickBranchImg2.angle.set(0.2);
add(SimpullFactory.createRectangle(thickBranchImg2, true, 1, 0, 1), thickBranchImg2, true);
ImageSprite thinBranchImg = new ImageSprite(branch2, 710, 72);
add(SimpullFactory.createRectangle(thinBranchImg, true, 1, 0, 1), thinBranchImg, true);
}
{ // star
CoreImage star4Img = CoreImage.load("img/star4.png");
star = new Composite(false, 8);
// The top-left point of the star is (710, 10), so I got the points
// on the start from the image creation software and added the reference
// location to get a good physical representation...cool trick!
star.add(new Circle(14 + 710, 7 + 10, 1f, false, 1f, 0.3f, 1f));
star.add(new Circle(29 + 710, 0 + 10, 1f, false, 1f, 0.3f, 1f));
star.add(new Circle(20 + 710, 14 + 10, 1f, false, 1f, 0.3f, 1f));
star.add(new Circle(29 + 710, 29 + 10, 1f, false, 1f, 0.3f, 1f));
star.add(new Circle(14 + 710, 22 + 10, 1f, false, 1f, 0.3f, 1f));
star.add(new Circle(0 + 710, 29 + 10, 1f, false, 1f, 0.3f, 1f));
star.add(new Circle(7 + 710, 14 + 10, 1f, false, 1f, 0.3f, 1f));
star.add(new Circle(0 + 710, 0 + 10, 1f, false, 1f, 0.3f, 1f));
star.setCompositeCompleted(new CustomBodyFinisher(3, 1));
ImageSprite wheelSpriteA = new ImageSprite(star4Img, 0, 0);
add(star, wheelSpriteA, true);
}
Label bounceTxt = new Label(CoreFont.getSystemFont().tint(Colors.WHITE), "Arrow keys!", 750, 15);
bounceTxt.setAnchor(Label.CENTER);
add(bounceTxt);
Timeline timeline = new Timeline();
timeline.at(0).animate(bounceTxt.angle, 0, Math.PI / 5, 300);
timeline.at(300).animate(bounceTxt.angle, Math.PI / 5, -Math.PI / 5, 600);
timeline.at(900).animate(bounceTxt.angle, -Math.PI / 5, 0, 300);
timeline.loopForever();
addTimeline(timeline);
{ // The tumbler
SimpullToTheCoreComposite stcTumbler = new SimpullToTheCoreComposite(true, 20);
CoreImage connectorImg = CoreImage.load("img/connector.png");
CoreImage grateImg = CoreImage.load("img/grate.jpg");
ImageSprite connector1 = new ImageSprite(connectorImg, 50, 10);
Circle connector1circle = SimpullFactory.createCircle(connector1, false, 1, 0.3f, 0);
stcTumbler.add(connector1circle, connector1);
ImageSprite connector2 = new ImageSprite(connectorImg, 150, 10);
Circle connector2circle = SimpullFactory.createCircle(connector2, false, 1, 0.3f, 0);
stcTumbler.add(connector2circle, connector2);
ImageSprite connector3 = new ImageSprite(connectorImg, 100, 60);
Circle connector3circle = SimpullFactory.createCircle(connector3, false, 1, 0.3f, 0);
stcTumbler.add(connector3circle, connector3);
// Finish the body by connecting the particles we just added with some constraints that have grateImg
// as a view (scaled to the right size to fit between each particle).
stcTumbler.setCompositeCompleted(new CustomBodyViewFinisher(stcTumbler, grateImg, true, 0.9f));
add(stcTumbler, true);
tumbler = stcTumbler.getComposite();
}
{ // TODO water inside the tumbler
for (int i = 0; i < 0; ++i) {
FilledSprite waterDrop = new FilledSprite(70 + i, 25, 5, 5, Colors.BLUE);
add(SimpullFactory.createCircle(waterDrop, false, 0.01f, 0.1f, 0), waterDrop, true);
}
}
// Until the water is ready, use a wheel inside to tumble
CoreImage wheelImg = CoreImage.load("img/wheel.png");
ImageSprite tumbleWheel = new ImageSprite(wheelImg.halfSize(), 90, 35);
add(SimpullFactory.createWheel(tumbleWheel, false, 0.5f, 0.3f, 0, 1), tumbleWheel, true);
// add a mountain (cosine wave), with walls at the edge of the screen up to the height of the wave
final int iterations = 50;
final float xMax = 800f / ((float)Math.PI * 2f);
float lastDangleX = 0f;
CoreImage squareWheelImg = CoreImage.load("img/squareWheel.jpg");
for (int i = 0; i < iterations; ++i) {
CoreImage img = (i % 2 == 0) ? rock1 : rock2;
float x = (float)Math.PI * 2f * ((float)i / (float)iterations);
float worldX = x * xMax;
float y = (float)Math.cos(x) * 100 + 330;
ImageSprite rock = new ImageSprite(img, worldX, y);
rock.angle.set(Math.random() * Math.PI * 2);
Rectangle rockRect = SimpullFactory.createRectangle(rock, true, 1, 0.3f, 0);
add(rockRect, rock, true);
// Every so often, add a side wall rock piece on either side
if (i % 4 == 0) {
ImageSprite right = new ImageSprite(img, 795, y);
ImageSprite left = new ImageSprite(img, 5, y);
right.angle.set(Math.random() * Math.PI * 2);
left.angle.set(Math.random() * Math.PI * 2);
add(SimpullFactory.createRectangle(left, true, 1, 0.3f, 0), left, true);
add(SimpullFactory.createRectangle(right, true, 1, 0.3f, 0), right, true);
}
// If the spacing is right, add a dangling participle!!!
if (worldX > 130 && worldX < 680) {
if ((worldX - lastDangleX) > 31) {
lastDangleX = worldX;
float magic = worldX > 400 ? 800 - worldX : worldX;
ImageSprite dangler = null;
Rectangle danglerRect = null;
if (pendulum == null) {
dangler = new ImageSprite(squareWheelImg.tint(Colors.YELLOW), worldX, y + 25 + (magic / 4));
danglerRect = SimpullFactory.createRectangle(dangler, false, 2, 0.3f, 0);
pendulum = danglerRect;
} else {
dangler = new ImageSprite(squareWheelImg, worldX, y + 25 + (magic / 4));
danglerRect = SimpullFactory.createRectangle(dangler, false, 2, 0.3f, 0);
}
add(danglerRect, dangler, true);
SimpleSpring spring = new SimpleSpring(rockRect, danglerRect, 0.5f, false, 2, 1, false);
add(spring, SimpullFactory.createDefaultView(spring, Colors.rgb(153, 127, 102)), true);
}
}
}
Label pendulumTxt = new Label("A must have in a physics demo!", 400, 425);
pendulumTxt.setAnchor(Label.CENTER);
add(pendulumTxt);
Timeline timeline2 = new Timeline();
timeline2.at(0).animate(pendulumTxt.x, 400, 450, 500);
timeline2.at(0).animate(pendulumTxt.y, 425, 435, 500);
timeline2.at(500).animate(pendulumTxt.x, 450, 400, 500);
timeline2.at(500).animate(pendulumTxt.y, 435, 445, 500);
timeline2.at(1000).animate(pendulumTxt.x, 400, 350, 500);
timeline2.at(1000).animate(pendulumTxt.y, 445, 435, 500);
timeline2.at(1500).animate(pendulumTxt.x, 350, 400, 500);
timeline2.at(1500).animate(pendulumTxt.y, 435, 425, 500);
timeline2.loopForever();
addTimeline(timeline2);
// FilledSprite floor = new FilledSprite(400, 240, 800, 20, Colors.WHITE);
// add(SimpullFactory.createRectangle(floor, true, 1, 0.3f, 0), floor, true);
{ // left side of tires
float x = 340;
ImageSprite leftWheel1 = new ImageSprite(wheelImg, x, 200);
add(SimpullFactory.createWheel(leftWheel1, false, 2, 0.3f, 0, 1), leftWheel1, true);
ImageSprite leftWheel2 = new ImageSprite(wheelImg, x, 160);
add(SimpullFactory.createWheel(leftWheel2, false, 2, 0.3f, 0, 1), leftWheel2, true);
ImageSprite leftWheel3 = new ImageSprite(wheelImg, x, 120);
add(SimpullFactory.createWheel(leftWheel3, false, 2, 0.3f, 0, 1), leftWheel3, true);
ImageSprite leftWheel4 = new ImageSprite(wheelImg, x, 80);
add(SimpullFactory.createWheel(leftWheel4, false, 2, 0.3f, 0, 1), leftWheel4, true);
ImageSprite leftWheel5 = new ImageSprite(wheelImg, x, 40);
add(SimpullFactory.createWheel(leftWheel5, false, 2, 0.3f, 0, 1), leftWheel5, true);
ImageSprite leftWheel6 = new ImageSprite(wheelImg, x, 0);
add(SimpullFactory.createWheel(leftWheel6, false, 2, 0.3f, 0, 1), leftWheel6, true);
}
{ // right side of tires
float x = 460;
ImageSprite leftWheel1 = new ImageSprite(wheelImg, x, 200);
add(SimpullFactory.createWheel(leftWheel1, false, 2, 0.3f, 0, 1), leftWheel1, true);
ImageSprite leftWheel2 = new ImageSprite(wheelImg, x, 160);
add(SimpullFactory.createWheel(leftWheel2, false, 2, 0.3f, 0, 1), leftWheel2, true);
ImageSprite leftWheel3 = new ImageSprite(wheelImg, x, 120);
add(SimpullFactory.createWheel(leftWheel3, false, 2, 0.3f, 0, 1), leftWheel3, true);
ImageSprite leftWheel4 = new ImageSprite(wheelImg, x, 80);
add(SimpullFactory.createWheel(leftWheel4, false, 2, 0.3f, 0, 1), leftWheel4, true);
ImageSprite leftWheel5 = new ImageSprite(wheelImg, x, 40);
add(SimpullFactory.createWheel(leftWheel5, false, 2, 0.3f, 0, 1), leftWheel5, true);
ImageSprite leftWheel6 = new ImageSprite(wheelImg, x, 0);
add(SimpullFactory.createWheel(leftWheel6, false, 2, 0.3f, 0, 1), leftWheel6, true);
}
}
@Override
protected void updatePrePhysics() {
float vel = 0.5f;
float lessVel = vel / 5f;
if (Input.isDown(Input.KEY_LEFT)) {
star.setAngularVelocity(-vel);
pendulum.addForce(new VectorForce(true, -40, 0));
tumbler.setAngularVelocity(-lessVel);
} else if (Input.isDown(Input.KEY_RIGHT)) {
star.setAngularVelocity(vel);
pendulum.addForce(new VectorForce(true, 40, 0));
tumbler.setAngularVelocity(lessVel);
} else if (Input.isReleased(Input.KEY_LEFT) || Input.isReleased(Input.KEY_RIGHT)) {
star.setAngularVelocity(0);
tumbler.setAngularVelocity(0);
}
}
}