Platforms in a class not moving when called in - java

For a university course I'm making a game with a friend. The general idea is that we have some platforms moving from right to left and each time one goes offscreen it is generated at a random x and y position on the right (within some limits). There will be a little sprite that jumps from platform to platform.
We have reached a problem we're not sure how to solve. We have all the right code and everything but the platforms just won't move. They should move to the left at a constant speed of -4 pixels per frame (rectVelocity).
We cannot get them to move, though; they are static on the screen at the position each one is initially called in at.
This is the code as condensed as I can make it:
Platforms [] mainPlats;
void setup() {
size(750, 400);
mainPlats = new Platforms[3];
}
void draw() {
level();
}
void level() {
//This is the code for the first platform
mainPlats[0] = new Platforms(200, 200, 100, 15); //These values need to be set inside the class so that
//they aren't constantly overwriting the movement variables in the class
mainPlats[0].displayPlat();
mainPlats[0].platTransition();
//This is the code for the second platform
mainPlats[1] = new Platforms(420, 300, 100, 15);
mainPlats[1].displayPlat();
mainPlats[1].platTransition();
//This is the code for the third platform
mainPlats[2] = new Platforms(570, 350, 100, 15);
mainPlats[2].displayPlat();
mainPlats[2].platTransition();
}
class Platforms {
PImage platform;
int rectX, rectY, rectWidth, rectHeight;
int rectVelocity = 4;
Platforms(int x, int y, int w, int h) {
rectX = x;
rectY = y;
// rectX = (int(random(600, 800))); //Tried to randomise start position, failed hilariously
//rectY = (int(random(150, 350)));
rectWidth = w;
rectHeight = h;
}
void displayPlat() {
platform = loadImage ("images/tiles.png");
//imageMode(CENTER);
image(platform, rectX, rectY, 100, 15); //rectangle platforms replaced with images
}
void platMove() {
rectX -= rectVelocity;
}
void platTransition() {
if (rectX < -200) {
rectX = (int(random(700, 1000)));
rectY = (int(random(150, 350)));
}
}
}

From the draw() function, you call your level() function, which initializes your Platform array every single frame.
This means that you create new Platforms at their starting positions every frame. You never see the platforms move, because as soon as you do move them, you replace them with new platforms at the starting positions again.
So step one is to move their initialization out of the level() function and only call them once, at the beginning of your sketch- the setup() function would be one place you could put them.
Your other problem is that you never actually call the platMove() function. So step two is to make sure you call that function.
A solution might look something like this:
Platforms [] mainPlats;
void setup() {
size(750, 400);
mainPlats = new Platforms[3];
mainPlats[0] = new Platforms(200, 200, 100, 15);
mainPlats[1] = new Platforms(420, 300, 100, 15);
mainPlats[2] = new Platforms(570, 350, 100, 15);
}
void draw() {
level();
}
void level() {
mainPlats[0].displayPlat();
mainPlats[0].platMove();
mainPlats[0].platTransition();
mainPlats[1].displayPlat();
mainPlats[1].platMove();
mainPlats[1].platTransition();
mainPlats[2].displayPlat();
mainPlats[2].platMove();
mainPlats[2].platTransition();
}
Also note that you shouldn't load the image every single frame, either. You should only load it once, at startup. You also might want to use a for loop to iterate over your Platforms instead of referring to every single index. But these don't really affect your problem.

You've got rectX as positive values (>0) when you construct the platforms, but you are checking for rectX < -200 when you call platTransition, which is why it never does anything.

Related

Java animation about reframing an image

Hi I am currently making a program that will show a spring that moves with the values that I enter and uses the formulas of physics. The problem is that, when I create a spring and make the animation start, the old image stays there and overrides without deleting the one before here's the code of the problem :
bouton3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
/*anime.animer();
anime.repaint();*/
for (int t = 0; t < 500; t += 5) {
for (int i = 105; i < 175; i += 5) {
Ellipse2D elp1 = new Ellipse2D.Double(i, 100, 15, 30);
((Graphics2D) dessinPanel.getGraphics()).draw(elp1);
}
for (int i = 105; i < 175; i += 5) {
Ellipse2D elp1 = new Ellipse2D.Double(i, 100, 15 + osi.simuler(t), 30);
((Graphics2D) dessinPanel.getGraphics()).draw(elp1);
dessinPanel.repaint();
Rectangle2D rect = new Rectangle2D.Double(186 + osi.simuler(t), 90, 50, 50);
((Graphics2D) dessinPanel.getGraphics()).draw(rect);
dessinPanel.repaint();
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Here`s also some pictures to show the problem:
before
after
You need to decouple your painting from your value adjustments.
Your painting operation should start by clearing the background, then paint the spring and box using the current input values.
When an input value changes, simply update the variable and invalidate() the display area.
For better performance, clearing the background can also be done by drawing the spring and box at their current positions in the background color. This also makes the updating of the input values more difficult.
One more technique you might use would be to widen the brush and draw first in the background color, then shrink the brush and draw the actual spring and rectangle in their correct form. This would be equivalent to erasing the background as long as you control the amount either can move in a single frame.

Tweaking an object created in setup() in Processing

I'm new to Processing, and I am trying to work with the Tweaking tool. My problem is that I can't seem to be able to tweak the values of variables created in the setup() method.
Below, an example:
Ellipse e;
void setup(){
size(640, 480);
e = new Ellipse();
}
void draw(){
background(220);
e.draw();
}
class Ellipse {
float w, l;
Ellipse(){
this.w = 300.0;
this.l = 300.0;
}
void draw(){
ellipse(300, 300 , w, l);
}
}
When I use "Tweak", I can tweak all four instances of 300 in the Ellipse class. It works exactly as expected for the 3rd and 4th ones, but when I tweak the values of w or l, nothing happens.
I assume this is because the Ellipse object is created from setup() and not draw(). Is this the right diagnostic, and is there a way around the problem? (I don't want to create a brand new object at every call of draw()).
The only changes you'll see are when you change numbers that haven't happened yet.
Your Ellipse has already been constructed, so changing the values of 300 in the constructor won't do anything. Note that if you were to create a new instance of Ellipse, then that new instance would indeed pick up the changes.
You are able to tweak the first two 300 values because they "happen" every frame.
If you want to be able to tweak the w and l variables, you need to put them in a place that happens every frame. You could do something like this:
void draw(){
w = 300;
l = 300;
ellipse(300, 300 , w, l);
}
Or you could just shorten it to this:
void draw(){
ellipse(300, 300 , 300, 300);
}
From the TweakMode homepage:
Scope of change
Without going into too much detail of how tweak mode operates
internally, you should remember that changing a number will have
effect only if the tweaked code will be executed in the future. For
example, take the following code:
void setup()
{
size(200, 200);
background(20);
}
void draw()
{
fill(100, 0, 0);
ellipse(100, 100, 50, 50);
}
In this code, changing the values of 'size(...)' and 'background(...)'
functions will have no effect while the sketch is running because
these lines of code happened once on setup and will never be executed
again during the sketch life. On the contrary, changing the values of
fill() and ellipse() will have effect because 'draw' is executed over
and over again.
The same principle applies to global variables, for example:
int CIRCLE_SIZE = 50;
void setup()
{
size(200, 200);
background(20);
}
void draw()
{
int red = 100;
fill(red, 0, 0);
ellipse(100, 100, CIRCLE_SIZE, CIRCLE_SIZE);
}
In this case, changing the value assigned to CIRCLE_SIZE (50) will
have no effect because the assignment of the value '50' to the
variable CIRCLE_SIZE happened only once during the sketch life, so the
value of CIRCLE_SIZE will remain the same even if the assigned value
is changed. On the contrary, changing the assigned value of the
variable 'red' (100) will have the expected effect because this
assignment happens every draw.
A simple solution to the problem with the global variables is to
reassign values you wish to tweak in the draw function. For example,
the following draw function will elliminate the issue we had with the
size of the ellipse in the previous code.
void draw()
{
CIRCLE_SIZE = 50;
int red = 100;
fill(red, 0, 0);
ellipse(100, 100, CIRCLE_SIZE, CIRCLE_SIZE);
}
Adding the line 'CIRCLE_SIZE = 50;' to the top of the draw function
made it possible to tweak this number and control also the size of the
circle in real time.

Animation issue using Processing 2.0 Java

I came across an issue while working on Processing 2.0 software using Java.
Each time I add an animation, I also add a background to erase the previous frame of this animation.
Unfortunately, this process also erases the rest of my graphics.
Is there a way to animate PShape without adding a new background?
Or is there a better way to animate shape in general?
I also would like to mention that I work with ActionScript language and my understanding of animation is based around MovieClip.
Thanks.
EDIT: Code added below:
Application Entry point
LineManager lineManager;
Character character;
void setup() {
size( 300, 600 );
background( 50 );
rectMode( CENTER );
frameRate( 24 );
lineManager = new LineManager();
character = new Character();
}
void draw() {
character.onTick();
}
Character Class
public class Character {
float MIN_VALUE = 80;
float value = MIN_VALUE;
float radius = 50.0;
int X, Y;
int nX, nY;
int delay = 16;
PShape player;
public Character() {
X = width / 2;
Y = height / 2;
nX = X;
nY = Y;
player = loadShape("player.svg");
}
public void onTick() {
value = value + sin( frameCount/4 );
X += (nX-X)/delay;
Y += (nY-Y)/delay;
/*
** My issue is the line below, as when adding it to render the animation
** I end up hiding the rest of my graphics
*/
background(0);
ellipse( X, Y, value, value );
shape( player, -10, 140, 320, 320 );
fill( 222, 222, 222, 222 );
}
}
The Processing dialect doesn't support indipendent graphics layers, but there are plenty of third party libraries that enable you to do that, like this one (last update: 2011).
Check out the updated list of the main libraries on Processing's site, under the Animation section.

Objects getting jerks when moving camera in downward direction

I have been making a game in which there is number of objects in negative 'y' for which I had taken the arrayList and I am moving the main character in downward direction.But when the camera move with the character the objects are not moving smooth, they are getting jerks after some interval of time.The code for that is following
#Override
public void create() {
camera = new OrthographicCamera(480, 720);
camera.position.set(480 / 2, 720 / 2, 0);
batch = new SpriteBatch();
int i;
this.baloonArrList = new ArrayList<Baloon>();
for (i = 0; i < 3000; i += 300) {
Baloon baloon = new Baloon(200, i);
baloonArrList.add(baloon);
System.out.println(baloon.balloon_y);
}
texture1 = new Texture(Gdx.files.internal("data/sheet_final.png"));
textureRegion1 = new TextureRegion(texture1, 561, 156, 115, 101);
}
#Override
public void render() {
GLCommon gl = Gdx.gl;
Gdx.gl.glClearColor(1, 1, 1, 1);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.position.y += 4;
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
int len = baloonArrList.size();
for (int i = 0; i < len; i++) {
batch.draw(textureRegion1, baloonArrList.get(i).balloon_x,
baloonArrList.get(i).balloon_y, 100, 100);
}
batch.end();
}
So, how can I make the motion of objects smooth.
I believe the source of your issue is the following line:
camera.position.y += 4;
You should instead change it to a smaller value, or better, make it based on the speed of the frame rate:
camera.position.y += 4 * Gdx.graphics.getDeltaTime();
This way your camera will move in the y direction 4 pixels every second, instead of 4 pixels every frame. (Of course you may need to increase the 4 to make it faster, but it will keep it quite smooth.)
If the rendering is jerky and inconsistent (use the builtin FPSLogger to find out what framerate you're getting), then something is taking more/variable amounts of time during rendering. You should use a profiler to figure out where time is going. The Android DDMS tools included with Eclipse are pretty good. Too-frequent garbage collection is often a source of variable runtimes, but its best to understand what is going on before trying to fix it.
That said, #Jyro117's suggestion to make your state updates frame-rate independent is always a good idea.

User-selected marker in time series data in Java

My code plots 5000 points of time series data in a panel that is 581 pixels wide by default, but this width changes when the user resizes the window. My code also plots several rectangular markers that each identify a local maximum/peak in this same space.
I need to enable the user to right click on any of the rectangular-peak-markers so that the user can manually delete any false peak. The problem is that my code is reporting different x-coordinates than expected when the user right-clicks on a peak-marker. I suspect that the reason may have to do with rounding error in converting from 581 x-pixels back to 5000 data indices. But I am not certain of the reason.
Can anyone suggest a solution that enables my users to manually select one of the above-described peak markers by right-clicking on it?
I am enclosing relevant sections of the code below. My actual code is very, very long, and too complicated to post. But the relevant portions below should be enough for someone to see the logic of my approach, and to then suggest a more effective approach.
The code that declares the class in question is:
class SineDraw extends JPanel implements MouseMotionListener, MouseListener {
// lots of code, including the two segments excerpted below
}
This segment of code overloads the paintComponent of the JPanel so that my data is plotted:
// declare some variables
ArrayList<Double> PeakList = new ArrayList<Double>() // this ArrayList is populated by an extraneous process
visiblePoints = 5000
hstep = getWidth()/visiblePoints //=581/5000 by default, but will change when user resizes window
int numPeaks = PeakList.size();
// scale (y-coordinate) data relative to height of panel
pts = new double[visiblePoints]
for (int i = 0; i < pts.length-1; i++){pts[i]=//data vertical scaled to fill panel;}
// plot the 5000 time-series-data-points within the 581 pixels in x-axis
for (int i = 1; i < visiblePoints; i++) {
int x1 = (int) ((i - 1) * hstep);
int x2 = (int) (i * hstep);
int y1 = (int)pts[i - 1];
int y2 = (int)pts[i];
g2.drawLine(x1, y1, x2, y2);
}
// plot a rectangle for each of the local peaks
for(int m=0;m<=(numPeaks-1);m++){
if(i==(int)(PeakList.get(m)){
int currentVal = (int)pts[(int)(PeakList.get(m)];
g2.drawRect((int)(PeakList.get(m), currentVal, 6, 6);
}
}
This section of code is for handling the right-clicking of the mouse:
public void mousePressed(MouseEvent e){
// check to see if right mouse button was clicked
boolean jones = (e.getModifiers()&InputEvent.BUTTON3_MASK)==InputEvent.BUTTON3_MASK;
if(jones==true){
// test the value returned as x-coordinate when user right-clicks (code always underestimates x-coordinate of local peaks by this test)
double ReverseHstep = visiblePoints/getWidth();
int getX_ConvertedTo_i = (int) (e.getX()*ReverseHstep);
System.out.println("getX_ConvertedTo_i is: "+getX_ConvertedTo_i );
// check to see if peaklist contains a value within the x-coordinates of the user-selected-rectangle
if(PeakList.contains((double)(e.getX()-3))
||PeakList.contains((double)(e.getX()-2))
||PeakList.contains((double)(e.getX()-1))
||PeakList.contains((double)(e.getX()))
||PeakList.contains((double)(e.getX()+1))
||PeakList.contains((double)(e.getX()+2))
||PeakList.contains((double)(e.getX()+3))
){
// handling code will go here, but for now it is a print test that never succeeds because x-coordinate is always underestimated
System.out.println("You just selected a peak!");
}
}
repaint();
}
I suggest you create objects (in this case Rectangles) for each thing you want to be clickable. Here is an over-simplified example of how you can make something you draw clickable. The key thing to take away from this is the mouseClicked method which will display a dialog only if the mouse clicked within the rectangle.
One tricky point is that I wasn't able to figure out how to make the rectangle filled in with color without drawing another rectangle over it. I'll leave that one for you ;-)
public class Canvas extends JPanel implements MouseListener{
private Rectangle rect = new Rectangle(100,100);
public Canvas(){
this.addMouseListener(this);
rect.setSize(100, 100);
}
#Override
public void paintComponent(Graphics g){
g.setClip(rect);
g.setColor(Color.RED);
g.fillRect(0, 0, 100, 100);
}
#Override
public void mouseClicked(MouseEvent e){
if(rect.contains(e.getPoint())){
JOptionPane.showConfirmDialog(this, "Click!");
}
}
// The rest of the MouseListener methods have been cut out
public static void main(String[] a){
JFrame frame = new JFrame("Canvas Thingy");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 300, 300);
frame.add(new Canvas());
frame.setVisible(true);
}
}

Categories