JFrame.dispose(); isn't doing anything - java

I've tried every solution I could find here and on forums but I cannot close the wind JFrame no matter what I do and I have no idea why. I need to dispose of the JFrame and launch a different one by creating a WarioWareGUI object.
Right now, the best I seem to be able to do is stop the ball from moving and just leave the old JFrame in the background, but that's not quite good enough. I need the wind JFrame to close
I've tried infinitely disposing, I've tried setting the JFrame as public static and initializing it as an object of BallGame so that I can dispose from anywhere. I've tried simply disposing it immediately after creating it. Nothing seems to get rid of it.
I even tried just setting the ball speed to 0 and making the frame invisible but wind.setVisible(false); doesn't do anything either.
package GameProject;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.Timer;
import javax.swing.WindowConstants;
public final class BallGame extends JComponent implements ActionListener, MouseMotionListener, KeyListener {
private int ballx = 150;
private int bally = 30;
private int paddlex = 0;
private static int ballySpeed = 7;
private static int ballxSpeed = 5;
private int score = 0;
private int round = 1;
private int bounces = 0;
private static int delay = 20;
public static boolean gameOver = false;
public static boolean gameOverFlag = false;
public boolean started;
public static void main(int round) {
//only true the first time the game is run
if ((gameOver == false) && (gameOverFlag == false)) {
gameMake(round);
}
//only true after the game has resulted in a loss
if ((gameOver == true) && (gameOverFlag==true)) {
gameOver = false;
//gameMake(round);
WarioWareGUI gui = new WarioWareGUI();
}
//only true after the game has resulted in a loss and
//returned to main menu
if ((gameOver == false) && (gameOverFlag==true)) {
}
}
public static void gameMake(int round) {
JFrame wind = new JFrame("RedBall/GamePinfo");
BallGame g = new BallGame();
wind.add(g);
wind.pack();
wind.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
wind.setLocationRelativeTo(null);
wind.setVisible(true);
wind.addMouseMotionListener(g);
wind.dispose();
//speed up the timer each round
Timer tt = new Timer(delay, g);
tt.start();
}
public void newball(int ballx, int bally, int ballxspeed, int ballyspeed) {
ballx = 150;
bally = 30;
ballxspeed = 5;
ballyspeed = 7;
JOptionPane.showMessageDialog(null, "new ball !");
return;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
#Override
protected void paintComponent(Graphics g) {
//draw the sky
g.setColor(Color.cyan);
g.fillRect(0, 0, 800, 600);
g.setColor(Color.GREEN);
g.fillRect(0, 550, 800, 100);
//draw the paddel
g.setColor(Color.black);
g.fillRect(paddlex, 500, 100, 20);
//draw the ball
g.setColor(Color.RED);
g.fillOval(ballx, bally, 30, 30);
g.setColor(Color.white);
g.setFont(new Font("Arial", 8, 50));
g.drawString(String.valueOf(score), 30, 80);
}
#Override
public void actionPerformed(ActionEvent e) {
//Manages ball movement
ballx = ballx + ballxSpeed;
bally = bally + ballySpeed;
if (gameOverFlag) {
round = 1;
BallGame.main(round);
}
else if (gameOver) {
gameOverFlag = true;
//displays the dialog box indicating victory
JOptionPane.showMessageDialog(this, "You lost on round"
+ round + "!");
ballx = 150;
bally = 30;
}
else if (bounces==10) {
//reset score
bounces = 0;
round++;
JOptionPane.showMessageDialog(this,"You Win! You move on to"
+ " round " + round + "!");
}
// Sets ball speed upward if it hits the paddle
else if (ballx >= paddlex && ballx <= paddlex + 100 && bally >= 475) {
ballySpeed = -7 - (round*2);
//monitors the number of times the ball is successfully hit
score++;
bounces++;
}
// Handles loss condition
else if (bally >= 500 ) {
gameOver = true;
}
// Sets ball movement down if it hits the ceiling
else if (bally <= 0) {
ballySpeed = 7 + (round*2);
}
// Sets ball
else if (ballx >= 775) {
ballxSpeed = -5 - (round*2);
}
// Window left
else if (ballx <= 0) {
ballxSpeed = 5 + (round*2);
}
//**********************************************************************
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
//places paddle in middle of mouse
paddlex = e.getX() - 50;
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
}
I expect calling wind.dispose to shut down the GUI but it won't, no matter where I put it or how I declare the JFrame. I can't just make it invisible either.
The code right now is just where it was when I gave up, I'm not trying to just dispose of it right away of course, but once I can get it to just dispose once successfully, hopefully I can get it to do that at the right time.

Related

How do I add a retry function to my Snake game?

I made a snake game following a youtube tutorial. The game has two states: either "RUNNING" when you start the game and play or "END" when you die. To play the game again you have to close the window and run the code again. I would like to make the game start again when i hit the ENTER key on the "END" screen. Ill attack some of the code and any help is appreciated.
this is the code for the GameUI
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import java.awt.Toolkit;
public class GameUI
// This is the code for the GameUI
implements KeyListener{
private Snake player;
private Food food;
private Drawing drawing;
private Superfood sfood;
private JFrame panel;
private ImageIcon icon;
public static final int width = 20;
public static final int height = 20;
public static final int dimension = 30;
public GameUI() {
// definde the Jframe within which the game is played
panel = new JFrame();
player = new Snake();
food = new Food(player);
sfood = new Superfood(player);
drawing = new Drawing(this);
panel.getContentPane().add(drawing);
panel.setTitle("Cryptic Snake v1");
panel.setSize(width * dimension + 2, height * dimension + dimension + 4);
panel.setVisible(true);
panel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
icon = new ImageIcon("images/SNAKE.png");
panel.setIconImage(Toolkit.getDefaultToolkit().getImage(GameUI.class.getResource("/images/SNAKE.png")));
}
public void start() {
drawing.state = "RUNNING"; //set state to running and initiate the game
}
// with this if else loop we can manage the game
public void checker() {
if(drawing.state == "RUNNING") { // given that the game is running...
if(foodcrash()) {
player.grow(); // call grow-method when snake bumps into food
food.random_spawn(player); // and spawn new food
}
if(sfoodcrash()) {
player.grow();
player.grow();
player.grow();
// call grow-method when snake bumps into food
food.random_spawn(player); // and spawn new food
}
else if(wallcrash() || autocrash()) { //end the game if the snake bumps into itself or a wall
drawing.state = "END";
}
else {
player.move();
}
}
}
//here we check if the snake is bumping into a wall
private boolean wallcrash() {
if(player.getX() < 0 || player.getX() >= width * dimension
|| player.getY() < 0|| player.getY() >= height * dimension) {
return true;
}
return false;
}
// here we check if the snake is bumping into food
private boolean foodcrash() {
if(player.getX() == food.getX() * dimension && player.getY() == food.getY() * dimension) {
return true;
}
return false;
}
// here we check if the snake is bumping into food
private boolean sfoodcrash() {
if(player.getX() == sfood.getSx() * dimension && player.getY() == sfood.getSy() * dimension) {
return true;
}
return false;
}
// here we check has bumped into itself
private boolean autocrash() {
for(int i = 1; i < player.getSnk().size(); i++) {
if(player.getX() == player.getSnk().get(i).x &&
player.getY() == player.getSnk().get(i).y) {
return true;
}
}
return false;
}
// now we add a keylistener that listens to the inputs on our keyboard
#Override
public void keyTyped(KeyEvent e) { }
#Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(drawing.state == "RUNNING") {
if(keyCode == KeyEvent.VK_UP && player.getMove() != "UP") { // up-arrow-key
player.up();
}
if(keyCode == KeyEvent.VK_DOWN && player.getMove() != "DOWN") { // down-arrow-key
player.down();
}
if(keyCode == KeyEvent.VK_LEFT && player.getMove() != "LEFT") { //left-arrow-key
player.left();
}
if(keyCode == KeyEvent.VK_RIGHT && player.getMove() != "RIGHT") {//right-arrow-key
player.right();
}
}
else {
this.start();}
}
#Override
public void keyReleased(KeyEvent e) { }
//auto-generated getters and setters
public Snake getPlayer() {
return player;
}
public void setPlayer(Snake player) {
this.player = player;
}
public Food getFood() {
return food;
}
public void setFood(Food food) {
this.food = food;
}
public JFrame getPanel() {
return panel;
}
public Superfood getSfood() {
return sfood;
}
public void setSfood(Superfood sfood) {
this.sfood = sfood;
}
public void setPanel(JFrame window) {
this.panel = window;
}
public Drawing getGraphics() {
return drawing;
}
public static int getWidth() {
return width;
}
public static int getHeight() {
return height;
}
public static int getDimension() {
return dimension;
}
public void setGraphics(Drawing drawing) {
this.drawing = drawing;
}
}
this is the code for the drawing class
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.awt.Font;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import java.awt.SystemColor;
//this code is responsible for the graphics, so everything you see on the screen
// we use a paint component that redraws everything within a given time interval
public class Drawing
extends JPanel
implements ActionListener {
private Timer t = new Timer(100, this); //we want to redraw the screen every 100 milliseconds, this defindes speed of snake
public String state; // we use states as there are two different situations: either the game is running or you died
private Superfood sf;
private Snake s;
private Food f;
private GameUI gameUI;
public Drawing(GameUI g) {
setBackground(SystemColor.activeCaptionBorder);
t.start();
state = "RUNNING";
gameUI = g;
s = g.getPlayer();
f = g.getFood();
sf= g.getSfood();
//add a keyListner
this.addKeyListener(g);
this.setFocusable(true);
this.setFocusTraversalKeysEnabled(false);
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGap(0, 450, Short.MAX_VALUE)
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
setLayout(groupLayout);
}
public void paintComponent(java.awt.Graphics g) {
super.paintComponent(g);
Font font = new Font("Playbill", 10,50);
Font sfont = new Font("Perpetua Titling MT", 10,30);
Graphics2D g2d = (Graphics2D) g; //make it 2D
//drawing the background
g2d.setColor(Color.gray);
g2d.fillRect(0, 0, GameUI.width * GameUI.dimension + 5, GameUI.height * GameUI.dimension + 5);
if(state == "RUNNING") { // drawing the food in the case that the game is running
g2d.setColor(Color.cyan);
g2d.fillOval(f.getX() * GameUI.dimension, f.getY() * GameUI.dimension, GameUI.dimension, GameUI.dimension);
g2d.setColor(Color.BLUE);
if (s.getSnk().size() % 5 == 0)
g2d.fillRoundRect(sf.getSx() * GameUI.dimension, sf.getSy() * GameUI.dimension, GameUI.dimension, GameUI.dimension,12,12);
g2d.setColor(Color.DARK_GRAY); //drawing the snake in the case the the game is runnng
for(Rectangle r : s.getSnk()) {
g2d.fill(r);
}
}
else { //if the game is not running display the score
g2d.setColor(Color.DARK_GRAY);
g2d.setFont(sfont);
g2d.drawString("Your score was", GameUI.width/2 * GameUI.dimension - 175, GameUI.height / 2 * GameUI.dimension - 25);
g2d.setFont(font);
g2d.drawString("" + (s.getSnk().size() ), GameUI.width/2 * GameUI.dimension + 117, GameUI.height / 2 * GameUI.dimension - 20);
}
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
gameUI.checker(); //check if the snake is bumping into a wall itself or food or nothing to determine what to draw next
}
}
I had something similar and I did this:
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
Main.frame.dispose();
new Main();
}
});
where the Main is a class you initializing the frame in it.

Stuttering Swing Animation

I'm attempting to recreate Pong, and can't quite get the animations to run as smooth as I would like them too. Sometimes the ball does motion where it slows and then jerks really fast. Where in my code do I go wrong? Also, if you could review my code as well it's be appreciated. I'm just trying to get better.
Code for the ball
import java.awt.geom.Ellipse2D;
public class Ball extends Ellipse2D.Double{
//Ball movement variables
boolean movementX = true;
boolean movementY = true;
// Player one info
private int p1Number = 0;
private String p1Score = "0";
// Player two info
private int p2Number = 0;
private String p2Score = "0";
// Constructor
public Ball(double x, double y){
this.x = x;
this.y = y;
height = 20;
width = 20;
}
//function created to move the puck based on the position of the Puck, and the Players
public void MovePuck(double PlayerX, double PlayerY, double PlayerTwoX, double PlayerTwoY) {
// automatically move the X values
if (movementX) {
x+=5;
if (x >= 580) {
movementX = false;
}
} else {
x-=5;
if (x <= 0) {
movementX = true;
}
}
// automatically move the Y values
if (movementY) {
y+=2;
if (y >= 380) {
movementY = false;
}
} else {
y-=2;
if (y <= 0) {
movementY = true;
}
}
// Make Puck Bounce Off Player One
if(x == PlayerX + 10 && y <= PlayerY + 50 && y >= PlayerY){
movementX = true;
}
// Make Puck Bounce off Player Two
if(x == PlayerTwoX - 10 && y <= PlayerTwoY + 50 && y >= PlayerTwoY){
movementX = false;
}
}
// function created to keep track of Player One's Score
public String p1Score(){
if(x == 580){
p1Number++;
}
p1Score = String.valueOf(p1Number);
return p1Score;
}
// function created to keep track of Player Two's Score
public String p2Score(){
if (x == 0) {
p2Number++;
}
p2Score = String.valueOf(p2Number);
return p2Score;
}
}
Code for the ball
import java.awt.geom.Rectangle2D;
public class Rectangle extends Rectangle2D.Double{
private boolean isMovingUp, isMovingDown;
public Rectangle(double x, double y){
this.x = x;
this.y = y;
width = 10;
height = 50;
}
public void movePlayerUP(){
y-=3;
}
public void movePlayerDown(){
y+=3;
}
public void setMovingDown(boolean movingDown) {
isMovingDown = movingDown;
}
public boolean isMovingDown() {
return isMovingDown;
}
public void setMovingUp(boolean movingUp) {
isMovingUp = movingUp;
}
public boolean isMovingUp() {
return isMovingUp;
}
#Override
public double getY() {return super.getY();}
public double getX(){return super.getX();}
}
And finally, the Board that holds the logic. The main just calls this and runs it.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
public class Board extends JPanel {
private BufferedImage background;
//player one information
private int p1X = 20;
private int p1Y = 150;
private Rectangle playerOne;
//player two information
private int p2X = 550;
private int p2Y = 150;
private Rectangle playerTwo;
// puck information
private int PuckX = 290;
private int PuckY = 190;
private Ball Puck;
public Board() {
// creating each player and puck
playerOne = new Rectangle(p1X, p1Y);
playerTwo = new Rectangle(p2X, p2Y);
Puck = new Ball(PuckX, PuckY);
setDoubleBuffered(true);
addKeyBinding(this, KeyEvent.VK_UP, "moveUpPressed", false, (evt) -> {
playerOne.setMovingUp(true);
});
addKeyBinding(this, KeyEvent.VK_UP, "moveUpReleased", true, (evt) -> {
playerOne.setMovingUp(false);
});
addKeyBinding(this, KeyEvent.VK_DOWN, "moveDownPressed", false, (evt) -> {
playerOne.setMovingDown(true);
});
addKeyBinding(this, KeyEvent.VK_DOWN, "moveDownReleased", true, (evt) -> {
playerOne.setMovingDown(false);
});
addKeyBinding(this, KeyEvent.VK_W, " moveP2UpPressed", false, (evt) -> {
playerTwo.setMovingUp(true);
});
addKeyBinding(this, KeyEvent.VK_W, " moveP2UpReleased", true, (evt) -> {
playerTwo.setMovingUp(false);
});
addKeyBinding(this, KeyEvent.VK_S, " moveP2DownPressed", false, (evt) -> {
playerTwo.setMovingDown(true);
});
addKeyBinding(this, KeyEvent.VK_S, " moveP2DownReleased", true, (evt) -> {
playerTwo.setMovingDown(false);
});
// Timer to represent frames per second and constantly check the status of each button pressed
Timer timer = new Timer(20, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Move puck
Puck.MovePuck(playerOne.getX(), playerOne.getY(), playerTwo.getX(), playerTwo.getY());
repaint();
//Only move if the player is pressing each button
//Player One Moving UP
if(playerOne.isMovingUp()){
playerOne.movePlayerUP();
}
//Player One Moving Down
if(playerOne.isMovingDown()){
playerOne.movePlayerDown();
}
//Player Two Moving Up
if(playerTwo.isMovingUp()){
playerTwo.movePlayerUP();
}
//Player Two Moving Down
if(playerTwo.isMovingDown()){
playerTwo.movePlayerDown();
}
}
});
//Start Timer
timer.start();
}
// Created a function that represents adding keybinding. Easier than re-writing a function each time
public void addKeyBinding(JComponent comp, int keyCode, String id, boolean movement, ActionListener ActionListener){
InputMap im = comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap ap = comp.getActionMap();
im.put(KeyStroke.getKeyStroke(keyCode, 0 , movement), id);
ap.put(id, new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
ActionListener.actionPerformed(e);
repaint();
}
});
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
setOpaque(false);
// setting background with image
background = new BufferedImage(600, 400, BufferedImage.TYPE_INT_RGB);
g.drawImage(background, 0, 0, this);
// drawing player one
g.setColor(Color.blue);
((Graphics2D) g).fill(playerOne);
// drawing player two
g.setColor(Color.red);
((Graphics2D) g).fill(playerTwo);
// drawing puck
g.setColor(Color.orange);
((Graphics2D) g).fill(Puck);
//Player One Score
g.setColor(Color.white);
g.setFont(new Font("Arial", Font.PLAIN, 20));
g.drawString(Puck.p1Score(), 100, 30);
//Player Two Score
g.setColor(Color.white);
g.setFont(new Font("Arial", Font.PLAIN, 20));
g.drawString(Puck.p2Score(), 450, 30);
g.dispose();
}
}

Java help: make image move across the screen

I've been having trouble with this for quite a while now
I am trying to make a space shooter but to no avail, I'm trying to make the bullet move across the screen like in space invaders etc
when the player presses the space bar a bullet should appear where the player's X position is and move right across the screen.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class game extends JFrame{
boolean run = true;
boolean fired = false;
Image player;
Image bullet;
int playerX = 100;
int playerY = 200;
int bulletX;
int bulletY;
public game(){
//Load Images:
ImageIcon playerI = new ImageIcon("C:/Users/Dan/workspace/shooterProject/bin/shooterProject/ship.png");
player = playerI.getImage();
ImageIcon bulletI = new ImageIcon("C:/Users/Dan/workspace/shooterProject/bin/shooterProject/bullet.png");
bullet = bulletI.getImage();
//Set up game
addKeyListener(new AL());
addMouseListener(new Mouse());
init();
}
private Image dbImage;
private Graphics dbg;
public static void main(String[] args) {
new game();
}
//When the program runs, thins are initialised here
public void init(){
windowManager();
}
public void paintComponent(Graphics g){
if(run == true){
g.drawImage(player, playerX, playerY, this);
}
if(fired == true){
g.drawImage(bullet, bulletX, bulletY, this);
}
repaint();
}
public void paint(Graphics g){
dbImage = createImage(getWidth(), getHeight());
dbg = dbImage.getGraphics();
paintComponent(dbg);
g.drawImage(dbImage,0,0,this);
}
public void bullet(){
bulletX = playerX;
bulletY = playerY;
while(fired == true){
bulletX = bulletX + 10;
if(bulletX == 800){
bullet = null;
fired = false;
}
}
}
public void windowManager(){
JFrame f = new JFrame();
setTitle("Engine");
setVisible(true);
setResizable(false);
setSize(800,400);
setBackground(Color.BLACK);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public class AL extends KeyAdapter{
public void keyPressed(KeyEvent e){
int keyCode = e.getKeyCode();
if((keyCode == KeyEvent.VK_UP) && (run == true) && (playerY - 20 > 0)){
playerY = playerY - 10;
}else if((keyCode == KeyEvent.VK_DOWN) && (run == true) && (playerY + 20 < 400)){
playerY = playerY + 10;
}
if((keyCode == KeyEvent.VK_SPACE) && (fired == false)){
fired = true;
if(fired == true){
bullet();
}
}
}
public void keyReleased(KeyEvent e){
}
}
public class Mouse extends MouseAdapter {
public void mousePressed(MouseEvent e) {
double x = e.getX();
double y = e.getY();
}
}
}
HOWEVER
When I run the code without the while loop the bullet appears at the player's X position
but
When the while loop is there when the player presses the X button nothing happens, the bullet doesnt even appear!
would anybody be able to assist me in how i can make the bullet appear and move across the screen?
thanks
This is because you are not drawing the bullet until it's out of range, you should not use the while loop this way, you probably need to google for 'Game Loop' but until you do here is a snipet that may help, Note that very bad but should work:
public void paintComponent(Graphics g){
if(run == true){
g.drawImage(player, playerX, playerY, this);
if(fired == true) {
bulletX = bulletX + 10;
if(bulletX > 800 || bulletX < 0){
fired = false;
}
g.drawImage(bullet, bulletX, bulletY, this);
}
repaint();
}
}
public void bullet(){
bulletX = playerX;
bulletY = playerY;
}
one final note, move this code in the paint methode dbImage = createImage(getWidth(), getHeight()) to the constructor or the init() because you are creating a new image every frame.

Collision detection in mouseMoved method

I am creating a game in java. In it, you control a square that follows your mouse. I want to implement collision detection for the square so that it stops slightly within the JFrame and not at the edge. This is very easy when doing this with the arrow keys, but I can't figure it out with the mouseMoved method. Here is the code where the mouseMoved method is:
public void mouseMoved(MouseEvent e){
repaint();
if(e.getX() <= 0)
playerX = 0;
if(e.getX() >= 300)
playerX = 500;
if(e.getY() <= 0)
playerY = 0;
if(e.getY() >= 300)
playerY = 500;
else
playerX = e.getX()-25;
playerY = e.getY()-25;
repaint();
}
Here's the code where the square is created:
public void paintComponent(Graphics g) {
Rectangle player = new Rectangle(playerX, playerY, 50, 50);
g.setColor(Color.blue);
g.fillRect(player.x, player.y, player.width, player.height);
repaint();
}
I don't think you'll need this, but just in case, here's all the code for the GamePanel class, which serves as the panel for my JFrame in the Main class. If you need the Main class let me know but I doubt you will:
package main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable{
//Global variables
//Double buffering
private Image dbImage;
private Graphics dbg;
//JPanel variables
static final int GWIDTH = 500, GHEIGHT = 500;
static final Dimension gameDim = new Dimension(GWIDTH, GHEIGHT);
//Game variable
private Thread game;
private volatile boolean running = false;
public boolean mouseClicked = false;
//Character variables
int playerX = 150, playerY = 150;
public class Mouse extends MouseAdapter{
public void mousePressed(MouseEvent e){
mouseClicked = true;
}
public void mouseReleased(MouseEvent e){
mouseClicked = false;
}
public void mouseMoved(MouseEvent e){
repaint();
if(e.getX() <= 0)
playerX = 0;
if(e.getX() >= 300)
playerX = 500;
if(e.getY() <= 0)
playerY = 0;
if(e.getY() >= 300)
playerY = 500;
else
playerX = e.getX()-25;
playerY = e.getY()-25;
repaint();
}
}
public GamePanel(){
addMouseMotionListener(new Mouse());
setPreferredSize(gameDim);
setBackground(Color.BLUE);
setFocusable(true);
requestFocus(true);
}
public void run(){
while(running){
}
}
public void addNotify(){
super.addNotify();
startGame();
}
private void startGame(){
if(game == null || !running){
game = new Thread(this);
game.start();
running = true;
}
}
public void stopGame(){
if(running){
running = false;
}
//Paint method
}
public void paint(Graphics g){
dbImage = createImage(getWidth(), getHeight());
dbg = dbImage.getGraphics();
paintComponent(dbg);
g.drawImage(dbImage, 0, 0, this);
}
public void paintComponent(Graphics g) {
Rectangle player = new Rectangle(playerX, playerY, 50, 50);
g.setColor(Color.blue);
g.fillRect(player.x, player.y, player.width, player.height);
repaint();
}
private void log(String s){
System.out.println(s);
}
}
Thank you for your help. Please let me know if you need anything.
Your movement code is a bit off. You set the x position only if the Y is not out of bounds and always replace the Y value. Can I suggest full blocks in future - they help avoiding problems like this.
playerX = e.getX()-25;
playerY = e.getY()-25;
if(e.getX() <= 0){
playerX = 0;
}
else if(e.getX() >= 300){
playerX = 500;
}
if(e.getY() <= 0){
playerY = 0;
}
else if(e.getY() >= 300){
playerY = 500;
}
This sets the position first and then corrects it if the player is out of the bounds.

How to make sprite jump in java?

I have KeyEvents for a sprite for moving left, right, up and down. I was just messing around and was thinking ahead for another project in which I want the sprite to jump. It doesn't have to be fully realistic as I am just beginning. What I have is when the space bar is pressed, it will cause the sprite to jump, lets say "dy = -3". So then I have the KeyEvent for keyReleased, it will fall, "dy = -2". This does not work as the sprite just continues to fall...can someone shine some light?
Entire code:
package collision;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Craft {
private String craft = "pelican.png";
private int dx;
private int dy;
private int x;
private int y;
private int width;
private int height;
private boolean visible;
private Image image;
private ArrayList missiles;
public Craft() {
ImageIcon ii = new ImageIcon(this.getClass().getResource(craft));
image = ii.getImage();
width = image.getWidth(null);
height = image.getHeight(null);
missiles = new ArrayList();
visible = true;
x = 100;
y = 300;
}
public void move() {
x += dx;
y += dy;
if (x < 1) {
x = 1;
}
if (y < 1) {
y = 1;
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return image;
}
public ArrayList getMissiles() {
return missiles;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public boolean isVisible() {
return visible;
}
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
}
if (key == KeyEvent.VK_V){
dx = 6;
}
if (key == KeyEvent.VK_LEFT) {
dx = -1;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 2;
}
if (key == KeyEvent.VK_UP) {
dy = -1;
}
if (key == KeyEvent.VK_DOWN) {
dy = 1;
}
}
public void fire() {
missiles.add(new Missile(x + width, y + height/2));
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = 0;
}
if (key == KeyEvent.VK_SPACE) {
}
if (key == KeyEvent.VK_RIGHT) {
dx = 0;
}
if (key == KeyEvent.VK_UP) {
dy = 0;
}
if (key == KeyEvent.VK_DOWN) {
dy = 0;
}
}
}
As you may have noticed Im new to Java as well as game programming. All I want is the sprite to go up, then come back down. It will always remain stationary if that helps. The sprite just keeps jumping until he is hit by an on coming obstacle. I know there is code for other movements, but those will be removed once I start on next sprite.
This is basic concept. Your implementation will change depending on the implementation of your engine.
The basic idea is the player has a vertical delta which is changed over time by gravity. This effects the sprites vertical speed.
This implementation also has a re-bound delta, which allows the sprite to re-bound rather the "stopping" suddenly. The re-bound is effected by a re-bound degradation, which reduces the amount of re-bound on each re-bound.
This simulates a game character, so you'll need to hit Space to start it bouncing...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class JumpingSprite {
public static void main(String[] args) {
new JumpingSprite();
}
public JumpingSprite() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
protected static final int SPRITE_HEIGHT = 10;
protected static final int SPRITE_WIDTH = 10;
private float vDelta; // The vertical detla...
private float rbDelta; // Rebound delta...
private float rbDegDelta; // The amount the rebound is degradation...
private int yPos; // The vertical position...
private float gDelta; // Gravity, how much the vDelta will be reduced by over time...
private Timer engine;
private boolean bounce = false;
public TestPane() {
yPos = getPreferredSize().height - SPRITE_HEIGHT;
vDelta = 0;
gDelta = 0.25f;
// This is how much the re-bound will degrade on each cycle...
rbDegDelta = 2.5f;
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "jump");
am.put("jump", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
// Can only bound when we're actually on the ground...
// You might want to add fudge factor here so that the
// sprite can be within a given number of pixels in order to
// jump again...
if (yPos + SPRITE_HEIGHT == getHeight()) {
vDelta = -8;
rbDelta = vDelta;
bounce = true;
}
}
});
engine = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int height = getHeight();
// No point if we've not been sized...
if (height > 0) {
// Are we bouncing...
if (bounce) {
// Add the vDelta to the yPos
// vDelta may be postive or negative, allowing
// for both up and down movement...
yPos += vDelta;
// Add the gravity to the vDelta, this will slow down
// the upward movement and speed up the downward movement...
// You may wish to place a max speed to this
vDelta += gDelta;
// If the sprite is not on the ground...
if (yPos + SPRITE_HEIGHT >= height) {
// Seat the sprite on the ground
yPos = height - SPRITE_HEIGHT;
// If the re-bound delta is 0 or more then we've stopped
// bouncing...
if (rbDelta >= 0) {
// Stop bouncing...
bounce = false;
} else {
// Add the re-bound degregation delta to the re-bound delta
rbDelta += rbDegDelta;
// Set the vDelta...
vDelta = rbDelta;
}
}
}
}
repaint();
}
});
engine.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth() - 1;
int xPos = (width - SPRITE_WIDTH) / 2;
g2d.drawOval(xPos, yPos, SPRITE_WIDTH, SPRITE_HEIGHT);
g2d.dispose();
}
}
}
Well I can think of one way. It involves some complex amounts of math (parabola). So i'm going to provide a very simple answer.
int y = 0;
and in the method that tests for the spacebar...
if (y !< 1){
if (y < 30){
y += 1;
}
if (y > 30){
y -= 1;
}
}
I haven't tested it out yet, but it should work in theory....But it won't animate anything, this code is only going to take the sprites Y value and make it go up. That's just about the easiest jumping method that can exist....

Categories