I draw many triangle polygons and store it in Linked List. My problem is that, when I store the drawing in a Notepad file, the data is unreadable (weird symbol). When I try to print it using println the output is like this java.awt.Polygon#1d6096.
How to store the coordinate of the polygon in Notepad?
...
java.util.List<Polygon> triangles = new LinkedList<Polygon>();
String pathname = "eyemovement.txt";
...
int[] xs = { startDrag.x, endDrag.x, midPoint.x };
int[] ys = { startDrag.y, startDrag.y, midPoint.y };
triangles.add(new Polygon(xs, ys,3));
...
public void actionPerformed(ActionEvent e) {
if(e.getSource() == saveBtn){
try {
FileOutputStream fos = new FileOutputStream(pathname);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(triangles);
oos.flush();
oos.close();
fos.close();
}
catch (Exception ex) {
System.out.println("Trouble writing display list vector");
}
}
EDITED:
I have tried all the suggestions but still I can't managed to get the output as the following. I have tried the "Printwriter" as well, but I cant solved the problem. Help me, please, my head is so heavy with this :-(
I draw the triangles, make changes, and store it in Linked List. After finished drawing, and make changes, I click save button and save it in Notepad.txt with hope that I will get the output in Notepad like this:
40 60 50 this line represents vertices Xs of triangle 1
40 40 50 this line represents vertices Ys of triangle 1
60 80 70 triangle 2
60 60 70
100 120 110 triangle 3
100 100 110
If you just want to store co-ordinates, and only want to write one way (into the file) then you should write an override method on your Polygon:
String toString() {
return this.x + ", " + this.y;
}
or something similar.
Of course the data is unreadable. It is "Data", not "Text". You have to read the file again with the ObjectInputStream class. Use the method `readObject(); This method returns an Object. Of course you have to cast it on this way:
Object o = ois.readObject(); // ois is the ObjectInputStream
List<Polygon> list = new ArrayList<Polygon>((List) o));
I think you just want to save the triangle to continue working with it after closing your program.
Nobody actually posted the absolute simplest way to do this, so here it goes.
Take a Polygon p, output a string representing the x/y coordinates of p (assuming p has at least 1 point) of the form "(x1 y1, x2 y2, x3 y3, ...)":
System.out.print("(" + p.xpoints[0] + p.ypoints[0]);
for (int i = 0; i < p.npoints; i++) {
System.out.print(", " + p.xpoints[i] + " " + p.ypoints[i]);
}
System.out.println(")");
I start with a test case.
import java.awt.Polygon;
import junit.framework.TestCase;
public class PolygonTest extends TestCase {
public void testToString() throws Exception {
Polygon polygon = new Polygon();
polygon.addPoint(0, 1);
polygon.addPoint(1, 1);
polygon.addPoint(1, 0);
assertEquals("(0,1;1,1;1,0)", polygon.toString());
}
}
I'm assuming here that you are using the awt Polygon class. This test fails, because awt's Polygon class doesn't override the default behavior. But Polygon has lots of good stuff in it you don't want to lose (maybe), so to add the new behavior we want (a toString() method), let's change this just a little bit:
import java.awt.Polygon;
import junit.framework.TestCase;
public class PolygonTest extends TestCase {
public void testToString() throws Exception {
Polygon polygon = new Triangle();
polygon.addPoint(0, 1);
polygon.addPoint(1, 1);
polygon.addPoint(1, 0);
assertEquals("(0,1;1,1;1,0)", polygon.toString());
}
}
This doesn't even compile, because the Triangle class doesn't exist yet. So let's create it (I'm using eclipse; I'll run QuickFix to create the class for me):
import java.awt.Polygon;
public class Triangle extends Polygon {
}
And now the test compiles, but fails as before. So let's write the toString() method:
import java.awt.Polygon;
public class Triangle extends Polygon {
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("(");
for (int i = 0; i < npoints; i++)
sb.append(String.format("%s,%s;", xpoints[i], ypoints[i]));
sb.deleteCharAt(sb.length() - 1); // get rid of the final semicolon
sb.append(")");
return sb.toString();
}
}
and now the test passes.
Note that I changed the format a little from what you requested, because I think you probably want to be able to distinguish between the point (5, 17) and the point (51, 7).
Related
I faced one problem which I’m struggling to solve.
Imagine simple game, where some object , lets call it car, remains motionless on X-axis ( x = 50 ) and is able to move only on Y-axis (up and down). At the same time, another objects are created beyond the screen at random point ( and move toward my first object ) , so their coordinates decrementing on X-axis. As soon as every object reaches my first object coordinates, some variable int scores; increments.
int scores;
if(cars.getX() == getCarPos_X() && cars.getY() != getCarPos_Y() )
scores++;
Basically this game looks like car which goes between other cars and avoid hitting, and counter scores increments every time my car pass next moving car.
So what is the problem?
I use timer which count time between repainting. All objects pass to the paintComponent where actually all graphic draw. In actionPerformed I call methods for all moves, and one method which checks if collision with another car occurred. In case of collision, game stops, and scores should be written in some txt file.
The problem is that while two objects have same coordinates, JVM write endless number of figures (scores) into the file ( I think it’s because coordinates stop decrementing and every timer interval it checks for collision and it’s == true , as game is stoped , and object remains where they are.)
So my scores in txt file looks like :
0
0
0
0
In one column.
Or it displays any score which I’ve got.
And so on...
Here is the crucial code snippet which I used
public void actionPerformed(ActionEvent e)
{
animate();
checkTouch();
}
private void animate()
{
//here code that creates obstacles and moves them
}
checkTouch()
{
//objects creating in some inner class Cars and add to ArrayList ( I don’t mention about it as it is beside the point )
for(Cars car : cars)
{
if((cars.getX() == getCarPos_X && cars. getY() == getCarPos_Y())
{
//boolean var which stops game
inGame = false;
writeScore();
}
}
}
public void writeScore()
{
File scoresTxt = new File("scores.txt");
FileWriter fw = null;
BufferedWriter bw = null;
try
{
fw = new FileWriter(scoresTxt, true);
bw = new BufferedWriter(fw);
bw.write(scores + "\n");
}catch (IOException e)
{
e.printStackTrace();
}finally
{
try
{
bw.flush();
bw.close();
fw.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
public void paintComponent (Graphics g)
{
if(inGame)
{
g.drawImage(myCar, 50, 100, this);
for(Cars car : cars)
{
g.drawImage(obstacleCar, car.getX(), car.getY(), this);
}
}
}
Should you need some extra code I used, write comment and I’ll add it.
And again I need to fix bug which write endless column of numbers instead of one final score from the moment of collision.
What’s wrong with my code , and how to solve this problem?
Give me advice for simplest decision, as I’m beginner.
Thanks in advance!
If your timer is started like this, or something similar, the you could cancel it when the inGame variable becomes false. Nice article on timers.
TimerTask task = new TimerTask() {
public void run() {
if (!inGame)
cancel();
else
// whatever it is that you are doing now
}
};
You might also want to stop processing events in the actionPerformed(e) method in a similar way.
if (!inGame)
return;
I am attempting to create an image based on string with RGB color values assigned on new lines. But for whatever reason the pixels are being placed in the wrong spots creating this odd chevron pattern. Clearly the issue is in how I am increasing the values but I can't seem to find the issue.
I've also confirmed multiple different ways that there is nothing wrong with the string
Chevron pattern I was talking about
static void AddPixels(String Data){
Scanner Scan = new Scanner(Data);
ArrayList<Integer> Table = new ArrayList<>();
while (Scan.hasNextLine() && !(XCount == XTotal)){
Scanner LineScan = new Scanner(Scan.nextLine());
while (LineScan.hasNext()){
Table.add(LineScan.nextInt());
}
if (Table.size() == 3){
Image.setRGB(XCount,YCount, new Color(Table.get(0),Table.get(1),Table.get(2),255).getRGB());
}
else{
Image.setRGB(XCount,YCount, new Color(0,0,0,0).getRGB());
}
Table.clear();
YCount++;
if (YCount == YTotal){
YCount = 0;
XCount++;
System.out.println(Math.floor(((double)XCount/XTotal)*100));
}
}
//System.out.println("Finished");
if (XCount >= XTotal){
System.out.println("Runnin");
try{
File ImageFile = new File("TestImage.png");
ImageIO.write(Image, "png", ImageFile);
}
catch(IOException e)
{
System.out.println("Error: " + e);
}
}
}
You're updating your y-coordinate each time you loop (for each of R, G, and B), and painting a black pixel 2/3rds of the time (the else block in your code).
If I understand your problem statement correctly, the file looks like:
200
100
0
where 200 is the R value, 100 is the B value, and 0 is the G value, for each pixel.
If this is the case, you need to be updating your Y value only every third value read from the file - and not painting black pixels at all.
I am struggling to read in 2D coordinates from an input file which should then create rectangles in a rectangle class. I am wondering how I would go about starting this as I am new to programming, such as how to layout the coordinates in the file and how to read them in using like a X1 Y1 X2 Y2 format to create a rectangle in the rectangle class. Thanks.
Read BufferedReader from https://www.mkyong.com/java/how-to-read-file-from-java-bufferedreader-example/ . It is an example of bufferedReader which is reading per line. Using this, you can put your text files values to your program.
This is a program I created for you
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFileExample2 {
//variable for file name with specified file path
private static final String FILENAME = "\*your directory*\filename.txt";
//List variable -> higher level of array because List is a flexible array
private static List<double> coordinates = new ArrayList<double>();
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader(FILENAME))) {
//this will add values from your textfile per line to List
while ((coordinates.add(br.readLine())) != null) { }
} catch (IOException e) {
e.printStackTrace();
}
}
}
This will solve one of your issue but this is just for you to move on not to solve all issues.
Your textfile should contain values like this
12
32
23
12
4 points for coordinates but per line. Your List coordinates will have it by running while ((coordinates.add(br.readLine())) != null) { }
research how to use list . It's a great thing to know.
Now study how to implement GUI using either JFrame or Applet.
Issues:
GUI : using JFrame
Read Text File : using BufferedReader
Array : using List, a higher level of array
I'm working on a game in java, based on the Atari game adventure. I got the basic KeyListener part working fine, but then I added another if statement, using another class, to test if if the player was going to hit a wall, and stopping movement if that was the case. The method I used also used if statements, and when I ran the code, it had MAJOR lag. I tried a while loop first, but that made it lag even worse. Anyway to make this not lag so much? It doesn't seem that complex a program to run, and I still have to add yet another if statement to make be able to move into another room, so I have to do something to massively cut down on the lag.
Here is the class:
class Player extends JPanel implements KeyListener{
private char c = 'e';
int x = 400;
int y = 400;
int mapX = 0;
int mapY = 0;
public Player() {
this.setPreferredSize(new Dimension(800, 500));
addKeyListener(this);
}
public void addNotify() {
super.addNotify();
requestFocus();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Environment Layout = new Environment();
Layout.drawRoom(mapX,mapY,g);
g.fillRect(x , y , 20, 20);
}
public void keyPressed(KeyEvent e) { }
public void keyReleased(KeyEvent e) { }
public void keyTyped(KeyEvent e) {
c = e.getKeyChar();
repaint();
Environment Layout = new Environment();
if(Layout.isWall(x,y,c)){}
else{
if (c == 'a'){
x = x - 3;
}
else if (c == 'w'){
y = y - 3;
}
else if (c == 's'){
y = y + 3;
}
else if (c == 'd'){
x = x + 3;
}
}
}
public static void main(String[] s) throws IOException{
JFrame f = new JFrame();
f.getContentPane().add(new Player());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
}
The draw room method I used in this was just to put the background of the room into place.
Here is the isWall method from the Environment class:
public boolean isWall(int moveX, int moveY, char let){
BufferedImage room = null;
try {
room = ImageIO.read(new File(xNum + "," + yNum + ".png"));
}
catch (IOException e) {
}
int[][] walls = convertImage(room);
boolean blocked = false;
if(let == 'w') {
if(walls[moveY-8][moveX] == -3584){blocked = true;}
}
else if(let == 's') {
if(walls[moveY+20][moveX] == -3584){blocked = true;}
}
else if(let == 'a') {
if(walls[moveY][moveX-5] == -3584){blocked = true;}
}
else if(let == 'd') {
if(walls[moveY][moveX+20] == -3584){blocked = true;}
}
return blocked;
}
the convertImage method just converts the image of the room into an int array, for the value of the colors. -3584 is the color of the walls. It's possible this is what's lagging it, but this seemed like the best way for each room to have the walls done automatically.
I also tried a timer, but either I did that wrong, or it just didn't help.
I can give more of my code if that's needed, but help with this would be much appreciated. I'm relatively new to this kind of stuff, so it's likely I'm missing something big. Thanks.
The lag here is almost certainly not from the if statements. Those are really fast. I think the bigger issue is in isWall. Notice that any time you want to check for whether a wall is present, you
Open a file,
read the file contents,
convert the file contents from an image to a grid of pixels, and
read exactly one pixel.
Reading files from disk is extremely slow compared to looking at values in memory. For example, a regular magnetic hard drive works at around 7200 RPM, so the seek time is measured in milliseconds. On the other hand, your processor can do about a billion operations per second, so other operations take nanoseconds. That means that a disk read is roughly a million times slower than other operations, which is almost certainly where you're getting the lag from!
To fix this, consider rewriting your isWall code so that you only read the file and do the conversion once and, having done that, then just look up the part of the image you need. This converts doing tons of (glacially slow) file reads to one single (slow but inevitable) file read followed by tons of fast memory reads.
You appear to be moving your walls further than you are moving your player.
Is it possible that your player object is getting stuck in a wall there by producing "blocked = true" continuously?
Your character gets +- 3 in every direction, however your walls seem inconsistent and range from 8 up to 20 down to 5 left to 20 right.
This is an extension to #templatetypedef's answer.
Instead of loading the image files upon calling the isWall method, you might want to consider caching all of the walls on game start.
So I am thinking;
have a HashMap data structure keyed by <String, Integer>. Where String is your coordinates. E.g. coordinate string = "100,238"
parse all the .png image files in the directories and store the coordinates as key and the value can just be any dummy value like 1 or 2.
Then when isWall() is invoked. Given the X and Y coordinate, build the coordinate string as mentioned in point 1 and check if the key exists. If it does then we know it is a piece of wall else not.
This should drastically reduce the I/O disk contention.
In future, if you would like to extend the solution to incorporate APIs like isTreasureChest() or isMonster(). It can be extended by building a immutable class call "Room" or "Tile" to represent the object. Then modify the HashMap to take in <String, Room>.
I have been messing around with javafx for practice and ran across something I couldn't figure out. I want to put a varying number of rectangles into an arraylist. Right now, instead of that, I am storing each rectangle as an double array (double[]) of the various properties, then setting a base rectangle to those values and returning that.
public class example{
Rectangle myRectangle = new Rectangle(0,0,25,25);
ArrayList<double[]> rectangles = new ArrayList();
double[] tempArray = [0,0];
public void addRect (double x, double y){
this.tempArray[0] = x;
this.tempArray[1] = y;
this.rectangles.add(this.tempArray);
};
public Rectangle getRect (int id){
this.myRectangle.setX(this.rectangles.get(id)[0]);
this.myRectangle.setY(this.rectangles.get(id)[1]);
return(this.rectangle);
};
}
In this example, when I call getRect, it sets the x and y of the base rect, then returns that rect. This works, but I am wondering if there is a way to store multiple instances of Rectangle in the ArrayList. The main issue I saw doing this is the fact that you have to name the instance(in the example above, myRectangle). I imagine that if there is a way around this issue, it would be to name the instance based on a string, in other words:
Rectangle "myRectangle" = new Rectangle();
which is not possible, as far as I know.
I am fairly new to Javafx and Java in general so if there is anything else off with my code feel free to correct that. Thanks!
You just need to make an ArrayList<Rectangle> and add rectangles to it.
public class Example {
private List<Rectangle> rectangles = new ArrayList<>();
public void addRectangle(double x, double y, double width, double height) {
rectangles.add(new Rectangle(x, y, width, height));
}
public Rectangle getRectangle(int index) {
return rectangles.get(index);
}
}
You should note that your original code really doesn't work as expected at all. For example, try:
// please do NOT name classes with lower case...
example e = new example();
e.addRectangle(0, 0);
e.addRectangle(100, 100);
Rectangle rect1 = e.getRectangle(0);
System.out.println("Rectangle 1: ["+rect1.getX()+", "+rect1.getY()+"]");
Rectangle rect2 = e.getRectangle(1);
System.out.println("Rectangle 2: ["+rect2.getX()+", "+rect2.getY()+"]");
// but:
System.out.println("Rectangle 1: ["+rect1.getX()+", "+rect1.getY()+"]");
// oops.
System.out.println("Rectangle 1 and 2 are the same: " + (rect1==rect2) );