Lock graphice object in J2ME - java

it seems to be very stupid question, but I really need a help, I'm making a task with drawing a background transparent gradient image and then draw some objects over it, the problem is I want to draw this image once but the other objects will be drawn multi time to perform some animation
the code is as following, this is the code that i want to run once, and I have created a boolen variable = false and then set it to true
public void drawLockLayer(Graphics g) {
try {
lock = Image.createImage(Paths.lock);
g.drawImage(lock, 0, 0, LGBMainMidlet.width, LGBMainMidlet.height);
System.out.println("After Draw Image");
drawOnce = true;
} catch (Exception ex) {
ex.printStackTrace();
}
}
other code is as following
public void paint(Graphics g, Rectangle rect) {
synchronized (g) {
if (drawOnce == false) {
drawLockLayer(g);
}
}
pos = (int) ((System.currentTimeMillis() % 2700) / 300);
int i = 0;
g.setColor(bgColor);
g.fillRoundRect(startX, startY, width, height, 20, 20);
g.setColor(fgColor);
g.setFont(font);
g.drawString(loadMsg, startX + (spacing / 4), startY + (spacing / 4));
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
int thickness = 6;
if (i == pos) {
thickness = 14;
} else if (i == pos - 1) {
thickness = 10;
}
g.fillRect((startX + x * spacing - (thickness / 2)) + (width / 3), (startY + y * spacing - (thickness / 2)) + (height / 3), thickness, thickness);
i++;
}
}
}
it is enter the method but it is not draw the background image , What I want to do is to lock the graphics object until he finish drawing the image then continue with other code
can anyone help please

Several issues with the code:
synchronizing on a Graphics is generally a bad idea
paint is only supposed to be called from one thread. are you sure it isn't and you actually need to synchronize? where does rect come from?
to make it easier to maintain, you should set drawOnce to true in paint()

You need to set drawOnce to false before calling paint.
It looks like your code is based on GameCanvas. What do you think of the below approach?
class MainCanvas extends GameCanvas {
// rect is an attribute
private void updateScreen() {
drawOnce = false;
paint(getGraphics(), rect);
}
public void start() {
new DataThread().start();
new AnimationThread().start();
}
class DataThread extends Thread {
public void run() {
while (/*IO stuff not done*/) {
// save data
updateScreen();
}
}
}
class AnimationThread extends Thread {
public void run() {
while (/*IO stuff not done*/) {
// sleep a little
updateScreen();
}
}
}
// drawLockLayer and paint(Graphics, Rectangle) methods
} // end of MainCanvas class

Related

Bouncing rectangle (Graphics g)

I'm playing around with graphics in Java. At the moment I have a rectangle that moves from left to right. I want it to start moving left once it hits the right side of the Canvas and left when it hits the right side, i have included a game loop as this will eventually turn into my first very basic game. Thanks.
P.S - I followed some tutorials for different parts of this code hence why it might be a bit messy, I'm working on it :)
Main Class:
public class Game extends JFrame implements Runnable {
private Canvas canvas = new Canvas();
private RenderHandler renderer;
private boolean running = true;
public static int WIDTH = 1200, HEIGHT = WIDTH / 12*9;
public static int moveX =WIDTH/2;
public Game() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(WIDTH, HEIGHT);
setLocationRelativeTo(null);
setLocationRelativeTo(null);
add(canvas);
setVisible(true);
canvas.createBufferStrategy(3);
renderer = new RenderHandler(getWidth(), getHeight());
}
public void update() {
}
public void render() {
BufferStrategy bufferStrategy = canvas.getBufferStrategy();
Graphics graphics = bufferStrategy.getDrawGraphics();
super.paint(graphics);
renderer.render(graphics);
graphics.dispose();
bufferStrategy.show();
}
public void run() {
BufferStrategy bufferStrategy = canvas.getBufferStrategy();
int FRAMES = 0;
int TICKS = 0;
long lastTime = System.nanoTime();
double unprocessed = 0;
double nsPerSecs = 1000000000 /60.0;
long Timer = System.currentTimeMillis();
while(running) {
long now = System.nanoTime();
unprocessed += (now - lastTime) / nsPerSecs;
lastTime = now;
if(unprocessed >= 1) {
TICKS ++;
update();
unprocessed -= 1;
}
try
{
Thread.sleep(3);
}catch (InterruptedException e) {
e.printStackTrace();
}
FRAMES++;
render();
if(System.currentTimeMillis() - Timer > 1000) {
System.out.println("Ticks: " + TICKS + " FPS: " + FRAMES);
TICKS = 0;
FRAMES = 0;
Timer += 1000;
}
}
}
public static void main(String[] args) {
Game game = new Game();
Thread gameThread = new Thread(game);
gameThread.start();
}
}
Class drawing the graphics:
public class RenderHandler {
public RenderHandler(int width, int height) {
}
public void render(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, Game.WIDTH, Game.HEIGHT);
g.setColor(Color.RED);
g.fillRect(Game.moveX, Game.HEIGHT/2, 50, 50);
if (Game.moveX >= Game.WIDTH) {
Game.moveX ++;
} else if (Game.moveX <= 0) {
Game.moveX --;
}else { Game.moveX++;
}
}
}
If you know how to draw on the screen and how stuffs work, I would think that this is more about getting the logic down.
This code slice I so brutally tore from your question is right next to where the rendering takes place (a problem because I view it as rather unorganized; I would recommend game logic and rendering to take place in two different functions). It basically says that it will move right if it is beyond the right of the screen, if not, it will move left if it is beyond the left of the screen, and finally, if not, it will just move left.
if (Game.moveX >= Game.WIDTH) {
Game.moveX ++;
} else if (Game.moveX <= 0) {
Game.moveX --;
}else { Game.moveX++;
}
If you want it to bounce, you will have to use a boolean to keep track of its moving state, or, if you want more versatility, use a pair of floats or doubles (floats are typically used in Java game design) to keep track of its position, and another for its velocity. I'm in a tight squeeze right now, I will return.
Add this to render handler instead of the current if statement in render
bool rol = true; // initialize this outside the method
If(Game.movex + 50 >= Game.width)
rol = false;
Else if(Game.movex <= 0)
rol = true;
If(rol)
Game.movex++;
Else
Game.movex--;
You need to store current moving direction somewhere, so add this to Game class:
public static int deltaX = 1;
And replace condition in render() with
if (Game.moveX >= Game.WIDTH-50) {
Game.deltaX =-1;
} else if (Game.moveX <= 0) {
Game.deltaX =1;
}
Game.moveX += Game.deltaX;

How can I detect the proximity between two images [duplicate]

I have two characters displayed in a game I am writing, the player and the enemy. defined as such:
public void player(Graphics g) {
g.drawImage(plimg, x, y, this);
}
public void enemy(Graphics g) {
g.drawImage(enemy, 200, 200, this);
}
Then called with:
player(g);
enemy(g);
I am able to move player() around with the keyboard, but I am at a loss when trying to detect a collision between the two. A lot of people have said to use Rectangles, but being a beginner I cannot see how I would link this into my existing code. Can anyone offer some advice for me?
I think your problem is that you are not using good OO design for your player and enemies. Create two classes:
public class Player
{
int X;
int Y;
int Width;
int Height;
// Getters and Setters
}
public class Enemy
{
int X;
int Y;
int Width;
int Height;
// Getters and Setters
}
Your Player should have X,Y,Width,and Height variables.
Your enemies should as well.
In your game loop, do something like this (C#):
foreach (Enemy e in EnemyCollection)
{
Rectangle r = new Rectangle(e.X,e.Y,e.Width,e.Height);
Rectangle p = new Rectangle(player.X,player.Y,player.Width,player.Height);
// Assuming there is an intersect method, otherwise just handcompare the values
if (r.Intersects(p))
{
// A Collision!
// we know which enemy (e), so we can call e.DoCollision();
e.DoCollision();
}
}
To speed things up, don't bother checking if the enemies coords are offscreen.
First, use the bounding boxes as described by Jonathan Holland to find if you may have a collision.
From the (multi-color) sprites, create black and white versions. You probably already have these if your sprites are transparent (i.e. there are places which are inside the bounding box but you can still see the background). These are "masks".
Use Image.getRGB() on the mask to get at the pixels. For each pixel which isn't transparent, set a bit in an integer array (playerArray and enemyArray below). The size of the array is height if width <= 32 pixels, (width+31)/32*height otherwise. The code below is for width <= 32.
If you have a collision of the bounding boxes, do this:
// Find the first line where the two sprites might overlap
int linePlayer, lineEnemy;
if (player.y <= enemy.y) {
linePlayer = enemy.y - player.y;
lineEnemy = 0;
} else {
linePlayer = 0;
lineEnemy = player.y - enemy.y;
}
int line = Math.max(linePlayer, lineEnemy);
// Get the shift between the two
x = player.x - enemy.x;
int maxLines = Math.max(player.height, enemy.height);
for ( line < maxLines; line ++) {
// if width > 32, then you need a second loop here
long playerMask = playerArray[linePlayer];
long enemyMask = enemyArray[lineEnemy];
// Reproduce the shift between the two sprites
if (x < 0) playerMask << (-x);
else enemyMask << x;
// If the two masks have common bits, binary AND will return != 0
if ((playerMask & enemyMask) != 0) {
// Contact!
}
}
Links: JGame, Framework for Small Java Games
You don't want to have the collision check code inside the painting code. The painting needs to be fast. Collision can go in the game loop. Therefore you need an internal representation of the objects independent of their sprites.
Here's the main class from my collision detection program.
You can see it run at: http://www.youtube.com/watch?v=JIXhCvXgjsQ
/**
*
* #author Tyler Griffin
*/
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.GraphicsDevice.*;
import java.util.ArrayList;
import java.awt.Graphics;
import java.awt.geom.Line2D;
public class collision extends JFrame implements KeyListener, MouseMotionListener, MouseListener
{
ArrayList everything=new ArrayList<tile>();
int time=0, x, y, width, height, up=0, down=0, left=0, right=0, mouse1=0, mouse2=0;
int mouseX, mouseY;
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice screen = environment.getDefaultScreenDevice();
DisplayMode displayMode = screen.getDisplayMode();
//private BufferStrategy strategy;
JLayeredPane pane = new JLayeredPane();
tile Tile;
circle Circle;
rectangle Rectangle;
textPane text;
public collision()
{
setUndecorated(screen.isFullScreenSupported());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLayout(null);
setResizable(false);
screen.setFullScreenWindow(this);
width=displayMode.getWidth();
height=displayMode.getHeight();
Circle=new circle(-(int)Math.round((double)height/7*2),-(int)Math.round((double)height/7*2),(int)Math.round((double)height/7*.85),this);
Rectangle=new rectangle(-(int)Math.round((double)height/7*1.5),-(int)Math.round((double)height/7*1.5),(int)Math.round((double)height/7*1.5),(int)Math.round((double)height/7*1.5),this);
Tile=Circle;
Tile.move(mouseX-Tile.width/2, mouseY-Tile.height/2);
text=new textPane(0,0,width,height,this);
everything.add(new circle((int)Math.round((double)width/100*75),(int)Math.round((double)height/100*15),(int)Math.round((double)width/100*10),this));
everything.add(new rectangle((int)Math.round((double)width/100*70),(int)Math.round((double)height/100*60),(int)Math.round((double)width/100*20),(int)Math.round((double)height/100*20),this));
//everything.add(new line(750,250,750,750,this));
/*everything.add(new line(width/700*419,height/700*68,width/700*495,height/700*345,this));
everything.add(new line(width/700*495,height/700*345,width/700*749,height/700*350,this));
everything.add(new line(width/700*749,height/700*350,width/700*549,height/700*519,this));
everything.add(new line(width/700*549,height/700*519,width/700*624,height/700*800,this));
everything.add(new line(width/700*624,height/700*800,width/700*419,height/700*638,this));
everything.add(new line(width/700*419,height/700*638,width/700*203,height/700*800,this));
everything.add(new line(width/700*203,height/700*800,width/700*279,height/700*519,this));
everything.add(new line(width/700*279,height/700*519,width/700*76,height/700*350,this));
everything.add(new line(width/700*76,height/700*350,width/700*333,height/700*345,this));
everything.add(new line(width/700*333,height/700*345,width/700*419,height/700*68,this));
everything.add(new line(width/950*419,height/700*68,width/950*624,height/700*800,this));
everything.add(new line(width/950*419,height/700*68,width/950*203,height/700*800,this));
everything.add(new line(width/950*76,height/700*350,width/950*624,height/700*800,this));
everything.add(new line(width/950*203,height/700*800,width/950*749,height/700*350,this));
everything.add(new rectangle(width/950*76,height/700*350,width/950*673,1,this));*/
everything.add(new line((int)Math.round((double)width/1350*419),(int)Math.round((double)height/1000*68),(int)Math.round((double)width/1350*624),(int)Math.round((double)height/1000*800),this));
everything.add(new line((int)Math.round((double)width/1350*419),(int)Math.round((double)height/1000*68),(int)Math.round((double)width/1350*203),(int)Math.round((double)height/1000*800),this));
everything.add(new line((int)Math.round((double)width/1350*76),(int)Math.round((double)height/1000*350),(int)Math.round((double)width/1350*624),(int)Math.round((double)height/1000*800),this));
everything.add(new line((int)Math.round((double)width/1350*203),(int)Math.round((double)height/1000*800),(int)Math.round((double)width/1350*749),(int)Math.round((double)height/1000*350),this));
everything.add(new rectangle((int)Math.round((double)width/1350*76),(int)Math.round((double)height/1000*350),(int)Math.round((double)width/1350*673),1,this));
addKeyListener(this);
addMouseMotionListener(this);
addMouseListener(this);
}
public void keyReleased(KeyEvent e)
{
Object source=e.getSource();
int released=e.getKeyCode();
if (released==KeyEvent.VK_A){left=0;}
if (released==KeyEvent.VK_W){up=0;}
if (released==KeyEvent.VK_D){right=0;}
if (released==KeyEvent.VK_S){down=0;}
}//end keyReleased
public void keyPressed(KeyEvent e)
{
Object source=e.getSource();
int pressed=e.getKeyCode();
if (pressed==KeyEvent.VK_A){left=1;}
if (pressed==KeyEvent.VK_W){up=1;}
if (pressed==KeyEvent.VK_D){right=1;}
if (pressed==KeyEvent.VK_S){down=1;}
if (pressed==KeyEvent.VK_PAUSE&&pressed==KeyEvent.VK_P)
{
//if (paused==0){paused=1;}
//else paused=0;
}
}//end keyPressed
public void keyTyped(KeyEvent e){}
//***********************************************************************************************
public void mouseDragged(MouseEvent e)
{
mouseX=(e.getX());
mouseY=(e.getY());
//run();
}
public void mouseMoved(MouseEvent e)
{
mouseX=(e.getX());
mouseY=(e.getY());
//run();
}
//***********************************************************************************************
public void mousePressed(MouseEvent e)
{
if(e.getX()==0 && e.getY()==0){System.exit(0);}
mouseX=(e.getX()+x);
mouseY=(e.getY()+y);
if(Tile instanceof circle)
{
Circle.move(0-Circle.width, 0-Circle.height);
Circle.setBounds(Circle.x, Circle.y, Circle.width, Circle.height);
Tile=Rectangle;
}
else
{
Rectangle.move(0-Rectangle.width, 0-Rectangle.height);
Rectangle.setBounds(Rectangle.x, Rectangle.y, Rectangle.width, Rectangle.height);
Tile=Circle;
}
Tile.move(mouseX-Tile.width/2, mouseY-Tile.height/2);
}
public void mouseReleased(MouseEvent e)
{
//run();
}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
//***********************************************************************************************
public void run()//run collision detection
{
while (this == this)
{
Tile.move(Tile.x + ((mouseX - (Tile.x + (Tile.width / 2))) / 10), Tile.y + ((mouseY - (Tile.y + (Tile.height / 2))) / 10));
//Tile.move((mouseX - Tile.width / 2), mouseY - (Tile.height / 2));
for (int i = 0; i < everything.size(); i++)
{
tile Temp = (tile) everything.get(i);
if (Temp.x < (Tile.x + Tile.width) && (Temp.x + Temp.width) > Tile.x && Temp.y < (Tile.y + Tile.height) && (Temp.y + Temp.height) > Tile.y)//rectangles collided
{
if (Temp instanceof rectangle)
{
if (Tile instanceof rectangle){rectangleRectangle(Temp);}
else {circleRectangle(Temp);}//Tile instanceof circle
}
else
{
if (Temp instanceof circle)
{
if (Tile instanceof rectangle) {rectangleCircle(Temp);}
else {circleCircle(Temp);}
}
else//line
{
if (Tile instanceof rectangle){rectangleLine(Temp);}
else{circleLine(Temp);}
}
}
}//end if
}//end for
try {Thread.sleep(16L);}
catch (Exception e) {}
Tile.setBounds(Tile.x, Tile.y, Tile.width, Tile.height);
//Rectangle.setBounds(x, y, width, height);
//Circle.setBounds(x, y, width, height);
repaint();
text.out=" ";
}//end while loop
}//end run
//***************************************special collision detection/handling functions************************************************
void rectangleRectangle(tile Temp)
{
int lapTop, lapBot, lapLeft, lapRight, small, scootX=0, scootY=0;
lapTop=(Temp.y+Temp.height)-Tile.y;
lapBot=(Tile.y+Tile.height)-Temp.y;
lapLeft=(Temp.x+Temp.width)-Tile.x;
lapRight=(Tile.x+Tile.width)-Temp.x;
small=999999999;
if (lapTop<small){small=lapTop; scootX=0; scootY=lapTop;}
if (lapBot<small){small=lapBot; scootX=0; scootY=lapBot*-1;}
if (lapLeft<small){small=lapLeft; scootX=lapLeft; scootY=0;}
if (lapRight<small){small=lapRight; scootX=lapRight*-1; scootY=0;}
Tile.move(Tile.x+scootX, Tile.y+scootY);text.out="collision detected!";
}
void circleRectangle(tile Temp)
{
if((Tile.x+Tile.width/2<=Temp.x+Temp.width && Tile.x+Tile.width/2>=Temp.x)||(Tile.y+Tile.height/2>=Temp.y && Tile.y+Tile.height/2<=Temp.y+Temp.height))
{
rectangleRectangle(Temp);
}
else//push from nearest corner
{
int x,y;
if(Tile.x+Tile.width/2>Temp.x+Temp.width && Tile.y+Tile.height/2<Temp.y){x=Temp.x+Temp.width; y=Temp.y;}
else if(Tile.x+Tile.width/2<Temp.x && Tile.y+Tile.height/2<Temp.y){x=Temp.x; y=Temp.y;}
else if(Tile.x+Tile.width/2>Temp.x+Temp.width && Tile.y+Tile.height/2>Temp.y+Temp.height){x=Temp.x+Temp.width; y=Temp.y+Temp.height;}
else {x=Temp.x; y=Temp.y+Temp.height;}
double distance = Math.sqrt(Math.pow(Tile.x+(Tile.width/2) - x, 2) + Math.pow(Tile.y+(Tile.height/2) - y, 2));
if((int)Math.round(distance)<Tile.height/2)
{
double normY = ((Tile.y+(Tile.height/2) - y) / distance);
double normX = ((Tile.x+(Tile.width/2) - x) / distance);
Tile.move(x-Tile.width/2+(int)Math.round(normX*((Tile.width/2))) , y-Tile.height/2+(int)Math.round(normY*((Tile.height/2))));text.out="collision detected!";
}
}
}
void rectangleCircle(tile Temp)
{
if((Temp.x+Temp.width/2<=Tile.x+Tile.width && Temp.x+Temp.width/2>=Tile.x)||(Temp.y+Temp.height/2>=Tile.y && Temp.y+Temp.height/2<=Tile.y+Tile.height))
{
rectangleRectangle(Temp);
}
else//push from nearest corner
{
int x,y;
if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2<Tile.y){x=Tile.x+Tile.width; y=Tile.y;}
else if(Temp.x+Temp.width/2<Tile.x && Temp.y+Temp.height/2<Tile.y){x=Tile.x; y=Tile.y;}
else if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2>Tile.y+Tile.height){x=Tile.x+Tile.width; y=Tile.y+Tile.height;}
else {x=Tile.x; y=Tile.y+Tile.height;}
double distance = Math.sqrt(Math.pow(Temp.x+(Temp.width/2) - x, 2) + Math.pow(Temp.y+(Temp.height/2) - y, 2));
if((int)Math.round(distance)<Temp.height/2)
{
double normY = ((Temp.y+(Temp.height/2) - y) / distance);
double normX = ((Temp.x+(Temp.width/2) - x) / distance);
if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2<Tile.y){Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2)))-Tile.width,(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2))));text.out="collision detected!";}
else if(Temp.x+Temp.width/2<Tile.x && Temp.y+Temp.height/2<Tile.y){Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2))),(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2))));text.out="collision detected!";}
else if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2>Tile.y+Tile.height){Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2)))-Tile.width,(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2)))-Tile.height);text.out="collision detected!";}
else {Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2))),(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2)))-Tile.height);text.out="collision detected!";}
}
}
}
void circleCircle(tile Temp)
{
double distance = Math.sqrt(Math.pow((Tile.x+(Tile.width/2)) - (Temp.x+(Temp.width/2)),2) + Math.pow((Tile.y+(Tile.height/2)) - (Temp.y+(Temp.height/2)), 2));
if((int)distance<(Tile.width/2+Temp.width/2))
{
double normX = ((Tile.x+(Tile.width/2)) - (Temp.x+(Temp.width/2))) / distance;
double normY = ((Tile.y+(Tile.height/2)) - (Temp.y+(Temp.height/2))) / distance;
Tile.move((Temp.x+(Temp.width/2))+(int)Math.round(normX*(Tile.width/2+Temp.width/2))-(Tile.width/2) , (Temp.y+(Temp.height/2))+(int)Math.round(normY*(Tile.height/2+Temp.height/2))-(Tile.height/2));text.out="collision detected!";
}
}
void circleLine(tile Temp)
{
line Line=(line)Temp;
if (Line.x1 < (Tile.x + Tile.width) && (Line.x1) > Tile.x && Line.y1 < (Tile.y + Tile.height) && Line.y1 > Tile.y)//circle may be hitting one of the end points
{
rectangle rec=new rectangle(Line.x1, Line.y1, 1, 1, this);
circleRectangle(rec);
remove(rec);
}
if (Line.x2 < (Tile.x + Tile.width) && (Line.x2) > Tile.x && Line.y2 < (Tile.y + Tile.height) && Line.y2 > Tile.y)//circle may be hitting one of the end points
{
rectangle rec=new rectangle(Line.x2, Line.y2, 1, 1, this);
circleRectangle(rec);
remove(rec);
}
int x1=0, y1=0, x2=Tile.x+(Tile.width/2), y2=Tile.y+(Tile.height/2);
x1=Tile.x+(Tile.width/2)-Line.height;//(int)Math.round(Line.xNorm*1000);
x2=Tile.x+(Tile.width/2)+Line.height;
if(Line.posSlope)
{
y1=Tile.y+(Tile.height/2)-Line.width;
y2=Tile.y+(Tile.height/2)+Line.width;
}
else
{
y1=Tile.y+(Tile.height/2)+Line.width;
y2=Tile.y+(Tile.height/2)-Line.width;
}
Point point=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection
if (point.x < (Line.x + Line.width) && point.x > Line.x && point.y < (Line.y + Line.height) && point.y > Line.y)//line intersects within line segment
{
//if(point!=null){System.out.println(point.x+","+point.y);}
double distance = Math.sqrt(Math.pow((Tile.x+(Tile.width/2)) - point.x,2) + Math.pow((Tile.y+(Tile.width/2)) - point.y, 2));
if((int)distance<Tile.width/2)
{
//System.out.println("hit");
double normX = ((Tile.x+(Tile.width/2)) - point.x) / distance;
double normY = ((Tile.y+(Tile.height/2)) - point.y) / distance;
Tile.move((point.x)+(int)Math.round(normX*(Tile.width/2))-(Tile.width/2) , (point.y)+(int)Math.round(normY*(Tile.height/2))-(Tile.height/2));text.out="collision detected!";
//System.out.println(point.x+","+point.y);
}
}
//new bullet(this, (int)Math.round(tryX), (int)Math.round(tryY));
}
void rectangleLine(tile Temp)
{
line Line=(line)Temp;
if(new Line2D.Double(Line.x1,Line.y1,Line.x2,Line.y2).intersects(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height)))
{
if (Line.x1 < (Tile.x + Tile.width) && (Line.x1) > Tile.x && Line.y1 < (Tile.y + Tile.height) && Line.y1 > Tile.y)//circle may be hitting one of the end points
{
rectangle rec=new rectangle(Line.x1, Line.y1, 1, 1, this);
rectangleRectangle(rec);
remove(rec);
}
if (Line.x2 < (Tile.x + Tile.width) && (Line.x2) > Tile.x && Line.y2 < (Tile.y + Tile.height) && Line.y2 > Tile.y)//circle may be hitting one of the end points
{
rectangle rec=new rectangle(Line.x2, Line.y2, 1, 1, this);
rectangleRectangle(rec);
remove(rec);
}
if(Line.posSlope)//positive sloped line
{
//first we'll do the top left corner
int x1=Tile.x-Line.height;
int x2=Tile.x+Line.height;
int y1=Tile.y-Line.width;
int y2=Tile.y+Line.width;
Point topPoint=new Point(-99,-99), botPoint=new Point(-99,-99);
double topDistance=0, botDistance=0;
topPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection
topDistance = Math.sqrt(Math.pow(Tile.x - topPoint.x,2) + Math.pow(Tile.y - topPoint.y, 2));
//new let's do the bottom right corner
x1=Tile.x+Tile.width-Line.height;
x2=Tile.x+Tile.width+Line.height;
y1=Tile.y+Tile.height-Line.width;
y2=Tile.y+Tile.height+Line.width;
botPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection
botDistance = Math.sqrt(Math.pow((Tile.x+Tile.width) - botPoint.x,2) + Math.pow((Tile.y+Tile.height) - botPoint.y, 2));
if(topDistance<botDistance)
{
if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(topPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(topPoint))
{
Tile.move(topPoint.x,topPoint.y);text.out="collision detected!";
}
}
else
{
if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(botPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(botPoint))
{
Tile.move(botPoint.x-Tile.width,botPoint.y-Tile.height);text.out="collision detected!";
}
}
}
else//negative sloped lne
{
//first we'll do the top right corner
int x1=Tile.x+Tile.width-Line.height;
int x2=Tile.x+Tile.width+Line.height;
int y1=Tile.y+Line.width;
int y2=Tile.y-Line.width;
Point topPoint=new Point(-99,-99), botPoint=new Point(-99,-99);
double topDistance=0, botDistance=0;
topPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection
topDistance = Math.sqrt(Math.pow(Tile.x + Tile.width - topPoint.x,2) + Math.pow(Tile.y - topPoint.y, 2));
//new let's do the bottom left corner
x1=Tile.x-Line.height;
x2=Tile.x+Line.height;
y1=Tile.y+Tile.height+Line.width;
y2=Tile.y+Tile.height-Line.width;
botPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection
botDistance = Math.sqrt(Math.pow(Tile.x - botPoint.x,2) + Math.pow((Tile.y+Tile.height) - botPoint.y, 2));
if(topDistance<botDistance)
{
if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(topPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(topPoint))
{
Tile.move(topPoint.x-Tile.width,topPoint.y);text.out="collision detected!";
}
}
else
{
if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(botPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(botPoint))
{
Tile.move(botPoint.x,botPoint.y-Tile.height);text.out="collision detected!";
}
}
}
}
}
public Point intersection(double x1, double y1, double x2, double y2,double x3, double y3, double x4, double y4)//I didn't write this. got it from http://www.ahristov.com/tutorial/geometry-games/intersection-lines.html (I altered it)
{
double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
double xi = ((x3 - x4) * (x1 * y2 - y1 * x2) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
double yi = ((y3 - y4) * (x1 * y2 - y1 * x2) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;
int x=(int)Math.round(xi);
int y=(int)Math.round(yi);
return new Point(x, y);
}
//***************************************************************************************
public static void main(String[] args)
{
final collision Collision=new collision();
Collision.run();
}//end main
}//end class
Since Java doesn't have an intersect function (really!?) you can do collision detection by simply comparying the X and Y, Width and Height values of the bounding boxes (rectangle) for each of the objects that could potentially collide.
So... in the base object of each colliding object... i.e. if your player and enemy have a common base you can put a simple Rectangle object called something like BoundingBox. If the common base is a built in Java class then you'll need to create a class that extends the build in class and have the player and enemy objects extend your new class or are instances of that class.
At creation (and each tick or update) you'll need to set the BoundingBox paremeters for both your player and enemy. I don't have the Rectangle class infront of me but its most likely something like X, Y, Width and finally Height. X and Y are that objects location in your game world. The width and height are self explanatory I think. They'll most likely come out from the right of the players location though so, if the X and Y were bothe at 0 and your Width and Height were both at 256 you wouldn't see anything because the character would be at the top left outside of the screen.
Anyways... to detect a collision, you'll want to compare the attributes of the player and enemy BoundingBoxes. So something like this...
if( Player.BoundingBox.X = Enemy.BoundingBox.X && If( Player.BoundingBox.Y = Enemy.BoundingBox.Y )
{
//Oh noes! The enemy and player are on top of eachother.
}
The logic can get sort of complicated but you'll need to compare the distances between each BoundingBox and compare locations.
Here's a useful of an open source game that uses a lot of collisions: http://robocode.sourceforge.net/
You may take a look at the code and complement with the answers written here.
is there a problem with:
Rectangle box1 = new Rectangle(100,100,100,100);
Rectangle box2 = new Rectangle(200,200,100,100);
// what this means is if any pixel in box2 enters (hits) box1
if (box1.contains(box2))
{
// collision occurred
}
// your code for moving the boxes
this can also be applied to circles:
Ellipse2D.Double ball1 = new Ellipse2D.Double(100,100,200,200);
Ellipse2D.Double ball2 = new Ellipse2D.Double(400,100,200,200);
// what this means is if any pixel on the circumference in ball2 touches (hits)
// ball1
if (ball1.contains(ball2))
{
// collision occurred
}
// your code for moving the balls
to check whether youve hit the edge of a screen you could use the following:
Rectangle screenBounds = jpanel.getBounds();
Ellipse2D.Double ball = new Ellipse2D.Double(100,100,200,200); // diameter 200
Rectangle ballBounds = ball.getBounds();
if (!screenBounds.contains(ballBounds))
{
// the ball touched the edge of the screen
}
Use a rectangle to surround each player and enemy, the height and width of the rectangles should correspond to the object you're surrounding, imagine it being in a box only big enough to fit it.
Now, you move these rectangles the same as you do the objects, so they have a 'bounding box'
I'm not sure if Java has this, but it might have a method on the rectangle object called .intersects() so you'd do if(rectangle1.intersectS(rectangle2) to check to see if an object has collided with another.
Otherwise you can get the x and y co-ordinates of the boxes and using the height/width of them detect whether they've intersected yourself.
Anyway, you can use that to either do an event on intersection (make one explode, or whatever) or prevent the movement from being drawn. (revert to previous co-ordinates)
edit: here we go
boolean
intersects(Rectangle r)
Determines whether or not this Rectangle and the specified
Rectangle intersect.
So I would do (and don't paste this code, it most likely won't work, not done java for a long time and I didn't do graphics when I did use it.)
Rectangle rect1 = new Rectangle(player.x, player.y, player.width, player.height);
Rectangle rect2 = new Rectangle(enemy.x, enemy.y, enemy.width, enemy.height);
//detects when the two rectangles hit
if(rect1.intersects(rect2))
{
System.out.println("game over, g");
}
obviously you'd need to fit that in somewhere.
No need to use rectangles ... compare the coordinates of 2 players constantly.
like
if(x1===x&&y1==y)
remember to increase the range of x when ur comparing.
if ur rectangle width is 30 take as if (x1>x&&x2>x+30)..likewise y
It's Java code for collision of two or more ImageViews not rectangles or other,use ImageViews Instead.
1.This code of Collision works every where in any views or layouts.
2.Add a timer to repeat it and to detect collision repeatedly.
3.It only works with views and layout.
if ((getLocationX(_v1) > (getLocationX(_v2) - ((_w2*3) + 40))) && (getLocationX(_v1) < (getLocationX(_v2) + ((_w2*3) +40)))){
if ((getLocationY(_v1) > (getLocationY(_v2) - ((_h2*3) + 40))) && (getLocationY(_v1) < (getLocationY(_v2) + ((_h2*3) +40)))){
showMessage("Collided");
}
}

Error displaying bufferedImage repainting with mouse Listening

Im having difficulty drawing a Sub Image of a Buffered Image everytime the Mouse Pointer Location equals that of the each border of the JPanel. The problem is that the BufferedImage that is equals the SubImage wont display
Here is the JPanel the initialization might not be correct Im still learning the components of Java and 2D graphics.
public class Map extends JPanel implements MouseListener, MouseMotionListener {
private final int SCR_W = 800;
private final int SCR_H = 600;
private int x;
private int y;
private int dx;
private int dy;
String dir = "C:\\imgs\\war\\";
private BufferedImage map_buffer;
public BufferedImage scr_buffer;
public void initScreen(int x, int y, int stage){
if(stage == 0){
try{ map_buffer = ImageIO.read(new File(dir + "map" + stage + ".jpg" ));
}catch(Exception error) { System.out.println("Error: cannot read tileset image.");
}
}
scr_buffer = map_buffer.getSubimage(x, y, SCR_W, SCR_H);
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if(scr_buffer == null)
initScreen(x, y, 0);
g.drawImage(scr_buffer, 0, 0, this);
}
boolean isLeftBorder = false;
boolean isRightBorder = false;
boolean isTopBorder = false;
boolean isBottomBorder = false;
public Map(){
addMouseListener(new MouseAdapter() {
public void mouseMoved(MouseEvent e) {
/**
* Check location of mouse pointer if(specified_edge)move(scr_buffer)
*
*/
System.out.println("MouseMove: " + e.getPoint().getX() + " , " + e.getPoint().getY());
if(e.getPoint().getX() == SCR_W)isRightBorder = true;
if(e.getPoint().getY() == SCR_H)isBottomBorder = true;
if(e.getPoint().getX() == 0 && e.getPoint().getY() == SCR_H)isLeftBorder = true;
if(e.getPoint().getY() == 0 && e.getPoint().getX() == SCR_W)isTopBorder = true;
if(e.getPoint().getX() != 0 && e.getPoint().getX() != SCR_W
&& e.getPoint().getY() != 0 && e.getPoint().getY() != SCR_H){
isLeftBorder = false;
isRightBorder = false;
isTopBorder = false;
isBottomBorder = false;
}
if(isRightBorder){ x += 2; repaint(); }
if(isBottomBorder){ y -= 2; repaint(); }
if(isLeftBorder){ x -= 2; repaint();}
if(isTopBorder){ y += 2; repaint(); }
}
});
}
}
In the main I init a JFrame to contain the Panel all im getting is a error
public static void main(String[] args) {
JFrame f = new JFrame("War");
f.setSize(800, 600);
f.setLayout(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Map m = new Map();
f.getContentPane().add(f);
f.setVisible(true);
}
In order to detect mouse movement you should use a MosuseMotionListener, while technically MouseAdapter implements this, you need to register it with the JPanel correctly
Instead of using addMouseListener, you'll want to use addMouseMotionListener instead
I'd also be worried about the use of SRC_W and SRC_H, as you can't guarantee the size of the panel. Instead, you should be using getWidth and getHeight, which will tell you the actual size of the component
You can improve the chances of obtaining the size you want by overriding the getPreferredSize and return the size you would like. You'd then use pack on the frame to wrap the frame about it
f.getContentPane().add(f); is adding the frame to itself, it should probably be more like f.getContentPane().add(m);
f.setLayout(null); will prevent any of the child components from been sized and positioned and is best avoid, just get rid of it.
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
This scr_buffer = map_buffer.getSubimage(x, y, SCR_W, SCR_H); is also a little dangerous, as it could be asking for more of the image then is available, you should be testing to see if x + SCR_W < image width (and same goes for the height)
I don't know if this deliberate or not, but you never reset the "border" flags, so once set, they will always be true...
addMouseMotionListener(new MouseAdapter() {
public void mouseMoved(MouseEvent e) {
/**
* Check location of mouse pointer if(specified_edge)move(scr_buffer)
*
*/
isRightBorder = false;
isBottomBorder = false;
isTopBorder = false;
isLeftBorder = false;
You may also want to have a "space" around the edge, which when the mouse enters it, it will set the border flags, for example...
if (e.getPoint().getX() >= getWidth() - 4) {
isRightBorder = true;
}
if (e.getPoint().getY() >= getHeight() - 4) {
isBottomBorder = true;
}
if (e.getPoint().getX() <= 4) {
isLeftBorder = true;
}
if (e.getPoint().getY() <= 4) {
isTopBorder = true;
}
Your logic for the vertical movement is wrong, when the mouse is within the bottom border, it should add to the y position and subtract when it's within the top border...
if (isBottomBorder) {
y += 2;
}
if (isTopBorder) {
y -= 2;
}
You need to perform some range checking after you've modified the x/y positions to make sure you're not request for a portion of the image which is not available...
if (x < 0) {
x = 0;
} else if (x + getWidth() > map_buffer.getWidth()) {
x = map_buffer.getWidth() - getWidth();
}
if (y < 0) {
y = 0;
} else if (y + getHeight() > map_buffer.getHeight()) {
y = map_buffer.getHeight() - getHeight();
}
There is a logic error within the initScreen method, src_buffer is never set to null, meaning that once it has a "sub image", it never tries to obtain a new one (also, you shouldn't be loading the map_buffer in there either).
scr_buffer = null;
repaint();
Thank you for you time and understanding.
Inside mouse moved
if (e.getPoint().getX() >= getWidth() - 4) {
isRightBorder = true; // unnecessary
scr_buffer = null;
x = x + 2;
repaint();
}

Graphics painting strategy(performance)

In my game I have a gamepanel which draws my map layers: 'ground/buildings/objects layer', then player sprite, then enemies/npcs/mobs, then 'above layer(tiles to draw above player)'. This was working great and running smoothly.
I then started to work on a minimap JInternalFrame. It actually looks great for what I need but I am concerned with performance. After adding the minimap I noted some slowdown of painting. My biggest resolution supports a map of:
else if (scrnsize.width >= 1440 && scrnsize.height >= 1024){ //large&wide
//45x29(32x32px tiles)
//1440, 1024
Basically my question is, is there a better way I can do this(than below code) or methods I can call for offscreen buffer or something?
This is the Minimap code. As you can see I have logic in the paintComponent to not redraw unless the refreshMinimap == true(the player moves or dies). This helped get rid of most noticable lag, but I still am noticing some. Any help would be super appreciated.
public MinimapGamePanel() {
super();
logger.addAppender(GUILog4JFileHelper.fileAppender);
gamePanelImage = new BufferedImage(32 * MyClient.xTiles, 32 * MyClient.yTiles, BufferedImage.TYPE_INT_ARGB);
setLayout(new BorderLayout());
setBorder(BorderFactory.createLineBorder(Color.black));
}
public void paintComponent(Graphics g) {
logger.trace("begin: REPAINTNG...");
g2 = (Graphics2D)g;
//map
if (refreshMinimap){
RefreshMinimap();
refreshMinimap = false;
}
g2.drawImage(gamePanelImage, 0, 0, null);
g2.dispose();
logger.trace("end: REPAINTNG...");
}
private void RefreshMinimap() {
logger.trace("Map drawing started.");
int count = (int) ((MyClient.characterX - (MyClient.xTiles*1.5)) + ((MyClient.characterY - (MyClient.yTiles*2)) * MyClient.mapWidth));
for (int x = 0; x < MyClient.xTiles*3; x++){
for (int y = 0; y < MyClient.yTiles*4; y++){
if (count > -1 && count < (MyClient.mapWidth * MyClient.mapHeight)){
if (!MyClient.groundLayer[count].equals("0")){ //don't draw full transparent tiles
//SpriteStore.get().getSprite("images/tiles/" + MyClient.groundLayer[count] + ".png").draw(gamePanelImage, x, y);
SpriteStore.get().getSprite("images/tiles/" + MyClient.groundLayer[count] + ".png").drawFirstPixel(gamePanelImage, x, y);
}
if (!MyClient.buildingLayer[count].equals("0")){ //don't draw full transparent tiles
SpriteStore.get().getSprite("images/tiles/" + MyClient.buildingLayer[count] + ".png").drawFirstPixel(gamePanelImage, x, y);
}
if (!MyClient.objectLayer[count].equals("0")){ //don't draw full transparent tiles
SpriteStore.get().getSprite("images/tiles/" + MyClient.objectLayer[count] + ".png").drawFirstPixel(gamePanelImage, x, y);
}
} else {
SpriteStore.get().getSprite("images/tiles/" + MyClient.groundLayer[0] + ".png").drawFirstPixel(gamePanelImage, x, y);
}
count += MyClient.mapWidth;
}
count -= MyClient.yTiles * 4 * MyClient.mapWidth;
count++;
}
logger.trace("Map drawing done.");
}
This is the drawing code which just draws pixel 0,0
public void drawFirstPixel(BufferedImage gamePanelImage, int xDraw, int yDraw) {
BufferedImage bufferedVersion = (BufferedImage) image;
gamePanelImage.getGraphics().drawImage(bufferedVersion.getSubimage(0, 0, 1, 1), xDraw, yDraw, null);
}
I am actually pretty happy with the look of just taking pixel 0,0. Apologies for the bad quality, shaky cell phone pic.
After adding the minimap I noted some slowdown of painting
SpriteStore.get().getSprite("images/tiles/" + MyClient.buildingLayer
Don't do I/O in a painting method. All images should be read into memory when you create your class.
Is this in tune to what you guys were suggesting I do?
public class MinimapGamePanel extends JPanel {
...
private static Thread t;
public MinimapGamePanel() {
super();
logger.addAppender(GUILog4JFileHelper.fileAppender);
gamePanelImage = new BufferedImage(320, 320, BufferedImage.TYPE_INT_ARGB);
//TODO:: change values above upon picking minimap size
setLayout(new BorderLayout());
setBorder(BorderFactory.createLineBorder(Color.black));
t = new Thread(new RefreshMinimapThread());
}
public void paintComponent(Graphics g) {
logger.trace("begin: REPAINTNG...");
g2 = (Graphics2D)g;
if (refreshMinimap){
t.start();
//RefreshMinimap();
refreshMinimap = false;
}
g2.drawImage(gamePanelImage, 0, 0, null);
g2.dispose();
logger.trace("end: REPAINTNG...");
}
private class RefreshMinimapThread implements Runnable {
#Override
public void run() {
RefreshMinimap();
}
}

Java Applet adding thread makes while loop infinite

I am trying to make a program that generates 25 random ovals then draw a ball and make it bounce, I got it somewhat done, I generated the ovals and I got the ball to move but when I added the thread it kept repeating the draw oval loop, I get somewhat why this is happening but I have no idea how to fix it.
Basically my program should:
draw 25 random sized ovals on random locations within the border - completed
draw a ball and make it move - completed
make the ball bounce - not done but I know how to do it
but it keeps repeating step one.
this is my code that I have written, oh and I have to use applets right now its part of the course please don't suggest I use swing or something else:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
public class As4B extends Applet implements Runnable
{
public int x, y;
public int width = 854;
public int height = 480;
public int border = 20;
public Image offscreen;
public Graphics d;
public void init()
{
setSize(width,height);
Thread th = new Thread(this);
th.start();
offscreen = createImage(width,height);
d = offscreen.getGraphics();
}
public void run()
{
x = 100;
y = 100;
while(true)
{
x ++;
y ++;
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void paint(Graphics gfx)
{
d.setColor(java.awt.Color.black);
d.fillRect(0, 0, width, height);
d.setColor(java.awt.Color.green);
d.fillRect(0 + border, 0 + border, (width - (border * 2)), (height - (border* 2)));
genOval(25, d);
d.setColor(Color.gray);
d.fillOval(x, y, 50, 50);
gfx.drawImage(offscreen, 0, 0, this);
}
public int random(int low, int high)
{
int answer =(int)((Math.random()*(high-low))+ low);
return answer;
}
public void genOval(int amount, Graphics f)
{
int ranWidth, ranHeight, ranX, ranY, red, blue, green;
int i = 0;
while(i < 25)
{
green = random(0,255);
blue = random(0,255);
red = random(0,255);
f.setColor(new Color(red,green,blue));
ranWidth = random(30,400);
ranHeight = random(30,200);
ranX = random(0 + border, ((width - border)- (ranWidth)));
ranY = random(0 + border , ((height - border)- (ranHeight)));
f.fillOval(ranX, ranY, ranWidth, ranHeight);
i++;
}
}
public void update(Graphics gfx) {
paint(gfx);
}
}
Your genOval() method has no persistent backing. Every time repaint() is called (by your thread), the paint() method is called, and this generates new locations for the random ovals. You need to create a persistent source for that information, like so:
List<Rectangle> rectangles = new ArrayList<Rectangle>();
List<Color> colors = new ArrayList<Color>();
public void init() {
...
for (int i = 0; i < 25; i++) {
int green = random(0,255);
int blue = random(0,255);
int red = random(0,255);
colors.add(new Color(red,green,blue));
ranWidth = random(30,400);
ranHeight = random(30,200);
ranX = random(0 + border, ((width - border)- (ranWidth)));
ranY = random(0 + border , ((height - border)- (ranHeight)));
rectangles.add(new Rectangle(ranX, ranY, ranWidth, ranHeight));
}
}
public void genOval(Graphics g) {
for (int i = 0; i < 25; i++) {
Color color = colors.get(i);
Rectangle rectangle = rectangle.get(i);
// Draw using color & rectangle
}
}

Categories