Try Again Button When Pressed Resets Everything But Everything Becomes Quicker - java

So, I had a problem concerning a Try Again button that would show on Game Over screen and when clicked on reset everything to initial value. Now that problem is partially solved but every time I click on it everything becomes crazy fast and with each click faster and faster.
Here is my code from class which does initialization:
public class game extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
private Menu menu;
private GameOver gameover;
//variables
public static int cyclesToWait = 50;
public static int enemiesKilled = 0;
public static int life = 3;
int roundCount = 0;
Timer gamelooptimer;
//objects
Player p;
ControllerEnemy c;
ControllerRocket r;
ControllerExplosion e;
//is it new round or not --> for enemy control
public static enum ROUND{
INPROGRESS,
NEW
}
public static enum STATE{
MENU,
GAME,
OVER
};
public static STATE State = STATE.MENU;
public static ROUND Round = ROUND.INPROGRESS;
public game(){
setFocusable(true);
initGame();
}
public void resetGame(){
initGame();
}
private void initGame(){
enemiesKilled = 0;
life = 3;
roundCount = 0;
gamelooptimer = new Timer(10, this);
gamelooptimer.start();
p = new Player(MainClass.width / 2 - 60, 400);
c = new ControllerEnemy();
r = new ControllerRocket();
e = new ControllerExplosion();
menu = new Menu();
gameover = new GameOver();
addKeyListener(new KeyInput(p));
addMouseListener(new MouseInput());
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(getBackgroundImage(), 0, 0, null);
Font fnt = new Font("arial", Font.BOLD, 22);
g.setFont(fnt);
if(State == STATE.GAME){
p.draw(g2d);
c.draw(g2d);
r.draw(g2d);
e.draw(g2d);
g.drawString("Round: " + roundCount, MainClass.width - 125, 22);
g.drawString("Enemies Killed: " + enemiesKilled, MainClass.width/2 - 95, 22);
if(cyclesToWait < 50)
cyclesToWait++;
}
else if (State == STATE.OVER)
gameover.render(g);
else
menu.render(g);
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
if(State == STATE.GAME){
p.update();
c.update();
r.update();
}
if(Round == ROUND.NEW)
roundCount += 1;
}
private Image getBackgroundImage(){
ImageIcon i = new ImageIcon(getClass().getResource("/images/Background.png"));
return i.getImage();
}
resetGame() is called from another class.

Related

Making a character land on a platform

Im trying to code a simple 2D game. I have a Square that you can move with a/w/d. I got jumping working with a sort of gravity but now I cant get myself to land on a platform. I know how to detect collision between two things but even still idk what to do. My gravity always pulls me down until I reach groundLevel which is part of the problem. Here is my code so far. There's a lot of experimenting happing so its pretty messy.
import javax.swing.Timer;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;
/**
* Custom Graphics Example: Using key/button to move a line left or right.
*/
public class PlatformingGame extends JFrame implements ActionListener, KeyListener{
// Name-constants for the various dimensions
public static final int CANVAS_WIDTH = 800;
public static final int CANVAS_HEIGHT = 400;
public static final Color LINE_COLOR = Color.BLACK;
public static final Color CANVAS_BACKGROUND = Color.WHITE;
public int GRAVITY = 10;
public int TERMINAL_VELOCITY = 300;
public int vertical_speed = 0;
public int jumpSpeed;
public int groundLevel = CANVAS_HEIGHT;
int Shapes;
private DrawCanvas canvas; // the custom drawing canvas (extends JPanel)
public enum STATE {
PLAYING,
PAUSED,
ONGROUND,
INAIR
};
JButton btnStartRestat, btnExit;
Timer timer;
Rectangle2D.Double guy, platform, platform2;
Shape[] shapeArr = new Shape[10];
int dx, dy;
/** Constructor to set up the GUI */
ArrayList myKeys = new ArrayList<Character>();
public static STATE gameState = STATE.PAUSED;
//public static STATE playerState = STATE.ONGROUND;
public PlatformingGame() {
dx = 3;
dy = 3;
guy = new Rectangle2D.Double( CANVAS_WIDTH/2 - 20, CANVAS_HEIGHT, 30, 20);
platform2 = new Rectangle2D.Double( CANVAS_WIDTH/4, CANVAS_HEIGHT/2+130, 50, 10);
platform = new Rectangle2D.Double( CANVAS_WIDTH/3, CANVAS_HEIGHT/2+50, 50, 10);
timer = new Timer(10, this);
// Set up a panel for the buttons
JPanel btnPanel = new JPanel();
// btnPanel.setPreferredSize(new Dimension(CANVAS_WIDTH/2, CANVAS_HEIGHT));
btnPanel.setLayout(new FlowLayout());
btnStartRestat = new JButton("Start/Restart");
btnExit = new JButton("Exit");
btnPanel.add(btnStartRestat);
btnPanel.add(btnExit);
btnStartRestat.addActionListener(this);
btnExit.addActionListener(this);
// Set up a custom drawing JPanel
canvas = new DrawCanvas();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
// Add both panels to this JFrame
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(canvas, BorderLayout.CENTER);
cp.add(btnPanel, BorderLayout.SOUTH);
// "this" JFrame fires KeyEvent
addKeyListener(this);
requestFocus(); // set the focus to JFrame to receive KeyEvent
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Handle the CLOSE button
pack(); // pack all the components in the JFrame
setVisible(true); // show it
}
public void generateSpikes(){
Rectangle2D.Double spikes = null;
for (int i = 0; i < 10; i++) {
spikes = new Rectangle2D.Double (CANVAS_WIDTH - 300 + i*20 , CANVAS_HEIGHT - 30 , 20, 30);
shapeArr[i] = spikes;
}
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource()==btnStartRestat)
{
generateSpikes();
dx = 3;
dy = 3;
guy = new Rectangle2D.Double( 100, CANVAS_HEIGHT - guy.height, 15, 30);
platform = new Rectangle2D.Double( CANVAS_WIDTH/3, CANVAS_HEIGHT/2+50, 50, 10);
platform2 = new Rectangle2D.Double( CANVAS_WIDTH/4, CANVAS_HEIGHT/2+130, 50, 10);
gameState = STATE.PLAYING;
}
else if (e.getSource()==btnExit)
{
// requestFocus(); // change the focus to JFrame to receive KeyEvent
}
else if (e.getSource()== timer){
if (isHitDetected(platform2, guy)){
// playerState = STATE.ONGROUND;
guy.y = platform2.y;
}
if (myKeys.contains('a')
&& (guy.x > 0)){
guy.x = guy.x - 5; }
if (myKeys.contains('d')
&& (guy.x < CANVAS_WIDTH - guy.width)){
guy.x = guy.x + 5; }
{
updateGuyPosition();
}
requestFocus();
canvas.repaint();
}
}
public void updateGuyPosition(){
double guyHeight = guy.height;
if (guy.x >= CANVAS_WIDTH - guy.width){
}
if(gameState == STATE.PLAYING) {
guy.y += jumpSpeed;
if (guy.y < groundLevel - guyHeight) {
// if(playerState == STATE.INAIR) {
jumpSpeed += 1;
}
// }
else {
// if(playerState == STATE.INAIR) {
//playerState = STATE.ONGROUND;
jumpSpeed = 0;
guy.y = groundLevel - guyHeight;
}
// }
if (myKeys.contains('w') == true && guy.y == groundLevel - guyHeight) {
jumpSpeed = -15;
// playerState = STATE.INAIR;
}
}
}
public static boolean isHitDetected(Shape shapeA, Shape shapeB) {
Area areaA = new Area(shapeA);
areaA.intersect(new Area(shapeB));
return !areaA.isEmpty();
}
public void keyPressed(KeyEvent evt) {
if (!myKeys.contains(evt.getKeyChar())){
myKeys.add(evt.getKeyChar());
}
}
public void keyReleased(KeyEvent evt) {
myKeys.remove(myKeys.indexOf(evt.getKeyChar()));
}
public void keyTyped(KeyEvent evt) {
}
/** The entry main() method */
public static void main(String[] args) {
PlatformingGame myProg = new PlatformingGame(); // Let the constructor do the job
myProg.timer.start();
}
/**
* DrawCanvas (inner class) is a JPanel used for custom drawing
*/
class DrawCanvas extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(CANVAS_BACKGROUND);
g.setColor(LINE_COLOR);
Graphics2D g2d = (Graphics2D)g;
if(gameState == STATE.PLAYING) {
g2d.fill(guy);
g.setColor(Color.lightGray);
g2d.fill(platform);
g2d.fill(platform2);
for (int i = 0; i < 10; i++) {
g2d.fill(shapeArr[i]);
}
}
if(gameState == STATE.PAUSED) {
g.drawString("Game Paused", CANVAS_WIDTH/2, CANVAS_HEIGHT/2);
}
}
}
}

How to use a reset button Java arkanoid game

So this is part of my game panel for my game. I got my start button to work, and created a reset button but I don't know how to reset the game every single time it is pressed. Does anyone know how to reset the game to its original position after you press "Reset"? Right now it will display the words "You have died", but it doesn't do anything when I press Reset.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class GamePanel extends JPanel
{
private Brick[][] bary;
private static final Color BACKGROUND = Color.black;
private BufferedImage myImage;
private Graphics myBuffer;
private Ball ball = new Ball();
public Bumper bumper;
private Timer t;
private int hits = 0;
private boolean isPlayingGame = false;
public GamePanel()
{
myImage = new BufferedImage(600, 800, BufferedImage.TYPE_INT_RGB);
myBuffer = myImage.getGraphics();
myBuffer.setColor(BACKGROUND);
myBuffer.fillRect(0, 0, 600,800);
JButton sbutton = new JButton("Start");
sbutton.setFocusable(false);
sbutton.addActionListener(new Listener());
add(sbutton);
JButton rbutton = new JButton("Reset");
rbutton.setFocusable(false);
rbutton.addActionListener(new Listener());
add(rbutton);
bary = new Brick[5][14];
bumper = new Bumper(270, 775, 60, 10, Color.BLUE);
ball = new Ball(300, 400, 10, Color.RED);
t = new Timer(5, new Listener());
setFocusable(true);
//addKeyListener(new Key());
}
// tick method is called every 10ms by Arkanoid.java
// only does stuff if game is actually being played
public void tick()
{
if(isPlayingGame)
{
ball.move(600,800, 600, 800);
death(ball);
}
}
// these get called by the BumperLitsener, which is added to the whole frame
public void moveBumperLeft()
{
bumper.setX(bumper.getX()-20);
//System.out.println("moving bumper left");
}
public void moveBumperRight()
{
bumper.setX(bumper.getX()+20);
//System.out.println("moving bumper right");
}
/*
public class Key extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_A)
bumper.setX(bumper.getX()+10 );
if(e.getKeyCode() == KeyEvent.VK_S)
bumper.setX(bumper.getX()-10 );
}
}
*/
public void startGame()
{
isPlayingGame = true;
}
public void paintComponent(Graphics g)
{
// draw myBuffer, then draw that onto g
myBuffer.setColor(BACKGROUND);
myBuffer.fillRect(0,0,600,800);
setLayout(new GridLayout(5, 14));
myBuffer.setColor(Color.WHITE);
int b=1;
int d=40;
for(int r = 0; r < bary.length; r++)
{
for(int c = 0; c < bary[0].length; c++)
{
bary[r][c] = new Brick(b, d,40,20, Color.BLUE);
b=b+43;
bary[r][c].draw(myBuffer);
}
d=d+23;
b=1;
}
ball.draw(myBuffer);
bumper.draw(myBuffer);
repaint();
if(ball.getColor()==Color.BLACK)
{
myBuffer.setFont(new Font("MS Comic Sans", Font.ITALIC, 45));
myBuffer.drawString("GAME OVER!", 168, 300);
ball.move(0, 0, 0, 0);
}
g.drawImage(myImage, 0, 0, getWidth(), getHeight(), null);
}
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
GamePanel.this.getTopLevelAncestor().requestFocus();
startGame(); // starts game when button is pressed
System.out.println("Game is starting!");
}
}
private void death(Ball ball)
{
double d = ball.getY() + ball.getRadius();
if(d>800.0)
{
ball.setX(300);
ball.setY(400);
ball.setdx(ball.getdx()*-1);
ball.setdy(ball.getdy()*-1);
ball.setColor(Color.BLACK);
}
}
/* private void collide(Ball ball, Bumper b)
{
double d = distance(ball.getX(), ball.getY(), b.getX(), b.getY());
if(d <= 37.5)
{
ball.move();
hits++;
}
}*/
// private double distance(double x1, double y1, double x2, double y2)
// {
// return(Math.sqrt(Math.pow(x2 - x1, 2.0) + Math.pow(y2 - y1, 2.0))); // enter the calculation here.
//}
}
Thank you so much!!!
Right now, you have a single Listener class and two buttons that have registered against the listener (sbutton and rbutton). It'd be easier if you had different classes that implemented ActionListener, but let's move past that for now.
You need to make modifications to your actionPerformed method such that:
You can differentiate the source of the action - i.e. which button was pressed - Reset or the Start? Hint: use the getSource() method from ActionEvent
If the button pressed was the Reset button, you need to reset the GUI to its initial state

Background image in different place every time

I have a large program that I will post some classes of and hopefully you guys can find the problem. Basically, sometimes when I start it, it creates the game just fine, and others the background is up a few pixels to the north and west directions leaving very unsightly whitespace. I cannot seem to find the missing piece of code that decides whether not it does this. It honestly feel like some kind of rendering glitch on my machine. At any rate, I have put a background getX and getY method in for debugging and have noticed that whether the background is fully stretched to the screen(its a custom background so the pixel height and width match perfectly), or its up and to the left, the background still reads that it is displaying at (0,0). I will post all the methods from the main thread to the creating of the background in the menu. I will leave notes indicating the path it takes through this code that gets it to creating the background. Thank you for your help and I will check in regularly for edits and more information.
EDIT: added background.java
EDIT2: added pictures explaining problem
Menu.java *ignore the FileIO code, the main point is the creation of a new GamePanel()
public class Menu {
private static File file;
public static void main(String[] args) throws IOException {
file = new File("saves.txt");
if(file.exists()){
FileIO.run();
FileIO.profileChoose();
}
else{
FileIO.profileCreate();
FileIO.run();
}
JFrame window = new JFrame("Jolly Jackpot Land");
window.setContentPane(new GamePanel());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.pack();
window.setLocationRelativeTo(null);
window.setVisible(true);
}
}
Next is the GamePanel.java
public class GamePanel extends JPanel implements Runnable, KeyListener {
// ID
private static final long serialVersionUID = 1L;
// Dimensions
public static final int WIDTH = 320;
public static final int HEIGHT = 240;
public static final int SCALE = 2;
// Thread
private Thread thread;
private boolean running;
private int FPS = 30;
private long targetTime = 1000 / FPS;
// Image
private BufferedImage image;
private Graphics2D g;
// Game State Manager
private GameStateManager gsm;
public GamePanel() {
super();
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setFocusable(true);
requestFocus();
}
public void addNotify() {
super.addNotify();
if (thread == null) {
thread = new Thread(this);
addKeyListener(this);
thread.start();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
private void init() {
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D) image.getGraphics();
running = true;
gsm = new GameStateManager();
}
#Override
public void run() {
init();
long start;
long elapsed;
long wait;
// Game Loop
while (running) {
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - (elapsed / 1000000);
if (wait < 0) {
wait = 5;
}
try {
Thread.sleep(wait);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void update() {
gsm.update();
}
private void draw() {
gsm.draw(g);
}
private void drawToScreen() {
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, WIDTH * SCALE, HEIGHT * SCALE, null);
g2.dispose();
}
#Override
public void keyPressed(KeyEvent k) {
gsm.keyPressed(k.getKeyCode());
}
#Override
public void keyReleased(KeyEvent k) {
}
#Override
public void keyTyped(KeyEvent arg0) {
}
}
This calls for the creation of a new GameStateManager object in its init() method and the class for that is here.
GameStateManager.java
public class GameStateManager {
private ArrayList<GameState> gameStates;
private int currentState;
public static final int MENUSTATE = 0;
public static final int SLOTGAMESTATE = 1;
public static final int DICEGAMESTATE = 2;
public static final int ROULETTEGAMESTATE = 3;
public static final int LEADERBOARDSTATE = 4;
public static final int SETTINGSSTATE = 5;
public static final int HELPSTATE = 6;
public GameStateManager() {
gameStates = new ArrayList<GameState>();
currentState = 0;
gameStates.add(new MenuState(this));
gameStates.add(new SlotGameState(this));
gameStates.add(new DiceGameState(this));
gameStates.add(new RouletteGameState(this));
gameStates.add(new LeaderboardState(this));
gameStates.add(new SettingsState(this));
gameStates.add(new HelpState(this));
}
public void setState(int state){
currentState = state;
gameStates.get(currentState).init();
currentState = 0;
}
public int getState() {
return currentState;
}
public void update() {
gameStates.get(currentState).init();
}
public void draw(java.awt.Graphics2D g){
gameStates.get(currentState).draw(g);
}
public void keyPressed(int k){
gameStates.get(currentState).keyPressed(k);
}
public void keyReleased(int k) {
gameStates.get(currentState).keyReleased(k);
}
}
GameState is an abstract class I have so its not worth posting, it only contains init(), draw(), etc. This next class is the last and final class and is called because GameStateMananger starts at MENUSTATE or 0, and when GSM is initialized it initializes its current state, thus taking us to the class MenuState
MenuState.java
public class MenuState extends GameState {
private Background bg;
public FontMetrics fontMetrics;
private int choice = 0;
private String[] options = { "Slot Machine", "Dice Toss", "Roulette Wheel", "Leaderboards", "Settings", "Help",
"Quit" };
private Color titleColor;
private Font titleFont;
private Font font;
public MenuState(GameStateManager gsm) {
this.gsm = gsm;
try {
bg = new Background("/Backgrounds/happybg.png");
titleColor = Color.WHITE;
titleFont = new Font("Georgia", Font.PLAIN, 28);
} catch (Exception e) {
e.printStackTrace();
}
font = new Font("Arial", Font.PLAIN, 12);
}
#Override
public void init() {
}
#Override
public void update() {
}
#Override
public void draw(Graphics2D g) {
Canvas c = new Canvas();
fontMetrics = c.getFontMetrics(font);
// Draw BG
bg.draw(g);
// Draw title
g.setColor(titleColor);
g.setFont(titleFont);
String title = "Jolly Jackpot Land!";
g.drawString(title, 36, 60);
g.setFont(font);
for (int i = 0; i < options.length; i++) {
if (i == choice)
g.setColor(Color.RED);
else
g.setColor(Color.WHITE);
g.drawString(options[i], 30, 120 + i * 15);
}
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.PLAIN, 10));
g.drawString("v1.1", 165, 235);
Object[] a = { ("Name: " + Player.getName()), ("Gil: " + Player.getGil()),
("Personal Best: " + Player.getPersonalBest()), ("Winnings: " + Player.getWinnings()),
("Wins: " + Player.getWins()), ("Losses: " + Player.getLosses()),
("Win/Loss Ratio: " + String.format("%.2f", Player.getRatio()) + "%") };
g.setFont(font);
if (Player.getName() != null) {
for (int x = 0; x < a.length; x++) {
g.drawString(a[x].toString(), GamePanel.WIDTH - fontMetrics.stringWidth(a[x].toString()) - 30,
120 + x * 15);
}
}
}
private void select() {
if (choice == 0) {
// Slots
gsm.setState(GameStateManager.SLOTGAMESTATE);
}
if (choice == 1) {
// Dice
gsm.setState(GameStateManager.DICEGAMESTATE);
}
if (choice == 2) {
// Roulette
gsm.setState(GameStateManager.ROULETTEGAMESTATE);
}
if (choice == 3) {
// Leaderboards
gsm.setState(GameStateManager.LEADERBOARDSTATE);
}
if (choice == 4) {
// Settings
gsm.setState(GameStateManager.SETTINGSSTATE);
}
if (choice == 5) {
// Help
gsm.setState(GameStateManager.HELPSTATE);
}
if (choice == 6) {
// Quit
System.exit(0);
}
}
#Override
public void keyPressed(int k) {
if (k == KeyEvent.VK_ENTER) {
select();
}
if (k == KeyEvent.VK_UP) {
choice--;
if (choice == -1) {
choice = options.length - 1;
}
}
if (k == KeyEvent.VK_DOWN) {
choice++;
if (choice == options.length) {
choice = 0;
}
}
}
#Override
public void keyReleased(int k) {
}
}
Background.java
public class Background {
private BufferedImage image;
private double x;
private double y;
public Background(String s) {
try {
image = ImageIO.read(getClass().getResourceAsStream(s));
} catch (Exception e) {
e.printStackTrace();
}
}
public void setPosition(double x, double y) {
this.setX(x);
this.setY(y);
}
public void draw(Graphics2D g) {
g.drawImage(image, 0, 0, null);
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
}
This is where it waits for input in the game loop basically. I know this is a lot of code, but a lot of it is skimming till a method call takes you to the next class. I just can't figure out why it only happens sometimes, if it was consistent I could debug it. Any help would be extremely appreciated.
These are both from clicking the .jar of the above program, exact same .jar, exact same source code, different result. I am bewildered.

Simon Says won't show sequence

Below is a Simon Says program I am working on. Right now it only displays a gray frame. I added in a keyListener to see if i could make the arcs light up.I wanted to display a flash animation sequence. Why isn't this working?
public class SimonShape extends JFrame implements KeyListener, ActionListener {
private JFrame f;
private JPanel p;
public static void main(String[] args) {
new SimonShape();
}
public SimonShape() {
f = new JFrame("Simon Says");
f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawStuff draw = new DrawStuff();
p = new JPanel();
p.setBackground(Color.GRAY);
p.setLayout(new BorderLayout());
draw.playSequence();
p.add(draw, BorderLayout.CENTER);
// initiates the sequence
f.add(p);
f.addKeyListener(this);
f.setLocationRelativeTo(null); // positions the frame in the middle of
// the screen
f.setVisible(true);
}
public class DrawStuff extends JComponent {
Color COLOR1;
Color COLOR2;
Color COLOR3;
Color COLOR4;
public void playSequence() {
ArrayList<Integer> Computer = new ArrayList<Integer>();
ArrayList<Integer> Player = new ArrayList<Integer>();
int compPick, compPick2, compPick3, compPick4;
Random gen = new Random();
compPick = gen.nextInt(4);
compPick2 = gen.nextInt(4);
compPick3 = gen.nextInt(4);
compPick4 = gen.nextInt(4);
Computer.add(compPick);
Computer.add(compPick4);
Computer.add(compPick2);
Computer.add(compPick3);
for (int i = 0; i < Computer.size(); i++) {
if (Computer.get(i) == 0) {
COLOR1 = Color.GREEN.brighter();
repaint();
} else if (Computer.get(i) == 1) {
COLOR2 = Color.BLUE.darker();
repaint();
} else if (Computer.get(i) == 2) {
COLOR3 = Color.RED.darker();
repaint();
} else if (Computer.get(i) == 3) {
COLOR4 = Color.YELLOW.brighter();
repaint();
}
}
}
}
public int flash = 0;
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Graphics2D g3 = (Graphics2D) g;
Graphics2D g4 = (Graphics2D) g;
Graphics2D g5 = (Graphics2D) g;
// assume d == 145 && e == 90
if (flash == 1) {
g2.setPaint(Color.GREEN);
} else {
g2.setPaint(Color.GREEN.darker());
}
g2.fill(new Arc2D.Double(150, 150, 200, 200, 145, 90, Arc2D.PIE));
if (flash == 2) {
g3.setPaint(Color.BLUE);
} else {
g3.setPaint(Color.BLUE.darker());
}
g3.fill(new Arc2D.Double(150, 150, 200, 200, 235, 90, Arc2D.PIE));
if (flash == 3) {
g4.setPaint(Color.RED);
} else {
g4.setPaint(Color.RED.darker());
}
g4.fill(new Arc2D.Double(150, 150, 200, 200, 325, 90, Arc2D.PIE));
if (flash == 4) {
g5.setPaint(Color.YELLOW);
} else {
g4.setPaint(Color.YELLOW.darker());
}
g5.fill(new Arc2D.Double(150, 150, 200, 200, 55, 90, Arc2D.PIE));
}
public void keyPressed(KeyEvent e) {
int event = e.getKeyCode();
if (event == KeyEvent.VK_RIGHT) {
flash = 1;
}
if (event == KeyEvent.VK_DOWN) {
flash = 2;
}
if (event == KeyEvent.VK_LEFT) {
flash = 3;
}
if (event == KeyEvent.VK_UP) {
flash = 4;
}
}
#Override
public void keyTyped(KeyEvent e) {//not used
}
#Override
public void keyReleased(KeyEvent e) {//not used
}
#Override
public void actionPerformed(ActionEvent e) {//not used
}
}
When creating any Swing GUI, you should always use the model / view / controller pattern. This pattern allows you to separate your concerns and focus on one part of the GUI at a time.
Divide and conquer.
Here's the GUI I created.
The first thing I did was create a model for the game. The GameModel class is a plain Java object that holds the computer sequence and the player sequence.
public class GameModel {
private List<Integer> computerSequence;
private List<Integer> playerSequence;
private Random random;
public GameModel() {
this.computerSequence = new ArrayList<Integer>();
this.playerSequence = new ArrayList<Integer>();
this.random = new Random();
}
public void addToComputerSequence() {
computerSequence.add(Integer.valueOf(random.nextInt(4)));
}
public void clearComputerSequence() {
computerSequence.clear();
}
public List<Integer> getComputerSequence() {
return computerSequence;
}
public void clearPlayerSequence() {
playerSequence.clear();
}
public void addToPlayerSequence(int number) {
playerSequence.add(Integer.valueOf(number));
}
public boolean doSequencesMatch() {
if (computerSequence.size() == playerSequence.size()) {
for (int i = 0; i < computerSequence.size(); i++) {
int computer = computerSequence.get(i);
int player = playerSequence.get(i);
if (computer != player) {
return false;
}
}
return true;
}
return false;
}
}
The model class allows us to add to the computer sequence, add to the player sequence, and determine if the computer and player sequence match.
Next, we need a model class to hold the 4 slices of the circle. The ArcModel class is another plain Java object that holds a slice.
public class ArcModel {
private final int closureType;
private final double startingAngle;
private final double extent;
private Color color;
private final Color originalColor;
private final Rectangle rectangle;
public ArcModel(Color color, Rectangle rectangle, double startingAngle,
double extent, int closureType) {
this.color = color;
this.originalColor = color;
this.rectangle = rectangle;
this.startingAngle = startingAngle;
this.extent = extent;
this.closureType = closureType;
}
public int getClosureType() {
return closureType;
}
public double getStartingAngle() {
return startingAngle;
}
public double getExtent() {
return extent;
}
public Rectangle getRectangle() {
return rectangle;
}
public Color getColor() {
return color;
}
public void brighterColor() {
this.color = Color.WHITE;
}
public void darkerColor() {
this.color = originalColor;
}
}
In addition to the getters and setters, we have a method to brighten the color and a method to darken the color. I've set the bright color to white to make it more easily visible.
Now that we've created the model classes, let's look at the view classes. The first view class is the DrawingPanel class.
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 70146219705119575L;
private List<ArcModel> segments;
public DrawingPanel() {
this.segments = new ArrayList<ArcModel>();
int margin = 50;
int diameter = 300;
Rectangle r = new Rectangle(margin, margin, diameter, diameter);
segments.add(new ArcModel(Color.GREEN, r, 180, 90, Arc2D.PIE));
segments.add(new ArcModel(Color.BLUE, r, 270, 90, Arc2D.PIE));
segments.add(new ArcModel(Color.RED, r, 360, 90, Arc2D.PIE));
segments.add(new ArcModel(Color.YELLOW, r, 90, 90, Arc2D.PIE));
int width = diameter + margin + margin;
this.setPreferredSize(new Dimension(width, width));
}
public void brighterArcModelColor(int index) {
segments.get(index).brighterColor();
repaint();
}
public void darkerArcModelColor(int index) {
segments.get(index).darkerColor();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (ArcModel arcModel : segments) {
g2d.setPaint(arcModel.getColor());
Rectangle r = arcModel.getRectangle();
g2d.fill(new Arc2D.Double(r.getX(), r.getY(), r.getWidth(), r
.getHeight(), arcModel.getStartingAngle(), arcModel
.getExtent(), arcModel.getClosureType()));
}
}
}
Here, we create a List of ArcModel segments. We set the size of the drawing panel based on the margin and diameter of the circle we want to create with the segments.
We have two methods, one for brightening a color of a segment, and another for darkening a color of a segment.
We do the drawing in the paintComponent method. Since we created the ArcModel class, the actual drawing is straightforward. The paintComponent method does nothing but draw the pie slices of the circle.
Next, we look at the main SimonShape class. This class creates the game model and creates the GUI.
public class SimonShape implements Runnable {
private GameModel gameModel;
private JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new SimonShape());
}
public SimonShape() {
this.gameModel = new GameModel();
}
#Override
public void run() {
frame = new JFrame("Simon Says");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawingPanel drawingPanel = new DrawingPanel();
frame.add(drawingPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
GameRunnable runnable = new GameRunnable(drawingPanel, gameModel);
new Thread(runnable).start();
}
}
The last two lines of the run method create the animation.
The controller class is the GameRunnable class. I wrote enough code to have the computer pick 10 random segments, and display the sequence of the segments. I'm leaving the rest of the game code up to you. It will go in the GameRunnable class.
public class GameRunnable implements Runnable {
private volatile boolean running;
private DrawingPanel drawingPanel;
private GameModel gameModel;
public GameRunnable(DrawingPanel drawingPanel, GameModel gameModel) {
this.drawingPanel = drawingPanel;
this.gameModel = gameModel;
}
#Override
public void run() {
running = true;
while (running && gameModel.getComputerSequence().size() < 10) {
generateComputerSequence();
sleep(1800L);
}
}
private void generateComputerSequence() {
gameModel.addToComputerSequence();
for (Integer index : gameModel.getComputerSequence()) {
drawingPanel.brighterArcModelColor(index);
sleep(1000L);
drawingPanel.darkerArcModelColor(index);
sleep(200L);
}
}
private void sleep(long duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
}
}
public synchronized void setRunning(boolean running) {
this.running = running;
}
}
Remember, divide and conquer.

How come the ball size wont increase?(Game)

I'm trying to make an addition to a pong game framework.I want the ball size to increase everytime the ball make contact with a paddle.
Here is my attempt. The first block of code is where I think the problem lays. The 2nd block is the whole class.
public class PlayState extends State {
private Paddle paddleRight, paddleLeft;
private static final int PADDLE_WIDTH = 30;
private static final int PADDLE_HEIGHT = 60;
private Ball ball;
//bDiam stands for ball diameter
private static int bDiam = 10;
private int playerScore = 0;
private Font scoreFont;
#Override
public void init() {
paddleLeft = new Paddle(0, 195, PADDLE_WIDTH, PADDLE_HEIGHT);
paddleRight = new Paddle(785, 195, PADDLE_WIDTH, PADDLE_HEIGHT);
scoreFont = new Font("SansSerif", Font.BOLD, 25);
ball = new Ball(300, 200, bDiam, bDiam);
}
#Override
public void onClick(MouseEvent e) {
// playerScore = 5;
}
#Override
public void update() {
paddleLeft.update();
paddleRight.update();
ball.update();
if (ballCollides(paddleLeft)) {
playerScore++;
bDiam+= 20;
ball.onCollideWith(paddleLeft);
Resources.hit.play();
} else
if (ballCollides(paddleRight)) {
playerScore++;
bDiam= bDiam + 20;
ball.onCollideWith(paddleRight);
Resources.hit.play();
} else if (ball.isDead()) {
playerScore -= 3;
ball.reset();
}
}
The Complete Class
public class PlayState extends State {
private Paddle paddleRight, paddleLeft;
private static final int PADDLE_WIDTH = 30;
private static final int PADDLE_HEIGHT = 60;
private Ball ball;
//bDiam stands for ball diameter
private static int bDiam = 10;
private int playerScore = 0;
private Font scoreFont;
#Override
public void init() {
paddleLeft = new Paddle(0, 195, PADDLE_WIDTH, PADDLE_HEIGHT);
paddleRight = new Paddle(785, 195, PADDLE_WIDTH, PADDLE_HEIGHT);
scoreFont = new Font("SansSerif", Font.BOLD, 25);
ball = new Ball(300, 200, bDiam, bDiam);
}
#Override
public void onClick(MouseEvent e) {
// playerScore = 5;
}
#Override
public void update() {
paddleLeft.update();
paddleRight.update();
ball.update();
if (ballCollides(paddleLeft)) {
playerScore++;
bDiam+= 20;
ball.onCollideWith(paddleLeft);
Resources.hit.play();
} else
if (ballCollides(paddleRight)) {
playerScore++;
bDiam= bDiam + 20;
ball.onCollideWith(paddleRight);
Resources.hit.play();
} else if (ball.isDead()) {
playerScore -= 3;
ball.reset();
}
}
#Override
public void render(Graphics g) {
// Draw Background
g.setColor(Resources.darkBlue);
g.fillRect(0, 0, GameMain.GAME_WIDTH, GameMain.GAME_HEIGHT);
g.setColor(Resources.darkRed);
g.fillRect(GameMain.GAME_WIDTH / 2, 0, GameMain.GAME_WIDTH / 2,
GameMain.GAME_HEIGHT);
// Draw Separator Line
g.drawImage(Resources.line, (GameMain.GAME_WIDTH / 2) - 2, 0, null);
// Draw Paddles
g.setColor(Color.white);
g.fillRect(paddleLeft.getX(), paddleLeft.getY(), paddleLeft.getWidth(),
paddleLeft.getHeight());
g.fillRect(paddleRight.getX(), paddleRight.getY(),
paddleRight.getWidth(), paddleRight.getHeight());
// Draw Ball
g.drawRect(ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight());
// Draw UI
g.setFont(scoreFont); // Sets scoreFont as current font
g.drawString("" + playerScore, 350, 40); // Draws String using current
// font
}
#Override
public void onKeyPress(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
paddleLeft.accelUp();
paddleRight.accelUp();
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
paddleLeft.accelDown();
paddleRight.accelDown();
}
}
#Override
public void onKeyRelease(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP
|| e.getKeyCode() == KeyEvent.VK_DOWN) {
paddleLeft.stop();
paddleRight.stop();
}
}
private boolean ballCollides(Paddle p) {
return ball.getRect().intersects(p.getRect());
}
}
Your diameter variable is being passed by value into your Ball constructor. That means changing its value in your main program won't change it for the ball.
You need something like
ball.setDiameter(ball.getDiameter() +20)

Categories

Resources