Low FPS and high memory usage with background image - background

I have a scene with orbiting 'planets', some orbiting others and all orbiting a sun in the centre.
When I run the code with the following it runs well.
void draw() {
background(0);
If I run this second example, there is a low frame rate and nearly 1Gb of memory is used.
void draw() {
PImage img;
img = loadImage("stars.jpg");
background(img);
Is this because of poor code and if so, what aspect should be changed?
I need the background re-drawn every frame as otherwise, the moving objects, 'draw' their path as they move.
Thank you

You shouldn't call the loadImage() function from the draw() function.
You're reading the file 60 times per second, when you only really need to read it once. Declare images at the sketch level, load them from setup(), and draw them from draw(). Like this:
PImage img;
void setup(){
img = loadImage("stars.jpg");
}
void draw() {
background(img);
}

Related

What image format should be employed for real time processing using Camera2 in android?

I am developing an android application which processes Camera2 preview frames and displays processed frames on the Texture. At first, I tested with camera1 api, it works fine for real time image processing.
private class CameraPreviewCallback implements Camera.PreviewCallback {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
processingRunnable.setNextFrame(data, camera);
}
}
Then, I changed my code which utilizes camera2 api. For getting preview frames, I set ImageFormat as YUV_420_888
mImageReaderPreview = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.YUV_420_888, 3);
mImageReaderPreview.setOnImageAvailableListener(mOnPreviewAvailableListener, mBackgroundHandler);
private final ImageReader.OnImageAvailableListener mOnPreviewAvailableListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader reader) {
Image mImage = reader.acquireLatestImage();
if(mImage == null) {
return;
}
processingRunnable.setNextFrame(convertYUV420888ToNV21(mImage));
mImage.close();
}
};
However, it's working slower than camera1. May be it's because of having one extra conversion from YUV_420_888 to NV21. Since Camera1 can directly provides NV21 frame from Camera1.
Conversion could be expensive, depending on how you implement it and what the layout of the YUV_420_888 on a given device is.
Certainly if it's written in pure Java is probably going to be slow.
That said, if the device you're using is at the LEGACY hardware level, camera2 has to run in a legacy mode that can be slow for receiving YUV information. For those devices, staying on API1 may be preferable for your use case.

How do I gradually apply velocity in Spigot?

I am using player.setVelocity(player.getLocation().getDirection().multiply(Main.instance.getConfig().getDouble("velocity_multiplier")).setY(Main.instance.getConfig().getInt("Y_axis"))); to set velocity to a player. It allows high configuration of movement via config, but the problem is that when you set it too high, Spigot blocks it. I do not want to enable:
server.properties: allow_flight.
So how can I avoid this? I bumped up the multiplier to 30 just for a test, and it would start to move you, glitch, and pull you back down. It also says that the player moved too quickly in console even from smaller amounts of velocity. I was thinking of making it gradually apply the velocity. When you jump, it applies the starting velocity and as you go it goes higher(Y_axis) and farther(velocity_multiplier), but I do not know how to do that.
You can enable just for the player before applying the velocity and in a delayed task disabled it
public void blabla(Player player){
player.setAllowFlight(true);
player.setVelocity(player.getLocation().getDirection().multiply(Main.instance.getConfig().getDouble("velocity_multiplier")).setY(Main.instance.getConfig().getInt("Y_axis")));
new BukkitRunnable() {
#Override
public void run() {
player.setAllowFlight(false);
}
}.runTaskLater(this, 20 * 5);
}
In the code I used 20 * 5 to disable the flight after 5 seconds, you can change it to what you want.
Beyond code, you likely would be best situated to address your issue by allowing flight in the Spigot file and installing or developing an anti-cheat in the game. Spigot's flight protection works poorly with many plugins and does not successfully block many players who attempt to fly.
Best advice would be to look beyond a makeshift code solution and rather create your own anti-fly.
The maximum velocity in bukkit (and spigot) is 10 blocks per tick. This is all directions combined.
If your initial velocity is to high, you can use the scheduler to repeatedly calculate the next velocity.
To calculate this, we need some magic values: The following values come from The Minecraft Wiki.
private final static double DECELERATION_RATE = 0.98D;
private final static double GRAVITY_CONSTANT = 0.08D;
private final static double VANILA_ANTICHEAT_THRESHOLD = 9.5D; // actual 10D
We first need to calculate the spot the player would reach using those speeds, and then teleport him while applying the velocity for the first part.
We are going to use a BukkitRunnable to run a task that calculates the above:
Vector speed = ...;
Player player = ...;
new BukkitRunnable() {
double velY = speed.getY();
Location locCached = new Location(null,0,0,0);
#Override
public void run() {
if (velY > VANILA_ANTICHEAT_THRESHOLD) {
player.getLocation(locCached).setY(locCached.getY() + velY);
player.teleport(locCached);
player.setVelocity(new Vector(0,ANILA_ANTICHEAT_THRESHOLD,0));
} else {
player.setVelocity(new Vector(0,velY,0));
this.cancel();
}
velY -= GRAVITY_CONSTANT;
velY *= DECELERATION_RATE;
}
}.runTaskTimer(plugin,0,1);
The above code will then handle the velocity problems for us and can be used in place of setVelocity.

World class doesn't display my background

I have a class called World that contains all the entities that make interaction with the player (obstacles, background, scenario) and this class has a method called drawWorld() in which draw all entities. The first thing I put on this method was the background, but it doesn't draw the background texture and I don't know why.
This render method is from my game screen and where I call the method drawWorld():
#Override
public void render(float delta) {
// OpenGL clear screen
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(Gdx.gl.GL_COLOR_BUFFER_BIT | Gdx.gl.GL_DEPTH_BUFFER_BIT);
// Set the projection matrix for the SpriteBatch
this.game.spriteBatch.setProjectionMatrix(this.game.orthoCamera.combined);
// Act stage
this.game.stage.act(delta);
// SpriteBatch begins
this.game.spriteBatch.begin();
// Draw world
this.world.drawWorld();
// Draw stage
this.game.stage.draw();
// SpriteBatch ends
this.game.spriteBatch.end();
}
And here I render the background:
public void drawWorld() {
// Draw background
this.game.spriteBatch.draw(this.background, 0, 0);
}
Without forget that I created the background texture:
// Load background image
this.background = Assets.manager.get(Assets.background);
What am I doing wrong?
When you create a Stage with only a ViewPort, under the hood, the Stage creates and uses it's own Batch. So, in your render method, you have game.spritBatch drawing your background and then Stage's Batch drawing the stage within between the begin and end of game.spriteBatch. That is a big no no.
The way this should be done is like this:
Creating the Stage:
this.game.stage = new Stage(this.viewPort, this.game.spriteBatch); // For efficiency, you can use the same spriteBatch
Render:
#Override
public void render(float delta) {
// OpenGL clear screen
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(Gdx.gl.GL_COLOR_BUFFER_BIT | Gdx.gl.GL_DEPTH_BUFFER_BIT);
// Set the projection matrix for the SpriteBatch
this.game.spriteBatch.setProjectionMatrix(this.game.orthoCamera.combined);
// Act stage
this.game.stage.act(delta);
// SpriteBatch begins
this.game.spriteBatch.begin();
// Draw world
this.world.drawWorld();
// SpriteBatch ends
this.game.spriteBatch.end();
// Draw stage
this.game.stage.draw(); // After spriteBatch.end()!!
}
See the docs for more about the Stage(Viewport viewport, Batch batch) constructor.

Unity: camera falls through terrain

Problem is:
I have created terrain and I need to fly over terrain with Camera. I added to Camera "Mouse Look" script, RigidBody: usegravity - unchecked and I have added my code in Update method:
float vert = Input.GetAxis("Vertical");
float hor = Input.GetAxis("Horizontal");
if (vert != 0)
{
if (!Physics.Raycast(this.transform.position, this.transform.forward, 5))
{
transform.Translate(Vector3.forward * flySpeed * vert);
}
else
{
transform.Translate(Vector3.up * flySpeed * vert);
}
}
if (hor != 0)
{
if (!Physics.Raycast(this.transform.position, this.transform.forward, 5))
{
transform.Translate(Vector3.right * flySpeed * hor);
}
else
{
transform.Translate(Vector3.up * flySpeed* hor);
}
}
if (Input.GetKey(KeyCode.E))
{
transform.Translate(Vector3.up * flySpeed);
}
else if (Input.GetKey(KeyCode.Q))
{
Vector3 v = Vector3.down * flySpeed;
if (!Physics.Raycast(this.transform.position, this.transform.forward, 5))
{
transform.Translate(v);
}
}
But sometimes then i go down - Q - camera goes through terrain. Why?
Also looks ugly if you are moving with camera forward as low as possible over terrain and camera does not fall through it - it starts to jump. Also why?
Make sure you have a Terrain Collider on your terrain.
In addition to S.Richmonds answer, you can add a character controller or other similar collider-component object to your camera.
See this answer in the unity questions network:
http://answers.unity3d.com/questions/45763/getting-camera-to-not-see-under-the-ground.html
The Update() method in a monobehavior gets called once each fram. Because the rate which update is called is dependent on frame rate, moving an object by a constant value in Update() can result in inconsistant motion. This can be corrected by multiplying a constant speed by Time.deltaTime, which is the time in seconds since the last frame was rendered. This will fix the fallthrough unless flySpeed is set too high (where the change in position each frame is greater than the collider's size). Additionally as suggested above, using a CharacterController without a rigidbody would be better suited to this situation. Rigidbodies are for objects primarily controlled by physics, while the CharacterController is for objects controlled by scripts.

Creating Touchjoints/Mousejoints on small objects in box2d

I'm using Cocos2d iPhone with Box2D to create a basic physics engine.
Occasionally the user is required to drag around a small box2D object.
Creation of touchjoints on small objects is a bit hit and miss, with the game engine seeing it as a tap on blank space as often as actually creating the appropriate touchjoint. In practice this means the user is constantly mashing their fingers against the screen in vain attempts to move a stubborn object. I want the game to select small objects easily without this 'hit and miss' effect.
I could create the small objects with larger sensors around them, but this is not ideal because objects above a certain size (around 40px diameter) don't need this extra layer of complexity; and the small objects are simply the big objects scaled down to size.
What are some strategies I could use to allow the user experience to be better when moving small objects?
Here's the AABB code in ccTouchBegan:
b2Vec2 locationWorld = b2Vec2(touchLocation.x/PTM_RATIO, touchLocation.y/PTM_RATIO);
b2AABB aabb;
b2Vec2 delta = b2Vec2(1.0/PTM_RATIO, 1.0/PTM_RATIO);
//Changing the 1.0 here to a larger value doesn't make any noticeable difference.
aabb.lowerBound = locationWorld - delta;
aabb.upperBound = locationWorld + delta;
SimpleQueryCallback callback(locationWorld);
world->QueryAABB(&callback, aabb);
if(callback.fixtureFound){
//dragging code, updating sprite location etc.
}
SimpleQueryCallback code:
class SimpleQueryCallback : public b2QueryCallback
{
public:
b2Vec2 pointToTest;
b2Fixture * fixtureFound;
SimpleQueryCallback(const b2Vec2& point) {
pointToTest = point;
fixtureFound = NULL;
}
bool ReportFixture(b2Fixture* fixture) {
b2Body* body = fixture->GetBody();
if (body->GetType() == b2_dynamicBody) {
if (fixture->TestPoint(pointToTest)) {
fixtureFound = fixture;
return false;
}
}
return true;
}
};
What about a minimum collision box for touches? Objects with less than 40px diameter use the 40px diameter, all larger objects use their actual diameter.
What I ended up doing - thanks to iforce2d, was change ReportFixture in SimpileQueryCallback to:
bool ReportFixture(b2Fixture* fixture) {
b2Body* body = fixture->GetBody();
if (body->GetType() == b2_dynamicBody) {
//if (fixture->TestPoint(pointToTest)) {
fixtureFound = fixture;
return true;
//}
}
return true;
}
And increase the delta to 10.0/PTM_RATIO.