Is anyone familiar with AndEngine and loading svg's?
Right now i am trying to load a background for a scene and it doesnt appear at all for some reason..
Here is th code i am using to load the SVG and attach it to the scene.
//In my onLoadResources method
this.mBuildableTexture = new BuildableBitmapTexture(1024, 1024, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
SVGTextureRegionFactory.setAssetBasePath("gfx/");
this.mSVGTestTextureRegions = SVGTextureRegionFactory.createFromAsset(this.mBuildableTexture, this, "background.svg", 16, 16);
//OnLoadScene method
final BaseTextureRegion baseTextureRegion = this.mSVGTestTextureRegions;
if(baseTextureRegion instanceof TextureRegion) {
final TextureRegion Region = (TextureRegion)baseTextureRegion;
final float centerX = this.mCamera.getWidth() / 2;
final float centerY = this.mCamera.getHeight() / 2;
final float x = centerX - SIZE * 0.5f;
final float y = centerY - SIZE * 0.5f;
Sprite backgroundSprite = new Sprite(x,y,SIZE,SIZE,Region);
/*protected void onInitDraw(final GL10 pGL)
{
super.onInitDraw(pGL);
GLHelper.enableTextures(pGL);
GLHelper.enableTexCoordArray(pGL);
GLHelper.enableDither(pGL);
}
};*/
mScene.setBackground(new SpriteBackground(0.0f,0.0f,0.0f,backgroundSprite));
backgroundSprite.setIgnoreUpdate(true);
}
Are you including the following statements in your code in loadResources:
try {
this.mBuildableTexture.build(new BlackPawnTextureBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(1));
} catch (final TextureAtlasSourcePackingException e) {
Debug.e(e);
}
this.mEngine.getTextureManager().loadTexture(this.mBuildableTexture);
Imo the naming of the BlackPawnTextureAtlasBuilder class is pretty intuitive, as:
It is an implementation ITextureAtlasBuilder interface
The class javadoc says:
#author Jim Scott (BlackPawn)
#since 16:03:01 - 12.08.2010
#see http://www.blackpawn.com/texts/lightmaps/default.html
:-)
Related
I am trying to set the registration point of an image to the bottom centre so it can rotate around that point. So far my code looks like this:
var img = new createjs.Bitmap("img.png");
img.x = 200;
img.y = 180;
img.scaleX = 0.35;
img.scaleY = 0.35;
img.regX = img.width/2;
img.regY = 0;
img.rotation = 15;
canvas.addChild(img);
I tried changing the numbers of img.regY but I can't seem to get it correct.
What is redBalloon.width?
The best approach is to wait until the image is loaded, and then use its natural width.
img.image.onload = function() {
img.regX = img.image.naturalWidth;
img.regY = img.image.naturalHeight;
}
Hope that helps.
My app features an InfiniteScrollAdapter populated with images through URLImage and URLImage.ImageAdapter.
In the simulator (Iphone3GS or Xoom or GoogleNexus7), and NPE is shown the first time the InfiniteScrollAdapter appears, although the file does exist on the server.
Please note : In this test there was only one entry in the database. So on the image below what you should see is the same row (image + text) duplicated 3 times.
Please note that the order in the undisplayed icon can differ
The code I used to download the image is :
Image tempPlaceholder = Image.createImage(
ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX,
ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX,
ParametresGeneraux.accentColor);
Graphics gr = tempPlaceholder.getGraphics();
gr.setAntiAliased(true);
gr.setColor(ParametresGeneraux.accentColor);
gr.fillArc(0, 0, ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX, ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX, 0, 360);
EncodedImage roundPlaceholder = EncodedImage.createFromImage(tempPlaceholder, true);
final Image reportImage = URLImage.createToStorage(
roundPlaceholder,
photoFilenameInStorage,
currentReport.getPhotoPath(),
ParametresGeneraux.RESIZE_SCALE_WITH_ROUND_MASK
);
And here is the overridden imageAdapter method :
public final static URLImage.ImageAdapter RESIZE_SCALE_WITH_ROUND_MASK = new URLImage.ImageAdapter() {
#Override
public EncodedImage adaptImage(EncodedImage downloadedImage, EncodedImage placeholderImage) {
final Image[] tmp = new Image[1];
if (!Display.getInstance().isEdt()) {
// The image scaling has to be called from EDT
Display.getInstance().callSeriallyAndWait(() -> {
tmp[0] = downloadedImage.scaledLargerRatio(placeholderImage.getWidth(), placeholderImage.getHeight());
if (tmp[0].getWidth() > placeholderImage.getWidth()) {
int diff = tmp[0].getWidth() - placeholderImage.getWidth();
int x = diff / 2;
tmp[0] = tmp[0].subImage(x, 0, placeholderImage.getWidth(), placeholderImage.getHeight(), true);
} else if (tmp[0].getHeight() > placeholderImage.getHeight()) {
int diff = tmp[0].getHeight() - placeholderImage.getHeight();
int y = diff / 2;
tmp[0] = tmp[0].subImage(0, y, Math.min(placeholderImage.getWidth(), tmp[0].getWidth()),
Math.min(placeholderImage.getHeight(), tmp[0].getHeight()), true);
}
});
} else {
tmp[0] = downloadedImage.scaledLargerRatio(placeholderImage.getWidth(), placeholderImage.getHeight());
if (tmp[0].getWidth() > placeholderImage.getWidth()) {
int diff = tmp[0].getWidth() - placeholderImage.getWidth();
int x = diff / 2;
tmp[0] = tmp[0].subImage(x, 0, placeholderImage.getWidth(), placeholderImage.getHeight(), true);
} else if (tmp[0].getHeight() > placeholderImage.getHeight()) {
int diff = tmp[0].getHeight() - placeholderImage.getHeight();
int y = diff / 2;
tmp[0] = tmp[0].subImage(0, y, Math.min(placeholderImage.getWidth(), tmp[0].getWidth()),
Math.min(placeholderImage.getHeight(), tmp[0].getHeight()), true);
}
}
EncodedImage[] image2Return = new EncodedImage[1];
if (!Display.getInstance().isEdt()) {
// The image scaling has to be called from EDT
Display.getInstance().callSeriallyAndWait(() -> {
Image roundMask = Image.createImage(tmp[0].getWidth(), tmp[0].getHeight(), 0xff000000);
Graphics gr = roundMask.getGraphics();
gr.setColor(0xffffff);
gr.fillArc(0, 0, tmp[0].getWidth(), tmp[0].getHeight(), 0, 360);
Object mask = roundMask.createMask();
tmp[0] = tmp[0].applyMask(mask);
image2Return[0] = EncodedImage.createFromImage(tmp[0], false);
});
} else {
Image roundMask = Image.createImage(tmp[0].getWidth(), tmp[0].getHeight(), 0xff000000);
Graphics gr = roundMask.getGraphics();
gr.setColor(0xffffff);
gr.fillArc(0, 0, tmp[0].getWidth(), tmp[0].getHeight(), 0, 360);
Object mask = roundMask.createMask();
tmp[0] = tmp[0].applyMask(mask);
image2Return[0] = EncodedImage.createFromImage(tmp[0], false);
}
return image2Return[0];
}
In the stacktrace, the NPE seems to stem from the overridden URLImage.ImageAdapter :
java.lang.IllegalArgumentException: create image failed for the given
image data of length: 0 at
com.codename1.ui.Image.createImage(Image.java:654) at
com.codename1.ui.EncodedImage.getInternal(EncodedImage.java:365) at
com.codename1.ui.EncodedImage.getInternalImpl(EncodedImage.java:340)
at com.codename1.ui.EncodedImage.getHeight(EncodedImage.java:522) at
com.codename1.ui.Image.scaledLargerRatio(Image.java:899) at
com.my.application.ParametresGeneraux$1.lambda$adaptImage$0(ParametresGeneraux.java:564)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:95) at
com.codename1.ui.Display.processSerialCalls(Display.java:1154) at
com.codename1.ui.Display.edtLoopImpl(Display.java:1098) at
com.codename1.ui.Display.invokeAndBlock(Display.java:1207) at
com.codename1.ui.Display.invokeAndBlock(Display.java:1244) at
com.codename1.ui.URLImage$DownloadCompleted.actionPerformed(URLImage.java:233)
at com.codename1.ui.URLImage$4.onSucess(URLImage.java:301) at
com.codename1.ui.URLImage$4.onSucess(URLImage.java:297) at
com.codename1.util.CallbackDispatcher.run(CallbackDispatcher.java:53)
at com.codename1.ui.Display.processSerialCalls(Display.java:1154) at
com.codename1.ui.Display.edtLoopImpl(Display.java:1098) at
com.codename1.ui.Display.mainEDTLoop(Display.java:999) at
com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120) at
com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
[EDT] 0:0:0,1 - Codename One revisions:
e5c43877074c18b4b5c7748d000e5cfac75ab749 2318
[EDT] 0:0:0,1 - Exception: java.lang.NullPointerException - null
java.lang.NullPointerException at
com.codename1.impl.javase.JavaSEPort.scale(JavaSEPort.java:3996) at
com.codename1.ui.Image.scale(Image.java:1007) at
com.codename1.ui.Image.scaledImpl(Image.java:953) at
com.codename1.ui.Image.scaled(Image.java:918) at
com.codename1.impl.javase.JavaSEPort$71.save(JavaSEPort.java:7659) at
com.codename1.ui.EncodedImage.scaledEncoded(EncodedImage.java:626) at
com.codename1.ui.EncodedImage.scaled(EncodedImage.java:653) at
com.codename1.ui.Image.scaledLargerRatio(Image.java:904) at
com.my.application.ParametresGeneraux$1.lambda$adaptImage$0(ParametresGeneraux.java:564)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:95) at
com.codename1.ui.Display.processSerialCalls(Display.java:1154) at
com.codename1.ui.Display.edtLoopImpl(Display.java:1098) at
com.codename1.ui.Display.invokeAndBlock(Display.java:1207) at
com.codename1.ui.Display.invokeAndBlock(Display.java:1244) at
com.codename1.ui.URLImage$DownloadCompleted.actionPerformed(URLImage.java:233)
at com.codename1.ui.URLImage$4.onSucess(URLImage.java:301) at
com.codename1.ui.URLImage$4.onSucess(URLImage.java:297) at
com.codename1.util.CallbackDispatcher.run(CallbackDispatcher.java:53)
at com.codename1.ui.Display.processSerialCalls(Display.java:1154) at
com.codename1.ui.Display.edtLoopImpl(Display.java:1098) at
com.codename1.ui.Display.mainEDTLoop(Display.java:999) at
com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120) at
com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
Moreover, a glance in the .cn1 directory shows the URLImage storage file name with the suffix "ImageURLTMP" which does not appear when everything works without NPE.
Finally, if I come back to this form later, everything works as expected (images were shown, no NPE). I tried to test for downloadedImage nullness in imageAdapter but the EncodedImage is not null.
How can I avoid this NPE?
Edit March 1st 2017
Following the answers from #Diamond and #Shai, I believe the NPE occurs because the InfiniteScrollAdapter wants to fill in the screen with rows and consequently launches the download of the same image simultaneously (because it is not in cache). So a solution could be to prevent the InfiniteScrollAdapter to loop (so it becomes finite). How can I do that ?
Please also note that there is not 404 error, the Network monitor shows response code 200 as depicted below. However the image should not be downloaded 3 times, should it ?
Change your ImageAdapter to the following:
public static final URLImage.ImageAdapter RESIZE_SCALE_WITH_ROUND_MASK = new URLImage.ImageAdapter() {
#Override
public EncodedImage adaptImage(EncodedImage downloadedImage, EncodedImage placeholderImage) {
Image tmp = downloadedImage.scaledLargerRatio(placeholderImage.getWidth(), placeholderImage.getHeight());
if (tmp.getWidth() > placeholderImage.getWidth()) {
int diff = tmp.getWidth() - placeholderImage.getWidth();
int x = diff / 2;
tmp = tmp.subImage(x, 0, placeholderImage.getWidth(), placeholderImage.getHeight(), true);
} else if (tmp.getHeight() > placeholderImage.getHeight()) {
int diff = tmp.getHeight() - placeholderImage.getHeight();
int y = diff / 2;
tmp = tmp.subImage(0, y, Math.min(placeholderImage.getWidth(), tmp.getWidth()),
Math.min(placeholderImage.getHeight(), tmp.getHeight()), true);
}
Image roundMask = Image.createImage(tmp.getWidth(), tmp.getHeight(), 0xff000000);
Graphics gr = roundMask.getGraphics();
gr.setColor(0xffffff);
gr.fillArc(0, 0, tmp.getWidth(), tmp.getHeight(), 0, 360);
Object mask = roundMask.createMask();
tmp = tmp.applyMask(mask);
return EncodedImage.createFromImage(tmp, false);
}
#Override
public boolean isAsyncAdapter() {
return true;
}
};
No need to check EDT.
Make sure your tempPlaceholder image is applied to your component first and at the end of your logic, call your URLImage in a callSerially() method:
Image tempPlaceholder = Image.createImage(
ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX,
ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX,
ParametresGeneraux.accentColor);
Graphics gr = tempPlaceholder.getGraphics();
gr.setAntiAliased(true);
gr.setColor(ParametresGeneraux.accentColor);
gr.fillArc(0, 0, ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX, ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX, 0, 360);
myComponent.setIcon(tempPlaceholder);
...
//Then call this at the end of everything
Display.getInstance().callSerially(() -> {
EncodedImage roundPlaceholder = EncodedImage.createFromImage(tempPlaceholder, true);
final Image reportImage = URLImage.createToStorage(
roundPlaceholder,
photoFilenameInStorage,
currentReport.getPhotoPath(),
ParametresGeneraux.RESIZE_SCALE_WITH_ROUND_MASK
);
myComponent.setIcon(reportImage);
myComponent.getComponentForm().repaint();
});
Edit:
Based on #Shai's answer, you could check if you are currently downloading the same image and prevent another one from being pulled. Because this usually causes a conflict:
//Declare this at the top of your class
final static private Map<String, Image> LOADED_URLS = new HashMap<>();
//Then change the URLImage image method to this
Display.getInstance().callSerially(() -> {
EncodedImage roundPlaceholder = EncodedImage.createFromImage(tempPlaceholder, true);
final Image reportImage = LOADED_URLS.containsKey(photoFilenameInStorage) ? LOADED_URLS.get(photoFilenameInStorage)
: URLImage.createToStorage(
roundPlaceholder,
photoFilenameInStorage,
currentReport.getPhotoPath(),
ParametresGeneraux.RESIZE_SCALE_WITH_ROUND_MASK
);
LOADED_URLS.put(photoFilenameInStorage, reportImage);
myComponent.setIcon(reportImage);
myComponent.getComponentForm().repaint();
});
In your adapter check if downloadedImage.getData() is null. I assume it's not and it's a 404 error page or something similar to that.
In that case your adapter can catch the exception and just return a fallback that matches what you expect to see when no image exists.
This works the second time around since the system sees the tmp file and assumes a download is in progress so it doesn't invoke the download code again. The tmp file is later renamed to the final downloadable file.
I have been trying to figure out a way to center text on a button, but can't find an easy, multi-purpose way to. I can do it, but it will only work for a certain string, not for any string. i would like to know if there is a way to center any string on a button. My button in this case is 185x50.
I have been able to center this button on the screen, like so:
buttonX = WIDTH / 2 - (screen.getRegionWidth() / 2);
buttonY = HEIGHT / 2 - (screen.getRegionHeight() / 2);
Any help would be much appreciated. :)
Updated the answer to libgdx version 1.7.1-SNAPSHOT:
The easiest way to do this, is to use the TextButton class from libgdx. The text from a TextButton is centered by default. This still works!
Updated example:
final BitmapFont font = new BitmapFont();
final String text = "Test";
final GlyphLayout layout = new GlyphLayout(font, text);
// or for non final texts: layout.setText(font, text);
final float fontX = objectX + (objectWidth - layout.width) / 2;
final float fontY = objectY + (objectHeight + layout.height) / 2;
font.draw(batch, layout, fontX, fontY);
Outdated example:
This no longer works!
If you do not want to use it, you can get the font width and height with:
font.getBounds("Test text");
So you can do something like this:
String fontText = "";
fontX = buttonX + buttonWidth/2 - font.getBounds(fontText).width/2;
fontY = buttonY + buttonHeight/2 + font.getBounds(fontText).height/2;
For the newer version of libgdx the function BitMapFont.getBounds() isn't there in api anymore. You can use GlyphLayout to get bounds.For example,
BitmapFont font;
SpriteBatch spriteBatch;
//... Load any font of your choice first
FreeTypeFontGenerator fontGenerator = new FreeTypeFontGenerator(
Gdx.files.internal("myFont.ttf")
);
FreeTypeFontGenerator.FreeTypeFontParameter freeTypeFontParameter =
new FreeTypeFontGenerator.FreeTypeFontParameter();
freeTypeFontParameter.size = size;
fontGenerator.generateData(freeTypeFontParameter);
font = fontGenerator.generateFont(freeTypeFontParameter);
//Initialize the spriteBatch as requirement
GlyphLayout glyphLayout = new GlyphLayout();
String item = "Example";
glyphLayout.setText(font,item);
float w = glyphLayout.width;
font.draw(spriteBatch, glyphLayout, (Game.SCREEN_WIDTH - w)/2, y);
Try the following:
label.setPosition(Gdx.graphics.getWidth()/2-(label.getPrefWidth()/2),Gdx.graphics.getHeight()-(label.getPrefHeight()/2));
I use jmonkeyengine and I downloaded a spaceship model from blendswap and converted it to j3o to load it with jmonkeyengine for a space scene where I can control the ship and travel around. However the spaceship is not loaded. The space and planets appear but I want the spaceship to be what the player controls and not first-person like it appears.
I expect the spaceship to appear because I load it without errors and add it to the scene but it stil doesn't show.
//add saucer
ufoNode = (Node) assetManager
.loadModel("usaucer_v01.j3o");
rootNode.attachChild(ufoNode);
What should I do to make the spaceship appear? The program is
public class PlanetSimpleTest extends SimpleApplication {
private PlanetAppState planetAppState;
private Geometry mark;
private Node ufoNode;
private GameCharControl ufoControl;
Camera cam2;
public static void main(String[] args){
AppSettings settings = new AppSettings(true);
settings.setResolution(1024,768);
PlanetSimpleTest app = new PlanetSimpleTest();
app.setSettings(settings);
//app.showSettings = true;
app.start();
}
#Override
public void simpleInitApp() {
// Only show severe errors in log
java.util.logging.Logger.getLogger("com.jme3").setLevel(java.util.logging.Level.SEVERE);
// Toggle mouse cursor
inputManager.addMapping("TOGGLE_CURSOR",
new MouseButtonTrigger(MouseInput.BUTTON_LEFT),
new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(actionListener, "TOGGLE_CURSOR");
// Toggle wireframe
inputManager.addMapping("TOGGLE_WIREFRAME",
new KeyTrigger(KeyInput.KEY_T));
inputManager.addListener(actionListener, "TOGGLE_WIREFRAME");
// Collision test
inputManager.addMapping("COLLISION_TEST",
new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
inputManager.addListener(actionListener, "COLLISION_TEST");
// Setup camera
// In orbit
this.getCamera().setLocation(new Vector3f(0f, 0f, 180000f));
// On surface
//this.getCamera().setLocation(new Vector3f(-6657.5254f, 27401.822f, 57199.777f));
//this.getCamera().lookAtDirection(new Vector3f(0.06276598f, 0.94458306f, -0.3222158f), Vector3f.UNIT_Y);
// Add sun
//PointLight sun = new PointLight();
//sun.setPosition(new Vector3f(-100000f,0,180000f));
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-.1f, 0f, -1f));
sun.setColor(new ColorRGBA(0.75f,0.75f,0.75f,1.0f));
rootNode.addLight(sun);
// Add sky
Node sceneNode = new Node("Scene");
sceneNode.attachChild(Utility.createSkyBox(this.getAssetManager(), "Textures/blue-glow-1024.dds"));
rootNode.attachChild(sceneNode);
// Create collision test mark
Sphere sphere = new Sphere(30, 30, 5f);
mark = new Geometry("mark", sphere);
Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mark_mat.setColor("Color", ColorRGBA.Red);
mark.setMaterial(mark_mat);
// Add planet app state
planetAppState = new PlanetAppState(rootNode, sun);
stateManager.attach(planetAppState);
// Add planet
FractalDataSource planetDataSource = new FractalDataSource(4);
planetDataSource.setHeightScale(900f);
Planet planet = Utility.createEarthLikePlanet(getAssetManager(), 63710.0f, null, planetDataSource);
planetAppState.addPlanet(planet);
rootNode.attachChild(planet);
// Add moon
FractalDataSource moonDataSource = new FractalDataSource(5);
moonDataSource.setHeightScale(300f);
Planet moon = Utility.createMoonLikePlanet(getAssetManager(), 20000, moonDataSource);
planetAppState.addPlanet(moon);
rootNode.attachChild(moon);
moon.setLocalTranslation(-150000f, 0f, 0f);
//add saucer
ufoNode = (Node) assetManager
.loadModel("usaucer_v01.j3o");
ufoNode.setLocalScale(100f);
rootNode.attachChild(ufoNode);
}
#Override
public void simpleUpdate(float tpf) {
// slow camera down as we approach a planet
Planet planet = planetAppState.getNearestPlanet();
if (planet != null && planet.getPlanetToCamera() != null) {
this.getFlyByCamera().setMoveSpeed(
FastMath.clamp(planet.getDistanceToCamera(), 100, 100000));
}
}
private ActionListener actionListener = new ActionListener(){
public void onAction(String name, boolean pressed, float tpf){
if (name.equals("TOGGLE_CURSOR") && !pressed) {
if (inputManager.isCursorVisible()) {
inputManager.setCursorVisible(false);
} else {
inputManager.setCursorVisible(true);
}
}
if (name.equals("TOGGLE_WIREFRAME") && !pressed) {
for (Planet planet: planetAppState.getPlanets()) {
planet.toogleWireframe();
}
}
if (name.equals("COLLISION_TEST") && !pressed) {
CollisionResults results = new CollisionResults();
Ray ray = new Ray(cam.getLocation(), cam.getDirection());
// Test collision with closest planet's terrain only
planetAppState.getNearestPlanet().getTerrainNode().collideWith(ray, results);
System.out.println("----- Collisions? " + results.size() + "-----");
for (int i = 0; i < results.size(); i++) {
// For each hit, we know distance, impact point, name of geometry.
float dist = results.getCollision(i).getDistance();
Vector3f pt = results.getCollision(i).getContactPoint();
String hit = results.getCollision(i).getGeometry().getName();
System.out.println("* Collision #" + i);
System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away.");
}
if (results.size() > 0) {
// The closest collision point is what was truly hit:
CollisionResult closest = results.getClosestCollision();
// Let's interact - we mark the hit with a red dot.
mark.setLocalTranslation(closest.getContactPoint());
rootNode.attachChild(mark);
} else {
// No hits? Then remove the red mark.
rootNode.detachChild(mark);
}
}
}
};
}
The spaceship I took from here and converted to jme3:s binary format j3o and added to the game, but I'm obviously not doing everything to make it appear in the scene. I've gotten this far in the jmonkeyengine IDE but then when I load it in Eclipse it doesn't work so I'm trying to create the scene with the jmonkeyengine IDE first.
I then try and create a scene with the spaceship but I get an Exception in the JME SDK.
After adding the lines
ufoNode.setLocalScale(300f);
ufoNode.setLocalTranslation((new Vector3f(10f, 10f, 180010f)));
the spaceship does appear but maybe not perfect. Can it be improved?
Update 140104 17:54 CET
It seems the spaceship was upside down(?) so I've rotated it now.
//add saucer
ufoNode = (Node) assetManager.loadModel("usaucer_v01.j3o");
ufoNode.setLocalScale(1000f);
ufoNode.setLocalTranslation((new Vector3f(10f, 10f, 165000f)));
/* This quaternion stores a 180 degree rolling rotation */
Quaternion roll180 = new Quaternion();
roll180.fromAngleAxis(FastMath.PI , new Vector3f(0,0,1));
/* The rotation is applied: The object rolls by 180 degrees. */
ufoNode.setLocalRotation(roll180);
rootNode.attachChild(ufoNode);
You add the spaceship at 0,0,0 (as you don't move it) but have moved your camera to 0f, 0f, 180000f. Most likely it is out of shot or far too small to see.
Try loading the spaceship within the jME SDK and confirm that it works within the engine using the scene editor there.
If that works then try a simple test scene just dropping the spaceship and camera in - then once that works move a step at a time towards your desired setting.
How do you call the microphone built into a computer to turn on when a user visits a site? I've heard that there a number of different ways to do so, but I'd like some advice on the best way.
To provide a meta-level view, I'm planning on having the mic pick up noise and display it as a graphic equalizer (of sorts) but not record it.
Code is appreciated!
Here is an example of a Java applet that reads from a microphone.
For my flash microphone i use this class
import org.bytearray.micrecorder.MicRecorder;
import org.bytearray.micrecorder.encoder.WaveEncoder;
import org.bytearray.micrecorder.events.RecordingEvent;
(just google it to get the code)
and its as easy as calling this
recorder = new MicRecorder(new WaveEncoder(),null,75,16);
recorder.addEventListener(RecordingEvent.RECORDING, onRecording)
recorder.addEventListener(Event.COMPLETE, onRecordComplete)
then you can do something like this to visualize the change in microphone noise. you of course have to make your own .fla movie clip that will display the "sound" in however you want to visualize it
public function onRecording(e:RecordingEvent)
{
var al:Number = recorder.microphone.activityLevel;
TweenMax.to(soundMeter, .1, {scaleX:al * .01, onUpdate:onActivitylevelUpdate});//, onUpdateParams:[al]})
}
public function onActivitylevelUpdate()
{
xpos = speedX;
ypos = centerY + Math.sin(angle) * amplitude
angle += speedAngle;
graphics.lineTo(xpos,ypos)
}
You want to look at the Microphone class to pick up sound off the mic, and at the computeSpectrum() method to calculate frequency values for the equalizer.
Here's an example of what you're trying to do, from the adobe samples:
package {
import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import flash.text.TextField;
public class SoundMixer_computeSpectrumExample extends Sprite {
public function SoundMixer_computeSpectrumExample() {
var snd:Sound = new Sound();
var req:URLRequest = new URLRequest("Song1.mp3");
snd.load(req);
var channel:SoundChannel;
channel = snd.play();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
}
private function onEnterFrame(event:Event):void {
var bytes:ByteArray = new ByteArray();
const PLOT_HEIGHT:int = 200;
const CHANNEL_LENGTH:int = 256;
SoundMixer.computeSpectrum(bytes, false, 0);
var g:Graphics = this.graphics;
g.clear();
g.lineStyle(0, 0x6600CC);
g.beginFill(0x6600CC);
g.moveTo(0, PLOT_HEIGHT);
var n:Number = 0;
for (var i:int = 0; i < CHANNEL_LENGTH; i++) {
n = (bytes.readFloat() * PLOT_HEIGHT);
g.lineTo(i * 2, PLOT_HEIGHT - n);
}
g.lineTo(CHANNEL_LENGTH * 2, PLOT_HEIGHT);
g.endFill();
g.lineStyle(0, 0xCC0066);
g.beginFill(0xCC0066, 0.5);
g.moveTo(CHANNEL_LENGTH * 2, PLOT_HEIGHT);
for (i = CHANNEL_LENGTH; i > 0; i--) {
n = (bytes.readFloat() * PLOT_HEIGHT);
g.lineTo(i * 2, PLOT_HEIGHT - n);
}
g.lineTo(0, PLOT_HEIGHT);
g.endFill();
}
private function onPlaybackComplete(event:Event):void {
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
}}