I'm working with java images for the first time and having a problem viewing them when the applet loads. If I resize the window they display fine. I feel like this is a common first-timer error. Has anyone else encountered this? Any idea what the fix could be? What I believe to be the pertinent parts of the code are listed below. Thanks for any and all help with this...
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.*;
public class example extends JApplet implements Runnable
{
boolean updating;
Thread thread;
private int width, height;
Table aTable; //used to create and store values
private AudioClip[] sounds = new AudioClip[4]; //array to hold audio clips
private int counter = 0; //counter for audio clip array
private Image GameImage;
private Graphics GameGraphics;
public example() //set up applet gui
{
this.resize(new Dimension(600, 500));
//setup table
aTable = new Table(50, 50, 50, 50, 16, 16, getImage("images/FLY.gif", Color.white),
getImage("images/FlySwatter.gif", Color.white)); //Table must be square or flyswatter wont move straight
//add cordTxtFlds to bottom of screen
//this.add(cordTxtFlds, BorderLayout.SOUTH);
super.resize(800, 600);
repaint();
}
public void init()
{
width = getSize().width;
height = getSize().height;
GameImage = createImage(width, height);
GameGraphics = GameImage.getGraphics();
// Automatic in some systems, not in others
GameGraphics.setColor(Color.black);
repaint();
validate();
//show the greeting
ImageIcon icon = new ImageIcon("images/FLY.gif",
"a fly");
repaint();
validate();
}
/** Description of paint(Graphics g)
*
* Function draws table and sets the table color
* #param g graphics object used to draw table
* #return void
*/
public void paint(Graphics g)
{
GameGraphics.clearRect(0, 0, getWidth(), getHeight());
aTable.draw(GameGraphics);
g.drawImage(GameImage, 0, 0, this);
}
public void update(Graphics g)
{
paint(g);
validate();
}
public void start()
{
thread = new Thread(this);
thread.start();
}
public void stop()
{
updating = false;
}
public void run()
{
while(updating)
{
aTable.update();
}
}
//returns a transparent image.
//color is made transparent
private Image getImage(String imgPath, final Color color)
{
Image img = Toolkit.getDefaultToolkit().getImage(imgPath);
ImageFilter filter = new RGBImageFilter() {
// the color we are looking for... Alpha bits are set to opaque
public int markerRGB = color.getRGB() | 0xFFFFFF;
public final int filterRGB(int x, int y, int rgb) {
if ( ( rgb | 0xFF000000 ) == markerRGB ) {
// Mark the alpha bits as zero - transparent
return 0x00FFFFFF & rgb;
}
else {
// nothing to do
return rgb;
}
}
};
ImageProducer ip = new FilteredImageSource(img.getSource(), filter);
img = Toolkit.getDefaultToolkit().createImage(ip);
return img;
}
}
and the class which handles the drawing (in drawValues())
import java.awt.*;
import java.util.Random;
public class Table extends Panel
{
private char[][]values = new char[10][10]; //probably better to use array of integer values(0 or 1)
private Point[]coordLoc;// = new Point[100]; //stores the x & y coordinates of points on the grid
private boolean[]itemMarker; //stores the truth value of wether or not an item
// is located at the coresponding point in cordLoc array
private int [][]coords;// = new int [100][2];
Image itemImg; // stores the item image
private int Rows; // stores number of rows
private int Columns; // stores number of columns
private int BoxWidth ; // stores the width of a box
private int BoxHeight; // stores the height of a box
public Point Pos = new Point(); // creates a new point to draw from
private int tableHeight; // stores the height of the table
private int tableWidth; // stores the width of the table
private int numOfGridLocs;
/** Description of public Table( x, y, width, height, col, rows, X, O)
*
* Constructor function
* #param x contains an x-coordinate of the table
* #param y contains a y-coordinate of the table
* #param width contains the width of a box in the table
* #param height contains the height of a box in the table
* #param col contains the number of columns in the table
* #param rows contains the number of rows in the table
* #param itemImg contains the "target" image ie: ant, fly, ... unicorn
* #return none
*/
public Table(int x, int y, int width, int height, int col, int rows, Image itemImg, Image swatterImg)
{
/*set values*/
numOfGridLocs = (col - 1) * (rows - 1);
//initialize arrays
coordLoc = new Point[numOfGridLocs];
for(int i = 0; i < numOfGridLocs; i++)
coordLoc[i] = new Point();
Rows = rows;
Columns = col;
BoxWidth = width;
BoxHeight = height;
Pos.x = x;
Pos.y = y;
this.itemImg = itemImg;
tableHeight = Rows*BoxHeight;
tableWidth = Columns*BoxWidth;
itemMarker = new boolean[numOfGridLocs];
coords = new int [numOfGridLocs][2];
this.setValues();
mapGrid();
}
/** Description of draw(Graphics g)
*
* Function draws the lines used in the table
* #param g object used to draw the table
* #return none
*/
public void draw(Graphics g)
{
Graphics2D g2=(Graphics2D)g;
//draw flyswatter
drawValues(g2); //draw values
//draw vertical table lines
for (int i = 0 ; i <= Columns ; i++)
{
//make center line thicker
if(i == Rows/2)
g2.setStroke(new BasicStroke(2));
else
g2.setStroke(new BasicStroke(1));
g2.drawLine(i*BoxWidth + Pos.x, Pos.y, i*BoxWidth + Pos.x, tableHeight+Pos.y);
}
//draw horizontal table line
for(int i = 0 ; i <= Rows ; i++)
{
//make center line thicker
if(i == Rows/2)
g2.setStroke(new BasicStroke(2));
else
g2.setStroke(new BasicStroke(1));
g2.drawLine(Pos.x, i*BoxHeight + Pos.y, tableWidth+Pos.x, i*BoxHeight + Pos.y);
}
drawLables(g);
}
/** Description of drawLables(Graphics g)
*
* Function draws the Lables of the Table
* #param g object used to draw the table
* #return none
*/
private void drawLables(Graphics g)
{
String Lable;
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Font font = new Font("Serif", Font.PLAIN, 10);
g2.setFont(font);
int xLabel = this.Columns/2 * -1;
int yLabel = this.Rows/2;
//draw Row lables
for (int i = 0 ; i <= Rows ; i++)
{
Lable = "" + yLabel;
g2.drawString(Lable, Pos.x - 25, Pos.y + BoxHeight*i);
yLabel--;
}
//draw Column lables
for (int i = 0 ; i <= Columns ; i++)
{
Lable = "" + xLabel;
g2.drawString(Lable, Pos.x + BoxWidth*i - 5, Pos.y - 20 );
xLabel++;
}
}
/** Description of randomChangeFunc()
*
* Function randomly determines which table value to change
* #param none
* #return void
*/
public int getX(int XCordinate)
{
int x = XCordinate+Columns/2;
if(x < 0) x *= -1; //x must be positive
x *= BoxWidth;
x += Pos.x;
return x-BoxWidth/2;
}
//returns Position of Y-cordinate
public int getY(int YCordinate)
{
int y = YCordinate -Rows/2;
if (y < 0) y *= -1; //y must be positive
y *= BoxHeight;
y += Pos.y;
return y-BoxHeight/2;
}
/** Description of getValue( col, row )
*
* Function draws the lines used in the table
* #param col contains a column coordinate
* #param row contains a row coordinate
* #return returns table coordinates
*/
public char getValue(int col, int row)
{
return values[row][col];
}
/** Description of isDrawable( x, y )
*
* Function returns true if (x,y) is a point in the table
* #param x contains a table column
* #param y contains a table row
* #return boolean if (x,y) is a point in the table
*/
public boolean isDrawable(int x, int y)
{
if((this.getRow(y)!=-1)||(this.getColumn(x)!=-1))
return true;
else
return false;
}
private void drawValues(Graphics g)
{
for(int i = 0; i < numOfGridLocs; i++)
if(itemMarker[i])
g.drawImage(itemImg,coordLoc[i].x+1, coordLoc[i].y+1, BoxWidth-1, BoxHeight-1, null);
g.setColor(Color.black); // set color of table to black
}
//sets the randomized boolean values in itemMarker array
private void setValues()
{
double probOfItem = .25;
for(int count = 0; count < numOfGridLocs; count++){
itemMarker[count] = randomBool(probOfItem);
if(itemMarker[count])
System.out.println("true");
else
System.out.println("false");
}
}
//returns random boolean value, p is prob of 'true'
private boolean randomBool(double p)
{
return (Math.random() < p);
}
public int getColumn(int x)
{
x += (BoxWidth/2); //aTable.getX/Y returns in the middle of squares not at upper left point
int offsetx=0;
for (int i = 0 ; i < Columns*2 ; i++)
{
offsetx = i*BoxWidth;
if((x>=Pos.x+offsetx)&& (x<Pos.x+offsetx+BoxWidth))
return i-Columns;
}
return -100;
}
public int getRow(int y)
{
int offsety=0;
y += (BoxHeight/2); //aTable.getX/Y returns in the middle of squares not at upper left point
for (int i = 0 ; i < Rows*2 ; i++) {
offsety = i * BoxHeight;
if((y >= (offsety+Pos.y))&& (y < (offsety+BoxHeight+Pos.y)))
{
return ((i)*-1)+Rows;
}
}
return -100;
}
public boolean isValidGuess(int x, int y)
{
if ((x > Columns/2) || (x < Columns/2*-1) || (y > Rows/2) || (y < Rows/2*-1))
return false;
return true;
}
/** Description of randomChangeFunc()
*
* Function randomly determines which table value to change
* #param none
* #return void
*/
public void randomChangeFunc()
{
//get random row and column
Random rand=new Random();
int randRow = rand.nextInt(Rows); // gets and holds a random column
int randCol = rand.nextInt(Columns); // gets and holds a random column
System.out.println("randRow = " + randRow + " randCol = " + randCol);
if(values[randRow][randCol] == 'X')
values[randRow][randCol] = 'O';
else if(values[randRow][randCol] == 'O')
values[randRow][randCol] = 'X';
else
System.out.println("ERROR SWAPPING SQUARE VALUE"); // error message
}
private void mapGrid() //set values for coordLoc array
{
//set counter variables
int count = 0;
int index = 0;
//loop through all points, assigning them to the coordLoc array
for (int r=0; r < Rows-1; r++)
for (int c=0; c < Columns-1; c++) {
//the width/height / 2 places the points on grid line intersections, not the boxes they create
coordLoc[count].x = Pos.x + (BoxWidth) * c + (BoxWidth/2); // record x-point
coordLoc[count].y = Pos.y + (BoxHeight) * r + (BoxHeight/2); // record y-point
System.out.println(coordLoc[count].getX() + ", " + coordLoc[count].getY());
count++;
} //end inner for
//set positive x coord values for coords array
int y_axisBeginingIndex = (Rows - 2)/2;
for(int greaterIndex = 0; greaterIndex < ((Rows) / 2); greaterIndex++){
for(int minorIndex = 0; minorIndex < (Rows - 1); minorIndex++){
index = y_axisBeginingIndex + greaterIndex + ((Rows - 1) * minorIndex);
coords[index][0] = greaterIndex;
}
}
//set negative x coord values for coords array
for(int greaterIndex = -1; greaterIndex > (0-((Rows) / 2)); greaterIndex--){
for(int minorIndex = 0; minorIndex < (Rows - 1); minorIndex++){
index = y_axisBeginingIndex + greaterIndex + ((Rows - 1) * minorIndex);
coords[index][0] = greaterIndex;
}
}
//set positive y values for coords array
int x_axisBeginingIndex = (Rows - 1) * ((Rows / 2) - 1);
for(int greaterIndex = 0; greaterIndex < ((Rows) / 2); greaterIndex++){
for(int minorIndex = 0; minorIndex < (Rows - 1); minorIndex++){
index = x_axisBeginingIndex + minorIndex;
coords[index][1] = greaterIndex;
}
x_axisBeginingIndex -= (Rows - 1);
}
//set negative y values for coords array
x_axisBeginingIndex = (Rows - 1) * ((Rows / 2) - 1) + (Rows - 1);
for(int greaterIndex = -1; greaterIndex > (0-((Rows) / 2)); greaterIndex--){
for(int minorIndex = 0; minorIndex < (Rows - 1); minorIndex++){
index = x_axisBeginingIndex + minorIndex;
coords[index][1] = greaterIndex;
}
x_axisBeginingIndex += (Rows - 1);
}
//print out the x and y coords
for(int i = 0; i < numOfGridLocs; i++){
System.out.println("[" + i + "] -> x = " + coords[i][0] + " y = " + coords[i][1]);
}
}
public boolean thereIsAnItemAt(int index){
return itemMarker[index];
}
public boolean bugsLeft(){
boolean thereAreBugsLeft = false;
for(int i = 0; i < numOfGridLocs; i++)
if(itemMarker[i])
thereAreBugsLeft = true;
return thereAreBugsLeft;
}
void update()
{
this.repaint();
}
}
Been stumped on this for weeks. Thanks again...
What I believe to be the pertinent
parts of the code are listed below.
By definition when you have a problem you don't know what part of the code is (or isn't) relevant. That is why you need to post a SSCCE that demonstrates the problem so we can see what you are doing.
The fact that is work "after" a resize means the problem is not with the painting. The problem could be that the images aren't loaded in which case you should be using:
drawImage(...., this);
The "this" instead of "null" notifies the panel to repaint the image when the image gets fully loaded.
Or maybe, you added the panel to the frame after the frame was visible and forgot to use
panel.revalidate().
By resizing the frame you force a revalidation.
The point is we are guessing. So save us time and post a SSCCE next time.
Sorry still too much code.
You need to read the article on Painting in AWT and Swing. Your code is a mixture of both.
Basically, as you where told in your last posting custom painting is done by overriding the paintComponent(...) method of JPanel. So you do the custom painting and then add the JPanel to the JApplet. I gave you a link to the Swing tutorial in your last posting and it also contains a section on how to write an Applet.
You should be extending JPanel, not Panel.
Also, you should NOT be overriding the paint() and upated() method of JApplet, this is old AWT code and should NOT be used with Swing.
Read the article and fix the problems first.
The answer is changing the draw() method in the class that extends JPanel to paintComponent() and switching the last parameter in the call to drawImage() to 'this' instead of 'null'. Worked instantly and perfectly!
Related
I have a homework task where I have to write a class responsible for contour detection. It is essentially an image processing operation, using the definition of euclidean distance between 2 points in the 3-dimensional space. Formula given to us to use is:
Math.sqrt(Math.pow(pix1.red - pix2.red,2) + Math.pow(pix1.green- pix2.green,2) + Math.pow(pix1.blue- pix2.blue,2));
We need to consider each entry of the two dimensional array storing the colors of the pixels of an image, and if some pixel, pix, the color distance between p and any of its neighbors is more than 70, change the color of the pixel to black, else change it to white.
We are given a seperate class as well responsible for choosing an image, and selecting an output, for which method operationContouring is applied to. Java syntax and convention is very new to me having started with python. Conceptually, I'm struggling to understand what the difference between pix1 and pix2 is, and how to define them. This is my code so far.
Given:
import java.awt.Color;
/* Interface for ensuring all image operations invoked in same manner */
public interface operationImage {
public Color[][] operationDo(Color[][] imageArray);
}
My code:
import java.awt.Color;
public class operationContouring implements operationImage {
public Color[][] operationDo(Color[][] imageArray) {
int numberOfRows = imageArray.length;
int numberOfColumns = imageArray[0].length;
Color[][] results = new Color[numberOfRows][numberOfColumns];
for (int i = 0; i < numberOfRows; i++)
for (int j = 0; j < numberOfColumns; j++) {
int red = imageArray[i][j].getRed();
int green = imageArray[i][j].getGreen();
int blue = imageArray[i][j].getBlue();
double DistanceColor = Math.sqrt(Math.pow(pix1.red - pix2.red,2) + Math.pow(pix1.green- pix2.green,2) + Math.pow(pix1.blue- pix2.blue,2));
int LIMIT = 70;
if (DistanceColor> LIMIT ) {
results[i][j] = new Color((red=0), (green=0), (blue=0));
}
else {
results[i][j] = new Color((red=255), (green=255), (blue=255));
}
}
return results;
}
}
This is a solution I wrote that uses BufferedImages. I tested it and it should work. Try changing it such that it uses your data format (Color[][]) and it should work for you too. Note that "pix1" is nothing more than a description of the color of some pixel, and "pix2" is the description of the color of the pixel you are comparing it to (determining whether the color distance > 70).
public static boolean tooDifferent(Color c1, Color c2) {
return Math.sqrt(Math.pow(c1.getRed() - c2.getRed(),2) + Math.pow(c1.getGreen()- c2.getGreen(),2) + Math.pow(c1.getBlue()- c2.getBlue(),2)) > 70;
}
public static Color getColor(int x, int y, BufferedImage img) {
return new Color(img.getRGB(x, y));
}
public static BufferedImage operationDo(BufferedImage img) {
int numberOfRows = img.getHeight();
int numberOfColumns = img.getWidth();
BufferedImage results = new BufferedImage(numberOfColumns, numberOfRows, BufferedImage.TYPE_INT_ARGB);
for (int y = 0; y < numberOfRows; y++) {
for (int x = 0; x < numberOfColumns; x++) {
Color color = new Color(img.getRGB(x, y));
boolean aboveExists = y > 0;
boolean belowExists = y < numberOfRows - 1;
boolean leftExists = x > 0;
boolean rightExists = x < numberOfColumns - 1;
if ((aboveExists && tooDifferent(color, getColor(x, y - 1, img))) ||
(belowExists && tooDifferent(color, getColor(x, y + 1, img))) ||
(leftExists && tooDifferent(color, getColor(x - 1, y, img))) ||
(rightExists && tooDifferent(color, getColor(x + 1, y, img)))) {
results.setRGB(x, y, Color.black.getRGB());
} else {
results.setRGB(x, y, Color.white.getRGB());
}
}
}
return results;
}
I am well and truly stuck on this method. I need to create an attack method for a ComputerPlayer that chooses a random location and attacks the other player's board. Then, there is an attack method where I have to just attack the other player's board. However, when I run the program and place my guesses on my board (GUI), the dots just appear on the ComputerPlayer's board. I don't know why my methods are wrong though.
/**
* Attack the specified Location loc. Marks
* the attacked Location on the guess board
* with a positive number if the enemy Player
* controls a ship at the Location attacked;
* otherwise, if the enemy Player does not
* control a ship at the attacked Location,
* guess board is marked with a negative number.
*
* If the enemy Player controls a ship at the attacked
* Location, the ship must add the Location to its
* hits taken. Then, if the ship has been sunk, it
* is removed from the enemy Player's list of ships.
*
* Return true if the attack resulted in a ship sinking;
* false otherwise.
*
* #param enemy
* #param loc
* #return
*/
#Override
public boolean attack(Player enemy, Location loc)
{
int[][] array = getGuessBoard();
if(!enemy.hasShipAtLocation(loc))
array[loc.getRow()][loc.getCol()] = -1;
else
{
array[loc.getRow()][loc.getCol()] = 1;
enemy.getShip(loc).takeHit(loc);
}
if(enemy.getShip(loc).isSunk()) {
enemy.removeShip(enemy.getShip(loc));
return true;
}
return false;
}
#Override
public boolean attack(Player enemy, Location loc)
{
int range = (10 - 0) + 1;
int r = (int) Math.random() * range;
int c = (int) Math.random() * range;
int[][] array = getGuessBoard();
if(array[r][c] != -1)
{
if(!enemy.hasShipAtLocation(loc))
array[loc.getRow()][loc.getCol()] = -1;
else
{
array[loc.getRow()][loc.getRow()] = 1;
enemy.getShip(loc).takeHit(loc);
}
if(getShip(loc).isSunk())
{
enemy.removeShip(enemy.getShip(loc));
return true;
}
}
return false;
}
GUI for Game
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class BattleshipDriver extends Canvas implements MouseListener
{
public static final int WIDTH = 1024, HEIGHT = WIDTH / 12 * 9;
private Battleship battleship;
private int x, y, squareSize, len;
private Player p1, p2;
private BufferedImage logo, end;
public BattleshipDriver()
{
battleship = new Battleship();
battleship.addPlayer(new HumanPlayer("Mr. Hubbard"));
battleship.addPlayer(new ComputerPlayer("AlphaBattleship"));
x = 90;
y = 200;
squareSize = 36;
len = squareSize * 10 - 1;
p1 = battleship.getPlayer(0);
p2 = battleship.getPlayer(1);
// Get Battleship Logo
try {
logo = ImageIO.read(new File("src/Logo.png"));
} catch (IOException e) {
e.printStackTrace();
}
// Get End Screen
try {
end = ImageIO.read(new File("src/End.png"));
} catch (IOException e) {
e.printStackTrace();
}
addMouseListener(this);
new Window(WIDTH, HEIGHT, "Battleship", this);
try {
Thread.sleep(100);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
render();
}
private void render()
{
Graphics g = getGraphics();
// Background
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, WIDTH, HEIGHT);
if(!battleship.gameOver())
{
// Boards
renderGrid(g, x, y, squareSize);
renderGuesses(g, p1, x, y, squareSize);
renderGrid(g, 570, y, squareSize);
renderGuesses(g, p2, 570, y, squareSize);
// Names
g.setColor(Color.WHITE);
g.drawString(p1.getName(), x, y + 25 + len);
g.drawString(p2.getName(), 570, y + 25 + len);
}
else
{
// End Screen
g.drawImage(end, 0, 0, this);
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", 1, squareSize));
String winner = battleship.getWinner().getName();
g.drawString(winner, WIDTH / 2 - (winner.length() * squareSize / 4), HEIGHT / 4);
g.drawString("Wins!", WIDTH / 2 - ("Wins!".length() * squareSize / 4), HEIGHT / 4 + squareSize);
}
// Battleship Logo
g.drawImage(logo, WIDTH / 2 - 246, 10, this);
g.dispose();
}
private void renderGrid(Graphics g, int x, int y, int s)
{
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", 1, s / 2));
// Row Lines
for(int i = 0; i < 11; i++)
g.drawLine(x, y+i*s, x+len, y+i*s);
// Column Lines
for(int i = 0; i < 11; i++)
g.drawLine(x+i*s, y, x+i*s, y+len);
// Row Markers
for(int i = 0; i < 10; i++) //marks row coordinates on side
g.drawString(i + "", x-(int)(s*0.43), y+(int)(s*0.67)+s*i);
// Column Markers
for(int i = 0; i < 10; i++) //marks column coordinates on top
g.drawString(i + "", x+(int)(s*0.4)+s*i, y-(int)(s*0.2));
}
public void renderGuesses(Graphics g, Player player, int x, int y, int s)
{
int[][] guessBoard = player.getGuessBoard();
for(int r = 0; r < guessBoard.length; r++)
for(int c = 0; c < guessBoard[r].length; c++)
if(guessBoard[r][c] > 0) // hit
{
g.setColor(Color.RED);
g.fillOval(c*s+x+(int)(s*0.35), r*s+y+(int)(s*0.35), (int)(s*0.33), (int)(s*0.33));
}
else if(guessBoard[r][c] < 0) // miss
{
g.setColor(Color.WHITE);
g.fillOval(c*s+x+(int)(s*0.35), r*s+y+(int)(s*0.35), (int)(s*0.33), (int)(s*0.33));
}
}
#Override
public void mouseClicked(MouseEvent e)
{
int r = e.getY();
int c = e.getX();
int len = squareSize * 10 - 1;
if(r > y && r < y + len && c > x && c < x + len) // clicked on board
{
int row = (r - y) / squareSize;
int col = (c - x) / squareSize;
System.out.println(row + ", " + col);
Location loc = new Location(row, col);
if(p1.getGuessBoard()[row][col] == 0)
{
p1.attack(p2, loc);
p2.attack(p1, loc);
}
battleship.upkeep();
render();
}
System.out.println(r + ", " + c);
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
public static void main(String[] args)
{
new BattleshipDriver();
}
}
I'm pretty fresh to java but I wanted to create a exploration type game. I researched for the last 2 weeks and was able to implement the diamond square algorithm for some pretty sweet terrain. But now I'm having trouble trying figure out how to move the map and how to continue the random generation. Here's what I have so far.
Game.java
package com.game.main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.util.Random;
//import java.util.Random;
public class Game extends Canvas implements Runnable{
private static final long serialVersionUID = 5420209024354289119L;
public static final int WIDTH = 1000, HEIGHT = WIDTH / 12 * 9;
private Thread thread;
private boolean running = false;
//private Random r;
private Handler handler;
public Game(){
handler = new Handler();
this.addKeyListener(new KeyInput(handler));
new Window(WIDTH, HEIGHT, "Game", this);
final int[][] map = DSAlgorithm.makeHeightMap(10, 45, 200);
//r = new Random();
handler.addObject(new Player(WIDTH/2 - 32, HEIGHT/2 - 32, ID.Player));
//handler.addObject(new World(0, 0, ID.World));
int squareSize = 10;
for(int y = 0; y < map.length; y+=squareSize){
for(int x = 0; x < map.length; x+=squareSize){
int value = map[x][y];
handler.addObject(new TerrianTile(x, y, value));
}
}
}
public synchronized void start(){
thread = new Thread(this);
thread.start();
running = true;
}
public synchronized void stop(){
try {
thread.join();
running = false;
} catch (Exception e) {
e.printStackTrace();
}
}
public void run(){
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while (running){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1){
tick();
delta --;
}
if (running)
render();
frames++;
if (System.currentTimeMillis() - timer > 1000){
timer += 1000;
System.out.println("FPS: " + frames);
frames = 0;
}
}
stop();
}
private void tick(){
handler.tick();
}
private void render(){
BufferStrategy bs = this.getBufferStrategy();
if (bs == null){
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
handler.render(g);
g.dispose();
bs.show();
}
public static void main(String args[]){
new Game();
}
public static int randInt(int min, int max){
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
}
Window.java
package com.game.main;
import java.awt.Canvas;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Window extends Canvas {
private static final long serialVersionUID = -1478604005915452565L;
public Window(int width, int height, String title, Game game) {
JFrame frame = new JFrame(title);
frame.setPreferredSize(new Dimension(width, height));
frame.setMaximumSize(new Dimension(width, height));
frame.setMinimumSize(new Dimension(width, height));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.add(game);
frame.setVisible(true);
game.start();
}
}
DSAlgorithm.java
package com.game.main;
public class DSAlgorithm {
/**
* This method uses the seed value to initialize the four corners of the
* map. The variation creates randomness in the map. The size of the array
* is determined by the amount of iterations (i.e. 1 iteration -> 3x3 array,
* 2 iterations -> 5x5 array, etc.).
*
* #param iterations
* the amount of iterations to do (minimum of 1)
* #param seed
* the starting value
* #param variation
* the amount of randomness in the height map (minimum of 0)
* #return a height map in the form of a 2-dimensional array containing
* integer values or null if the arguments are out of range
*/
public static int[][] makeHeightMap(int iterations, int seed, int variation) {
if (iterations < 1 || variation < 0) {
return null;
}
int size = (1 << iterations) + 1;
int[][] map = new int[size][size];
final int maxIndex = map.length - 1;
// seed the corners
map[0][0] = seed;
map[0][maxIndex] = seed;
map[maxIndex][0] = seed;
map[maxIndex][maxIndex] = seed;
for (int i = 1; i <= iterations; i++) {
int minCoordinate = maxIndex >> i;// Minimum coordinate of the
// current map spaces
size = minCoordinate << 1;// Area surrounding the current place in
// the map
diamondStep(minCoordinate, size, map, variation);
squareStepEven(minCoordinate, map, size, maxIndex, variation);
squareStepOdd(map, size, minCoordinate, maxIndex, variation);
variation = variation >> 1;// Divide variation by 2
}
return map;
}
/**
* Calculates average values of four corner values taken from the smallest
* possible square.
*
* #param minCoordinate
* the x and y coordinate of the first square center
* #param size
* width and height of the squares
* #param map
* the height map to fill
* #param variation
* the randomness in the height map
*/
private static void diamondStep(int minCoordinate, int size, int[][] map,
int variation) {
for (int x = minCoordinate; x < (map.length - minCoordinate); x += size) {
for (int y = minCoordinate; y < (map.length - minCoordinate); y += size) {
int left = x - minCoordinate;
int right = x + minCoordinate;
int up = y - minCoordinate;
int down = y + minCoordinate;
// the four corner values
int val1 = map[left][up]; // upper left
int val2 = map[left][down]; // lower left
int val3 = map[right][up]; // upper right
int val4 = map[right][down];// lower right
calculateAndInsertAverage(val1, val2, val3, val4, variation,
map, x, y);
}
}
}
/**
* Calculates average values of four corner values taken from the smallest
* possible diamond. This method calculates the values for the even rows,
* starting with row 0.
*
* #param minCoordinate
* the x-coordinate of the first diamond center
* #param map
* the height map to fill
* #param size
* the length of the diagonals of the diamonds
* #param maxIndex
* the maximum index in the array
* #param variation
* the randomness in the height map
*/
private static void squareStepEven(int minCoordinate, int[][] map,
int size, int maxIndex, int variation) {
for (int x = minCoordinate; x < map.length; x += size) {
for (int y = 0; y < map.length; y += size) {
if (y == maxIndex) {
map[x][y] = map[x][0];
continue;
}
int left = x - minCoordinate;
int right = x + minCoordinate;
int down = y + minCoordinate;
int up = 0;
if (y == 0) {
up = maxIndex - minCoordinate;
} else {
up = y - minCoordinate;
}
// the four corner values
int val1 = map[left][y]; // left
int val2 = map[x][up]; // up
int val3 = map[right][y];// right
int val4 = map[x][down]; // down
calculateAndInsertAverage(val1, val2, val3, val4, variation,
map, x, y);
}
}
}
/**
* Calculates average values of four corner values taken from the smallest
* possible diamond. This method calculates the values for the odd rows,
* starting with row 1.
*
* #param minCoordinate
* the x-coordinate of the first diamond center
* #param map
* the height map to fill
* #param size
* the length of the diagonals of the diamonds
* #param maxIndex
* the maximum index in the array
* #param variation
* the randomness in the height map
*/
private static void squareStepOdd(int[][] map, int size, int minCoordinate,
int maxIndex, int variation) {
for (int x = 0; x < map.length; x += size) {
for (int y = minCoordinate; y < map.length; y += size) {
if (x == maxIndex) {
map[x][y] = map[0][y];
continue;
}
int left = 0;
int right = x + minCoordinate;
int down = y + minCoordinate;
int up = y - minCoordinate;
if (x == 0) {
left = maxIndex - minCoordinate;
} else {
left = x - minCoordinate;
}
// the four corner values
int val1 = map[left][y]; // left
int val2 = map[x][up]; // up
int val3 = map[right][y];// right
int val4 = map[x][down]; // down
calculateAndInsertAverage(val1, val2, val3, val4, variation,
map, x, y);
}
}
}
/**
* Calculates an average value, adds a variable amount to that value and
* inserts it into the height map.
*
* #param val1
* first of the values used to calculate the average
* #param val2
* second of the values used to calculate the average
* #param val3
* third of the values used to calculate the average
* #param val4
* fourth of the values used to calculate the average
* #param variation
* adds variation to the average value
* #param map
* the height map to fill
* #param x
* the x-coordinate of the place to fill
* #param y
* the y-coordinate of the place to fill
*/
private static void calculateAndInsertAverage(int val1, int val2, int val3,
int val4, int variation, int[][] map, int x, int y) {
int avg = (val1 + val2 + val3 + val4) >> 2;// average
int var = (int) ((Math.random() * ((variation << 1) + 1)) - variation);
map[x][y] = avg + var;
}
public static void main(String[] args) {
}
}
Handler.java
package com.game.main;
import java.awt.Graphics;
import java.util.LinkedList;
public class Handler {
LinkedList<GameObject> object = new LinkedList<GameObject>();
LinkedList<Tiles> tile = new LinkedList<Tiles>();
public void tick(){
for (int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.tick();
}
for (int t = 0; t < tile.size(); t++){
Tiles tempObject = tile.get(t);
tempObject.tick();
}
}
public void render(Graphics g){
for (int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.render(g);
}
for (int t = 0; t < tile.size(); t++){
Tiles tempObject = tile.get(t);
tempObject.render(g);
}
}
public void addObject(GameObject object){
this.object.add(object);
}
public void removeObject(GameObject object){
this.object.remove(object);
}
public void addObject(Tiles tile){
this.tile.add(tile);
}
public void removeObject(Tiles tile){
this.tile.remove(tile);
}
}
Tiles.java
package com.game.main;
import java.awt.Graphics;
import java.util.LinkedList;
public class Handler {
LinkedList<GameObject> object = new LinkedList<GameObject>();
LinkedList<Tiles> tile = new LinkedList<Tiles>();
public void tick(){
for (int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.tick();
}
for (int t = 0; t < tile.size(); t++){
Tiles tempObject = tile.get(t);
tempObject.tick();
}
}
public void render(Graphics g){
for (int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.render(g);
}
for (int t = 0; t < tile.size(); t++){
Tiles tempObject = tile.get(t);
tempObject.render(g);
}
}
public void addObject(GameObject object){
this.object.add(object);
}
public void removeObject(GameObject object){
this.object.remove(object);
}
public void addObject(Tiles tile){
this.tile.add(tile);
}
public void removeObject(Tiles tile){
this.tile.remove(tile);
}
}
TerrianTile.java
package com.game.main;
import java.awt.Color;
import java.awt.Graphics;
public class TerrianTile extends Tiles {
public TerrianTile(int x, int y, int tileType) {
super(x, y, tileType);
}
public void tick(){
}
public void render(Graphics g){
if (tileType <= 0){
g.setColor(Color.BLUE);
g.fillRect(x, y, 10, 10);
}
//water
if (tileType > 0 && tileType < 40){
g.setColor(Color.BLUE);
g.fillRect(x, y, 10, 10);
}
//sand
if (tileType >= 40 && tileType < 55){
g.setColor(Color.YELLOW);
g.fillRect(x, y, 10, 10);
}
//grass
if (tileType >= 55 && tileType < 120){
g.setColor(Color.GREEN);
g.fillRect(x, y, 10, 10);
}
//forest
if (tileType >= 120 && tileType < 140){
g.setColor(Color.LIGHT_GRAY);
g.fillRect(x, y, 10, 10);
}
//stone
if (tileType >= 140 && tileType < 170){
g.setColor(Color.GRAY);
g.fillRect(x, y, 10, 10);
}
//snow
if (tileType >= 170){
g.setColor(Color.WHITE);
g.fillRect(x, y, 10, 10);
}
}
}
KeyInput.java
package com.game.main;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class KeyInput extends KeyAdapter{
private Handler handler;
public KeyInput(Handler handler){
this.handler = handler;
}
public void keyPressed(KeyEvent e){
int key = e.getKeyCode();
for (int i = 0; i < handler.object.size(); i++){
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ID.Player){
// key events for player 1
if (key == KeyEvent.VK_W) tempObject.setVelY(-5);
if (key == KeyEvent.VK_S) tempObject.setVelY(5);
if (key == KeyEvent.VK_D) tempObject.setVelX(5);
if (key == KeyEvent.VK_A) tempObject.setVelX(-5);
}
}
}
public void keyReleased(KeyEvent e){
int key = e.getKeyCode();
for (int i = 0; i < handler.object.size(); i++){
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ID.Player){
// key events for player 1
if (key == KeyEvent.VK_W) tempObject.setVelY(0);
if (key == KeyEvent.VK_S) tempObject.setVelY(0);
if (key == KeyEvent.VK_D) tempObject.setVelX(0);
if (key == KeyEvent.VK_A) tempObject.setVelX(0);
}
}
}
}
Not sure if there is way to container the tiles in a rectangle and then move the rectangle. Any help would be much appreciated.
I dont really know what you mean by moving the tiles in a rectangle but if you just simply want to move all of them in a certain direction you could use g.translate(dx, dY) before you draw them.
Or if the terrain doesnt change you could draw them on an image at the beginning and then draw the image each frame at diffrent positions.
I am newbie to the java....working on a piece of applet code...............as I am still going through the OOPs concepts and java understanding and need to develop below mentioned functionality.
The piece of code I have works like this :
First it reads all parameters from HTML tags and stores in global variables. Then it sends query to CGI to read graph data. Then it converts data for plotting and draws graph. There is a option for user to select 1-24 hours. Based on the selection graph will be plotted by plotting only selected data. Every 30 sec it sends query to CGI for collecting data.
The code uses following library and uses java 1.5 environment and i cannot change it due to embeded requirements :
I need to enchance it by implementing zoom in zoom out feature with x-y axis granuality changing with zoom in .
My worry is how to do that?I know its Frustrating question ...but i am here to get suggestion from the java experts so that I can quickly learn and implement this stuff.
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.applet.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.text.*;
/******************************************************************************
*
* Class - Graph
*
* This is the entry point.
* This class extends Applet class and implements Runnable.
*
*****************************************************************************/
public class GraphPerf extends Applet implements Runnable,ItemListener,MouseMotionListener
{
//Global variables
int MAX_DATA_X ;
int SIZE_X= 480;
int SIZE_Y= 250;
int SIZE_Y1= 240;
int MIN_ERROR = -1;
int MAX_LOG10_ERROR_COUNT = 1001;
int MAX_ERROR_COUNT = 101;
int SIZE_Y_EXTENDED_BOTTOM = 20;
int MAX_DISP_PARMS = 16;
int MAX_NUM_INTERVELL_PER_DAY = 96;
int MAX_DISP_PARMS_STD = 7;
int refreshTime;
String serverAddress,hostAddr;
Color plotColor1,plotColor8;
float graphData[][];
float graph_data_rf_east,graph_data_rf_west;
int xOffset = 50;
int yOffset = 40;
int Y1_MAX_VALUE = 100;
int Y2_MAX_VALUE = 3;
float RANGE2;
Thread graphThread;
Image Buffer;
Graphics plot;
Choice timeChoice, modeChoice, seloptChoice;
int duration=1, viewMode=1, line_type = 0,viewOpt = 1;
Label valueLabel1, valueLabel2,valueLabel3,valueLabel4,valueLabel5;
boolean GraphBottomExtendFlag=true;
/******************************************************************************
*
* method - init
*
* This is the method called first after applet loaded in to browser.
* This function reads configurable parameters from HTML tag and updates
* global variables.
*****************************************************************************/
public void init()
{
MAX_DATA_X = 672;//Integer.parseInt(getParameter("max_data_x"));
//refreshTime = 30;//Integer.parseInt(getParameter("refresh_sec"));
/*URL url = getDocumentBase();
String host = url.getHost();
try
{
InetAddress addr = InetAddress.getByName(host);
hostAddr=addr.getHostAddress();
}catch (UnknownHostException ex) {
ex.printStackTrace();
}
*/
//serverAddress = new String ( getParameter("access_str")+ hostAddr + getParameter("data_server"));
graphData = new float[MAX_DISP_PARMS][MAX_DATA_X+1];
/*initialize the array with -1 not with 0(0 also valid for graph data) */
int i =0,j = 0;
for( j=0; j<MAX_DISP_PARMS; j++)
{
for( i=0; i<MAX_DATA_X+1; i++)
{
graphData[j][i] = -1;
}
}
graph_data_rf_east = -1;
graph_data_rf_west = -1;
plotColor1 = Color.orange;
plotColor2 = Color.black;
plotColor8 = Color.red;
plotColor9 = Color.green;
setBackground(Color.white);
setLayout(null);
timeChoice = new Choice();
timeChoice.add("1");
timeChoice.add("2");
timeChoice.add("3");
timeChoice.add("4");
timeChoice.add("5");
timeChoice.add("6");
timeChoice.add("7");
add(timeChoice);
timeChoice.setBounds(190,340,40,23);
timeChoice.addItemListener(this);
Label timeLabel1 = new Label("View graph for last");
Label timeLabel2 = new Label("day(s)");
add(timeLabel1);
timeLabel1.setBounds(xOffset+30,340,160,23);
add(timeLabel2);
timeLabel2.setBounds(240,340,50,23);
valueLabel1 = new Label();
add(valueLabel1);
valueLabel1.setBounds(300,340,50,23);
valueLabel2 = new Label();
add(valueLabel2);
valueLabel2.setBounds(370,340,70,23);
valueLabel3 = new Label();
add(valueLabel3);
valueLabel3.setBounds(440,340,70,23);
valueLabel4 = new Label();
add(valueLabel4);
valueLabel4.setBounds(500,340,70,23);
valueLabel5 = new Label();
add(valueLabel5);
valueLabel5.setBounds(370,370,80,25);
modeChoice = new Choice();
modeChoice.add("East");
modeChoice.add("West");
/* Display this only for Protected and East-West Mode */
if(2/*Integer.parseInt(getParameter("mode"))*/ == 2)
{
add(modeChoice);
}
else
{
viewOpt = 1;
}
modeChoice.setBounds(xOffset+SIZE_X-55, 0, 60, 25);
modeChoice.addItemListener(this);
addMouseMotionListener(this);
}
public void start()
{
graphThread = new Thread(this);
graphThread.start();
}
public void stop()
{
graphThread = null;
}
/******************************************************************************
*
* This method will be called after starting the thread. This is a
* infinite loop which will call query method for every 30 sec to read data
* from CGI. Then it plots graph by calling plotGraph method
* the thread.
*****************************************************************************/
public void run()
{
/*while (false)
{
try
{//getData(serverAddress);
int sizeY = SIZE_Y;
if(GraphBottomExtendFlag)
{
sizeY += SIZE_Y_EXTENDED_BOTTOM;
}
repaint(xOffset+1,yOffset+1,SIZE_X-1,sizeY-1);
//graphThread.sleep(refreshTime*1000);
}catch (Exception e) { System.out.println(e); }
}*/
}
/******************************************************************************
*
* method - paint
*
* This method displays the graph plotted by plotGraph method
* in the screen. Then it draws axis for the graph
*
*****************************************************************************/
public void paint(Graphics g1)
{
int sizeY = SIZE_Y;
/*If Graph Bottom is to be Etended
*soo that zero is displayed properly
*/
if(GraphBottomExtendFlag)
{
sizeY += SIZE_Y_EXTENDED_BOTTOM;
}
if( duration <= 5 )
{
Buffer = createImage(SIZE_X, sizeY);
plot = Buffer.getGraphics();
plotGraph(plot);
g1.drawImage (Buffer,xOffset,yOffset,this);
}
else
{
Buffer = createImage(MAX_DATA_X*duration/7,sizeY);
plot = Buffer.getGraphics();
plotGraph(plot);
g1.drawImage (Buffer,xOffset,yOffset,SIZE_X,sizeY,this);
}
g1.setColor(Color.black);
g1.drawRect(70,150,270,80);
/*Dram Graph boarder */
g1.drawRect(xOffset,yOffset,SIZE_X,sizeY);
g1.drawRect(xOffset-1,yOffset-1,SIZE_X+2,sizeY+2);
/*Plot X axis*/
int max_x_marks = 8;
int temp = 1,cnt_graph = 0;
int float_temp,float_temp2;
/*max 8 plots on x axis*/
for(int x=max_x_marks; x>0; x--)
{
float_temp = (int)((MAX_NUM_INTERVELL_PER_DAY*duration)/max_x_marks)*((max_x_marks+1)-x);
float_temp2 = SIZE_X-(60*cnt_graph);
g1.drawString(String.valueOf(float_temp),(float_temp2-20) ,SIZE_Y+yOffset+35);
cnt_graph++;
}
/*Plot Y1 AXIS*/
temp = Y1_MAX_VALUE;
for(int x = 0; x <= SIZE_Y; x+= 25)
{
g1.drawString(String.valueOf(temp), 25, x + yOffset+10);
temp -= (Y1_MAX_VALUE - 0)/10;
}
temp = 1000;
/*Plot Y2 AXIS*/
int index_log = 1;
for(int x = 0; x <= SIZE_Y1; x+= 80)
{
if(x== 240)
index_log--;
if(temp>=1)
{
g1.drawString(String.valueOf(temp), 550, x+yOffset+8-index_log);
g1.drawLine(530,x+yOffset+5-index_log, 540, x+yOffset+5-index_log);
}
temp = temp/10;
}
Font thisFont = new Font("Times New Roman", Font.BOLD, 14);
g1.setFont(thisFont);
g1.drawString("Y2", 550, 160);
g1.drawString("Y1",5, 160);
}
/******************************************************************************
*
* method - plotGraph
*
* Depending on the mode, "East", "West" or "Combined", it plots
* single or two graphs in the same applet.
*
* Inputs :
* g - Graphics object
*****************************************************************************/
public void plotGraph(Graphics g)
{
g.setColor(new Color(255,255,220));
/*If Error-Sec-Count Graph
*Then extend the lower portion
*soo that zero is displayed properly
*/
if(GraphBottomExtendFlag)
{
g.fillRect(0,0,MAX_DATA_X,SIZE_Y + SIZE_Y_EXTENDED_BOTTOM);
}
else
{
g.fillRect(0,0,MAX_DATA_X,SIZE_Y);
}
switch(viewMode)
{
case 1 :
plot1(g);
plot_timeelapsed_east(g);
break;
case 2 :
plot8(g);
plot_timeelapsed_west(g);
break;
}
}
/******************************************************************************
*
* method - plot1
*
* This method uses graphData[0][] global variable and plots series of lines
* in the applet
*
* Inputs :
* g - Graphics object
*****************************************************************************/
void plot1(Graphics g)
{
int end = MAX_DATA_X;
int localPlotBuffer[];
localPlotBuffer = new int[2];
g.setColor(plotColor1);
if(duration > 5)
{
for(int x=(duration*MAX_NUM_INTERVELL_PER_DAY); x > 0 ; x--)
{
/*if data is valid data then plot else ignore*/
if((graphData[0][end]>MIN_ERROR)&&(graphData[0][end-1]<MAX_LOG10_ERROR_COUNT)&&(graphData[0][end-1]>MIN_ERROR)&&(graphData[0][end]<MAX_LOG10_ERROR_COUNT))
{
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[0][end] == 0)
{
localPlotBuffer[0] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[0][end]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[0][end])/(float)Y2_MAX_VALUE));
}
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[0][end-1] == 0)
{
localPlotBuffer[1] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[0][end-1]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[1] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[0][end-1])/(float)Y2_MAX_VALUE));
}
g.drawLine(x-1,(localPlotBuffer[0]+5), x-2,(localPlotBuffer[1]+5));
g.drawLine(x,(localPlotBuffer[0]+5), x-1,(localPlotBuffer[1]+5));
}
end--;
}
}
else
{
float temp = SIZE_X;
for(int x=(duration*MAX_NUM_INTERVELL_PER_DAY) ; x > 0 ; x--)
{
float LocalTemp1 = temp;
float LocalTemp2 = (int)(temp-(double)5/(double)duration);
/*Normalise the pixcel positions */
/*Normalise the pixcel positions */
if(duration == 1)
{
if(LocalTemp1>(SIZE_X-3))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-3))
LocalTemp2 = SIZE_X;
}
/*Normalise the pixcel positions */
else if(duration == 2)
{
if(LocalTemp1>(SIZE_X-2))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-2))
LocalTemp2 = SIZE_X;
}
/*Normalise the pixcel positions */
else if(duration == 3)
{
if(LocalTemp1>(SIZE_X-1))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-1))
LocalTemp2 = SIZE_X;
}
/*if data is valid data then plot else ignore*/
if((graphData[0][end]>MIN_ERROR)&&(graphData[0][end-1]<MAX_LOG10_ERROR_COUNT)&&(graphData[0][end-1]>MIN_ERROR)&&(graphData[0][end]<MAX_LOG10_ERROR_COUNT))
{
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[0][end] == 0)
{
localPlotBuffer[0] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[0][end]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[0][end])/(float)Y2_MAX_VALUE));
}
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[0][end-1] == 0)
{
localPlotBuffer[1] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[0][end-1]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[1] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[0][end-1])/(float)Y2_MAX_VALUE));
}
g.drawLine((int)LocalTemp1,(localPlotBuffer[0]+5), (int)LocalTemp2,(localPlotBuffer[1]+5));
}
temp-=(double)5/(double)duration;
end--;
}
}
}
/******************************************************************************
*
* method - plot8
*
* This method uses graphData[7][] global variable and plots series of lines
* in the applet
*
* Inputs :
* g - Graphics object
*****************************************************************************/
void plot8(Graphics g)
{
int end = MAX_DATA_X;
int localPlotBuffer[];
localPlotBuffer = new int[2];
g.setColor(plotColor1);
if(duration > 5)
{
for(int x=(duration*MAX_NUM_INTERVELL_PER_DAY); x > 0 ;x-- )
{
/*if data is valid data then plot else ignore*/
if((graphData[8][end]>MIN_ERROR)&&(graphData[8][end-1]<MAX_LOG10_ERROR_COUNT)&&(graphData[8][end-1]>MIN_ERROR)&&(graphData[8][end]<MAX_LOG10_ERROR_COUNT))
{
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[8][end] == 0)
{
localPlotBuffer[0] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[8][end]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[8][end])/(float)Y2_MAX_VALUE));
}
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[8][end-1]== 0)
{
localPlotBuffer[1] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[8][end-1]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[1] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[8][end-1])/(float)Y2_MAX_VALUE));
}
g.drawLine(x-1,(localPlotBuffer[0]+5), x-2,(localPlotBuffer[1]+5));
g.drawLine(x,(localPlotBuffer[0]+5), x-1,(localPlotBuffer[1]+5));
}
end--;
}
}
else
{
float temp = SIZE_X;
for(int x=(duration*MAX_NUM_INTERVELL_PER_DAY) ; x > 0 ; x--)
{
float LocalTemp1 = temp;
float LocalTemp2 = (int)(temp-(double)5/(double)duration);
/*Normalise the pixcel positions */
if(duration == 1)
{
if(LocalTemp1>(SIZE_X-3))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-3))
LocalTemp2 = SIZE_X;
}
/*Normalise the pixcel positions */
else if(duration == 2)
{
if(LocalTemp1>(SIZE_X-2))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-2))
LocalTemp2 = SIZE_X;
}
/*Normalise the pixcel positions */
else if(duration == 3)
{
if(LocalTemp1>(SIZE_X-1))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-1))
LocalTemp2 = SIZE_X;
}
/*if data is valid data then plot else ignore*/
if((graphData[8][end]>MIN_ERROR)&&(graphData[8][end-1]<MAX_LOG10_ERROR_COUNT)&&(graphData[8][end-1]>MIN_ERROR)&&(graphData[8][end]<MAX_LOG10_ERROR_COUNT))
{
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[8][end] == 0)
{
localPlotBuffer[0] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[8][end]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[8][end])/(float)Y2_MAX_VALUE));
}
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[8][end-1]== 0)
{
localPlotBuffer[1] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[8][end-1]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[1] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[8][end-1])/(float)Y2_MAX_VALUE));
}
g.drawLine((int)LocalTemp1,(localPlotBuffer[0]+5), (int)LocalTemp2,(localPlotBuffer[1]+5));
}
temp-=(double)5/(double)duration;
end--;
}
}
}
/******************************************************************************
*
* method - plot_timeelapsed_east
*
* This method uses graph_data_rf_east global variable and plots series of lines
* in the applet
*****************************************************************************/
void plot_timeelapsed_east(Graphics g)
{
int end = MAX_DATA_X;
int localPlotBuffer[];
int x= 0;
localPlotBuffer = new int[2];
x= (duration*MAX_NUM_INTERVELL_PER_DAY);
g.setColor(plotColor9);
/*if data is valid data then plot else ignore*/
if((graph_data_rf_east>0)&&(graph_data_rf_east<MAX_LOG10_ERROR_COUNT))
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graph_data_rf_east)/(float)Y2_MAX_VALUE));
if(duration>5)
g.drawLine(x-1,SIZE_Y+5, x-2,(localPlotBuffer[0]+5));
else
g.drawLine(SIZE_X,SIZE_Y+5, 474+duration,(localPlotBuffer[0]+5));
}
}/*End for plot_timeelapsed_east() */
/******************************************************************************
*
* method - plot_timeelapsed_west
*
* This method uses graph_data_rf_east global variable and plots series of lines
* in the applet
*****************************************************************************/
void plot_timeelapsed_west(Graphics g)
{
int end = MAX_DATA_X;
int localPlotBuffer[];
int x= 0;
localPlotBuffer = new int[2];
x= (duration*MAX_NUM_INTERVELL_PER_DAY);
g.setColor(plotColor9);
/*if data is valid data then plot else ignore*/
if((graph_data_rf_east>MIN_ERROR)&&(graph_data_rf_east<MAX_LOG10_ERROR_COUNT))
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graph_data_rf_west)/(float)Y2_MAX_VALUE));
if(duration>5)
g.drawLine(x-1,SIZE_Y+5, x-2,(localPlotBuffer[0]+5));
else
g.drawLine(SIZE_X,SIZE_Y+5, 474+duration,(localPlotBuffer[0]+5));
}
}
/******************************************************************************
*
* method - getData
*
* This method sends query to CGI to collect data. Then it converts the
* data for applet area then updates global variable.
*
* Inputs :
* serverAddress - server CGI path
*****************************************************************************/
public void getData(String serverAddress)
{
URL addr;
BufferedReader in;
String inputLine;
int count = 0;
int i=0,j = 0;
try
{
addr = new URL(serverAddress);
URLConnection connection = addr.openConnection();
in = new BufferedReader(new InputStreamReader(addr.openStream()));
/*Read data for first link */
for( j=0; j<MAX_DISP_PARMS_STD; j++)
{
for( i=0; i<MAX_DATA_X+1; i++)
{
inputLine = in.readLine();
graphData[j][i] = Integer.parseInt(inputLine);
}
}
for( i=0; i<MAX_DATA_X; i++)
{
inputLine = in.readLine();
graphData[7][i] = Integer.parseInt(inputLine);
if(graphData[7][i] == 1)
graphData[7][i] = 10;
}
inputLine = in.readLine();
graph_data_rf_east = Integer.parseInt(inputLine);
/*Reading data for second link */
if(Integer.parseInt(getParameter("mode")) == 2)
{
for( j=8; j<15; j++)
{
for( i=0; i<MAX_DATA_X+1; i++)
{
inputLine = in.readLine();
graphData[j][i] = Integer.parseInt(inputLine);
}
}
for( i=0; i<MAX_DATA_X; i++)
{
inputLine = in.readLine();
graphData[15][i] = Integer.parseInt(inputLine);
if(graphData[15][i] == 1)
graphData[15][i] = 10;
}
inputLine = in.readLine();
graph_data_rf_west = Integer.parseInt(inputLine);
}
in.close();
}catch (Exception e) { System.out.println("Server Data Read Error:"+e); }
}
/******************************************************************************
*
* method - itemStateChanged
*
* This method will be called whenever event occured on this choice.
* it read the current status and changes scale accordingly.
* *****************************************************************************/
public void itemStateChanged(ItemEvent evt)
{
if( evt.getSource() == timeChoice )
duration = Integer.parseInt(timeChoice.getSelectedItem());
else
viewMode = modeChoice.getSelectedIndex()+1;
repaint();
}
/******************************************************************************
*
* method - mouseMoved
*
* This method will be called whenever mouse cursor is moved over the
* applet. Depending on the cursor position, it will display Actual
* X and Y values of the graph.
*****************************************************************************/
public void mouseMoved(MouseEvent evt)
{
int x = evt.getX()-xOffset;
int y = evt.getY()-yOffset-5;
int a = evt.getX();
int b = evt.getY();
int duration = Integer.parseInt(timeChoice.getSelectedItem());
if( (x>=0) && (x<=SIZE_X) && (y>=0) && (y<=SIZE_Y) )
{
valueLabel1.setText("X ");
valueLabel2.setText("Y1 ");
valueLabel3.setText("Y2 ");
try
{
int x_max_value = ((SIZE_X*duration)/5);
int x1 = (int)((float)((float)((float)(SIZE_X*duration))/5) * ((float)((float)(SIZE_X - x))/((float)SIZE_X)));
/*For Durations less than 16 scale starts with 1*/
int y1 = (int)((float)Y1_MAX_VALUE * (((float)SIZE_Y - (float)y)/((float)SIZE_Y)));
int y2 = (int) Math.pow(10,((float)(3 * ((float)(1 - (float)y/((float)SIZE_Y1))))));
valueLabel1.setText("X="+x1);
valueLabel2.setText("X pix="+a);
valueLabel3.setText("Y="+y1);
valueLabel4.setText("Y pix="+b);
valueLabel5.setText("Y2="+y2);
}
catch(Exception e) {System.out.println("Mouse Moved Error" + e);}
}
else
{
valueLabel1.setText(" ");
valueLabel2.setText(" ");
valueLabel3.setText(" ");
}
}
public void mouseDragged(MouseEvent evt) { }
}
There are many ways to do this. Here are two:
You can simply scale the values: Multiply every coordinate with the zoom factor.
Use Java2D and AffineTransform:
AffineTransform transformer = new AffineTransform();
transformer.scale(zoom, zoom);
Graphics2D g2d = (Graphics2D)g;
g2d.setTransform(transformer);
// draw to g2d.
[EDIT] If you want to do everything yourself, see this page for a refresh of basic linear algebra: 2D Transformations
Don't mind the 3D example at the top; the rest of the page is about 2D.
I used JCC kit for my target platform and it's less than 100kb library. You need to understand the library and after that you can play without worrying about size. :)
Good library to use in embedded systems whether size is always the issue. it has inbuilt function o transform coordinates into screen coordinates and vice-verse.
In the body of the Picture class create a new public method named "specialEffect" that has return type void and takes no parameters.
The method should contain four loops that each iterate over the pixels of an image in such a way that each loop iterates through 1/4 of the total number of pixels and performs a different effect as follows:
The first loop is to apply an effect that removes the both the blue and green component from each pixel leaving the red component unchanged.
The next loop continuing from where the last left off is to remove the blue and red component from each pixel leaving the green component unchanged.
The next loop continuing from where the last left off it to remove the green and red component from each pixel leaving the blue component unchanged.
The final loop continuing from where the last off is to convert each pixel to greyscale.
How would I go about doing that? I only know how to divide it in half and change the top part.. not sure how to go about doing sections.
Thanks!
The code below produces this picture:
private static BufferedImage specialEffect(BufferedImage in) {
BufferedImage out = new BufferedImage(in.getWidth(), in.getHeight(),
BufferedImage.TYPE_INT_ARGB);
for (int x = 0; x < out.getWidth() / 2; x++) {
for (int y = 0; y < out.getHeight() / 2; y++) {
Color c = new Color(in.getRGB(x, y));
out.setRGB(x, y, new Color(c.getRed(), 0, 0).getRGB());
}
}
for (int x = out.getWidth() / 2; x < out.getWidth(); x++) {
for (int y = 0; y < out.getHeight() / 2; y++) {
Color c = new Color(in.getRGB(x, y));
out.setRGB(x, y, new Color(0, c.getGreen(), 0).getRGB());
}
}
for (int x = 0; x < out.getWidth() / 2; x++) {
for (int y = out.getHeight() / 2; y < out.getHeight(); y++) {
Color c = new Color(in.getRGB(x, y));
out.setRGB(x, y, new Color(0, 0, c.getBlue()).getRGB());
}
}
for (int x = out.getWidth() / 2; x < out.getWidth(); x++) {
for (int y = out.getHeight() / 2; y < out.getHeight(); y++) {
Color c = new Color(in.getRGB(x, y));
int m = Math.max(c.getRed(),Math.max(c.getGreen(),c.getBlue()));
out.setRGB(x, y, new Color(m, m, m).getRGB());
}
}
return out;
}
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("Test");
frame.add(new JComponent() {
BufferedImage image = specialEffect(ImageIO.read(new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png")));
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
I am assuming that your Picture class has the following methods:
int getNumberOfPixels()
float getRValueOfNthPixel(int n)
float getGValueOfNthPixel(int n)
float getBValueOfNthPixel(int n)
void setRValueOfNthPixel(int n, float r)
void setGValueOfNthPixel(int n, float g)
void setBValueOfNthPixel(int n, float b)
If the number of pixels is always a multiple of 4, then one possible implementation of "specialEffect" method would be:
public void specialEffect() {
int n = getNumberOfPixels();
int limit1 = 1 * n / 4;
int limit2 = 2 * n / 4;
int limit3 = 3 * n / 4;
int limit4 = 4 * n / 4;
/*
* The first loop is to apply an effect that removes the both the blue
* and green component from each pixel leaving the red component
* unchanged.
*/
for (int i = 0; i < limit1; i++) {
setBValueOfNthPixel(i, 0);
setGValueOfNthPixel(i, 0);
}
/*
* The next loop continuing from where the last left off is to remove
* the blue and red component from each pixel leaving the green
* component unchanged.
*/
for (int i = limit1; i < limit2; i++) {
setBValueOfNthPixel(i, 0);
setRValueOfNthPixel(i, 0);
}
/*
* The next loop continuing from where the last left off it to remove
* the green and red component from each pixel leaving the blue
* component unchanged.
*/
for (int i = limit2; i < limit3; i++) {
setGValueOfNthPixel(i, 0);
setRValueOfNthPixel(i, 0);
}
/*
* The final loop continuing from where the last off is to convert each
* pixel to greyscale.
*/
for (int i = limit3; i < limit4; i++) {
float grayValue = (getRValueOfNthPixel(i)
+ getGValueOfNthPixel(i)
+ getBValueOfNthPixel(i)) / 3;
setRValueOfNthPixel(i, grayValue);
setGValueOfNthPixel(i, grayValue);
setBValueOfNthPixel(i, grayValue);
}
}