How do I refresh a panel after a mouseClicked? - java

I have a game to code in java with Swing. The classes of the game work but I'm having troubles with the GUI class. The printing methods use an object Graphics as parameter but I don't know how to use this. Here is the portion of the code :
panel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
Piece piece = joueur.getPosition();
int positionClick = numberPiece(e.getX(), width) + numberPiece(e.getY(), height) * 10;
int positionJoueur = Scenario.pieces.get(piece) - 1;
if (positionClick==positionJoueur-1)
joueur.deplacer('O');
else if (positionClick==positionJoueur+1)
joueur.deplacer('E');
else if (positionClick==positionJoueur-10)
joueur.deplacer('N');
else if (positionClick==positionJoueur+10)
joueur.deplacer('S');
panel.updateUI();
repaint();
}
private int numberPiece(int coord, int size) {
for (int i = 1; i < 11; i++) {
int x = i * size;
if (coord < x) {
return (i - 1);
}
}
return 0;
}
});
Please help me, thank you.

Related

Creating new levels

As a beginner in Java, I'm working on a project of Space Invaders. Looking to add more levels.
private void LevelInit() {
aliens = new ArrayList<>();
int currentLevel = 1;
if (currentLevel == 1) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
//System.out.println(currentLevel);
}
}
}
else if (currentLevel == 2) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
// System.out.println(currentLevel);
}
}
}
else if (currentLevel == 3) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
//System.out.println(currentLevel);
}
}
}
player = new Player();
bullet = new Bullet();
}
This function is the logic behind the code that initializes the game and gets called by the constructor. The simple way of adding levels is adding more Aliens.
This is how it looks after being updated from yesterday, levels are being added but the arraylists are being stuck together. Like the 12 - 16 - 24 aliens are together printed, some spaceships take 1 hit some 2 and some 3 and when they are all destroyed system give message of You passed level 1 and 2 and 3 together which is confusing me why are they bound together like that and not being passed.
And I can't figure it out. Also,
private void update() {
if (deaths == 12) {
inGame = false;
timer.stop();
message = "Next Level!";
}
// player
player.act();
// shot
if (bullet.isVisible()) {
int shotX = bullet.getX();
int shotY = bullet.getY();
for (Alien alien : aliens) {
int alienX = alien.getX();
int alienY = alien.getY();
if (alien.isVisible() && bullet.isVisible()) {
if (shotX >= (alienX)
&& shotX <= (alienX + Constants.ALIEN_WIDTH)
&& shotY >= (alienY)
&& shotY <= (alienY + Constants.ALIEN_HEIGHT)) {
var ii = new ImageIcon(explImg);
alien.setImage(ii.getImage());
alien.setDying(true);
deaths++;
bullet.die();
}
}
}
int y = bullet.getY();
y -= 4;
if (y < 0) {
bullet.die();
} else {
bullet.setY(y);
}
}
// aliens
for (Alien alien : aliens) {
int x = alien.getX();
if (x >= Constants.BOARD_WIDTH - Constants.BORDER_RIGHT && direction != -1) {
direction = -1;
for(Alien a2 : aliens) {
a2.setY(a2.getY() + Constants.GO_DOWN);
}
}
if (x <= Constants.BORDER_LEFT && direction != 1) {
direction = 1;
for(Alien a : aliens) {
a.setY(a.getY() + Constants.GO_DOWN);
}
}
}
for(Alien alien : aliens) {
if (alien.isVisible()) {
int y = alien.getY();
if (y > Constants.GROUND - Constants.ALIEN_HEIGHT) {
inGame = false;
message = "Invasion!";
}
alien.act(direction);
}
}
// bombs
var generator = new Random();
for (Alien alien : aliens) {
int shot = generator.nextInt(15);
Alien.Bomb bomb = alien.getBomb();
if (shot == Constants.CHANCE && alien.isVisible() && bomb.isDestroyed()) {
bomb.setDestroyed(false);
bomb.setX(alien.getX());
bomb.setY(alien.getY());
}
int bombX = bomb.getX();
int bombY = bomb.getY();
int playerX = player.getX();
int playerY = player.getY();
if (player.isVisible() && !bomb.isDestroyed()) {
if (bombX >= (playerX)
&& bombX <= (playerX + Constants.PLAYER_WIDTH)
&& bombY >= (playerY)
&& bombY <= (playerY + Constants.PLAYER_HEIGHT)) {
var ii = new ImageIcon(explImg);
player.setImage(ii.getImage());
player.setDying(true);
bomb.setDestroyed(true);
}
}
if (!bomb.isDestroyed()) {
bomb.setY(bomb.getY() + 1);
if (bomb.getY() >= Constants.GROUND - Constants.BOMB_HEIGHT) {
bomb.setDestroyed(true);
}
}
}
}
This function is to update the game whenever anything happens. The code is made from a bunch of YouTube videos and GitHubs, so excuse the copying if you see any.
I need to create new levels by simply adding more aliens, tried using a for loop but that resulted in either the aliens move faster or the bullet doesn't destroy an alien, it just hits.
Board class:
public class Board extends JPanel {
private Dimension d;
private List<Alien> aliens;
private Player player;
private Bullet bullet;
private int level;
private int direction = -1;
private int deaths = 0;
private boolean inGame = true;
private String explImg = "src/images/explosion.png";
private String message = "Game Over";
private Timer timer;
public Board() {
initBoard();
gameInit();
LevelInit();
}
private void initBoard() {
addKeyListener(new TAdapter());
setFocusable(true);
d = new Dimension(Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
setBackground(Color.black);
timer = new Timer(Constants.DELAY, new GameCycle());
timer.start();
gameInit();
}
private void gameInit() {
aliens = new ArrayList<>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j,
Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
player = new Player();
bullet = new Bullet();
}
private void LevelInit() {
inGame = true;
timer.start();
int level = 1;
if (aliens.isEmpty()) {
level++;
int AlienCount;if(level == 2) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
} else if (level == 3) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
}
}
player = new Player();
bullet = new Bullet();
}
private void drawAliens(Graphics g) {
for (Alien alien : aliens) {
if (alien.isVisible()) {
g.drawImage(alien.getImage(), alien.getX(), alien.getY(), this);
}
if (alien.isDying()) {
alien.die();
}
}
}
private void drawPlayer(Graphics g) {
if (player.isVisible()) {
g.drawImage(player.getImage(), player.getX(), player.getY(), this);
}
if (player.isDying()) {
player.die();
inGame = false;
}
}
private void drawShot(Graphics g) {
if (bullet.isVisible()) {
g.drawImage(bullet.getImage(), bullet.getX(), bullet.getY(), this);
}
}
private void drawBombing(Graphics g) {
for (Alien a : aliens) {
Alien.Bomb b = a.getBomb();
if (!b.isDestroyed()) {
g.drawImage(b.getImage(), b.getX(), b.getY(), this);
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
private void doDrawing(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, d.width, d.height);
g.setColor(Color.green);
if (inGame) {
g.drawLine(0, Constants.GROUND,
Constants.BOARD_WIDTH, Constants.GROUND);
drawAliens(g);
drawPlayer(g);
drawShot(g);
drawBombing(g);
} else {
if (timer.isRunning()) {
timer.stop();
}
gameOver(g);
}
Toolkit.getDefaultToolkit().sync();
}
private void gameOver(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
g.setColor(new Color(0, 32, 48));
g.fillRect(50, Constants.BOARD_WIDTH / 2 - 30, Constants.BOARD_WIDTH - 100, 50);
g.setColor(Color.white);
g.drawRect(50, Constants.BOARD_WIDTH / 2 - 30, Constants.BOARD_WIDTH - 100, 50);
var small = new Font("Helvetica", Font.BOLD, 14);
var fontMetrics = this.getFontMetrics(small);
g.setColor(Color.white);
g.setFont(small);
g.drawString(message, (Constants.BOARD_WIDTH - fontMetrics.stringWidth(message)) / 2,
Constants.BOARD_WIDTH / 2);
}
private void update() {
if (deaths == aliens.size()) {
inGame = false;
timer.stop();
message = "Next Level!";
}
// player
player.act();
// shot
if (bullet.isVisible()) {
int shotX = bullet.getX();
int shotY = bullet.getY();
for (Alien alien : aliens) {
int alienX = alien.getX();
int alienY = alien.getY();
if (alien.isVisible() && bullet.isVisible()) {
if (shotX >= (alienX)
&& shotX <= (alienX + Constants.ALIEN_WIDTH)
&& shotY >= (alienY)
&& shotY <= (alienY + Constants.ALIEN_HEIGHT)) {
var ii = new ImageIcon(explImg);
alien.setImage(ii.getImage());
alien.setDying(true);
deaths++;
bullet.die();
}
}
}
int y = bullet.getY();
y -= 4;
if (y < 0) {
bullet.die();
} else {
bullet.setY(y);
}
}
// aliens
for (Alien alien : aliens) {
int x = alien.getX();
if (x >= Constants.BOARD_WIDTH - Constants.BORDER_RIGHT && direction != -1) {
direction = -1;
Iterator<Alien> i1 = aliens.iterator();
while (i1.hasNext()) {
Alien a2 = i1.next();
a2.setY(a2.getY() + Constants.GO_DOWN);
}
}
if (x <= Constants.BORDER_LEFT && direction != 1) {
direction = 1;
Iterator<Alien> i2 = aliens.iterator();
while (i2.hasNext()) {
Alien a = i2.next();
a.setY(a.getY() + Constants.GO_DOWN);
}
}
}
Iterator<Alien> it = aliens.iterator();
while (it.hasNext()) {
Alien alien = it.next();
if (alien.isVisible()) {
int y = alien.getY();
if (y > Constants.GROUND - Constants.ALIEN_HEIGHT) {
inGame = false;
message = "Invasion!";
}
alien.act(direction);
}
}
// bombs
var generator = new Random();
for (Alien alien : aliens) {
int shot = generator.nextInt(15);
Alien.Bomb bomb = alien.getBomb();
if (shot == Constants.CHANCE && alien.isVisible() && bomb.isDestroyed()) {
bomb.setDestroyed(false);
bomb.setX(alien.getX());
bomb.setY(alien.getY());
}
int bombX = bomb.getX();
int bombY = bomb.getY();
int playerX = player.getX();
int playerY = player.getY();
if (player.isVisible() && !bomb.isDestroyed()) {
if (bombX >= (playerX)
&& bombX <= (playerX + Constants.PLAYER_WIDTH)
&& bombY >= (playerY)
&& bombY <= (playerY + Constants.PLAYER_HEIGHT)) {
var ii = new ImageIcon(explImg);
player.setImage(ii.getImage());
player.setDying(true);
bomb.setDestroyed(true);
}
}
if (!bomb.isDestroyed()) {
bomb.setY(bomb.getY() + 1);
if (bomb.getY() >= Constants.GROUND - Constants.BOMB_HEIGHT) {
bomb.setDestroyed(true);
}
}
}
}
private void doGameCycle() {
update();
repaint();
}
private class GameCycle implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
doGameCycle();
}
}
private class TAdapter extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
player.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
player.keyPressed(e);
int x = player.getX();
int y = player.getY();
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
if (inGame) {
if (!bullet.isVisible()) {
bullet = new Bullet(x, y);
}
}
}
}
}
}
As #JoachimSauer mentioned, your code needs refactoring. Here is one possible solution to your problem.
Additions
You will need two extra variables and one extra method.
Variables
1: int currentLevel - keeps track of the current level
2: boolean isLevelOver - keeps track if the current level is still active or not
Method
private void levelInit(int currentlevel)
{
aliens = new ArrayList<>();
int alienCount = //calculate alien count depending upon the current level
//Add aliens to aliens ArrayList
player = new Player();
bullet = new Bullet();
}
You have to provide implementation of how alienCount will be calculated depending upon currentLevel. The nested loop you used earlier to add aliens to aliens will also change. You have to make the loop dependent upon currentLevel.
Changes
Few of your methods will require some change.
public Board()
{
initBoard();
}
private void initBoard()
{
addKeyListener(new TAdapter());
setFocusable(true);
d = new Dimension(Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
setBackground(Color.black);
levelInit(currentLevel);
timer = new Timer(Constants.DELAY, new GameCycle());
timer.start();
}
private void update()
{
if (deaths == aliens.size())
{
isLevelOver = true;
currentLevel++;
message = "Next Level!";
return;
}
...
}
private void doGameCycle()
{
if (isLevelOver)
{
levelInit(currentLevel);
isLevelOver = false;
}
update();
repaint();
}
Notes
This is one of the possible ways to achieve what you want. There
might be other ways, probably better, but this is what I came up
with.
I tried to find as many additions and updation required in your code. However, I do not know its structure, you do. So there might be more additions or changes required.
I noticed you are were calling gameInit() in initBoard() and then again in Board() constructor. I think that might be unnecessary, please look into it.
You made one call to timer.stop() after setting isGame = false. This again might be unnecessary since you are already doing so inside doDrawing(...). Please also check that.
You should probably set a limit to either the levelCount() or max alien that can be on the screen since if you just keep on adding more aliens in each new level, they might fill up the entire screen.
I have provided many hints which should help you in your problem. If you still face any more problems or someone finds anything wrong with the answer, please comment.

How to update the position of snakes and ladders in an 2D array code?

public class ChutesAndLadders2d {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] numbersOnBoard = new int [6][6];
boardSetUpA (numbersOnBoard);
printTwoD(numbersOnBoard);
}
public static void boardSetUpA (int[][]twoD) {
//Square with even size
//even rows
for (int row = 0;row<twoD.length; row ++) {
if (row %2 ==0) {
int num = twoD.length*(twoD.length-row);
for (int col = 0; col<twoD[row].length; col ++ ) {
twoD[row][col] = num;
num--;
}
}//
else {
int num = twoD.length*(twoD.length-(row + 1))+ 1;
for (int col = 0; col<twoD[row].length; col ++ ) {
twoD[row][col] = num;
num++;
}
}
}//for row
}//
public static void printTwoD(int [][] array){
for (int row = 0; row < array.length; row++){
for (int column = 0; column < array[row].length; column++){
System.out.print(array[row][column] + "\t");
}
System.out.println();
}
}
public static void boardDetails(String[][]board) {
for (int row = 0;row<board.length; row++){
for (int col = 0;col<board[row].length; col++){
if( col+2 == row||col+1 == row*2 ){
board[row][col] = "Lad"; // Append value
}
else if (col*2 == row|| row*2 == col){
board[row][col] = "Cht";// Append value
}
else {
board[row][col] = " ";
}
}
board[board.length-1][0] = "Start";
if (board.length%2 ==0) {
board[0][0] = "End";}
else {
board[0][board.length-1]="End";
}
}
}
public static void printBoard (int[][]twoD, String[][]strTwoD) {
//Printing
for (int row = 0;row<twoD.length;row++) {
for (int col = 0;col<twoD[row].length;col++) {
System.out.print(twoD[row][col] + " "+strTwoD[row][col]+"\t\t");
}
System.out.println("\n");
}
}
}
This is the starter code I have for setting up the snakes and ladders game. I also tried to set the chutes/snakes and ladders on the board but it is not printing. How should I fix it and how do I develop this code to have three methods: update the moves of a player once he reaches a snake, a ladder, and once he rolls his die, from one place to another?
Is it possible to implement a Shutes & Ladders game using a 2D Array? For sure! Does that make sense in an object-oriented language such as Java? I dont know ....
What do you need for that?
A square board with e.g. 36 playing fields.
Connections between two playing fields. (shutes and ladders)
Pawns and a dice.
A renderer that outputs the playing field (as text or graphics).
A program that allows input and connects everything to a functioning game.
Here is an example that works with a List instead of an Array. That can certainly be changed if it is necessary for your purposes.
I hope this is of some help to you.
P.S .: After the start, the board is displayed with field numbers. Shutes are shown as red lines. Ladders as green lines. Keys 1-6 on the keyboard simulate rolling the dice..
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.*;
public class ChutesAndLadders2d {
public static void main(String[] args) {
JFrame frame = new JFrame("Chutes and Ladders 2D");
Game game = new ChutesAndLadders2d().new Game();
game.setPreferredSize(new Dimension(400, 400));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setContentPane(game);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
#SuppressWarnings("serial")
class Game extends JPanel{
private final Font defaultFont = new Font("Arial", Font.PLAIN, 16);
private final BasicStroke stroke = new BasicStroke(4f);
private static final int SCALE = 64;
// board and pawns
private final Board board = new Board(6);
private final List<Pawn> pawns = new ArrayList<>();
public Game(){
setFocusable(true); // receive Keyboard-Events
addKeyListener(new KeyAdapter(){
#Override
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if(c >= '1' && c <= '6'){
int steps = Integer.parseInt(Character.toString(c));
Pawn pawn = pawns.get(0);
pawn.move(steps);
Field field = board.get(pawn.fieldIndex);
if(field.targetKind() != Kind.NONE){
pawn.move(field.getTarget().index - field.index);
}
repaint();
}
}
});
board.connect(5, 12); // Ladder 5 -> 12
board.connect(8, 4); // Shute 8 -> 4
board.connect(15, 32); // Ladder 15 -> 32
board.connect(35, 17); // Shute 35 -> 17
board.connect(23, 30); // Ladder 23 -> 30
pawns.add(new Pawn(Color.BLUE, board.size() - 1));
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
setFont(defaultFont);
for(Field field : board){
Point p = field.getLocation();
g2d.drawRect(p.x * SCALE, p.y * SCALE, SCALE, SCALE);
g2d.drawString(field.text, p.x * SCALE + 24, p.y * SCALE + 40);
}
for(Field field : board){
if(field.targetKind() != Kind.NONE){
g2d.setColor(field.targetKind() == Kind.LADDER ? Color.GREEN : Color.RED);
g2d.setStroke(stroke);
Point source = field.getLocation();
Point target = field.getTarget().getLocation();
g2d.drawLine(source.x * SCALE + 40, source.y * SCALE + 24, target.x * SCALE + 40, target.y * SCALE + 24);
}
}
for(Pawn pawn : pawns){
Point loc = board.get(pawn.fieldIndex).getLocation();
g2d.setColor(pawn.color);
g2d.fillOval(loc.x * SCALE + 32, loc.y * SCALE + 32, 16, 16);
}
}
}
class Board implements Iterable<Field>{
private final List<Field> fields = new ArrayList<>();
public Board(int size){
for(int index = 0; index < size * size; index++)
fields.add(new Field(index, size));
}
public Field get(int index){
return fields.get(index);
}
public void connect(int startFieldnumber, int targetFieldnumber){
get(startFieldnumber - 1).setTarget(get(targetFieldnumber - 1));
}
#Override
public Iterator<Field> iterator() {
return fields.iterator();
}
public int size(){
return fields.size();
}
}
class Field{
final int index;
final String text;
final int size;
private Field target;
public Field(int index, int size){
this.index = index;
this.size = size;
text = "" + (index + 1);
}
public void setTarget(Field target){
if(target == this) return;
this.target = target;
}
public Field getTarget(){
return target;
}
public Kind targetKind(){
if(target == null) return Kind.NONE;
return index < target.index ? Kind.LADDER : Kind.SHUTE;
}
public Point getLocation(){
int x = index % size;
int y = index / size;
if(y % 2 != 0) x = size - x - 1;
return new Point(x, size - y - 1);
}
}
class Pawn{
int fieldIndex = 0;
int maxIndex;
Color color;
public Pawn(Color color, int maxIndex){
this.color = color;
this.maxIndex = maxIndex;
}
public void move(int steps){
fieldIndex += steps;
if(fieldIndex < 0) fieldIndex = 0;
if(fieldIndex > maxIndex) fieldIndex = maxIndex;
}
}
enum Kind{
NONE, SHUTE, LADDER
}
}

Java game throwing IndexOutOfBoundsException with 2 arraylists?

I am making a fairly simple game in java and I keep getting this IndexOutofBoundsException from my arraylist. I have 1 that creates an arraylist of "bullets", and another that stores "missles". The program runs and I can fire bullets for about 5 seconds and then it freezes giving me this error. I'm not sure what is happening.
This is part of my Canvas class that creates the array lists.
ArrayList ms = craft.getMissles();
ArrayList bs = craft.getBullets();
for (int i = 0; i < ms.size(); i++ ) {
Missle m = (Missle) ms.get(i);
g2d.drawImage(m.getImage(), m.getX(), m.getY(), this);
}
for (int b = 0; b < bs.size(); b++ ) {
Bullet a = (Bullet) bs.get(b);
g2d.drawImage(a.getImage(), a.getX(), a.getY(), this);
}
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
public void actionPerformed(ActionEvent e) {
ArrayList ms = craft.getMissles();
ArrayList bs = craft.getBullets();
for (int i = 0; i < ms.size(); i++) {
Missle m = (Missle) ms.get(i);
if (m.isVisible())
m.move();
else ms.remove(i);
}
for (int b = 0; b < bs.size(); b++) {
Bullet a = (Bullet) bs.get(b);
if (a.isVisible())
a.move();
else ms.remove(b);
}
craft.move();
repaint();
}
And here are parts of my Craft class that has the actions for the missiles. I declare them above and the code worked fine when I only had the missile parts. The error came when I added a second arraylist.
public Craft() {
ImageIcon ii = new ImageIcon(this.getClass().getResource(craft));
image = ii.getImage();
missles = new ArrayList();
bullets = new ArrayList();
x = 1000;
y = 60;
}
private ArrayList missles;
private ArrayList bullets;
private final int CRAFT_SIZE = 85;
private final int CRAFT_SIZE2 = 20;
public void move() {
x += dx;
y += dy;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return image;
}
public ArrayList getMissles() {
return missles;
}
public ArrayList getBullets() {
return bullets;
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = -2;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 1;
}
if (key == KeyEvent.VK_UP) {
dy = -2;
}
if (key == KeyEvent.VK_DOWN) {
dy = 3;
}
if (key == KeyEvent.VK_SPACE) {
fire();
}
if (key == KeyEvent.VK_V) {
fire2();
}
}
public void fire() {
missles.add(new Missle(x + CRAFT_SIZE, y + CRAFT_SIZE/2));
}
public void fire2() {
bullets.add(new Bullet(x + CRAFT_SIZE2, y + CRAFT_SIZE/2));
}
I spotted one bug at least:
else ms.remove(b);
should be
else bs.remove(b);

Why does this Java grid not function correctly?

I am trying to make a grid (with minimal code) that blocks can snap to. What I want is when the mouse is in the grid square, the block moves to that square. What I have written essentially says that if the X or Y are beyond the grid block times the size of the block, move to the next grid block. Currently, this code creates a 3x3 grid, though the code SHOULD generate infinite gridspaces. I cannot move the block outside of this 3x3 grid.
public class Player extends Entity {
public Player(double entSize, boolean collideA, boolean collideB, double x, double y) {
super(entSize, collideA, collideB, x, y);
}
public void init() {
Texture texFile = loadTexture("stone");
texture(false, true);
texFile.bind();
render();
}
void input() {
int gridPosX = 1;
int gridPosY = 1;
if(getX() > gridPosX*entSize) {
gridPosX += 1;
} if(getX() < gridPosX*entSize) {
gridPosX -= 1;
} if(getY() > gridPosY*entSize) {
gridPosY += 1;
} if(getY() < gridPosY*entSize) {
gridPosY -= 1;
}
this.x = gridPosX*entSize;
this.y = gridPosY*entSize;
}
}
The X and Y values are what define the blocks position and shape parameters.
Fixed by using for loops for the positive grid increments!
NEW CODE:
public class Player extends Entity {
public Player(double entSize, boolean collideA, boolean collideB, double x, double y) {
super(entSize, collideA, collideB, x, y);
}
public void init() {
Texture texFile = loadTexture("stone");
texture(false, true);
texFile.bind();
render();
}
void input() {
int gridPosX = 0;
int gridPosY = 0;
for(gridPosX = 0; getX() > gridPosX*entSize; gridPosX++) {
gridPosX += 0;
} if(getX() < gridPosX*entSize) {
gridPosX -= 1;
} for(gridPosY = 0; getY() > gridPosY*entSize; gridPosY++) {
gridPosY += 0;
} if(getY() < gridPosY*entSize) {
gridPosY -= 1;
}
this.x = gridPosX*entSize;
this.y = gridPosY*entSize;
}
}

Extending a JFrame (empty window error)

I'm doing a project that does the following in a nutshell:
reads integers from a file
stores them in an array
creates a bargraph of the numbers with an average line
the numbers above average go up, the numbers below go down (both are also different colors)
It compiles correctly, the JFrame window pops up, but no data is printed out. It's just an empty window.
Here is my code:
package basicgraphicstester;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
public class BasicGraphicsTester extends JFrame {
private Image fImageBuffer;
private Insets fInsets;
private Graphics g;
private static final int WIDTH = 800, HEIGHT = 600;
private static final Color OVER_AVERAGE = Color.blue,
UNDER_AVERAGE = Color.red;
int[] data;
public BasicGraphicsTester() throws FileNotFoundException
{ ReadInputData();
addWindowListener(new WindowCloser());
setVisible(true);
fInsets = getInsets();
setSize(WIDTH + fInsets.left + fInsets.right, HEIGHT + fInsets.top +fInsets.bottom);
setTitle("Bar Graph");
setResizable(false);
if (((fImageBuffer = createImage(WIDTH, HEIGHT)) != null) &&
((g = fImageBuffer.getGraphics()) != null)) Run();
else System.exit(1);
}
class WindowCloser extends WindowAdapter
{ public void WindowClosing(WindowEvent e )
{ System.exit(0); }
}
private void Run()
{ DrawAverageLine();
DrawBars();
}
private void DrawBars()
{
double arrayAverage = arrayAverage(data);
int average = averageLine(data);
int max = getMaxValue(data);
int min = getMinValue(data);
int barWidth = 57;
double barHeight;
for (int i = 0; i < data.length; i++) {
barHeight = (600 * (max - data[i]))/(max - min);
if (data[i] > average) {
g.setColor(OVER_AVERAGE);
g.fillRect((int)barWidth * i, (int)barHeight, (int)barWidth,
(average - (int)barHeight));
}
else if (barHeight == average) {
g.setColor(Color.green);
g.fillRect((int)barWidth * i, average, (int)barWidth, 0);
}
else {
g.setColor(UNDER_AVERAGE);
g.fillRect((int)barWidth * i, average, (int)barWidth,
((int)barHeight - average));
repaint();
}
} //for loop
} //DrawBar
private void DrawAverageLine()
{
int average = averageLine(data);
g.drawLine(0, average, 800, average);
}
public static int getMaxValue(int[] data) {
int maxValue = data[0];
for (int i=1;i < data.length;i++) {
if (data[i] > maxValue)
maxValue = data[i];
}
return maxValue;
}
public static int getMinValue(int[] data) {
int minValue = data[0];
for (int i = 1; i < data.length; i++) {
if (data[i] < minValue)
minValue = data[i];
}
return minValue;
}
public static double arrayAverage(int[] data) {
double result = 0.0;
for (int i = 0; i < data.length; i++) {
result = result + data[i];
}
result = result/data.length;
return result;
}
public static int averageLine (int[] data) {
int max = getMaxValue(data);
int min = getMinValue(data);
return (HEIGHT * max - (int)arrayAverage(data)) / (max - min);
}
public void paint( Graphics g)
{ if (fImageBuffer != null )
g.drawImage(fImageBuffer, fInsets.left, fInsets.top, null);
}
public void ReadInputData() throws FileNotFoundException {
try {Scanner readFile = new Scanner(new File("BarChart.data"));
data = new int [13];
for (int i = 0; i < data.length; i++)
data[i] = readFile.nextInt();
} //try
catch (FileNotFoundException e) {
System.out.println(e);
}
} // ReadInputData
public static void main(String[] args) throws FileNotFoundException {
new BasicGraphicsTester();
}
}
Please help. Thanks in advance.
A JFrame is an empty frame. You need to put a JPanel inside your frame, and override the latter's paintComponent() method in order to render your data on screen.
This is not how you do graphics or drawing with Swing, and I'd be interested to see what tutorial you've read recommends you to get the Graphics object as you're doing. Instead you should draw in the paintComponent(...) method of a class that extends JComponent such as a JPanel, using the Graphics instance provided as a parameter by the JVM, and then add this component to your JFrame. You will want to read the painting in Swing tutorial which is part of the standard Swing tutorials.
If you want to draw right into the JFrame you still have to override ContentPane's paint, not JFrame's paint method AFAIK.
And yes, a better way would be to implement your own component (for example by extending JPanel) and place it inside the JFrame (remember it has to be placed in ContentPane).
Check JFrame javadocs about ContentPane.
I recently wrote something similar in JavaFX using the BarGraph component. I'll post the source code if it would be helpful, but maybe you need to use swing and the point of your project is to make your own bar graph.
View my javafx bar graph

Categories