I'm making an Ultimate Tic-Tac-Toe game. If you aren't familiar with the rules, that's fine. But the board layout is just a 3x3 of Tic-Tac-Toe boards. I need an algorithm, for lack of a better term, to make it so I can make x and y wherever I want and it will draw it there correctly.
int width = 67; // Note: I've determined this variable means a lot to this "algorithm" because changing it changed the lines dramatically.
g.drawRect(0, 0, x, y); // Changing this made the boxes go to the center, so this works
g.drawLine(width, 0, width, y);
g.drawLine(width*2, 0, width*2, y);
g.drawLine(0, width, x, width);
g.drawLine(0, width*2, x, width*2);
The Class Constructor calls for the x and y to be input, so those are varying.
Specifically, I want this to work no matter what I make the x and y coordinates be.
The last 4 lines in the code make the 4 intersection bars (shaped like a very large #).
Making 1: This works fine.
Making 2: The Horizontal(--) lines work, not the Vertical(|).
Making 3: Third box doesn't even show up.
Also note that these above 3 tests are just 1 row of Tic-Tac-Toe boards.
I also understand that width can not be a single value (like it is now) but changing it makes the lines go far from where they're supposed to be so I don't know what to change it to.
Please refer to the Java Platform documentation for the Graphics class. Specifically the documentation for the drawLine() method, and also the drawRect() method (although you don't strictly need drawRect() to accomplish the task).
Based on your description, it sounds like you want to reuse the four drawLine() statements from your code sample to create each of the nine small grids as well as the one big grid.
Assuming your calling code looks something like this:
int totalWidth = 200;
// draw big grid
drawGrid(g, 0, 0, totalWidth);
// draw small grids
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
drawGrid(g, totalWidth / 3 * i, totalWidth / 3 * j, totalWidth / 3);
}
}
Here's what I would do:
private void drawGrid(Graphics g, int x, int y, int width) {
// draw box around grid (not necessary)
//g.drawRect(x, y, width, width);
// draw vertical grid lines
g.drawLine(width / 3 + x, y, width / 3 + x, y + width);
g.drawLine(width / 3 * 2 + x, y, width / 3 * 2 + x, y + width);
// draw horizontal grid lines
g.drawLine(x, width / 3 + y, x + width, width / 3 + y);
g.drawLine(x, width / 3 * 2 + y, x + width, width / 3 * 2 + y);
}
Note this doesn't put any padding around the small grids, so it looks like one huge grid. I imagine you'll want to add some padding to make it look right. You'd do that from the calling code where it loops to create the small grids.
Um. Besides the fact that it appears your asking us to do the work for you...
I would suggest not even using the Java Graphics to draw the shape of an x and to draw the shape of an o (it'll make your program all dirty, but you know.. whatever this is a tutorial). Rather, I would a series of panels JTextAreas. Give them a giant font, and make their 'isFocusable()' boolean to false. Then, I would add mouse listeners to each of them, so whenever the mouse clicks the JTextArea, it runs a method. I will write a method for you here, it's very simple. It will take one parameter, a JTextArea. This will be the area that was clicked, which can be easily be found out, because you'll be calling this method inside the mouseListener's mousePressed() method. Bare in mind, this will require a mouseListener for all 9 of your JTextAreas. This method also assumes you have created two booleans, one for the first player and one for the second. If it is Player1's turn, this method will find out, then change the turn to Player2's and vise versa. ****NOTE**** make sure you set the value of Player1 to true when you create it, or at least before this method is called.
public void makingMove(JTextArea jta) {
if (player1) {
jta.setText("x");
player1 = false;
player2 = true;
}
if (player2) {
jta.setText("o");
player1 = true;
player2 = false;
}
}
Hmm will this work? NO! what if you click a JTextArea that already has a letter in it? it'll replace it! We can't have that! so, now we need to change up our makingMove method, so we know we don't break any rules:
public void makingMove(JTextArea jta) {
if (jta.getText() == null) {
if (player1) {
jta.setText("x");
player1 = false;
player2 = true;
}
if (player2) {
jta.setText("o");
player1 = true;
player2 = false;
}
}
else {
JOptionPane.showMessageDialog(null, "You can't move there, someone already has!");
}
}
Done right? WRONG! Now we need to create a method that will check to see if anyone has won yet!
We will call this after our else statement in our makingMove() method. Like so:
.....
}
else {
JOptionPane.showMessageDialog(null, "You can't move there, someone already has!");
}
checkWinnerX(1, 2, 3, 4, 5, 6, 7, 8, 9);
checkWinnerY(1, 2, 3, 4, 5, 6, 7, 8, 9);
}
The checkWinnerX method will have to take 9 parameters, same with our checkWinnerO method. Each input object will be a JTextArea, so we can compare their input. This method assumes, your JTextAreas are named 1-9, counting like it would be a phone's dialpad. In addition, we have our checkWinnerX and checkWinnerO methods calling a method to clear everything, and reset the game, which you can assign to a button if you'd like, but I would definitely recommend having one.
*****NOTE******
I will not write the checkWinnerO method because it is the same as the checkWinnerX, but with all o's instead. and I'm sure you get the idea. AND this is an EXTREMELY inefficient way of handling this, but oh well.
public static void checkWinnerX(JTextArea 1, JTextArea 2, etc.. up to 9) {
if (1.equals("x") && 2.equals("x") && 3.equals("x")) {
JOptionPane.showMessageDialogue(null, "The winner is X!");
clear();
}
if (4.equals("x") && 5.equals("x") && 6.equals("x")) {
JOptionPane.showMessageDialogue(null, "The winner is X!");
clear();
}
if (7.equals("x") && 8.equals("x") && 9.equals("x")) {
JOptionPane.showMessageDialogue(null, "The winner is X!");
clear();
}
if (1.equals("x") && 2.equals("x") && 3.equals("x")) {
JOptionPane.showMessageDialogue(null, "The winner is X!");
clear();
}
if (1.equals("x") && 5.equals("x") && 9.equals("x")) {
JOptionPane.showMessageDialogue(null, "The winner is X!");
clear();
}
if (7.equals("x") && 5.equals("x") && 3.equals("x")) {
JOptionPane.showMessageDialogue(null, "The winner is X!");
clear();
}
if (1.equals("x") && 4.equals("x") && 7.equals("x")) {
JOptionPane.showMessageDialogue(null, "The winner is X!");
clear();
}
if (2.equals("x") && 5.equals("x") && 8.equals("x")) {
JOptionPane.showMessageDialogue(null, "The winner is X!");
clear();
}
if (3.equals("x") && 6.equals("x") && 9.equals("x")) {
JOptionPane.showMessageDialogue(null, "The winner is X!");
clear();
}
}
public static void clear() {
1.setText(null);
2.setText(null);
3.setText(null);
4.setText(null);
5.setText(null);
6.setText(null);
7.setText(null);
8.setText(null);
9.setText(null);
}
Now if you've got your mouseListeners set up correctly, and you use GridBagConstraints to correctly format your playing board. You pretty much have it done.
I could make this a thousand ways, using a thousand different methods and objects and blah, I chose this way because you specified you wanted an 'algorithm' for it. Now, you should be able to refer to this VERY broken down tutorial of a not-so-great way of making this game, and write your own code for it.
Hope this helps.
If I understand you correctly, you want a 3 x 3 grid of tic tac toe boards.
Here's a quick Swing application that draws a 3 x 3 grid of tic tac toe boards. 9 tic tac toe boards on 9 panels.
And here's the code. The drawing code is in the DrawingPanel class.
package com.ggl.testing;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TicTacToe implements Runnable {
private JFrame frame;
private List<DrawingPanel> drawingPanels;
public TicTacToe() {
this.drawingPanels = new ArrayList<>();
}
#Override
public void run() {
frame = new JFrame();
frame.setTitle("Ultimate Tic Tac Toe");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent event) {
exitProcedure();
}
});
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(3, 3, 10, 10));
for (int i = 0; i < 9; i++) {
DrawingPanel drawingPanel = new DrawingPanel();
mainPanel.add(drawingPanel);
drawingPanels.add(drawingPanel);
}
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private void exitProcedure() {
frame.dispose();
System.exit(0);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new TicTacToe());
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = -3774580797998095321L;
public DrawingPanel() {
this.setPreferredSize(new Dimension(170, 170));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(5.0F));
Rectangle r = new Rectangle(0, 0, getWidth(), getHeight());
int sectionWidth = r.width / 3;
int sectionHeight = r.height / 3;
g2d.setColor(Color.BLACK);
g2d.drawLine(r.x, r.y + sectionHeight,
r.x + r.width, r.y + sectionHeight);
g2d.drawLine(r.x, r.y + sectionHeight + sectionHeight,
r.x + r.width, r.y + sectionHeight + sectionHeight);
g2d.drawLine(r.x + sectionWidth, r.y, r.x + sectionWidth,
r.y + r.height);
g2d.drawLine(r.x + sectionWidth + sectionWidth, r.y,
r.x + sectionWidth + sectionWidth, r.y + r.height);
}
}
}
Related
I'm a noob programmer, and I'm working on a little project that involves a 2D grid of 1000 x 1000 boolean values that change based on an instruction pattern. "After x instructions, how many values in the grid are true?" That kind of thing.
I want to put a little spin on it and render the values as a grid of pixels which are black if their corresponding values are false and white if they're true and that animates in real time as instructions are processed, but I'm pretty lost -- I've never dabbled with 2D graphics in Java. I've read through Oracle's tutorial, which helped, but the way I'm doing things is sufficiently different from its demo that I still feel lost.
My most immediate problem is that I can't even seem to initialize a grid of 1000 x 1000 black pixels using a BufferedImage. Running my code yields a very tiny window with nothing (grayness) in it. Can anyone tell me what I'm doing wrong and suggest how to proceed? My code follows:
import java.awt.image.BufferedImage;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PixelGrid extends JPanel {
private BufferedImage grid;
// Ctor initializing a grid of binary (black or white) pixels
public PixelGrid(int width, int height) {
grid = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
}
/**
* Fill an area with a given color
* #param color 0 for black; 1 for white
* #param x1 Starting x coordinate
* #param y1 Starting y coordinate
* #param x2 Ending x coordinate
* #param y2 Ending y coordinate
*/
public void toggleBlock(int color, int x1, int y1, int x2, int y2) {
if (color == 0) {
color = Color.BLACK.getRGB();
}
else {
color = Color.WHITE.getRGB();
}
for (int x = x1; x <= x2; x++) {
for (int y = y1; y <= y2; y++) {
grid.setRGB(x, y, color);
}
}
}
// Clear the grid (set all pixels to black)
public void clear() {
toggleBlock(0, 0, 0, grid.getWidth() - 1, grid.getHeight() - 1);
}
public static void main(String[] args) {
int width = 1000;
int height = 1000;
PixelGrid aGrid = new PixelGrid(width, height);
JFrame window = new JFrame("A Wild Pixel Grid Appears!");
window.add(aGrid); // Incorporates the pixel grid into the window
window.pack(); // Resizes the window to fit its content
window.setVisible(true); // Makes the window visible
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Note that it doesn't yet deal at all with an actual 2D array of booleans or instruction processing; I'm pretty sure I can handle that on my own, but, for now, I'm just trying to understand how to set up the graphical component.
Your code creates a BufferedImage, but then doesn't do anything with it (graphically). A few options:
Option 1: Override paintComponent of the PixelGrid class and draw the image to the JPanel
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(grid, 0, 0, this);
}
Option 2: Use a JLabel and ImageIcon
JLabel label = new JLabel(new ImageIcon(grid));
add(label);
In either case, you will have to call repaint on the Component every time the BufferedImage is changed
//some code
grid.setRGB(x, y, color);
//some more code
repaint();//or label.repaint() if Option 2
Just started messing around with Swing for a class project GUI in Java. I'm trying to draw a game board, however, not a conventional one. I'm trying to draw one more like a parchessi board, so each board tile needs to have a specific location rather than a grid.
So far, I've run into this issue. In paint(), I'm trying to paint 5 rectangles, odd ones blue and empty, even ones red and filled in. However, instead of a nice checkered pattern, I get this:
Can anyone help me figure out why it's doing this?
Code:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Rectangles extends JPanel {
public static void main(String[] a) {
JFrame f = new JFrame();
f.setSize(800, 800);
f.add(new Rectangles());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
public void paint(Graphics g) {
int x = 15;
int y = 15;
int w = 15;
int h = 15;
for(int i = 0; i < 5; i++){
if(i%2==0){
g.setColor(Color.RED);
g.fillRect (x, y, x+w, y+h);
}
else{
g.setColor(Color.BLUE);
g.drawRect (x, y, x+w, y+h);
}
x+=15;
System.out.println(Integer.toString(x) + ' ' + Integer.toString(y) + '|' + Integer.toString(w) + ' ' + Integer.toString(h));
}
}
}
Output from the Println statement(x,y,width,height):
30 15|15 15
45 15|15 15
60 15|15 15
75 15|15 15
90 15|15 15
It looked like there was overlap in the first image, so I modified the code and tried this:
for(int i = 0; i < 5; i++){
g.setColor(Color.BLUE);
g.drawRect (x, y, x+w, y+h);
x+=15;
}
Here's what happens with this code:
Why is there overlap? What causes this?
Also, does anyone know a good way to make an easily modifiable array of Rectangles? Or any good advice or tools for drawing that type of board?
Welcome to the reasons you should not break the paint chain...
Start by calling super.paint(g) as the first line of your paint method, before you do any custom painting.
A better solution would be to override paintComponent instead of paint, but still making sure you call super.paintComponent before you perform any custom painting...
Take a look at Performing Custom Painting and Painting in AWT and Swing for more details
Next, start reading the JavaDocs on Graphics#fillRect, you will see that the last two parameters represent the width and height, not the x/y position of the bottom corner
public class Rectangles extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 15;
int y = 15;
int w = 15;
int h = 15;
for (int i = 0; i < 5; i++) {
if (i % 2 == 0) {
g.setColor(Color.RED);
g.fillRect(x, y, w, h);
} else {
g.setColor(Color.BLUE);
g.drawRect(x, y, w, h);
}
x += 15;
System.out.println(Integer.toString(x) + ' ' + Integer.toString(y) + '|' + Integer.toString(w) + ' ' + Integer.toString(h));
}
}
}
I am making a Java applet for school whose function is to randomly select six numbers for coordinates of three points and connect them to make a triangle. It is only supposed to draw one triangle and find the "length of the sides". However when I put it on my website it will redraw itself multiple times.
I made another applet, simpler, that only selects 4 random numbers for coordinates to draw a line. Same problem.
The redrawing problem seems to happen when the user moves the screen, e.g. when I scroll or when I resize the applet viewer in Eclipse. My source code is posted here.
I appreciate any help! Thanks!
import javax.swing.JApplet;
import java.awt.*;
#SuppressWarnings("serial")
public class LineApplet extends JApplet {
/**
* Create the applet.
*/
static int width;
int height;
public void init() {
width = getSize().width;
height = getSize().height;
}
public static int[] randomLine() {
int[] pointArray = new int[4];
int x;
for (int i = 0; i < 4; i++) {
x = ((int)(Math.random()*(width/10-2)))*20+10;
pointArray[i] = x;
}
return pointArray;
}
public void paint(Graphics g) {
g.setColor(Color.blue);
int[] coords = new int[4];
coords = randomLine();
g.drawLine(coords[0], coords[1], coords[2], coords[3]);
g.drawString(coords[0]/10 + ", " + coords[1]/10, coords[0], coords[1]);
g.drawString(coords[2]/10 + ", " + coords[3]/10, coords[2], coords[3]);
int midpointx = (coords[0] + coords[2])/2;
int midpointy = (coords[1] + coords[3])/2;
g.drawString(midpointx/10 + ", " + midpointy/10, midpointx, midpointy);
}
}
As pointed out by Reimues, you are re-generating your coords each time the applet is repaint.
The other problem with your paint method is actually you're not clear the previous state of the graphics context (this would have being done by paint, but you failed to respect it's functionality when you overrode it).
You have two choices.
call super.paint(g)
call super.paint(g) and call Graphics#clearRect(int, int, int, int) or Graphics#fillRect(int, int, int, int)
You should also, very rarely, need to override the paint method of top level containers. One of the reasons is that they're not double buffered, the other is the paint chain is complex and easily broken...
You're better off using a JPanel (or such) and overriding the paintComponent method instead...
UPDATED
I updated your code to demonstrate the issues.
public class TestBadApplet extends JApplet {
public void init() {
}
#Override
public void start() {
final LinePane linePane = new LinePane();
setLayout(new BorderLayout());
JButton update = new JButton("Update");
add(linePane);
add(update, BorderLayout.SOUTH);
update.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
linePane.regenerate();
}
});
}
protected class LinePane extends JPanel {
private int[] coords = new int[4];
public void regenerate() {
coords = randomLine();
repaint();
}
public int[] randomLine() {
int[] pointArray = new int[4];
int x;
for (int i = 0; i < 4; i++) {
x = ((int) (Math.random() * (Math.min(getWidth(), getHeight()) / 10 - 2))) * 20 + 10;
pointArray[i] = x;
}
return pointArray;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.blue);
g.drawLine(coords[0], coords[1], coords[2], coords[3]);
g.drawString(coords[0] / 10 + ", " + coords[1] / 10, coords[0], coords[1]);
g.drawString(coords[2] / 10 + ", " + coords[3] / 10, coords[2], coords[3]);
int midpointx = (coords[0] + coords[2]) / 2;
int midpointy = (coords[1] + coords[3]) / 2;
g.drawString(midpointx / 10 + ", " + midpointy / 10, midpointx, midpointy);
}
}
}
With super.paintComponent
Without super.paintComponent
You are calculating new co-ordinates every time paint() is called.
paint() is called every time the applet window is resized or regains focus.
To fix, you could make
int[] coords = new int[4];
a class member variable and move
coords = randomLine();
to your init() method, which will only be called once upon initialization.
Addendum:
Always call super.paint(g); when overriding paint().
For custom painting using Swing, the preferred approach is to extends a JComponent component leveraging the enhanced paint functionality offered by using paintComponent.
For more see: Performing Custom Painting.
The trouble seems to be that paint() is called every time the component needs repainting.
paint() methods should be written in a way that doesn't produce side effects and they shouldn't change the internal state of the applet. paint() must be restricted to doing just that: painting.
Hello all I have this problem that I can't seem to fix. I've been given some code and have to make a "tic tac toe" game. Fairly primitive. At the moment what it want's me to do is take user input (it just asks for what row / column you want to place the marker) and it is meant to draw an oval on the appropriate square of the board. My current code is as following the work has specified that I make a new class to deal with user input.
I am currently just mucking around with trying to get it to add new items to the JFrame but am having little success. I have a dummy call for input, it doesn't check to see what I've typed it just calls an oval that SHOULD sit in the first square in the top left corner. I can get the object to draw onto the JFrame (albeit it takes up the whole frame) but it is always BEHIND the actual board (ie: if I stretch the frame I can see the circle). I've tried adding JPanels and so forth so that they sit on top of the board but so far I am having little luck.
Here is the code for creating the Oval which I was given for the task. All I am doing is instantiating a new oval with position (0,0,10,10). When it draws however it takes up the WHOLE JFrame but it is also BEHIND the actual board...... any ideas?
package lab4;
import javax.swing.*;
import java.awt.*;
/** Oval Supplier Class
* Author: David D. Riley
* Date: April, 2004
*/
public class Oval extends JComponent {
/** post: getX() == x and getY() == y
* and getWidth() == w and getHeight() == h
* and getBackground() == Color.black
*/
public Oval(int x, int y, int w, int h) {
super();
setBounds(x, y, w, h);
setBackground(Color.black);
}
/** post: this method draws a filled Oval
* and the upper left corner of the bounding rectangle is (getX(), getY())
* and the oval's dimensions are getWidth() and getHeight()
* and the oval's color is getBackground()
*/
public void paint(Graphics g) {
g.setColor( getBackground() );
g.fillOval(0, 0, getWidth()-1, getHeight()-1);
paintChildren(g);
}
}
EDIT: THIS IS NOW THE CODE WE ARE LOOKING AT--
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package lab4;
/**
*
* #author Scott
*/
import java.awt.*;
import java.util.Scanner;
import javax.swing.*;
public class GameBoard {
private JFrame win;
private int count = 1;
//Create new GUI layout
GridLayout layout = new GridLayout(3, 3);
JPanel panel = new JPanel(layout);
//Create a new Array of Rectangles
Rectangle[][] rect = new Rectangle[3][3];
public GameBoard() {
//Create new JFrame + Set Up Default Behaviour
win = new JFrame("Tic Tac Toe");
win.setBounds(0, 0, 195, 215);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setResizable(true);
//Loop goes through each line of the array. It creates a new rectangle
//determines it's colour based on modulus division
//Add's the rectangle to the JPanel.
for (int i = 0; i < rect.length; i++) {
for (int j = 0; j < rect[i].length; j++) {
rect[i][j] = new Rectangle(0, 0, 1, 1);
if (count % 2 != 0) {
rect[i][j].setBackground(Color.black);
} else {
rect[i][j].setBackground(Color.red);
}
panel.add(rect[i][j]);
count++;
}
}
//Sets the game to be visible.
win.add(panel);
win.setVisible(true);
//userInput();
}
private void userInput() {
Scanner scan = new Scanner(System.in);
}
}
Let's start with your oval class...
This is a VERY bad idea...
public void paint(Graphics g) {
// No super.paint(g) call, hello to a world of pain...
// Paint some stuff
g.setColor( getBackground() );
g.fillOval(0, 0, getWidth()-1, getHeight()-1);
// Then draw the children over it...???
paintChildren(g);
}
This is a better approach.
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor( getBackground() ); // Might want to pick a better color...
g.fillOval(0, 0, getWidth()-1, getHeight()-1);
}
At a guess, I suggest that your window is using a layout manager that is overriding your setBounds call
Answer ended up being that I need to stick with the flow layout, manually size the rectangles and use a JLayeredPane instead. Was not aware this existed, talked to my lecturer who said that my thought process was right and that was the way he intended for me to do it......what a pain but all done thanks to those that helped.
I'm creating a small space invaders project and I have the aliens constantly in a left to right loop. When they hit the end of the screen they repaint on the right side going again left to right. I have set the window size already and I have looked at various tutorials on how to make space invaders in Java, however most of them say the same thing that I have tried. Is it possible someone can point out where I am going wrong with my coding so that I know how to fix it.
This is the code for the alien class. There are different aliens, however all the classes look pretty much the same as this one:
package spaceinvaders2;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
class Alien extends MoveObject
{
Image Alien = new ImageIcon(getClass().getResource("alien.gif")).getImage();
Alien(int x, int y, int w, int h)
{
super(x, y);
bounds.width = w;
bounds.height = h;
}
public void paint(Graphics g)
{
System.out.println("Alien generated");
bounds.x = bounds.x - 2;
if ((bounds.x + bounds.width)< 0)
{
bounds.x = 750;
dead = false;
}
g.drawImage(Alien,bounds.x,bounds.y,bounds.width, bounds.height, this);
}
}
Edit: My paint method is being called in the main game functionality part where it draws all the graphics. The drawing isn't the problem it is the movement of the alien which is in this class.
I think the paint Method ist just running once.
You have to add a thread to call the paint() method periodi.
You need to give the Alien a direction attribute (+1 or -1) which tells it which direction it is moving in. When it is about to go off-screen, flip the direction. For example, if the direction was +1 change it to -1 and vice versa.
Here is a simple example I created:
public class Alien extends JPanel
private int x = 5;
private int y = 5;
private int direction = 1;
#Override
public void paint(Graphics g) {
super.paint(g);
g.clearRect(x, y, getWidth(), getHeight());
// draw the alien.
g.drawRect(x, y, 10, 10);
// move it
x = x + 5 * direction;
// is it about to go off-screen?
if (x < 0 || x + 10 > getWidth()) {
// change the direction
direction *= -1;
}
}
}
According to your comment, you want the aliens to move from left to right once they hit the screen boundaries, instead of re-entering at the other side.
The solution is simple, you have to keep track of the direction of the alien. An easy way to do this is to make it's step size a variable.
You give your Alien class a step member like this:
int step = -2;
Then:
bounds.x = bounds.x + direction;
if ((bounds.x + bounds.width)< 0)
{
step = +2;
}
else if ((bounds.x - bound.width) > 750)
{
step = -2;
}
dead = false;
g.drawImage(Alien,bounds.x,bounds.y,bounds.width, bounds.height, this);
Off-topic, I think the dead = false doesn't belong in your paint method.