Java Hangman Game - java
Hi I've been making a hangman game in Java over ther holidays. Im almost done, but i'm having a few problems with repainting/updating the window.
So when ever a life is lost, I'm removing the panel and then adding another one, but for some reason it keeps shifting to the left or sometimes to the right, which means some of my lines are n't being redrawn.
edit: I'm still having trouble, I think I will just leave it now, unless anyone else has some other suggestions.
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
/** class to display a JFrame object using border layout */
public class HangmanJFrame extends JFrame implements ActionListener {
private JPanel centerPanel;
private JPanel southPanel;
private JTextField textField;
private LinePanel line;
private String [] wordList = {"computer","java","activity","alaska","appearance","article",
"automobile","basket","birthday","canada","central","character","chicken","chosen",
"cutting","daily","darkness","diagram","disappear","driving","effort","establish","exact",
"establishment","fifteen","football","foreign","frequently","frighten","function","gradually",
"hurried","identity","importance","impossible","invented","italian","journey","lincoln",
"london","massage","minerals","outer","paint","particles","personal","physical","progress",
"quarter","recognise","replace","rhythm","situation","slightly","steady","stepped",
"strike","successful","sudden","terrible","traffic","unusual","volume","yesterday" };
public ArrayList<String> usedLetters = new ArrayList(); // list of used letter by user
public ArrayList<String> correctLetters = new ArrayList();
public String userInput = "";
private int numLives = 6; // number of lives
public String theWord; // the wrong which is chosen
JButton exitButton;
JButton playAgain;
// no-argument constructor
public HangmanJFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theWord = pickWord();
correctLetters = new ArrayList(theWord.length());
setSize(600,500);
setLocation(100, 100);
setTitle("Hangman Game");
setLayout(new BorderLayout());
centerPanel = new JPanel();
line = new LinePanel(15,theWord,usedLetters);
centerPanel.setSize(500,500);
centerPanel.setBackground(Color.WHITE);
centerPanel.add(line);
add(centerPanel, BorderLayout.CENTER);
textField = new JTextField(20);
textField.addActionListener(this);
playAgain = new JButton("Play Again");
exitButton = new JButton("Exit");
exitButton.addActionListener(this);
playAgain.addActionListener(this);
southPanel = new JPanel();
southPanel.setBackground(Color.BLACK);
southPanel.setLayout(new GridLayout(0,3));
southPanel.add(playAgain);
southPanel.add(textField);
southPanel.add(exitButton);
add(southPanel, BorderLayout.SOUTH);
}
// Picks a word, latter it will be picked randomly.
private String pickWord(){
return wordList[0];
}
// This method check wither the input is valid
// i.e. its in the alphabet.
private boolean checkInput(String s){
String [] alphabet = {"a","b","c","d","e","f",
"g","h","i","j","k","l","m","n","o","p",
"q","r","s","t","u","v","w","x","y","z"};
for (int i = 0; i < alphabet.length; i++){
if (s.equals(alphabet[i]) && s.length() <= 1){
return true;
}
}
return false;
}
/**
*
*/
public void Play(){
if (numLives > 0){
if (userInput.length() == 1 && usedLetters.contains(userInput) == false &&
checkInput(userInput) == true){
usedLetters.add(userInput);
if (theWord.contains(userInput) == true){
correctLetters.add(userInput);
centerPanel.removeAll();
line = new LinePanel(20,theWord,correctLetters);
centerPanel.add(line);
centerPanel.revalidate();
}
else{
numLives = numLives - 1;
centerPanel.removeAll();
line = new LinePanel(numLives,theWord,correctLetters);
centerPanel.add(line);
centerPanel.revalidate();
}
}
else if (userInput.length() > 1)
System.out.println("Enter a valid letter");
else if (userInput.length() == 1 && checkInput(userInput) == true && theWord.contains(userInput)){
correctLetters.add(userInput);
}
centerPanel.removeAll();
line = new LinePanel(20,theWord,usedLetters);
centerPanel.add(line);
centerPanel.revalidate();
}
}
// return true if the word and the correctly used letters list match
public boolean checkWord(String s, ArrayList<String> t){
String temp = "";
for (int i = 0; i < s.length(); i++){
if ( t.contains(s.substring(i, i+1)) == true){
temp += s.substring(i, i+1);
}
}
if (s.equals(temp)){
return true;
}
return false;
}
public void actionPerformed(ActionEvent evt) {
String temp = textField.getText();
if (temp.length() == 1){
userInput = temp;
}
textField.selectAll();
if (checkWord(theWord, correctLetters) != true){
Play();
}
if (evt.getSource() == exitButton){
System.exit(0);
}
// if (evt.getSource() == playAgain){
// removeAll();
// repaint();
//
// }
}
}
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import javax.swing.JPanel;
public class LinePanel extends JPanel {
int x = 5;
String theWord = "";
ArrayList<String> letterList;
public LinePanel(int num, String t, ArrayList<String> s) {
super(); // 300,350
setPreferredSize(new Dimension(400,400));
setBackground(Color.RED);
this.x = num;
this.theWord = t;
letterList = cloneList(s);
}
private ArrayList<String> cloneList(ArrayList<String> aList) {
ArrayList<String> clonedList = new ArrayList<String>(aList.size());
for (String letter : aList)
clonedList.add(letter);
return clonedList;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (x == 15 || x != 15){
Line2D line = new Line2D.Double(0, 250, 80, 250); // Creates base
Line2D line2 = new Line2D.Double(40, 50, 40, 250); // Creates vertical line
Line2D line3 = new Line2D.Double(40, 50, 150, 50); // Creates horizontal line
Line2D line4 = new Line2D.Double(150, 50, 150, 80); // Creates small line to hang the man
g2.setStroke(new BasicStroke(5.0f)); // Line thickness
g2.setColor(Color.BLACK); // Line colour
//draw shape of line
g2.draw(line);
g2.draw(line2);
g2.draw(line3);
g2.draw(line4);
int x1 = 0; int y = 320;
for (int i = 0; i < theWord.length();i++){
g2.drawLine(x1, y, x1 + 20, y);
x1 += 50;
}
}
// head
if (x == 5 || x < 5){
System.out.println("uheuheuha");
g2.setStroke(new BasicStroke(5.0f));
g2.drawOval(135, 85, 35, 35);
}
// body
if (x == 4 || x < 4){
g2.drawLine(150, 120, 150, 190);
}
// left arm
if (x == 3 || x < 3){
g2.drawLine(150, 140, 125, 155);
}
// right arm
if (x == 2 || x < 2){
g2.drawLine(150, 140, 175, 155);
}
// left leg and foot
if (x == 1 || x < 1){
g2.drawLine(150, 190, 125, 200); // leg
g2.drawLine(125, 200, 120, 190); // foot
}
// right leg and foot
if (x == 0){
g2.drawLine(150, 190, 175, 200); // leg
g2.drawLine(175, 200, 180, 190); // foot
}
// Show whole word on screen
if (x == 20){
int x1 = 3; int y = 317;
String temp = "";
for (int i = 0; i < theWord.length(); i++){
if ( letterList.contains(theWord.substring(i, i+1)) == true){
temp += theWord.substring(i, i+1);
}
else{
temp += " ";
}
}
for (int i = 0; i < temp.length() ;i++){
g2.setColor(Color.BLACK);
Font font = new Font("Arial", Font.PLAIN, 25);
g2.setFont(font);
g2.drawString(temp.substring(i, i+1), x1, y);
x1 += 50;
}
x1 = 3; y = 370;
for (int i = 0; i < letterList.size() ;i++){
if (theWord.contains(letterList.get(i)) == false){
g2.drawString(letterList.get(i), x1, y );
x1 += 50;
}
}
}
}
}
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import javax.swing.JPanel;
public class LinePanel extends JPanel {
int x = 5;
String theWord = "";
ArrayList<String> letterList;
public LinePanel(int num, String t, ArrayList<String> s) {
super(); // 300,350
setPreferredSize(new Dimension(400,400));
setBackground(Color.RED);
this.x = num;
this.theWord = t;
letterList = cloneList(s);
}
private ArrayList<String> cloneList(ArrayList<String> aList) {
ArrayList<String> clonedList = new ArrayList<String>(aList.size());
for (String letter : aList)
clonedList.add(letter);
return clonedList;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (x == 15 || x != 15){
Line2D line = new Line2D.Double(0, 250, 80, 250); // Creates base
Line2D line2 = new Line2D.Double(40, 50, 40, 250); // Creates vertical line
Line2D line3 = new Line2D.Double(40, 50, 150, 50); // Creates horizontal line
Line2D line4 = new Line2D.Double(150, 50, 150, 80); // Creates small line to hang the man
g2.setStroke(new BasicStroke(5.0f)); // Line thickness
g2.setColor(Color.BLACK); // Line colour
//draw shape of line
g2.draw(line);
g2.draw(line2);
g2.draw(line3);
g2.draw(line4);
int x1 = 0; int y = 320;
for (int i = 0; i < theWord.length();i++){
g2.drawLine(x1, y, x1 + 20, y);
x1 += 50;
}
}
// head
if (x == 5 || x < 5){
g2.setStroke(new BasicStroke(5.0f));
g2.drawOval(135, 85, 35, 35);
}
// body
if (x == 4 || x < 4){
g2.drawLine(150, 120, 150, 190);
}
// left arm
if (x == 3 || x < 3){
g2.drawLine(150, 140, 125, 155);
}
// right arm
if (x == 2 || x < 2){
g2.drawLine(150, 140, 175, 155);
}
// left leg and foot
if (x == 1 || x < 1){
g2.drawLine(150, 190, 125, 200); // leg
g2.drawLine(125, 200, 120, 190); // foot
}
// right leg and foot
if (x == 0){
g2.drawLine(150, 190, 175, 200); // leg
g2.drawLine(175, 200, 180, 190); // foot
}
// Show whole word on screen
if (x == 20){
int x1 = 3; int y = 317;
String temp = "";
for (int i = 0; i < theWord.length(); i++){
if ( letterList.contains(theWord.substring(i, i+1)) == true){
temp += theWord.substring(i, i+1);
}
else{
temp += " ";
}
}
for (int i = 0; i < temp.length() ;i++){
g2.setColor(Color.BLACK);
Font font = new Font("Arial", Font.PLAIN, 25);
g2.setFont(font);
g2.drawString(temp.substring(i, i+1), x1, y);
x1 += 50;
}
x1 = 3; y = 370;
for (int i = 0; i < letterList.size() ;i++){
if (theWord.contains(letterList.get(i)) == false){
g2.drawString(letterList.get(i), x1, y );
x1 += 50;
}
}
}
}
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class PlayHangman {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
HangmanJFrame window = new HangmanJFrame();
window.setVisible(true);
}
}
Don't remove and add the panel. Just change the variable that stores the lives left and force a repaint.
Although I couldn't really test with your code I have two vague ideas:
Keep in mind, that updates of swing and/or awt components should always be executed in the correct thread. Consider some tests with invokeLater:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// do your display modifications here
}
});
You could try to use invalidate/validate on your panels, that might help java to realize, that something changed.
I hope this helps solving your problem - good luck!
Related
How to give each cloud an individual x position so that I could draw it based on that
So basically I have a scenery project where I created a list of "clouds" based on the constructor in my Cloud class. Each time I created a list of those clouds I am generating a random number for x. When I draw the cloud it has that x value. In the animation I am adding the cloud's x-axis and I want to make it so that each time an individual cloud's x-axis is more than 800 they go to -150. I thought I did it right, but for some reason the clouds are moving really fast :( 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 java.util.concurrent.ThreadLocalRandom; import javax.swing.JButton; import javax.swing.JPanel; public class Scenery extends JPanel implements ActionListener { private RainSnowDrop[] rain, snow; private Cloud[] cloud; private double cloudX; private Background background; private Tree[] tree; private Mountain mountain; private JButton fallB, winterB, springB, summerB; private boolean fall, winter, spring, summer; private Color skyColor, grassColor, treeColor, treeStickColor, mountainColor; int[] getXs = new int[7]; public Scenery() { setLayout(null); fallB = new JButton("Fall"); fallB.setBounds(50, 475, 80, 40); fallB.addActionListener(this); add(fallB); winterB = new JButton("Winter"); winterB.setBounds(250, 475, 80, 40); winterB.addActionListener(this); add(winterB); springB = new JButton("Spring"); springB.setBounds(450, 475, 80, 40); springB.addActionListener(this); add(springB); summerB = new JButton("Summer"); summerB.setBounds(650, 475, 80, 40); summerB.addActionListener(this); add(summerB); skyColor = (Color.WHITE); grassColor = (Color.WHITE); treeColor = (Color.WHITE); treeStickColor = (Color.WHITE); mountainColor = (Color.WHITE); snow = new RainSnowDrop[200]; rain = new RainSnowDrop[200]; tree = new Tree[5]; cloud = new Cloud[7]; background = new Background(); mountain = new Mountain(); for (int i = 0; i < rain.length; i++) { rain[i] = new RainSnowDrop(); } for (int i = 0; i < snow.length; i++) { snow[i] = new RainSnowDrop(); } for (int i = 0; i < tree.length; i++) { tree[i] = new Tree(); } for (int i = 0; i < cloud.length; i++) { cloud[i] = new Cloud(); getXs[i] = Cloud.xs.get(i); } setFocusable(true); } public Dimension getPreferredSize() { return new Dimension(800, 600); } public void paintComponent(Graphics g) { super.paintComponents(g); background.drawBackground(g, grassColor, skyColor); mountain.drawMountain(g, mountainColor, Color.WHITE, winter); for (int i = 0; i < tree.length; i++) { tree[i].drawTree(g, treeColor, treeStickColor, winter); } if (spring) { mountainColor = new Color(68, 73, 68); treeStickColor = new Color(179, 23, 23); treeColor = (Color.GREEN); grassColor = new Color(120, 225, 120); skyColor = new Color(198, 245, 242); for (int i = 0; i < rain.length; i++) { rain[i].drawRain(g); } } if (winter) { mountainColor = new Color(68, 73, 68); treeStickColor = new Color(179, 23, 23); treeColor = new Color(210, 210, 210); skyColor = (Color.LIGHT_GRAY); grassColor = new Color(190, 228, 200); for (int i = 0; i < cloud.length; i++) { cloud[i].drawCloud(g, getXs[i] + cloudX); } for (int i = 0; i < snow.length; i++) { snow[i].drawSnow(g); } } //Summer //Fall } public void animate() { while (true) { for (int i = 0; i < cloud.length; i++) { System.out.println(getXs[i]); } try { Thread.sleep(5); //in milliseconds } catch(InterruptedException ex) { Thread.currentThread().interrupt(); } cloudX += 0.2; for (int i = 0; i < cloud.length; i++) { getXs[i] += (int) cloudX; if (getXs[i] > 800) getXs[i] = -150; } if (spring) { for (int i = 0; i < rain.length; i++) { rain[i].moveDownRain(); } } else if (winter) { for (int i = 0; i < snow.length; i++) { snow[i].moveDownSnow(); } } repaint(); } } public void actionPerformed(ActionEvent e) { if (e.getSource() == fallB) { fall = true; spring = false; winter = false; summer = false; } else if (e.getSource() == winterB) { winter = true; spring = false; summer = false; fall = false; } else if (e.getSource() == springB) { spring = true; winter = false; fall = false; summer = false; } else if (e.getSource() == summerB) { summer = true; spring = false; winter = false; fall = false; } } } Here is the Cloud class: import java.awt.Color; import java.awt.Graphics; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ThreadLocalRandom; public class Cloud { private Color cloudColor; public static List<Integer> xs = new ArrayList<Integer>(); private int x, y; private int x1 = 25, x2 = 65, x3 = 106; public Cloud () { cloudColor = new Color(128, 128, 128); x = ThreadLocalRandom.current().nextInt(50, 790); y = ThreadLocalRandom.current().nextInt(1, 100); xs.add(x); } public void drawCloud(Graphics g, double x) { g.setColor(cloudColor); g.fillOval((int) x + x1 + this.x, 25 + y, 70, 58); g.fillOval((int) x + x2 + this.x, 15 + y, 70, 58); g.fillOval((int) x + x2 + this.x, 50 + y, 70, 58); g.fillOval((int) x + x3 + this.x, 33 + y, 70, 58); } }
but for some reason the clouds are moving really fast Not really sure what the problem is just some general comments about the code: Thread.sleep(5); //in milliseconds Sleeping for 5 ms would be a refresh rate of 200 which is way too high. Also, I don't think the Java clock is that precise to allow you to sleep for that small of a time slice. People tend to go for 60 frames which would be about 16 ms. cloudX += 0.2; Then you increment the movement by .2, which means the cloud will only move every 5 times through the loop anyway. So why do all the extra processing. Just increment the x value by 1 and change the sleep to 25ms. public static List<Integer> xs = new ArrayList<Integer>(); You should not be using a static variable. Properties of the cloud should be instance variables.That is the Cloud object should be self contained so it has all the information necessary to paint itself. So you need a variable like locationX. for (int i = 0; i < cloud.length; i++) { getXs[i] += (int) cloudX; if (getXs[i] > 800) getXs[i] = -150; } After the above suggestion you get rid of the "getXs" variable. Instead you create a method like move(int pixels) to the Cloud class. The move(...) method simply updates the locationX variable to its new value. The drawCloud(...) method would then be changed to only need the Graphics object. The painting would be changed to use the locationX variable. public static List<Integer> xs = new ArrayList<Integer>(); I would guess the problem is the static variable. This means every Cloud object uses the same variable. So every time you increment the value for each Cloud you increase it for all clouds. The "x location" should be in instance variable. snow = new RainSnowDrop[200]; rain = new RainSnowDrop[200]; tree = new Tree[5]; cloud = new Cloud[7]; Don't use arrays. Instead use ArrayList. This will allow your code to dynamically add objects without a limitation. while (true) { Don't use an infinite loop. Animation is done by using a Swing Timer. Read the section from the Swing tutorial on How to Use Timers for more information. Check out: get width and height of JPanel outside of the class for an example that implements all the above suggestion. Note how the "Ball" class has all the properties needed to paint the ball. This allows you to customize its behaviour to be a different color and motion.
Detecting if a 2D Graphics fill Rect is in another fillRect(eclipse)
private JPanel contentPane; private KeyListener myKeyListener; JLabel lblUp; JLabel lblMiddle; JLabel lblDown; JButton btnStart; JLabel lblScore; int lblu = 0; int x = 0; int y = 50; int u = 1; int w = 1; int rxx = 0; int ryy = 0; int s = 0; Timer timer; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { Game_1 frame = new Game_1(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public Game_1() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 300); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); JLabel lblScore = new JLabel("0"); lblScore.setHorizontalAlignment(SwingConstants.CENTER); lblScore.setForeground(Color.GREEN); lblScore.setBounds(388, 0, 46, 14); contentPane.add(lblScore); addKeyListener(this); } public void keyPressed(KeyEvent arg0) { Graphics pen = this.contentPane.getGraphics(); int maxh = contentPane.getHeight(); int maxw = contentPane.getWidth(); if(y < 0){ y = maxh -50; } if(y > maxh-45){ y = 0; } if (arg0.getKeyCode() == KeyEvent.VK_UP) { if(u ==0){ pen.setColor(Color.BLACK); pen.fillRect(0, 0, maxw, maxh); y = y - 10; pen.setColor(Color.GREEN); pen.fillRect(x, y, 50, 50); pen.setColor(Color.BLACK); pen.fillRect(x - 50, y, 50, 50); x = x + 1; if (x >= maxw) { pen.fillRect(x - 30, y, 50, 50); x = 0; } } } else if (arg0.getKeyCode() == KeyEvent.VK_RIGHT) { if(u ==1){ pen.setColor(Color.BLACK); pen.fillRect(0, 0, maxw, maxh); pen.setColor(Color.BLACK); pen.fillRect(0, 0, maxw, maxh); Timer timer = new Timer(100, this); timer.start(); u = 0; }else if(u ==0){ x = x +10; } } else if (arg0.getKeyCode() == KeyEvent.VK_DOWN) { if(u ==0){ pen.setColor(Color.BLACK); pen.fillRect(0, 0, maxw, maxh); pen.setColor(Color.BLACK); y = y+ 10; if (x >= maxw) { pen.fillRect(x - 30, y, 50, 50); x = 0; } } } else if (arg0.getKeyCode() == KeyEvent.VK_LEFT) { if(u ==0){ pen.setColor(Color.BLACK); pen.fillRect(0, 0, maxw, maxh); pen.setColor(Color.BLACK); x = x- 10; if (x < 0) { pen.fillRect(x - 30, y, 50, 50); x = maxw; } } } } public void keyReleased(KeyEvent arg0) { } public void keyTyped(KeyEvent arg0) { } public void run() { } #Override public void actionPerformed(ActionEvent arg0) { Graphics pen = this.contentPane.getGraphics(); int maxh = contentPane.getHeight(); int maxw = contentPane.getWidth(); pen.setColor(Color.BLACK); pen.fillRect(0, 0, maxw, maxh); pen.setColor(Color.GREEN); pen.fillRect(x, y, 50, 50); pen.setColor(Color.BLACK); pen.fillRect(x - 50, y, 50, 50); x = x + 1; if (x >= maxw) { pen.fillRect(x - 30, y, 50, 50); x = 0; } if(w ==1){ Random r = new Random(); int ry = r.nextInt(maxh - 0) + 100; int rx = r.nextInt(maxw - 0) + 100; rxx = rx; ryy = ry; pen.setColor(Color.RED); pen.fillRect(rx, ry, 10, 10); w = 0; } pen.setColor(Color.RED); pen.fillRect(rxx, ryy, 10, 10); if(x-50 <= rxx && x > rxx && y > ryy && y-50 <= ryy){ s ++; System.out.println("PUNKT"); pen.setColor(Color.BLACK); pen.fillRect(rxx, ryy, 10, 10); w = 1; } } } here is the Problem: it only detects that they touch in the left top >corner(the wrong code is at the end, the last if) you can start the game by pressing the Right arrow Button on you're Keyboard.Moving upwards: up Key on you're Keyboard.Moving downwards:down Key on your're Keyboard.The right Button also lets you move to the right, the left Button to the left.Picture of the Game
I want, that the Rect detects that it touches the other in every part of it, not only in the left top corner Let's assume you've got first rect with: x1, y1, width1, height1 and second rect with x2, y2, width2, height2. The first rect touched the second in every part of it (so the second one is contained in the first one) when x1 <= x2 && x2+width2 <= x1+width2 && y1 <= y2 && y2+height <= y1+height so if (x1 <= x2 && x2+width2 <= x1+width2 && y1 <= y2 && y2+height <= y1+height) { // the second rect is contained in the first rect }
So I finally fixed it. For those who are interested, here is the fixed part of the code: if (x+d >= x2 && x <= x2 && y+d >=y2 && y <= y2) { s++; d = d + s*10; System.out.println("PUNKT"); pen.setColor(Color.BLACK); pen.fillRect(x2, y2, 10, 10); w = 1; if (s == 10) { JOptionPane.showMessageDialog(frame, "Achievement get: " + s + "Punkte!"); }
drawString() isn't drawing the String on my game
I am using drawString() to write text on the string, but nothing shows up. I set the color to white and set the coordinates to (100,100). Is there anything else that I am doing wrong? import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.Random; import javax.swing.JPanel; public class Screen extends JPanel implements Runnable { private static final long serialVersionUID = 1L; public static final int WIDTH = 800, HEIGHT = 800; private Thread thread; private boolean running = false; private BodyPart b; private ArrayList<BodyPart> snake; private Apple apple; private ArrayList<Apple> apples; private Random r; private int xCoor = 20, yCoor = 20; private int size = 10; private int score = 0; private boolean right = true, left = false, up = false, down = false; private int ticks = 0; private Key key; public Screen() { setFocusable(true); key = new Key(); addKeyListener(key); setPreferredSize(new Dimension(WIDTH, HEIGHT)); r = new Random(); snake = new ArrayList<BodyPart>(); apples = new ArrayList<Apple>(); start(); } public void reset() { snake.clear(); apples.clear(); xCoor = 20; yCoor = 20; size = 10; score = 0; running = true; } public void tick() { if(snake.size() == 0) { b = new BodyPart(xCoor, yCoor, 20); snake.add(b); } if(apples.size() == 0) { int xCoor = r.nextInt(40); int yCoor = r.nextInt(40); apple = new Apple(xCoor, yCoor, 20); apples.add(apple); } for(int i = 0; i < apples.size(); i++) { if(xCoor == apples.get(i).getxCoor() && yCoor == apples.get(i).getyCoor()) { size++; apples.remove(i); score += 10; i--; } } for(int i = 0; i < snake.size(); i++) { if(xCoor == snake.get(i).getxCoor() && yCoor == snake.get(i).getyCoor()) { if(i != snake.size() - 1) { reset(); } } } if(xCoor < 0) xCoor = 40; if(xCoor > 40) xCoor = 0; if(yCoor < 0) yCoor = 40; if(yCoor > 40) yCoor = 0; ticks++; if(ticks > 250000) { if(right) xCoor++; if(left) xCoor--; if(up) yCoor--; if(down) yCoor++; ticks = 185000; b = new BodyPart(xCoor, yCoor, 20); snake.add(b); if(snake.size() > size) { snake.remove(0); } } } public void paint(Graphics g) { g.clearRect(0, 0, WIDTH, HEIGHT); g.drawString("Score: " + score, 100, 100); g.setColor(Color.WHITE); g.setColor(new Color(20, 50, 0)); g.fillRect(0, 0, WIDTH, HEIGHT); g.setColor(Color.BLACK); for(int i = 0; i < WIDTH / 20; i++) { g.drawLine(i * 20, 0, i * 20, HEIGHT); } for(int i = 0; i < HEIGHT / 20; i++) { g.drawLine(0, i * 20, WIDTH, i * 20); } for(int i = 0; i < snake.size(); i++) { snake.get(i).draw(g); } for(int i = 0; i < apples.size(); i++) { apples.get(i).draw(g); } } public void start() { running = true; thread = new Thread(this, "Game Loop"); thread.start(); } public void stop() { running = false; try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } public void run() { while(running) { tick(); repaint(); } } private class Key implements KeyListener { public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if(key == KeyEvent.VK_RIGHT && !left) { up = false; down = false; right = true; } if(key == KeyEvent.VK_LEFT && !right) { up = false; down = false; left = true; } if(key == KeyEvent.VK_UP && !down) { left = false; right = false; up = true; } if(key == KeyEvent.VK_DOWN && !up) { left = false; right = false; down = true; } } }
The order in which you do things is very important, remember, painting in Swing is like painting on paper, if you paint the text first, then paint over it, it will no longer be visible... #Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(new Color(20, 50, 0)); g.fillRect(0, 0, WIDTH, HEIGHT); g.setColor(Color.BLACK); for (int i = 0; i < WIDTH / 20; i++) { g.drawLine(i * 20, 0, i * 20, HEIGHT); } for (int i = 0; i < HEIGHT / 20; i++) { g.drawLine(0, i * 20, WIDTH, i * 20); } for (int i = 0; i < snake.size(); i++) { snake.get(i).draw(g); } for (int i = 0; i < apples.size(); i++) { apples.get(i).draw(g); } g.setColor(Color.WHITE); g.drawString("Score: " + score, 100, 100); } Don't override paint, override paintComponent, you've circumvented the painting process, meaning you could end up with all sorts of nasty glitches Call super.paintComponent Take a look at Painting in AWT and Swing and Performing Custom Painting for more details about how painting is done. Swing is also not thread safe and you need to be careful any time you are changing anything that the paint process uses to update the UI, as painting may occur at any time and for any reason. Consider using a Swing Timer instead of Thread. The timer executes it's tick events within the context of the Event Dispatching Thread, making it safer to update the UI from within. See Creating a GUI With JFC/Swing
You have a few things in the wrong order. When painting, you need to paint in the correct order, otherwise you will paint over the top of other objects. So, in your code, the first 5 lines of the paint() method should look like this... (note the same code, but a different order) g.clearRect(0, 0, WIDTH, HEIGHT); g.setColor(new Color(20, 50, 0)); g.fillRect(0, 0, WIDTH, HEIGHT); g.setColor(Color.WHITE); g.drawString("Score: " + score, 100, 100); You need to paint the background color first. Then you can paint the String on top of it.
Need to add Scroll Bar
I am an enthusiast rather than a programmer. I have thousands of pdf files to go through and extract some data. The data is in X inside boxes (I suspect a graphic within the pdf) there is no evidence of this data if I convert the PDF to text so... I am converting the PDF to image then looking at the image in certain areas where I expect the X to be and counting black pixels, so far so good. The PDF does not fit in the window height-wise so I need to add a scrollbar. I don't understand how I can add a scrollbar to the main window. Can someone just steer me in the right direction Thank you The code is incomplete but working: import java.awt.Color; import java.awt.EventQueue; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JScrollPane; public class ImageViewer { public static void main(String[] args){ EventQueue.invokeLater(new Runnable() { public void run(){ ImageFrame frame = new ImageFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } } ); } } class ImageFrame extends JFrame{ /** * */ private static final long serialVersionUID = 1L; public ImageFrame(){ setTitle("Image Viewer"); setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); ImageComponent component = new ImageComponent(); add(component); } public static final int DEFAULT_WIDTH = 860; public static final int DEFAULT_HEIGHT = 1000; } class ImageComponent extends JComponent{ /** * */ private static final long serialVersionUID = 1L; private Image image; public ImageComponent(){ try{ File image2 = new File("Files/4.jpg"); image = ImageIO.read(image2); } catch (IOException e){ e.printStackTrace(); } } public void paintComponent (Graphics g){ if(image == null) return; int imageWidth = image.getWidth(this); int imageHeight = image.getHeight(this); g.drawImage(image, 0, 0, this); // Draw on the BufferedImage via the graphics context. g.setColor(Color.RED); g.drawRect(445, 153, 20, 20); g.drawRect(552, 153, 20, 20); g.drawRect(661, 153, 20, 20); g.drawRect(445, 182, 20, 20); g.drawRect(552, 182, 20, 20); g.drawRect(661, 182, 20, 20); g.drawRect(445, 226, 20, 20); g.drawRect(552, 226, 20, 20); g.drawRect(661, 226, 20, 20); g.drawRect(445, 271, 20, 20); g.drawRect(552, 271, 20, 20); g.drawRect(661, 271, 20, 20); for (int i = 0; i*imageWidth <= getWidth(); i++) for(int j = 0; j*imageHeight <= getHeight();j++) if(i+j>0) g.copyArea(0, 0, imageWidth, imageHeight, i*imageWidth, j*imageHeight); //Count black pixels to see if the box contains an X int A1 = 0; for (int y = 153; y < 173; y++) { for (int x = 445; x < 465; x++) { int c = ((BufferedImage) image).getRGB(x,y); Color color = new Color(c); if (c != -1) { A1++; } } } System.out.println("First box pixel count = " + A1); //Count black pixels to see if the box contains an X int A2 = 0; for (int y = 153; y < 173; y++) { for (int x = 552; x < 572; x++) { int c = ((BufferedImage) image).getRGB(x,y); if (c != -1) { A2++; } } } System.out.println("Second box pixel count = " + A2); //Count black pixels to see if the box contains an X int A3 = 0; for (int y = 153; y < 173; y++) { for (int x = 661; x < 681; x++) { int c = ((BufferedImage) image).getRGB(x,y); if (c != -1) { A3++; } } } System.out.println("Third box pixel count = " + A3); } }
Look for something like JScrollPane myPane = new JScrollPane();
Collision() not working properly
So when I collide into getBoundsBlock() it stops the player like it should but, it will not let me go up, only left and right. But, the main problem comes in when I collide into getBoundsBlock2(). When I collide into that one I can go threw the left and right sides of it. If I collide into the bottom or top of it my player gets stuck and can only go left or right. player.java package com.questkings.game; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import java.awt.event.KeyEvent; import javax.swing.ImageIcon; public class Player{ int x = 1; // Location of player int y = 314; // location of player int xa = 0; // Representation of where the player goes int ya = 0; // Representation of where the player goes private int speed = 2; int[] playerPos = {x, y}; private static final int WIDTH = 30; private static final int HEIGHT = 30; private Game game; public Player(Game game){ this.game=game; } public void move(){ if(x + xa < 0) // Left Bounds xa = 0; else if (x + xa > game.getWidth() - WIDTH) // Right Bounds xa = 0; else if (y + ya < 0) // Top Bounds ya = 0; else if(y + ya > game.getHeight() - WIDTH) ya = 0; else if (collision()) // Tile bounds ya = 0; else if (collision2()) ya = 0; x = x + xa; y = y + ya; } // Method to find where player is located public int[] Playerposition(){ return playerPos; } public void paint(Graphics2D g2d){ //Draws player to screen g2d.drawImage(getPlayerImg(), x, y, null); } public Image getPlayerImg(){ ImageIcon ic = new ImageIcon("C:/Users/AncientPandas/Desktop/KingsQuest/Misc/Images/Sprites/player.png"); return ic.getImage(); } public void keyReleased(KeyEvent e){ xa = 0; ya = 0; } public void keyPressed(KeyEvent e){ if (e.getKeyCode() == KeyEvent.VK_S) xa = -speed; if (e.getKeyCode() == KeyEvent.VK_F) xa = speed; if (e.getKeyCode() == KeyEvent.VK_E) ya = -speed; if (e.getKeyCode() == KeyEvent.VK_D) ya = speed; } public Rectangle getBoundsPlayer(){ return new Rectangle(x, y, WIDTH, HEIGHT); } private boolean collision(){ return game.maplayout.getBoundsBlock().intersects(getBoundsPlayer()); } private boolean collision2(){ return game.maplayout.getBoundsBlock2().intersects(getBoundsPlayer()); } } MapLayout.java package com.questkings.game; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import javax.swing.ImageIcon; public class MapLayout { int[] blockPlacementX = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360, 390, 420, 450, 480, 510, 540, 570, 600, 630, 660, 690, 720, 750, 780, 810}; int[] blockPlacementY = {344, 254}; #SuppressWarnings("unused") private Game game; public MapLayout(Game game){ this.game=game; } //Map size 810(x), 420(y) public void paint(Graphics2D g2d){ for(int i = 0; i < blockPlacementX.length; i++){ g2d.drawImage(getBlockIMG(), blockPlacementX[i], blockPlacementY[0], null); } for(int i = 13; i < blockPlacementX.length - 10; i++) { g2d.drawImage(getBlockIMG(), blockPlacementX[i], blockPlacementY[1], null); } } public Image getBlockIMG(){ ImageIcon ic = new ImageIcon("C:/Users/AncientPandas/Desktop/KingsQuest/Misc/Images/Sprites/grassWall.png"); return ic.getImage(); } // Bug: Bounds are making it so I can not go back up if I hit block 344 public Rectangle getBoundsBlock(){ return new Rectangle(0, 344, 810, 30); } public Rectangle getBoundsBlock2(){ return new Rectangle(390, 254, 150, 30); } }
On collision, you are setting the delta y as ya=0 which means no change in the vertical movement(up or down) when a collision occurs. You probably want to rethink what you want here.