Alright, so I've been trying to move my polygon so it bounces around the screen. Right now it does so but leave a trail the entire way. I have a GUI class, extended by an Aquarium class, which fills the screen with the color blue, creates a "creature" object (from Creature class) and uses update to move it down the screen. When it updates however, a trail is left behind. I have tried many methods mentioned in similar cases on the site but nothing works. Can somebody please help me?
GUI class (that holds JPanel etc)
package artilife;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class AquariumGUI {
private GooPanel gooPanel;
private boolean loop = true;
protected int width, height;
private int frameTimeInMillis = 300;
private RenderingHints renderingHints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
#SuppressWarnings("serial")
class GooPanel extends JPanel {
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHints(renderingHints);
draw(g2d);
}
}
public AquariumGUI() {
this(800, 500);
}
public AquariumGUI(int w, int h) {
width = w;
height = h;
JFrame frame = new JFrame();
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gooPanel = new GooPanel();
gooPanel.setPreferredSize(new Dimension(w, h));
frame.getContentPane().add(gooPanel);
frame.pack();
frame.setVisible(true);
}
public void go() {
while (loop) {
gooPanel.repaint();
update();
try {
Thread.sleep(frameTimeInMillis);
} catch (InterruptedException e) {
}
}
}
public void draw(Graphics2D g) {
}
public void update(){
}
public void setFrameTime(int millis){
frameTimeInMillis = millis;
}
}
Aquarium class that extended this and attempts to color the screen and place a Polygon creature on it:
package artilife;
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Random;
public class MyAquarium extends AquariumGUI {
Creature tester;
public MyAquarium()
{
tester = new Creature();
}
public void draw(Graphics2D g) {
// Fill background
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
tester.draw(g);
}
public void update(){
tester.move(width, height);
}
public static void main(String[] args) {
MyAquarium aquarium = new MyAquarium();
aquarium.go();
}
}
And the creature that is being drawn, and holds the move method:
package artilife;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Creature
{
// Position and radius of the drop
private double x, y, r, Vx, Vy;
Polygon p = new Polygon();
int numSides;
public Creature() {
x = 800 / 2;
r = 10;
y = 50;
Vx = 10;
Vy = 3;
numSides = 3;
//creatureShape(numSides);
}
public void creatureShape (int sides)
{
if (sides <= 10){
for (int i = 0; i < sides; i++){
p.addPoint((int) (x + 50 * Math.cos((i) * 2 * Math.PI / sides)),
(int) (y + 50 * Math.sin((i) * 2 * Math.PI / sides)));
}
}
else{
for (int i = 0; i < 360; i++) {
double value = i / 360.0;
p.addPoint((int) (90 + 50 * value * Math.cos(8 * value * Math.PI)),
(int) (50 + 50 * value * Math.sin(8 * value * Math.PI)));
}
}
}
public void draw(Graphics2D g) {
creatureShape(numSides);
g.setColor(Color.BLUE);
g.fillPolygon(p);
}
public void move(int width, int height){
// Move the drop
x = x + Vx;
y = y +Vy;
if (y >= height){
Vy = -Vy;
y = height;
}
else if(y <= 0){
Vy = -Vy;
y = 0;
}
if(x >= width){
Vx = -Vx;
x = width;
}
if(x <= 0){
Vx = -Vx;
x = 0;
}
}
/*
public void attraction ()
{
if (
}*/
/*
public boolean check4Creatures ()
{
boolean isThere = false;
//if there is an another create object within a 60 point radius
isThere = true;
return isThere;
}*/
}
SOLUTION:
So fiddle for what feels like forever and it works now.
When drawing polygons in motion, some java functions store bits of information regarding the vertices. The best way to move them cleanly is to use translate() instead of manipulating the vertices directly (by updating x and y values) when updating the information, and then draw the fresh polygon.
Thank everyone for taking the time to look at my problem though!
You need to clear the screen between two drawing operations. You can either leave it to the framework, by calling the super.paintComponent() method, or you can do it your way, by filling the screen with something, like a g.fillRect() call.
The first method will actually make a call the the fillRect function, using the panel background color.
Related
is it possible to simply make 360 degree movement in java(swing) without any game engine? all I have is this attempt:
public class Game extends JPanel implements Runnable {
int x = 300;
int y = 500;
float angle = 30;
Game game;
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(new Game());
frame.setSize(600, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public Game() {
setSize(600, 600);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void paint(Graphics g) {
g.setColor(Color.WHITE);
g.drawRect(0, 0, 600, 600);
g.setColor(Color.CYAN);
g.fillOval(x, y, 10, 10);
g.dispose();
}
#Override
public void run() {
while(true) {
angle += -0.1;
x += Math.sin(angle);
y--;
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException ex) {}
}
}
}
as you can see in following picture, I don't know how to handle movement rotating, this is the output:
image http://screenshot.cz/GOXE3/mvm.jpg
Actually, this is quite possible.
My preferred way is to actually take advantage of the Graphics transform so that you don't have to do any computation, it's all left to the Graphics
By the way:
since you did not create the Graphics object, don't ever dispose it.
override paintComponent() rather than paint()
It's always a good pattern to call super.paintComponent()
Small demo example:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class TestRotate {
public static class ShapeAndColor {
private final Shape shape;
private final Color color;
public ShapeAndColor(Shape shape, Color color) {
super();
this.shape = shape;
this.color = color;
}
public Shape getShape() {
return shape;
}
public Color getColor() {
return color;
}
}
public static class RotatingShapesPanel extends JComponent {
private List<ShapeAndColor> shapes;
private double rotation = 0.0;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
AffineTransform translate = AffineTransform.getTranslateInstance(-getWidth() / 2, -getHeight() / 2);
AffineTransform rotate = AffineTransform.getRotateInstance(rotation);
AffineTransform t = AffineTransform.getTranslateInstance(getWidth() / 2, getHeight() / 2);
t.concatenate(rotate);
t.concatenate(translate);
g2d.setTransform(t);
AffineTransform scale = AffineTransform.getScaleInstance(getWidth(), getHeight());
for (ShapeAndColor shape : shapes) {
Area area = new Area(shape.getShape());
g2d.setColor(shape.getColor());
area.transform(scale);
g2d.fill(area);
}
}
public void setShapes(List<ShapeAndColor> shapes) {
this.shapes = shapes;
repaint();
}
public double getRotation() {
return rotation;
}
public void setRotation(double rotation) {
this.rotation = rotation;
repaint();
}
}
protected void initUI(final boolean useBorderLayout) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
List<ShapeAndColor> shapes = new ArrayList<>();
Random r = new Random();
for (int i = 0; i < 10; i++) {
double x = r.nextDouble();
double y = r.nextDouble();
double w = r.nextDouble();
double h = r.nextDouble();
w = Math.min(w, 1 - x) / 2;
h = Math.min(h, 1 - y) / 2;
double a = Math.min(w, h) / 10.0;
RoundRectangle2D.Double shape = new RoundRectangle2D.Double(x, y, w, h, a, a);
Color color = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
shapes.add(new ShapeAndColor(shape, color));
}
final RotatingShapesPanel panel = new RotatingShapesPanel();
panel.setShapes(shapes);
frame.add(panel);
frame.setSize(600, 600);
frame.setVisible(true);
Timer t = new Timer(0, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
double rotation = panel.getRotation() + 0.02;
if (rotation > Math.PI * 2) {
rotation -= Math.PI * 2;
}
panel.setRotation(rotation);
}
});
t.setRepeats(true);
t.setDelay(10);
t.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestRotate().initUI(true);
}
});
}
}
Change a few lines...
int basex = 300; // midpoint of the circle
int basey = 400;
int radius = 100; // radius
int x;
int y;
float angle = 0; // Angles in radians, NOT degrees!
public void run() {
while(true) {
angle += 0.01;
x = (int)(basex + radius*Math.cos(angle));
y = (int)(basey - radius*Math.sin(angle));
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException ex) {}
}
}
Not sure what you were trying to code there, but this is the correct formula for a circular movement.
To calculate the rotation around a point, you need a center point for the rotation (cx, cy), the radius or distance of the point from the center, you need the angle (in radians, not degrees), and you need to use sine and cosine to calculate the offset of the point from the center as it rotates around it.
int cx, cy, radius; // I'll let you determine these
double theta = Math.toRadians(30);
double dtheta = Math.toRadians(-0.1);
double dx = Math.cos(theta) * radius;
double dy = Math.sin(theta) * radius;
int x = (int)(cx + dx);
int y = (int)(cy + dy);
repaint();
theta += dtheta; // step the angle
You program has some problems:
int x = 300;
int y = 500;
You should use a floating point data type like double to store the coordinates. You can cast them to int when you want to draw them. If you store them in int, you'll lose precision.
x += Math.sin(angle);
y--;
This doesn't work, since y is decremented instead of calculated using Math.sin(angle). (us Math.cos for x)
This is your fixed code (unchanged parts are omitted):
double x = 300;
double y = 500;
float angle = 30;
double radius = 10D; // new variable to increase the radius of the drawn circle
Game game;
// main method
// constructor
#Override
public void paint(Graphics g) {
// ... stuff omitted
g.fillOval((int)x, (int)y, 10, 10); // you can cast to int here
g.dispose();
}
#Override
public void run() {
while (true) {
angle -= 0.1; // is the same as `angle += -0.1`
x += radius * Math.cos(angle);
y += radius * Math.sin(angle);
repaint();
// ... try catch block
}
}
This currenlty draw the circle counter-clockwise. If you want to draw it clockwise, then change angle to:
angle += 0.1;
How can I draw in java figure like this?
Here is my code which has to draw at least half of this figure
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class Main {
public static void main(String[] a) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 300, 300);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}
class MyCanvas extends JComponent {
private static final long serialVersionUID = 1L;
public void paint(Graphics g) {
int i =0;
for ( i = 0; i < 100; i++) {
int x=1+i*3;
g.drawLine(x, 200, 2+(x+(i/2)), 400-((i*i)/20));
}
}
}
And I get this one.
A little animation to show you the logic you need to be looking for in terms of line rotation. Think of the line like a hand on a clock. How would to animate a hand on a clock. It's pretty much the exact same concept. The only difference is that the x1 (the x point for the center point of the clock hand), instead of remaining still, it moves along the x axis (which is the y1 constant) while the hand is turning. So for every tick of the clock (hand rotation), the x location is also moved horizontally. That's the way I looked at it.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Main {
public static void main(String[] a) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.getContentPane().add(new MyCanvas());
window.pack();
window.setVisible(true);
}
}
class MyCanvas extends JPanel {
int x1 = 0;
int rotate = 50;
List<Line> lines;
Timer timer = null;
public MyCanvas() {
lines = new ArrayList<>();
timer = new Timer(75, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (rotate < -50) {
((Timer) e.getSource()).stop();
} else {
lines.add(new Line(x1, rotate));
repaint();
x1 += 5;
rotate--;
}
}
});
JButton start = new JButton("Start the Magic");
start.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
add(start);
}
public Dimension getPreferredSize() {
return new Dimension(502, 400);
}
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
for (Line line : lines) {
line.drawLine(g);
}
}
class Line {
int x1;
int rotate;
int y1 = 200;
public Line(int x1, int rotate) {
this.x1 = x1;
this.rotate = rotate;
}
void drawLine(Graphics g) {
int Radius = (int) (Math.min(getWidth(), getHeight()) * 0.4);
int sLength = (int) (Radius * 0.9);
int xSecond = (int) (x1 + sLength * Math.sin(rotate * (2 * Math.PI / 100)));
int ySecond = (int) (y1 - sLength * Math.cos(rotate * (2 * Math.PI / 100)));
g.setColor(Color.GREEN);
g.drawLine(x1, y1, xSecond, ySecond);
}
}
}
Me so much :D
float centerY = 250;
float x1 = 0;
float x2 = 0;
float y2 = 400;
float way2 = 0;
for (int i = 0; i < 125; i++)
{
x2 += cos(way2*PI/-180)*10;
y2 += sin(way2*PI/-180)*10;
way2 += centerY/y2*0.235*10;
x1 += y2/600*10;
g.drawLine(x1,centerY,x2,y2);
}
Here's what I figured out, little different though :)
public void paint(Graphics g) {
for (int i = 0; i < 100; i++) {
int x = 1 + i * 3;
g.drawLine(x, 200, x + i, 400 - i * i / 20);
g.drawLine(600 - x, 200, 600 - (x + i), 400 - i * i / 20);
}
}
We need to rework on the function '400 - i * i / 20'.
For this program I'm required to recursively draw a 'pagoda', which is a series of diminishing rectangles, aligned centrally, stacked on top of each other. I think I've gotten the logic behind the actual figure, but I'm having trouble figuring out how to actually get the figure drawn as Rectangles with Graphics2D. I tried to shoehorn it into a basic shape drawing program and couldn't find out how to work recursion into it.
This is the code that I've written to this point, without taking graphics into account:
import java.awt.Rectangle;
public class PagodaDrawer
{
private int initialY; //Top of the bottom rectangle
private int initialHeight; //Height for the bottom rectangle
private double scale; //Amount to reduce each layer
public PagodaDrawer(int initialY, int initialHeight, double scaleFactor)
{
this.initialY = initialY;
this.initialHeight = initialHeight;
scale = scaleFactor;
}
public void drawPagoda()
{
drawLayer(0, initialY, 2 * initialHeight, initialHeight);
}
public void drawLayer(double x, double y, double width, double height)
{
if(y < 0 || height < 5) //If off the top of the screen, or less than 5 tall
{
return;
}
drawLayer(x - (((1 - scale)* x) / 2), y + (y * scale), width * scale, height * scale );
Rectangle r = new Rectangle((int)x, (int)y, (int)(2 * height), (int)height);
//Draw r?
}
}
How can I recursively draw layers of the figure in a frame?
EDIT:
For any interested, this is the final code
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PagodaDrawer extends JPanel
{
private int initialX;
private int initialY; //Top of the bottom rectangle
private int initialHeight; //Height for the bottom rectangle
private double scale; //Amount to reduce each layer
private boolean isRenderable;
private ArrayList<Rectangle> recs;
public PagodaDrawer(int initialX, int initialY, int initialHeight, double scaleFactor)
{
this.initialX = initialX;
this.initialY = initialY;
this.initialHeight = initialHeight;
scale = scaleFactor;
isRenderable = false;
recs = new ArrayList<Rectangle>();
}
public void drawPagoda()
{
drawLayer(initialX, initialY, 2 * initialHeight, initialHeight);
}
public void drawLayer(double x, double y, double width, double height)
{
if(y < 0 || height < 5) //If off the top of the screen, or less than 5 tall
{
isRenderable = true;
return;
}
drawLayer(x + .5 * (width - (width * scale)), y - (height * scale), width * scale, height * scale );
Rectangle r = new Rectangle((int)x, (int)y, (int)(2 * height), (int)height);
recs.add(r);
}
public void paintComponent(Graphics g)
{
if(!isRenderable)
return;
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for(int i = 0; i < recs.size(); i++)
{
g2.draw(recs.get(i));
System.out.println(recs.get(i));
}
}
}
Coupled with this JFrame:
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DisplayComponent extends JFrame
{
private static final long serialVersionUID = -4279682826771265863L;
private static final int FRAME_WIDTH = 500;
private static final int FRAME_HEIGHT = 500;
private JPanel panel;
private PagodaDrawer p;
public DisplayComponent(int initialHeight, double scaleFactor)
{
p = new PagodaDrawer(FRAME_WIDTH / 2, FRAME_HEIGHT, initialHeight, scaleFactor);
panel = new JPanel();
p.drawPagoda();
add(p);
pack();
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setVisible(true);
}
}
Instead of making drawLayer() recursive, write a recursive createRectangle() that adds each new Rectangle instance to a List<Rectangle>. Render the list in your implementation of paintComponent(), illustrated here.
In Java AWT and Swing you draw with Graphics / Graphics2D methods.
Example: graphics.fillRect(x, y, w, h);
You should get the graphics(?:2d) object from the component where you want to draw into, usually the main Frame or some Component.
Calling your drawings within paintComponent() of the frame should work fine like this:
How to use paintComponent in Java to paint multiple things, but rotate one?
Here is the Java6 docs:
http://docs.oracle.com/javase/6/docs/api/
I'm working on my first java game for a school project, and I'm having some problems drawing the graphics based on information in an array.
What I'm basically trying to do is to create a 2D array (matrix) which will store all the information about the world in which the player can move. So some elements in the array will contain a wall, others open space for the player to move in, and so on...
I have this sample code which I'm working from:
/**
*
* #author Rasztemberg
*/
package simpleGame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
/**
* GameBoard is a part of JPanel.
* It has a Graphical Object {#link Graphics}
* that can be used to render shapes etc. Pass it's reference to any object you
* want to display in the gameBoard panel.
*/
public class GameBoard extends JPanel implements KeyListener{
Player player;
Player enemy;
public GameBoard(){
// SETUP PLAYER ON THE BOARD;
int xPos = 0;
int yPos = 0;
int width = 20;
int height = 20;
Color playerC = Color.BLUE;
player = new Player(xPos, yPos, width, height, playerC);
// SETUP ENEMY ON THE BOARD;
enemy = new Player(100, 100, width, height, Color.RED);
addKeyListener(this);
}
/*
*
* JPanel function to display all gameBoard object graphics.
*/
#Override
public void paint(Graphics g){
super.paint(g); // Call it's parent for proper rendering.
player.display(g);
enemy.display(g);
}
#Override
public void keyTyped(KeyEvent e) {}
#Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT) {
player.moveLeft();
}
if (keyCode == KeyEvent.VK_RIGHT) {
player.moveRight();
}
if (keyCode == KeyEvent.VK_DOWN) {
player.moveDown();
}
if (keyCode == KeyEvent.VK_UP) {
player.moveUp();
}
}
#Override
public void keyReleased(KeyEvent e) {}
/**
* Set's focus on the panel so key events are catch.
*/
public boolean isFocusTraversable() {
return true;
}
}
And,
/**
* #author Rasztemberg
*/
package simpleGame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import javax.swing.JPanel;
/**
* This is main player Class.
*
*/
public class World {
// Snake parameters
private int x;
private int y;
private int width;
private int height;
private Color color;
/**
* Class constructor. Called when instantiated.
* Assigns x and y coordinates to position the player.
* Sets width, height and color to the rendered object.
*
*/
public World(int x, int y, int w, int h, Color c){
this.x = x;
this.y = y;
this.width = w;
this.height = h;
this.color = c;
}
/**
* Accepts Graphics object to render
* player 1 shape
*/
public void display(Graphics g) {
// This is player rendered graphics.
Graphics2D walls = (Graphics2D) g; // Graphical library to render shapes.
walls.setColor(color);
walls.drawRect(x, y, width, height);
walls.fillRect(x, y, width, height);
}
}
Now, I made this for loop to populate a test Array:
int[][] wallArray = new int[800][600];
for (int x = 0; x < wallArray.length; x++) {
for (int y = 0; y < wallArray.length; y++) {
wallArray[x][y] = 1;
}
}
wallArray[100][100] = 0;
greatWall = new World(wallArray);
Do you know how I could draw this array? I apologize for the length of the code...
Just paint something based on the array in your GameBoard's paint:
#Override
public void paint(Graphics g){
super.paint(g); // Call it's parent for proper rendering.
for (int i = 0; i<wallArray.length; i++)
for (int j = 0; j<wallArray[0].length; j++){
//do something for every field in the array
//i.e. g.setColor(Color.getColor(wallArray[i][j], 50, 50));
//g.drawLine(i,j,i,j);
}
player.display(g);
enemy.display(g);
}
But you should first go through some tutorial on Painting in Java:
http://www.oracle.com/technetwork/java/painting-140037.html
It is better to have the walls as
List<Rectangle> walls = new ArrayList<>();
That is more optimal, as you can simply do:
for (Rectangle rect: walls) {
g.fillRect(rect.x, rect.y, rect.width, rect.height);
}
Wall detection goes alike.
Well, as the title says, I am having trouble with double buffering. I read this Java Ebook and it doesn't give you code for what they are teaching you - at least not completely. So I have to do a lot of guess work.
Objective : Bouncing ball in an applet.
It's not working in the way that the ball is still flashing. Aka double buffering is failing to work.
I use three classes, ball class, double buffering class, and MainApplet class. MainApplet extends double buffering, and ball class extends MainApplet
import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
#SuppressWarnings("serial")
public class MainApplet extends DoubleBuffering implements Runnable {
public Ball ball;
public Graphics g;
private Thread ticker;
public boolean running = false;
public void init() {
setSize(100,100);
ball = new Ball(getWidth() / 5f, getHeight() / 4f, 1.5f,
2.3f, 12, Color.red);
moveBall();
}
public void run() {
while(running) {
try {
Rectangle bou = new Rectangle(getWidth(), getHeight());
ball.move(bou);
ball.update(getGraphics());
Thread.sleep(1000 / 15);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
repaint();
}
}
public void moveBall() {
start();
}
public synchronized void start() {
running = true;
ticker = new Thread(this);
ticker.setPriority(Thread.MIN_PRIORITY + 1);
ticker.start();
}
public synchronized void stop() {
running = false;
ticker.stop();
}
}
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
public class DoubleBuffering extends Applet
{
Image offScreenBuffer;
#SuppressWarnings("deprecation")
public void update(Graphics g)
{
System.out.println("We are buffing");
Graphics gr;
if (offScreenBuffer==null ||
(! (offScreenBuffer.getWidth(this) == this.size().width
&& offScreenBuffer.getHeight(this) == this.size().height)))
{
offScreenBuffer = this.createImage(size().width, size().height);
}
gr = offScreenBuffer.getGraphics();
System.out.println("Something else");
paint(gr);
g.drawImage(offScreenBuffer, 0, 0, this);
}
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
public class Ball extends MainApplet{
int size;
private Color color;
public float x, y, dx, dy;
public Ball ball;
public int width, height;
public Image offscreenImage;
public Graphics offscr;
private MainApplet ma;
Ball (float x, float y, float dx, float dy, int size,
Color color) {
this.x = x;
this.y = y;
this.dy = dx;
this.dy = dy;
this.color = color;
this.size = size;
}
public void draw (Graphics g) {
g.setColor(this.color);
g.fillOval((int) x, (int) y, size, size);
}
public void update(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
draw(g);
}
public void move(Rectangle bounds) {
// Add velocity values dx/dy to position to
// ball s new position
x += dx;
y += dy;
// Check for collision with left edge
if (x < bounds.x && dx < 0) {
dx = -dx;
x -= 2 * (x - bounds.x);
}
// Check for collision with right edge
else if (x + size > bounds.x + bounds.width &&
dx > 0) {
dx = -dx;
x -= 2 * ((x + size) - (bounds.x + bounds.width));
}
// Checks for collision with top edge
else if (y < bounds.y && dy < 0) {
dy = -dy;
y -= 2 * (y - bounds.y);
}
// Checks for collision with bottom edge
else if (y + size > bounds.y + bounds.height && dy >0) {
dy = -dy;
y -= 2 * ((y + size) - (bounds.y + bounds.width));
}
}
}
Note: I'm not too sure how this code will come out >.< it looks as if it's being choppy with the 'code:' function.
Anyways, don't hate too hard on my conventions, I'm still rather new. Tips and answers would be appreciated. Thanks.
Instead of calling Thread.Sleep() try using the swing Timer like this.
private Timer t;
public void moveBall() {
t = new Timer(1000/15, new ActionListener() {
public void actionPerformed(ActionEvent e) {
Rectangle bou = new Rectangle(getWidth(), getHeight());
ball.move(bou);
ball.update(getGraphics());
repaint();
}
});
t.start();
}
public void destroy() {
if(t!=null) t.stop();
super.destroy();
}
that should help at least a little bit.
I'm assuming the class DoubleBuffering is some tutorial class. I'm guessing it derives from Applet and not JApplet. If you use JApplet you will get double buffering by default.