public void actionPerformed(ActionEvent e){
grid=new JButton[length+20][width+20];
grid1=new JButton[length+20][width+20];
for(int i=0;i<length+2;i++)
{
for(int j=0;j<width+2;j++)
{
grid1[i][j]=grid[i][j];
}
}
for(int i=1;i<length+1;i++)
{
for(int j=1;j<width+1;j++)
{
//final int row = i;
//final int col = j;
int count=0;
if(grid[i][j-1].getBackground() == Color.BLACK);
count++;
if(grid[i][j+1].getBackground()==Color.BLACK)
count++;
if(grid[i-1][j-1].getBackground()==Color.BLACK)
count++;
if(grid[i-1][j].getBackground()==Color.BLACK)
count++;
if(grid[i-1][j+1].getBackground()==Color.BLACK)
count++;
if(grid[i+1][j-1].getBackground()==Color.BLACK)
count++;
if(grid[i+1][j].getBackground()==Color.BLACK)
count++;
if(grid[i+1][j+1].getBackground()==Color.BLACK)
count++;
if(count==3) // exactly three neighbors
{
if(grid[i][j].getBackground()==Color.WHITE)
{
grid1[i][j].setBackground(Color.BLACK); // birth cell
}
}
if(count==2 || count==3) // 2 or 3 neighbors
{
if(grid[i][j].getBackground()==Color.BLACK)
{
grid1[i][j].setBackground(Color.BLACK); // survives
}
}
if(count>=4 || count<=1) //4 or more neighbors, or 1 or less neighbor
{
if(grid[i][j].getBackground()==Color.BLACK)
{
grid1[i][j].setBackground(Color.WHITE); // dies from over-population or isolation
}
}
}
}
for(int i=0;i<length+2;i++)
{
for(int j=0;j<width+2;j++)
{
grid[i][j]=grid1[i][j];
}
}
for(int i=1;i<length+1;i++)
{
for(int j=1;j<width+1;j++)
{
System.out.print(grid[i][j]);
}
System.out.println("\n");
}
}
I am getting a nullpointer exception when I try to display the next generation of conway game of life using a GUI. Please suggest whats wrong with my code. The action performed method is executed when a start button is clicked
The cause of the NullPointerException is this:
grid = new JButton[length+20][width+20];
grid1 = new JButton[length+20][width+20];
This way, you have a 2D-array of JButtons, but it is still full of null values. You have to initialize the individual "cells" in the array:
for (int i = 0; i < length+20; i++) {
for(int j = 0; j < width+20; j++) {
grid1[i][j] = new JButton();
}
}
Also, is the size of the array intentional, or should it be length+2 x width+2 instead, as in your for-loop?
But this is not your actual problem: You create a new buttons-array, and then check the background colors of those newly created buttons. Assuming that grid represents the current state of the game, you are erasing the game state before doing the update. More likely, you have to drop the line grid = new JButton[length+20][width+20]; entirely.
And even this will not work correctly, as the two arrays grid and grid1 will hold the same buttons, so when you change the background color of one, you also change the background color in the backup. With grid1[i][j]=grid[i][j] you just copy the reference to the button to the other array, but do not create a new button. And even if you did, you would have the problem that that new button would not be in the GUI at all.
Instead of storing your game state in the GUI elements, you should rather use two 2D-arrays of booleans (one for the current state, one as backup of the previous state during the state update) and set the background color of the buttons based on those booleans.
Related
I hope i find someone to help finish the game ( 2048 )., since I'm in a computing programmer for only 2 month it's been difficult for me to do it.
The basis of this game that the user can choose what ever dimension he wants, and i kind of figured it out but now I'm struggling in a question saying:
In the beginning of the game two ‘1’ tiles are added to two random cells in the grid. Every subsequent turn a ‘1’ tile is added to an unoccupied cell in the grid, at the end of every turn you should make a list of all free cells and randomly select a free cell using that list".
I tried my best best still didn't work.
Another question was challenging says:
After the user makes a move all number tiles should attempt to move in the selected direction. A tile should continue to move in the given direction until it either hits another tile with a different number and stops or hits a tile with the same name and merges with it. Make sure that the only reason a tile stopped moving is if there are no empty cells in the direction it is supposed to move, or that all tiles that were supposed to merge do merge.
My current code:
import java.util.*;
public class The1024Game {
public static void main(String[] args) {
// TODO Auto-generated method stub
// QEUSTION 1: Asking the user to choose the desired dimensions of the grid
Scanner in = new Scanner(System.in);
System.out.print("Enter board size (IT MUST BE BETWEEN 4 AND 10): ");
int Dimension = 0;
do {
Dimension = in.nextInt();
if ( Dimension>10 | Dimension<4) {
System.out.print("THE DIMENSION MUST BE BETWEEN 4 AND 10!! PLEASE TRY AGAIN: ");
}
}while (Dimension>10 | Dimension<4);
System.out.println("The dimension has been set correctly");
// QEUSTION 2 : The frame of the game
int [][] GameFrame = new int[Dimension][Dimension];
//System.out.println(GameFrame[0][0]);
//GameFrame[0][0]=1000;
for(int i = 0; i<Dimension; i++) {
System.out.print("|");
for (int j=0; j<Dimension; j++) {
System.out.print(GameFrame[i][j]);
if(GameFrame[i][j]>=100 & GameFrame[i][j]<1000) {
System.out.print(" ");
}
if(GameFrame[i][j]>=10 & GameFrame[i][j]<100) {
System.out.print(" ");
}if(GameFrame[i][j]>=0 & GameFrame[i][j]<10 ){
System.out.print(" ");
}if(GameFrame[i][j]>=1000) {
}
System.out.print("|");
}
System.out.println();
for(int k=0; k<Dimension; k++) {
System.out.print("| ");}
System.out.print("|");
System.out.println();
System.out.print(" ");
for(int k=0; k<Dimension; k++) {
System.out.print("-----");
}
//testing another methode:
//StringBuilder rowLine = new StringBuilder();
//for (int c = 0; c<Dimension; c++) {
// rowLine.append("+-----");
//}
//rowLine.append("+");
System.out.print("\n");
}
// question 3:
int [] Free_coordinates;
for (int i=0; i<Dimension; i++) {
int [] Coordinates={0,0};
for (int j=0; j<Dimension; j++) {
if (GameFrame[i][j]==0) {
Coordinates[0]=i;
Coordinates[1]=j;
}
}
}
I have a 2D array of buttons called arr. For my game's win condition, I want to compare the graphics of the buttons to a 2D array of WritableImage's called newImage, where the condition is met once each button graphic is equal to the corresponding image. e.g. arr[0][0] equals newImage[0][0] etc. The code below doesn't seem to compare them, as nothing happens, guessing because of the different objects. Could anyone give any suggestions on how I should tackle this?
if (arr[3][3].getText().equals("blank")) {
System.out.println("this runs");
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (Objects.equals(arr[i][j].getGraphic(), newImage[i][j])) { //If the each button contains the correct corresponding graphic, puzzle is complete
System.out.println(arr[i][j] + " is correct");
}
setWin = true;
}
}
}
}
I have a school project, I have to build a Tetris Game.
So I began with the creation of my menu with the different level, when I click on one level i go to my second activity (the game area) and I have also created my custom block.
My problem is a visual issue, indeed I don't know what type of layout I have to use for my surface game (gridlayout, linearlayout, grid etc. ...).
And then how to affect my blocks custom in this surface game, in this layout?
See the result expected.
enter image description here
I'm not sure I understand what you want entirely but ill give it a shot from what i think you mean.
You should use a nested for loop to do it, if your array was int[10,20](not right syntax but i cant be bothered to count the actual size of your array).
you should go:
(pseudocode)
also assume your resolution is 100, 200
For(int i = 1 To 10){
For(int k = 1 To 20){
DrawSquare(i*10, k*10, "block type")
k = k + 1
}
i = i + 1
}
Then it will fill your 100, 200 area with the block type specified. Now if you want to load what block type you want freom the array you can just call the array in the block type.
DrawSquare(i*10, k*10, Array[i,k])
Obviously bear in mind that its all pseudocode to display the logic.
Hope this helps
Building on Valhalla's answer with a Java-specific example, it's still a bit unclear what you're asking, but assuming you want to initialise the grid to begin with you can use this code:
private final int columns = 10;
private final int rows = columns * 2;
private int[][] grid;
private void initialise() {
grid = new int[columns][rows];
for (int i = 0; i < columns; i++) {
for(int j = 0; j < rows; j++) {
grid[i][j] = 0;
}
}
}
And assuming that you have a block that starts at the top, and falls one square with each iteration provided there's nothing underneath, you can try this:
private void blockFall() {
// Start from 1 row above the bottom and parse upwards
// so a block won't drop right to the bottom on a single iteration
for (int i = 0; i < columns; i++) {
for(int j = rows - 2; j >= 0; j--) {
if (grid[i][j] > 0 && grid[i][j+1] == 0) {
grid[i][j+1] = grid[i][j];
grid[i][j] = 0;
}
}
}
}
I'm trying to create a bunch of the same objects (Grass) with a loop in different spaces. I have a grid and I want it to fill up the entire grid with different colors.
So I have this code so far:
public stage() {
super(null);
cast = new Cast();
cast.setBounds(10, 10, cast.getWidth(), cast.getHeight());
this.add(grid);
for (int i = 0; i <= 19; i++) {
obj = new Object[] {
new Grass (cast.cells[i][i])
};
}
}
This obviously doesn't work and only makes a colored cell in the last spot of the grid. Is there anyway to make a loop for objects in every spot?
Your code is going to create an new Object[1] 20 times. That Array will contain an instance of Grass. Try this instead.
public stage() {
super(null);
cast = new Cast();
cast.setBounds(10, 10, cast.getWidth(), cast.getHeight());
this.add(grid);
Object obj[] = new Object[20];
for (int i = 0; i <= 19; i++) {
obj[i] = new Grass (cast.cells[i][i])l
}
}
}
I want to write a board game using LibGDX and during a game I want make it possible to add or remove rows / columns on that board. First, I made some tests to prepare myself to that. Here is the code :
public class Test extends Game {
Skin skin;
Stage stage;
Texture texture1;
static int columns = 7;
static int rows = 12;
Window window2;
Table table2;
ArrayList<ArrayList<TextButton>> buttons;
#Override
public void create () {
skin = new Skin(Gdx.files.internal("data/uiskin.json"));
buttons = new ArrayList<ArrayList<TextButton>>();
for(int i = 0 ; i< rows; ++i)
{
buttons.add(new ArrayList<TextButton>());
for( int k = 0; k < columns; ++k)
{
buttons.get(i).add(new TextButton(("ASD" + i + k), skin));
}
}
texture1 = new Texture(Gdx.files.internal("data/badlogicsmall.jpg"));
TextureRegion image = new TextureRegion(texture1);
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
ImageButtonStyle style = new ImageButtonStyle(skin.get(ButtonStyle.class));
style.imageUp = new TextureRegionDrawable(image);
ImageButton iconButton = new ImageButton(style);
window2 = new Window("Dialog2", skin);
window2.getTitleTable().add(new TextButton("X", skin)).height(window2.getPadTop());
window2.setSize(300, 400);
table2 = new Table();
for(int i = 0 ; i< rows; ++i)
{
for( int k = 0; k < columns; ++k)
{
table2.add(buttons.get(i).get(k));
}
table2.row();
}
ScrollPane pane= new ScrollPane(table2,skin);
pane.setScrollbarsOnTop(false);
pane.setFadeScrollBars(false);
window2.add(iconButton).row();
window2.add(pane);
stage.addActor(window2);
iconButton.addListener(new ChangeListener() {
public void changed (ChangeEvent event, Actor actor) {
new Dialog("Some Dialog", skin, "dialog") {
protected void result (Object object) {
System.out.println("Chosen: " + object);
if((Boolean) object )
{
for(int i = 0 ; i <columns; ++i){
table2.getCells().removeIndex(0).getActor().remove();}
}
}
}.text("Are you enjoying this demo?").button("Yes", true).button("No", false).key(Keys.ENTER, true)
.key(Keys.ESCAPE, false).show(stage);
}
});
}
#Override
public void render () {
Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
stage.draw();
}
As you can see here, I'm creating a standalone button and a table and fill it with buttons. Then after button clicked I want to remove first row of that table and also move rest of rows up. It works but only once (for first row), then (with second click) I got this exception :
Exception in thread "LWJGL Application" java.lang.IndexOutOfBoundsException: index can't be >= size: 70 >= 70
Don't know what to do and how to fix it. Hope you can help me with this.
UPDATE
Thanks for reply; my code looks like this now :
// initialization
for(int i = 0 ; i< rows; ++i)
{
for( int k = 0; k < columns; ++k)
{
table2.add(new TextButton(("ASD" + i + k), skin));
}
table2.row();
}
// sample operation - remove left column
for(int i = 0 ; i <rows; ++i){
table2.removeActor( table2.getChildren().get(i*columns-i) );
}
columns--;
Also, I got similar Array in logical model and want to change state of UI table based on that array. So is this approach correct or should I change something?
The issue is about row() you are using - before the first row there is no row cell (marked with row() method) and that's why it does not cause error but when removing the second one it does.
Compare with table2 without any rows to test it:
for(int i = 0 ; i< rows; ++i)
{
for( int k = 0; k < columns; ++k)
{
table2.add(buttons.get(i).get(k));
}
//table2.row(); - we don't want any rows!
}
Ok we know where problem lays but it is not the solution (ok maybe some solution it is:) ). Instead of hard removing indexes of Table cells you should operate on Actors of table using following code:
for(int i = 0 ; i <columns; ++i){
table2.removeActor( table2.getChildren().first() );
}
Working with a table in such a way is a bit cumbersome, at least I don't know better. A quick fix for your code would be:
// Global field
int removedRows = 0;
// In your listener
System.out.println("Chosen: " + object);
if ((Boolean) object)
{
for (int i = 0; i < columns; ++i)
{
table2.getCells().get(i + columns * removedRows).clearActor();
}
removedRows++;
}
But if you want to remove complete rows, I would use a VerticalGroup and add each row there, so you can directly access a row and remove it from the VerticalGroup. If you use a fixed size for the buttons then it will align properly, too.
table2.getCells()
Returns an Array, this means we now operate on that Array and NOT the table2 anymore!
This means if you execute this:
table2.getCells().removeIndex(0);
It will just remove that cell from the array. This does NOT update the table2 as a complete object, just the cells array of that table (since no copy of that array is returned)
In other words you are doing this:
Array<Cell> table2Cells = table2.getCells();
Cell tableCell = table2Cells.removeIndex(0);
tableCell.clearActor();
So you delete the cell from the table2 cell array, and then you clear the cells contents (actor in this case). But you are not updating the table to reflect the changes of the removed cell, table2 still "thinks" that the cell is there, but you deleted it.
Thus you get the index error, because the stage draws the table, and the table wants to draw a cell that no longer exists.
So if you want to create some kind of board for a game the best way would be to code your own class that provides the functionality you desire.
A workaround would be that you reset the table and fill it again:
int table2Rows = table2.getRows();
table2.reset();
// Omit the first row
for (int i = rows - table2Rows + 1; i < rows; ++i)
{
for (int k = 0; k < columns; ++k)
{
table2.add(buttons.get(i).get(k));
}
table2.row();
}
table2.layout();
Thus the first cell will contain the first button and so on, since the table internal values are properly updated.