I was making a random line generator for fun, and when I run the program, the "Y (End): " string looks very strange. The numbers are displayed as rectangular symbols, that have no meaning.
Here is my code:
public class LineFractal extends Applet {
Random random = new Random();
int width = 640;
int height = 640;
int x = 1000;
int endy1 = random.nextInt(width/2);
int endx1 = random.nextInt(width/2);
int starty1 = random.nextInt(width/2);
int startx1 = random.nextInt(width/2);
int space = random.nextInt(25);
public void init() {
setSize(width, height);
Frame c = (Frame)this.getParent().getParent();
c.setTitle("Line Generator");
}
public void paint(Graphics g) {
while (x > 0) {
x -= 1;
g.drawLine(startx1, starty1, endx1, endy1);
g.drawString("Space: " + space, width-100, height-10);
g.drawString("Y (End): " + endy1, width-100, height-20);
endy1 += space;
endx1 -= space;
}
}
}
Why does it do this?
EDIT: Just tried the program again, and the y was actually displayed correctly for once. But then I ran it again, and only the last number could be seen. The last time I ran it, there were no numbers that were readable...
You seem to be printing the string Y (End) and then a number over the top of itself 1000 times. Obviously that's OK for the text, but the number part is going to look messy very quickly! Imagine writing 0 1 2 3 4 5 6 7 8 9 all on top of each other.
You probably mean to draw a white (or whatever background colour) filled rectangle to the area where the strings are to be printed, just to clear what's there already.
I fixed it by putting the two drawString() outside the while loop.
Related
I made a program where user enters number of rectangles to be drawn and coordinates at which the rectangles are drawn. My rectangles are currently drawn like this:
and I want to achieve this:
This is the code I use to draw the rectangles:
int povecaj_kvadrat=0;
for(int x=0;x<broj_kvadrata;x++) {
Rectangle2D.Float kvadrat=new Rectangle2D.Float(brojevi_koordinate[0],brojevi_koordinate[1],50+povecaj_kvadrat,50+povecaj_kvadrat);
ploca.draw((kvadrat));
povecaj_kvadrat=povecaj_kvadrat+15;
}
}
How do I set the coordinates of the rectangles so that they are drawn like in the second image?
You will have to take into account the additional size of each Rectangle, along with its position within the loop to compute the correct coordinates of each rectangle.
The additional size has been moved as a variable (diffSize), so that your loop can use its value.
The difference in coordinates between two iterations will be half this diff size, multiplied by the inverse of the position in the loop, because the lower the increment (x) and the Rectangle size, the bigger the coordinates .
int gap = 0;
int maxNumber = 3;
int diffSize = 20;
int[] coordinates = { 10, 10 };
for (int x = 0; x <= maxNumber; x++) {
Rectangle2D.Float rectangle = new Rectangle2D.Float(
coordinates[0] + ((diffSize / 2) * (maxNumber - x)),
coordinates[1] + ((diffSize / 2) * (maxNumber - x)),
50 + gap, 50 + gap);
g2d.draw((rectangle));
gap = gap + diffSize;
}
Note that I am unsure of the correct behaviour if diffSize is odd (because (diffSize / 2) will be rounded down to the nearest int value), so I would keep an even value for diffSize.
I am making a minecraft mod that implements a new system of "energy" for the player. There are various ways to acquire this energy and I want it to display the player's amount of energy onto the screen. My plan for this is to make a GUI (with OpenGL, as minecraft uses) that uses a file called "energybar.png":
to print numbers. This is the code I have for the method that will do as described.
#SubscribeEvent
public void onGUIRenderEvent(RenderGameOverlayEvent event){
if(event.isCancelable() || event.type != RenderGameOverlayEvent.ElementType.EXPERIENCE)
{
return;
}
int xPos = 10;
int yPos = 10;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
GL11.glDisable(GL11.GL_LIGHTING);
mc.renderEngine.bindTexture(energybar);
String energyString = Integer.toString(Energy.PlayerTotalEnergy);
for(int i=0; i < energyString.length(); i++) {
LogHelper.info("Energy: " + energyString);
drawTexturedModalRect(xPos, yPos, (Energy.PlayerTotalEnergy / (int)Math.pow(10, i))*16, 0, 16, 16);
xPos += 16;
}
}
Each number in the photo is spaced out so it should be in its respective 16 pixels (ie: 0 is x positions 0-16, 1 is x positions 17-32, etc). The photo is 256x256 as defined by the standards of minecraft's GUI system. This is the layout of the method to draw a picture:
void drawTexturedModalRect(int xPosition, int yPosition, int uPosition, int vPosition, int width, int height)
The problem I have with this is that the U Positions for the numbers i need to print onto the screen are not working right.
I have also tried passing:
energyString.substring(i, i)
to a method that takes the substring and converts it back to an integer and multiplies it by 16 to get the uPosition, but when I do the:
String energyString = Integer.toString(Energy.PlayerTotalEnergy);
the Integer.toString() and also String.valueOf() methods have trouble with zeros. For example if Energy.PlayerTotalEnergy was just 0, they would not return a string "0", they just return "".
If someone could help me figure out why I can't get this to work or come up with a better idea of how I can use Minecraft and OpenGL to print this number onto my screen. The reason I'm not just printing it as a number is because I want to keep the red numbers as they look.
This is more of a guess.
It seems to me that if Energy.PlayerTotalEnergy was, let's say, 327, then your uPosition will be:
i=0: u= 327*16
i=1: u= 32*16
i=2: u= 3*16
Did you mean for them to be 7*16, 2*16, and 3*16?
In that case you should mod them with 10:
drawTexturedModalRect(xPos, yPos, ( (Energy.PlayerTotalEnergy / (int)Math.pow(10, i))%10)*16, 0, 16, 16);
I'm relatively new to programming, and i'm trying to create a program that creates a purple ball where i click that moves to the right until it is off the screen, where i can have unlimited balls on the screen at once. I've made a program that does this, but i can only have one on the screen at once, if i click a second time, the first ball disappears and is replaced with a new one. Oh, and when i click a second time, the ball doesn't start where the cursor is, it starts from where the last ball was on the X-Axis.
Help please!
Here's the code:
int moveX, moveY;
void setup() {
background(255);
moveY = 200;
moveX = 0;
size(500,400);
}
void mouseClicked() {
moveY = mouseY;
moveX++;
}
void draw() {
if (moveX >= 1){
background(255);
fill(255, 0, 255);
ellipse(moveX, moveY, 40, 40);
moveX++;
}
}
As donfuxx suggests, giving each ball it's own coordinates.
One way to do this is using an array to store multiple values(coordinates).
To do this you need to get familiar with for loops and arrays.
They may look scary at first, but once you get the hang of them they're quite easy.
Wherever you can think of a situation where repetition is needed, you can use a for loop to make your life easier.
For loop have the following syntax:
for keyword (3 elements: a start point,an end point(condition) and an increment,(separated by the ; character)
Let's say you want to move from a(0) to b(10) one step at a time:
for(int currentPos = 0 ; currentPos < 10; currentPos++){
println("step: " + currentPos);
}
If you can walk, you can also skip :)
for(int currentPos = 0 ; currentPos < 10; currentPos+=2){
println("step: " + currentPos);
}
even backwards if you want:
for(int currentPos = 10 ; currentPos > 0; currentPos--){
println("step: " + currentPos);
}
This is very useful when traversing all sort of data(coordinates of a ball in a scene, etc.)
How do you organize your data ? You place it in a list or array.
An array contains elements of the same type and has a set length.
The syntax to declare an array is like so:
ObjectType[] nameOfArray;
and you can initialize an empty array:
int[] fiveNumbers = new int[5];//new keyword then the data type and length in sq.brackets
or you can initialize the array with values:
String[] words = {"ini","mini","miny","moe"};
You access elements in an array using square brackets and the index of the object in the list you want to access. Arrays have a length property so you can easily count objects.
background(255);
String[] words = {"ini","mini","miny","moe"};
for(int i = 0 ; i < words.length; i++){
fill(map(i,0,words.length, 0,255));
text(words[i],10,10*(i+1));
}
Now back to your original question.
Here is your code using for loops and arrays:
int ballSize = 40;
int maxBalls = 100;//maximum number of balls on screen
int screenBalls = 0;//number of balls to update
int[] ballsX = new int[maxBalls];//initialize an empty list/array of x coordinates
int[] ballsY = new int[maxBalls];//...and y coordinates
void setup() {
size(500, 400);
fill(255, 0, 255);
}
void mouseClicked() {
if (screenBalls < maxBalls) {//if still have room in our arrays for new ball coordinates
ballsX[screenBalls] = mouseX;//add the current mouse coordinates(x,y)
ballsY[screenBalls] = mouseY;//to the coordinate arrays at the current ball index
screenBalls++;//increment the ball index
}
}
void draw() {
println(screenBalls);
background(255);
for (int i = 0 ; i < screenBalls; i++) {//start counting from 0 to how many balls are on screen
ballsX[i]++;//increment the x of each ball
if(ballsX[i]-ballSize/2 > width) ballsX[i] = -ballSize/2;//if a ball goes off screen on the right, place it back on screen on the left
ellipse(ballsX[i], ballsY[i], ballSize, ballSize);//display each ball
}
}
There are multiple ways to tackle this. Arrays have fixed size. If you don't want to be constrained by that you can use an ArrayList (sort of a variable size array). Later you might want to look into how you can make an object that can update and draw itself. Have fun!
I am trying to diffuse a color in java Draw (which doesn't have the capability to diffuse normally) but I ran into an error and I can't seem to spot it.
The way I went about diffusing was by writing a small script that would draw my shape hundreds of times, each time smaller and slightly varying in color. This is my snippet:
import javax.swing.*;
import java.awt.*;
public class DiffuseDraw extends JFrame
{
//set size of window here
final int length = 350;
final int height = 370;
public DiffuseDraw()
{
super("Graphics Project Window");
Container container = getContentPane();
setBackground(new Color(0,0,0));
setSize(length, height);
setVisible(true);
}
// my problem comes here:
public void paint(Graphics g)
{
Draw.fillRectangle(g,0,0,length,height,new Color(19,24,32));
int rad = 325; // size of the biggest circle
float floatGreen = 0; // Color components for black
float floatBlue = 0;
float floatRed = 0;
int counter = 0; // the counter
while (counter < 290) {
rad = rad - 1; // Here we shrink the by a small incriment
floatRed = floatRed + 87/290; //red component slowly goes brighter
floatBlue = floatBlue + 178/290; // blue component slowly goes brighter
floatGreen = floatGreen + 211/290; // green component slowly goes brighter
int intRed = (int)Math.round(floatRed);
int intBlue = (int)Math.round(floatBlue);
int intGreen = (int)Math.round(floatGreen);
Draw.fillCircle(g,173,307,rad,new Color(intRed,intBlue,intGreen));
counter = counter + 1;
}
}
public static void main(String args[]) {
DiffuseDraw prog = new DiffuseDraw();
prog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
When I compile and run, I only get a black screen. I am guessing that the problem is coming from the colors not changing. The number I am adding the float red blue and green by came from me wanting to diffuse a type of blue, so I took the the brightest color of blue that would appear and divided it by 290, the number of times the loop would run.
Instead of
87/290, 178/290, and 211/290,
try using
(float)87/290, (float)178/290, and (float)211/290.
That will, at least, add some color to the window- the problem is that by default, a number like 87/290 will be evaluated to 0; casting it to a float will give the desired result of 0.3 instead.
I am having a problem with my java code. I'm trying to make it so the top left quadrant produces a set number of lines input by a user through JOption Pane which are in random colors and in random positions. The programs builds successfully but it does not produce the number of lines the user input, nor does it set a random color (This it at the very bottom of my code). Can someone please explain how to fix this problem? Thanks very much.
Edit: fixed the curve braces but still will not work.
Edit: Everything works now except the random colors
import javax.swing.*; //for JFrame
import java.awt.*; //for Graphics and Container
import java.util.Random;
import javax.swing.JOptionPane;
// other import statements here
public class RandomGraphics
{
// constants are used to draw the grid, and for you to put shapes in the grid
public static final int MIDX = 400;
public static final int MIDY = 300;
public static final int MAXX = 799;
public static final int MAXY = 599;
public static final int COLOR = (int) (Math.random() * 256);
// make another constant for the color value that will
// be used to generate a random color
public static void main( String[] args )throws InterruptedException
{
//*** This next section sets up the graphics window.
//*** You are not required to understand it
Container contentPane;
Graphics g;
JFrame win = new JFrame("Random Graphics");
win.setSize(825,650);
win.setLocation(0,0);
win.setVisible(true);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = win.getContentPane();
contentPane.setBackground(Color.white);
g = contentPane.getGraphics();
Thread.sleep(50);
//*** done setting up graphics window
// Draws Grid - DO NOT CHANGE
// After you use JOptionPane to get the number of lines, you can move this
// section of code to just after that, so the lines will not disappear
g.drawRect(0,0,MAXX+1,MAXY+1);
g.drawLine(0,MIDY,MAXX,MIDY); // horizontal line
g.drawLine(MIDX,0,MIDX,MAXY); // vertical line
// Create Random object
Random r = new Random();
// Top left quadrant:
// Use a JOptionPane to ask the user to enter the number of lines 1 to 100.
int count = 0;
do
{
String morelines = JOptionPane.showInputDialog("Enter a number of lines between 1 to 100");
count = Integer.parseInt(morelines);
}
while(count > 100 || count < 1);
for(int i = 1; i >= count; i++)
{
g.setColor(new Color (r.nextInt(COLOR), r.nextInt(COLOR), r.nextInt(COLOR)));
g.drawLine(r.nextInt(MIDX), r.nextInt(MIDY), r.nextInt(MIDX), r.nextInt(MIDY));
}
g = contentPane.getGraphics();
Graphics objects are not persistent, the programmer needs to draw the GUI to them when asked to do so. For tips, see the Performing Custom Painting Lesson of the tutorial.
Beside the 'always include curly braces around loops advice', note..
for(int i = 1; i >= count; i++)
Should be..
for(int i = 1; i <= count; i++)
But don't ignore the advice about custom painting. The app. will not render reliably until that is fixed.
for(int i = 1; i >= count; i++)
g.setColor(new Color (r.nextInt(COLOR), r.nextInt(COLOR), r.nextInt(COLOR)));
g.drawLine(r.nextInt(MIDX), r.nextInt(MIDY), r.nextInt(MIDX), r.nextInt(MIDY));
Looking at your indenting, it looks like you want g.setColor(...) and g.drawLine(...) to be inside your for loop. You need to enclose them in curly braces {}, otherwise only the statement immediately following your for loop will be inside the loop.