Program freeze after input? - java

After the user inputs their choices, the program seems to offer the same choices again, followed by it completely freezing. It's only set on there to give them the option once (I believe) and then follow the selections below. Instead it seems to revert back to the top, and then just freeze for some odd reason. Tried figuring it out for a while, but no avail.
public void init() //Initialize method {
setSize(1000, 800); //Set size
Container c = getContentPane();
c.setBackground(Color.GREEN); //Set background
}
public void paint(Graphics g) {
super.paint(g); //Start paint method
g.setFont(new Font("Veranda", Font.PLAIN, 20));
g.setColor(Color.BLACK);
g.drawString("Hello", 250, 25); //top display message
String number = JOptionPane.showInputDialog("Would you like a custom loop count or an infinite? 1. Custom 2. Infinite"); //test choice
n = Integer.parseInt(number);
while (n>0 || n<2)
if (n==1) {
String number2 = JOptionPane.showInputDialog("How many times would you like to loop?");
integer = Integer.parseInt(number2);
while (integer>0)
while (x < integer) {
g.drawString("hi", 200, y);
x+=1;
y = y+40; //test
}//end while
}//end if
else if (n==2) {
while (true); //im aware this is an endless loop. Can't find anything more stable for an endless one, so its just there for now..
}//end if
else;
g.drawString("Please pick a valid choice", 200, 200);
}//end paint
}//end

This is what I understood
while (integer>0) {
while (x < integer)
{
g.drawString("hi", 200, y);
x+=1;
y = y+40; //test
}//end while
integer --; // <-- This is missing
}
break; // <-- Also missing
The inner while ends when x = integer
but integer is always > 0
you have to do integer -- at the end of the outer loop
So it can go to 0 at some point
Please use proper indentation... it helps
I edited the code... see where I put the 'integer --'
try converting your while(n>0 || n<2) to if(n>0 && n<2)
Try not using while instead of if, it creates less confusion
Add brackets {} for all your code blocks, easier to read, hence easier to debug, maybe you'll figure it out by just doing that
Also is the ; after the last else intended?

Related

Make my rectangle randomly fall down from my screen?

I am trying to make a game and am almost done with the code. But I can't make my rectangle randomly fall down from my screen.
I am coding a car game that is supposed to dodge the other cars. But is not working. can someone help me?
int carx = 200;
int cary = 0;
float speedx = 0;
float speedy = 0;
float accy = 0.1;
color rod = color(255, 0, 0);
color vit = color(255);
final int START_STATE = 1;
final int PLAY_STATE = 2;
final int GAMEOVER_STATE = 3;
final int RESTART = 4;
int state = START_STATE;
void setup() {
size(400, 700);
}
void draw() {
switch (state) {
case START_STATE:
drawStart();
break;
case PLAY_STATE:
drawPlay();
break;
case GAMEOVER_STATE:
drawGameOver();
case RESTART:
drawrestart();
}
}
void init() {
carx = 200;
cary = 0;
speedx = 0;
speedy = 0;
accy = 0.1;
}
void drawStart() {
background(0);
textAlign(CENTER, CENTER);
textSize(16);
text("Click the mouse button to start the game", width / 2, height / 2);
if (mousePressed) {
state = PLAY_STATE;
}
}
void drawGameOver() {
textAlign(CENTER, CENTER);
textSize(20);
text("you have crashed your car", width / 2, height / 2);
if (mousePressed) {
state = PLAY_STATE;
init();
}
}
void drawrestart() {
textAlign(CENTER, CENTER);
textSize(15);
text("press mouse to restart", 200, 400);
if (keyPressed) {
state = RESTART;
}
}
void drawPlay() {
background(0);
if (get(carx, cary) == vit) {
speedy = -1 * speedy;
}
fill(rod);
rect(carx, cary, 50, 30);
if (get(mouseX, 600) == color(255, 0, 0)) {
state = GAMEOVER_STATE;
}
fill(#FFFFFF);
rect(mouseX, 600, 30, 50);
carx += speedx;
cary += speedy;
speedy += accy;
}
The code you have at the moment only has one rectangle fall down from the top for each 'round' of the game. I'm not sure if you wanted to have multiple blocks falling; I think that would be a good next step.
For now, here's a simple hack which will cause the block to fall from a random position each time, like you requested.
At the very start of your code, outside of the functions, place:
boolean randomise;
Then, within void init() you should add:
randomise = true;
Finally, add this section into drawPlay(), right at the start of the function:
if (randomise){
carx = int(random(width-50));
randomise = false;
}
Note that a new random x co-ordinate will only generate every time you set the boolean 'randomise' to true again. So if you generate a new iteration with more than one block falling inside the drawPlay() function, you should bear this in mind and adjust the code accordingly.
------- [EDIT] -------
Hi, glad that this helped.
I've actually noticed another little issue which I will help you fix.
Currently, you are checking at mouseX to see whether there has been a collision. This works (mostly), but if the right side of the player's white car drives through the left edge of a red falling block, then the game continues as though nothing has happened. What should occur is that the game is over because a collision is detected. You want to find out if any part of the two shapes have overlapped.
To do this, you should alter the code like so. In drawPlay(), replace:
if (get(mouseX, 600) == color(255, 0, 0)) {
state = GAMEOVER_STATE;
}
with:
if (get(mouseX, 600) == color(255, 0, 0) || get(mouseX + 30, 600) == color(255, 0, 0)) {
state = GAMEOVER_STATE;
}
This is an OR statement - checking whether either side of the player's car has collided. This way, every time they bump into each other, the game will end.
Now for your question: how to add multiple cars?
There are a few ways you could go about this, but I'll show you the most straightforward.
In drawPlay(), you want to add this little if statement:
if (cary > height){
init();
}
Basically what we're doing here is checking if the previous red block/car has fallen off the bottom of the sketch. If it has, i.e. if the red block's y co-ordinate is larger than the height of the whole sketch, we call init() again. This will reset everything, including making randomise true. Once randomise is true, the previous code you added will select a random start point for the block, and it will fall all over again.
I hope you've understood everything I explained - whilst my code will fix your problem, the best way to learn is to try to solve things by yourself. Check out Dan Shiffman's videos on YouTube. These are a great starting place to get to grips with Processing - hopefully you'll be more confident writing your own code after following along with his examples :)
Use random to generate a random x coordinate:
carx = (int)random(0, width-50);
Reset the position and the speed of the care, once the car reached to bottom of the window:
void drawPlay() {
if (cary > height) {
carx = (int)random(0, width-50);
cary = 0;
speedy = 0;
}
// [...]

Java | Buffered Image working But Not How I Want and Keybindings doing the same

Background Stuff
So I have been working on a Java game for the past 3-4 weeks for a class final project. What it is supposed to do is generate a "map" that the player has to navigate through to get to the "exit" in the bottom right corner (shown as black dot for now). The "map" is randomly generated so that no two are the same and will cause the player to possibly need to use more "tools"(not added yet) than they would like.
Problem
1.)The first problem at hand is that I have attempted to make "keybindings" and they compile and don't break the game, when ever the key is pressed the player does not move in the indicated direction.
I know one part of the problem is I do not have boundaries on the "map" due to not knowing how to make them which is causing an out of bounds exception to my array.
The other that coincides with this is that when I repaint() it completely redoes the whole "map" when all I wanted was the player to be moved to the new location while removing any "terrain" that they encounter (not removing terrain till later).
2.) Trying to figure out problem 1 I looked back at one of my previous posts (Rows and columns with multidimensional array java) where this was said by MadProgrammer Personally, in mapGen, I would create a BufferedImage which was 24*20 wide and 24*20 high, paint all the tiles to it and the in the paintComponent method, paint the image
So I read up on what a BufferedImage does and how it works and tried to implement it into my game. The results where catastrophic. It compiled and ran okay but the outcome was very far away from what I was trying to achieve
Result:
What I was Shooting For:
Code I Added That Did This/Not Working Code
The "keybinding":
//I have all imports neccessary
public class gamePanel extends JPanel implements ActionListener, KeyListener
{ //added^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
public gamePanel()
{
//left out my bounds for shortening reasons
addKeyListener(this);//added
setFocusable(true);//added
setFocusTraversalKeysEnabled(false);//added
}
//................................
public void actionPerformed(ActionEvent e){
repaint();
}
// below process is repeated for left, right, and down
//for now just trying to get the player to move
//not worried about removing terrain just yet
public void up(){
if(coords[playerX[pcX]][playerY[pcY-1]] == terrain[floor]){
playerY[pcY] = playerY[pcY- 1] ;
}
if(coords[playerX[pcX]][playerY[pcY]-1] == terrain[dirt]){
playerY[pcY] = playerY[pcY] - 1;
}
if(coords[playerX[pcX]][playerY[pcY]-1] == terrain[stone]){
playerY[pcY] = playerY[pcY] - 1;
}
if(coords[playerX[pcX]][playerY[pcY]-1] == terrain[iron]){
playerY[pcY] = playerY[pcY] - 1;
}
if(coords[playerX[pcX]][playerY[pcY]-1] == terrain[gold]){
playerY[pcY] = playerY[pcY] - 1;
}
if(coords[playerX[pcX]][playerY[pcY]-1] == terrain[diamond]){
playerY[pcY] = playerY[pcY] - 1;
}
if(coords[playerX[pcX]][playerY[pcY]-1] == terrain[emerald]){
playerY[pcY] = playerY[pcY] - 1;
}
//................
public void keyTyped(KeyEvent e){}//would not compile without these two lines
public void keyReleased(KeyEvent e){}
}
}
Code for Buffered Image:
//player coords
int pcY = 1;
int pcX = 1;
int[] playerX = new int[pcX + 1];
int[] playerY = new int[pcY + 1]; // x,y for the player
//^^^^pretty sure this is the wrong way to make array start at 1
#Override
public void paintComponent(Graphics g)//what will paint each 20x20 square on the grid what it is assigned
{
super.paintComponent(g);
Image img = drawmap();//draw the below bufferedimage
g.drawImage(img, 520, 520, this);
g.setColor(Color.red);//creates the player "model"
g.fillOval((pcX*20),(pcY*20),20,20);
g.setColor(Color.black);
g.fillOval((23*20),(23*20),20,20);
}//end paintComponent
private Image drawmap(){
BufferedImage map = new BufferedImage(width*20, height*20, BufferedImage.TYPE_INT_RGB);
Graphics g = map.getGraphics();
for(int x = 1; x < width; x++)
{
for(int y = 1; y < height; y++)
{
if(coords[x][y] == terrain[floor])// paints floor color at marked coordinates
{
g.setColor(new Color(249,249,249));
g.fillRect((x*20), (y*20), 20, 20);
}
//^^^^same proccess for all the rest of the terrain
}
}
return map;
}
Notes
If all explanations could please be but into layman's terms that would be fantastic because engineer lingo confuses me.
Also if this needs to be two different posts please let me know without being rude about it.
Here is a link to code I have that compiles and generates what I want but keybinding does not work(if you want a look): https://www.dropbox.com/sh/78mj9aes2c0598a/AADZoJWlw79I5Z0Ub3uon6ZVa?dl=0
Here is a link to "working" code where I attempted the BufferedImage(if you want to look):https://www.dropbox.com/sh/hujm1ztrttkdq4f/AAB9j9P3PvPQpRNi_ckzTHOha?dl=0

Drawing tic-tac-toe boards

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);
}
}
}

How to repaint over images in Java game

Hello everyone I am having trouble with painting over coins that the user intersects with. What I want this code to do is when the user sprite intersects with any of the ten coin images it paints over the coin so that it no longer appears on the screen (also need to add in some kind of counter so that when the user collects all ten coins it will stop the thread, and say "You Win!"). My question is how would I go about doing this because I have tried using repaint() in the if statements, and it is not compiling correctly anymore. Any help on how to paint over the coins, and possibly even add some kind of counter (thinking a for loop would come in handy) would be greatly appreciated! Here is the code:
public void paint(Graphics g)
{
g.clearRect(0, 0, this.getWidth(), this.getHeight());
one.paintComponent(g);
two.paintComponent(g);
three.paintComponent(g);
four.paintComponent(g);
five.paintComponent(g);
six.paintComponent(g);
seven.paintComponent(g);
eight.paintComponent(g);
nine.paintComponent(g);
ten.paintComponent(g);
monster.setLocation(r.nextInt(10) - 5 + monster.x, r.nextInt(10 - 5 + monster.y));
monster.paintComponent(g);
user.paintComponent(g);
if(user.intersects(one))
{
}
if(user.intersects(two))
{
}
if(user.intersects(three))
{
}
if(user.intersects(four))
{
}
if(user.intersects(five))
{
}
if(user.intersects(six))
{
}
if(user.intersects(seven))
{
}
if(user.intersects(eight))
{
}
if(user.intersects(nine))
{
}
if(user.intersects(ten))
{
}
if(user.intersects(monster))
{
g.setFont(new Font("Serif", Font.BOLD, 35));
g.drawString("YOU HAVE DIED, YOU LOSE!", 100, 100); //Prints this when you lose
thread.interrupt(); //Stopping the thread if you die
}
}
At first, you should put the coins in a list. Then, if there's an interection, you simply remove the item (coin) of the list. Like this:
private List<Coin> coins;
public ClassConstructor() {
coins = new ArrayList();
coins.add(new Coin(type value,...)); //this ten times if every Coin is different from other
//or this if every Coin are same:
for (int i = 0; i < 10; i++) {
coins.add(new Coin(type value,...));
}
}
public void update() {
//whatever
for (int i = coins.size(); i >= 0; i--) {
if (user.intersects(coins.get(i))) {
coins.remove(i);
//...
}
}
}
public void paint(Graphics g) {
for (int i = coins.size(); i >= 0; i--) {
coins.get(i).paintComponent(g);
}
}
Now, you shouldnt end a Thread with thread.interrupt(). If that thread is your game loop, you should send a flag that ends the loop. The Thread of you game loop:
#Override
public void run() {
while (running) { //boolean running
update();
paint(g);
}}
And, finally, your update will be like:
public void update() {
//whatever
for (int i = coins.size(); i >= 0; i--) {
if (user.intersects(coins.get(i))) {
coins.remove(i);
//...
}
}
if (user.intersects(monster)) {
youThread.setRunning(false);
try {
gameLoopThread.join(); //"wait" until thread ends
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
This code is taken from my current project (that is working), I tried adjusting it to your project.
private void render () {
BufferStrategy bufferstrategy = getBufferStrategy ();
if (bufferstrategy == null) {
createBufferStrategy(3);
return;
}
Graphics g = bufferstrategy.getDrawGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
paint (g);
g.dispose();
bufferstrategy.show();
}
render() is called from run(), where the Thread is.
Let's break it down and see if it can help you.
It gets a BufferStrategy for how many images to have ready. It can be set to anything like you like within reason. 2 - 4 will do the trick. One can even work.
It sets your current BufferStrategy to your Graphics.
It then fills the screen with the color of white (could be a clear as well).
Then it paints all components, in your case it calls paint (Graphics g) while in my case it iterates through all drawable objects.
It re-renders everything as it now should look.
Hope you take some points out from this.
Off the top of my head, put while(true) within your Run() method (you said you were using a thread) and call repaint() within the loop, at the end of the loop (within a try/catch) put something like //thread//.sleep(allotted time) This will stop the thread for the set amount of Milliseconds. Within the Javadoc of repaint() you'll see that it calls the nearest paint(Graphics g) method. By doing this you can access your paint() method from wherever you are in your program.
My suggestion to the coin's is make it it's own class. The class would look similar to this:
public class Coin{
int x;
int y;
public void Coin(int x, int y, Graphics g){
Graphics2D g2 = (Graphics2D) g;
Image img1 = (//File Location);
g2.drawImage(img1, x, y, //this);
//If you have trouble with the ImageObserver (this part) try //class name of the applet.this
this.x = x;
this.y = y;
g2.finalize();
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
After that, in your paint method you could make 10 Coin objects and use g which you instantiate in the parameters. You could then make an array of Coin objects and add 10 Coins that you make in your paint method manually (yeah, it's a pain) (you have to make them in paint to pass the Graphics variable)
Coin[] coins = new Coin[10];
Is how you make the array, by the way. After you make the array of coin's, then make a for loop in your paint method. It should look something like this:
for(int i = 0; i < coins.length; i++){
if(coins[i].getX == //user X && coins[i].getY == //user Y){
g.clearRect(coins[i].getX, coins[i].getY, //Coin radius, //Coin radius);
}
}
This will make a clear rectangle be drawn over wherever the Coin is at if the user's X and Y is equal to the Coin's X and Y.

How to change the Color of paint inside a timer

Here is the portion of my code I'm concerned with, When I try to change the color of squaresToDisplay object again using the Timer, it makes the frame white (blank) but it works only 1 time. So when I run this piece of code, it will do what I want 1 time then make the screen blank. I am wondering what causes this specifically. My own assumption is that I might be blocking the EDT when I start the SQTimer, in which case I'm at a loss because I don't know enough java to fix this :/
private Timer SQTimer;
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Code that removes unrelated things from the frame
final SquareObjects squaresToDisplay = new SquareObjects(x,y);//Creates the Object based on GUI width and height
squaresToDisplay.setFocusable(true);
squaresToDisplay.setVisible(true);//Allows it to be visible
frame.add(squaresToDisplay);//Adds it to the frame
SQTimer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e){
squaresToDisplay.repaint();
System.out.println("Repainted");
}
});
System.out.println("Completed adding pixels");
SQTimer.setRepeats(true);
SQTimer.start();
}
});
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
System.out.println("Beginning of paintComponent");
System.out.println("Completed making the Graphics objects");
for(int i = 0;i<(x*y)/64;i++){
if(xInterceptLocation == 0){
g.fillRect(xInterceptLocation, yInterceptLocation, 8, 8);
xInterceptLocation += 8;
}else{
Color newColor = changingColors();
g.setColor(newColor);
g.fillRect(xInterceptLocation, yInterceptLocation, 8, 8);
xInterceptLocation += 8;
if(xInterceptLocation == 1920){
xInterceptLocation = 0;
yInterceptLocation += 8;
}
}
}
}
Just for clarification, these to methods are in seperate classes, the first one is in a class called GUI while the second one is in a class called SquareObjects
the problem was that the yInterceptLocation was never set back to 0, so when the program repainted, it continued adding 8, thus leaving the screen blank because it was out of the frames bounds.
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
System.out.println("Beginning of paintComponent");
System.out.println("Completed making the Graphics objects");
//yIntercept needs to be reinitialized when the repaint(); is called again
if(yInterceptLocation == 1080){
yInterceptLocation = 0;
}
for(int i = 0;i<(x*y)/64;i++){
if(xInterceptLocation == 0){//If i == 0 then it wont add 8 first (thus preventing a gap)
g.fillRect(xInterceptLocation, yInterceptLocation, 8, 8);
xInterceptLocation += 8;
}else{//Any other time we want to add 8 to space out the squares
Color newColor = changingColors();
g.setColor(newColor);
g.fillRect(xInterceptLocation, yInterceptLocation, 8, 8);
xInterceptLocation += 8;
if(xInterceptLocation == 1920){//if xInterceptLocation = 1920 then it adds 8 to yIntercept and sets x to 0 (creating a new line)
xInterceptLocation = 0;
yInterceptLocation += 8;
}
}
}
}
Credits to HoverCraft Full Of Eels, for noticing it wasn't reinitialized

Categories

Resources