Im currently am working on a game in Java that spawns blocks on the top of the screen and they fall down (you have to dodge them). Currently I have the game spawning blocks on the top of the screen from an array but I do not know how to make their y position go down by (int).
Basically I just need help making a public void that checks an object array and with every instance of a object it finds it drops the y position of it by 12.
Selected snippits from code:
static Object[][] food = new Object[7][700];
public void draw() {
try {
Graphics g = bufferStrategy.getDrawGraphics();
g.clearRect(0, 0, this.getSize().width, this.getSize().height);
// Draw to back buffer
g.setColor(Color.WHITE);
g.fillRect(0, 0, this.getSize().width, this.getSize().height);
g.setColor(Color.BLUE);
g.fillRect(Player.getX(), Player.getY(), Player.WIDTH, Player.HEIGHT);
g.setColor(Color.GRAY);
for(int x = 0; x < food.length; x++) {
for(int y = 0; y < food[x].length; y ++) {
Object o = food[x][y];
if(o instanceof Hamburger) {
new Hamburger(x * 100, y, g);
}
else if(o instanceof Salad) {
new Salad(x * 100, y, g);
}
}
}
GUI.draw(g);
} catch(Exception e) {
e.printStackTrace();
} finally {
bufferGraphics.dispose();
}
}
public void dropBlocks() {
}
public void addBlock() {
if(new Random().nextInt(2) == 1) {
food[new Random().nextInt(7)][0] = new Hamburger(0, 0);
} else food[new Random().nextInt(7)][0] = new Salad(0, 0);
}
public void drawBackbufferToScreen() {
bufferStrategy.show();
Toolkit.getDefaultToolkit().sync();
}
public void run() {
int i = 0;
while(running) {
i++;
draw();
Player.update();
drawBackbufferToScreen();
if(i == 50) {
addBlock();
i = 0;
}
dropBlocks();
Thread.currentThread();
try {
Thread.sleep(10);
} catch(Exception e) {
e.printStackTrace();
}
}
}
Food.java (What Hamburger and Salad extend)
public class Food {
public static int x;
public static int y;
public static int HEIGHT;
public static int WIDTH;
public int type;
private static Image blockImage;
// Default constructor
public Food() {
Food.x = 0;
Food.y = 0;
Food.HEIGHT = 80;
Food.WIDTH = 80;
}
public Food(int x, int y) {
Food.x = x;
Food.y = y;
Food.HEIGHT = 80;
Food.WIDTH = 80;
}
// Getters and setters
I would do something like this:
Object[][] board = new Object[7][700]; //Game board.
//you can also switch the width and height
//Initialization
for (int x = 699; x >= 0; x--) {
for (int y = 0; y < 7; y++) {
if (x == 699) {
board[y][x] = BLANK; //set spot to open if it is the bottom row
continue;
}
board[y][x+1] = board[y][x]; //move row down
}
}
//Generate new Objects if needed for the top row of the board.
Clearly Object does not have a getY() method. You could do ugly things with casting and instanceof, but this design is rather putrid. Try moving towards an object oriented model.
interface Drawable {
int getX();
int getY();
void moveDown(int numSpaces);
}
class Hamburger implements Drawable {
private int x;
private int y;
public Hamburger(final int xPos, final int yPos) {
x = xPos;
y = yPos;
}
#Override
public void moveDown(final int numSpaces) {
// eg negative number, off the screen
if(isValid(numSpaces)) {
setY(getY() - numSpaces);
}
}
}
class Positioner {
public static void moveMyObjects(final Drawable[][] objs) {
for(Drawable[] rows : objs) {
for(Drawable col : rows) {
// clearly Object doesn't have a getY() method, so you should create your own interface and implement it
col.moveDown(12);
}
}
}
}
Related
I am having some issues trying to set my character to spawn in the right color spot in my map sheet in java.
In the vídeos that I am watching to learn this I have every single line code identical to the vídeo but yet my character instead of spawning in the right spot is spawning in the up middle corner of the screen.
I'm using those code lines to make him and all Tiles and Entities spawn in the right spot :
public class World {
private Tile[] tiles;
public static int WIDTH,HEIGHT;
public World(String path) {
try {
BufferedImage map = ImageIO.read(getClass().getResource(path));
int[] pixels = new int[map.getWidth() * map.getHeight()];
WIDTH = map.getWidth();
HEIGHT = map.getHeight();
tiles = new Tile[map.getWidth() * map.getHeight()];
map.getRGB(0, 0, map.getWidth(), map.getHeight(), pixels, 0, map.getWidth());
for(int xx = 0; xx < map.getWidth(); xx++) {
for(int yy = 0; yy < map.getHeight(); yy++) {
int pixelAtual = pixels[xx + (yy*map.getWidth())];
tiles[xx + (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_FLOOR);
if(pixelAtual == 0xFF000000) {
//FLOOR
tiles[xx + (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_FLOOR);
}else if(pixelAtual == 0xFFFFFFFF){
//PAREDE
tiles[xx + (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_WALL);
}else if(pixelAtual == 0xFF0026FF) {
//Player
Game.player.setX(xx*16);
Game.player.setY(yy*16);
}else if(pixelAtual == 0xFFFF0000){
//Enemy
}else if(pixelAtual == 0xFFFF00DC) {
//WEAPON
}else if(pixelAtual == 0xFFFF7F7F) {
//LIFEPACK
}else if(pixelAtual == 0xFFFFD800) {
//BULLET
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void render(Graphics g) {
for(int xx = 0; xx < WIDTH; xx++) {
for(int yy = 0; yy < HEIGHT; yy++) {
Tile tile = tiles[xx + (yy*WIDTH)];
tile.render(g);
}
}
}
}
But when I use these two code lines that are from my Entity Class that are suposed to make my character spawn in the right place it doesn't work at all!
Game.player.setX(xx16);
Game.player.setY(yy16);
Here's my Entity Class for you to see if i did something wrong, and again, i did everything exactely like int the vídeo an in the vídeo it worked.
public class Entity {
public static BufferedImage LIFEPACK_EN = Game.spritesheet.getSprite(78, 0, 16, 16);
public static BufferedImage WEAPON_EN = Game.spritesheet.getSprite(96, 0, 16, 16);
public static BufferedImage BULLET_EN = Game.spritesheet.getSprite(78, 16, 16, 16);
public static BufferedImage ENEMY_EN = Game.spritesheet.getSprite(96, 16, 16, 16);
protected double x;
protected double y;
protected int width;
protected int height;
private BufferedImage sprite;
public Entity(int x, int y, int width, int height, BufferedImage sprite) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.sprite = sprite;
}
public void setX(int newX) {
this.x = newX;
}
public void setY(int newY) {
this.x = newY;
}
public int getX() {
return (int)this.x;
}
public int getY() {
return (int)this.y;
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public void update() {
}
public void render(Graphics g) {
g.drawImage(sprite, this.getX(), this.getY(), null);
}
}
I saw where I was wrong.
public void setY(int newY) {
this.x = newY;
In this line code here, it's suposed to be this.y and I thought that I did that, but I couldn't see.
I have been having some trouble with attempting to create constantly "spawning" objects (called Rushers) that chase after a single object that is user-controlled (called Character). My main issue is the coordinates for the Rushers seem to be the exact same as that of the Character.
I have my code split into several classes. Here is the code for the Character first:
public class Gamepanel {
private boolean right = false, left = false, up = false, down = false;
public Character mainChar;
private static int xCoor = 230;
private static int yCoor = 210;
This is the main loop:
public void tick(){
mainChar = new Character(xCoor, yCoor, 30, 50);
mainChar.setxCoor(xCoor);
mainChar.setyCoor(yCoor);
if(right && mainChar.getxCoor() < 469) xCoor+=5;
if(left && mainChar.getxCoor() > 0) xCoor -= 5;
if(up && mainChar.getyCoor() > 0) yCoor -= 5;
if(down && mainChar.getyCoor() < 449) yCoor+=5;
}
The GFX:
mainChar.draw(g);
The controls are basic keyPressed and keyReleased methods. I will not post them for sake of brevity, as they seem to be working fine.
This is the code for the Character class:
public class Character {
int xCoor = 230;
int yCoor = 210;
int width = 30;
int height = 50;
public Character(int xCoor, int yCoor, int width, int height) {
this.xCoor = xCoor;
this.yCoor = yCoor;
}
public void draw(Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(xCoor, yCoor, width, height);
}
public int getxCoor() {
return xCoor;
}
public void setxCoor(int xCoor) {
this.xCoor = xCoor;
}
public int getyCoor() {
return yCoor;
}
public void setyCoor(int yCoor) {
this.yCoor = yCoor;
}
}
These all appear to work as normal with no massive issues. The biggest problems I was having was with my other objects, the Rushers. Here is their code in the Gamepanel:
public class Gamepanel {
private Rusher rusher;
ArrayList<Rusher> rushers;
int spawnTimer = 0;
public Gamepanel() {
rushers = new ArrayList <Rusher>();
}
public void tick(){
spawnTimer++;
if(spawnTimer > 75) {
spawn();
spawnTimer = 0;
}
if(rushers.size() > 0) {
for(int i = 0; i < rushers.size(); i++) {
rushers.get(i).tick();
}
}
}
The GFX:
if(rushers.size() > 0) {
for(int i = 0 ; i < rushers.size(); i++) {
rushers.get(i).draw(g);
}
}
Spawn method (pretty sure the error is in here):
public void spawn() {
int xSpawn[] = new int[4];
int ySpawn[] = new int[4];
ySpawn[0] = 250; ySpawn[1] = 499; ySpawn[2] = 250; ySpawn[3] = 0;
xSpawn[0] = 0; xSpawn[1] = 250; xSpawn[2] = 499; xSpawn[3] = 250;
int spawnCoor = randomRange(0, 3);
rusher = new Rusher(xSpawn[spawnCoor], ySpawn[spawnCoor], 10, 10);
rusher.setxCoor(xSpawn[spawnCoor]);
rusher.setyCoor(ySpawn[spawnCoor]);
rushers.add(rusher);
}
and finally, the Rusher class:
public class Rusher {
private static int xCoor;
private static int yCoor;
private int width = 20;
private int height = 20;
public Rusher(int xCoor, int yCoor, int width, int height) {
super(xCoor, yCoor, width, height);
Rusher.xCoor = xCoor;
Rusher.yCoor = yCoor;
}
public void tick() {
if(xCoor > Gamepanel.mainxCoor()) xCoor -= 2;
if(yCoor > Gamepanel.mainyCoor()) yCoor -= 2;
if(xCoor < Gamepanel.mainxCoor()) xCoor += 2;
if(yCoor < Gamepanel.mainyCoor()) yCoor += 2;
}
public void draw(Graphics g) {
g.setColor(Color.RED);
g.fillRect(xCoor, yCoor, width, height);
}
public int getxCoor() {
return xCoor;
}
public void setxCoor(int xCoor) {
Rusher.xCoor = xCoor;
}
public int getyCoor() {
return yCoor;
}
public void setyCoor(int yCoor) {
Rusher.yCoor = yCoor;
}
}
Just to recap, the main issue is that the Rushers will spawn with the same coordinates as the Character, and will also move just as fast, despite me setting their motion to 3 slower than the Character. I tried to make this as brief as possible. If more code is needed, I do have some others that relate to these objects.
Thanks in advance.
I found it out. I was setting the coordinates for the Rushers as static, so they all shared the same ones. When I changed that, and adjusted some other, smaller things, it worked out much better.
I have an application where you place tiles. You can place tiles over tiles and I don't want that. I know that I need something like if the tile rectangle contains the mouse then don't place a tile over it. But this doesn't work. Look at this code:
for (int i = 0; i < b.toArray().length; i++) {
b.get(i).tick();
if (b.get(i).r.contains(Comp.mx, Comp.my)) {
canPlaceATile = false;
// System.out.println("yes");
}
else {
canPlaceATile = true;
//System.out.println("no");
}
if (b.get(i).remove) {
b.remove(i);
i--;
}
}
This is how I check if the mouse is inside the area of one of the tiles.
Block class:
public abstract class block {
public int x,id;
public int y;
protected Image img;
public boolean remove;
public int rotate;
public Rectangle r;
protected int bx, by;
public block() {
}
public abstract void tick();
public abstract void render(Graphics g);
public void createCollisionRect() {
r.setBounds(x - (int) play.camx, y - (int) play.camy, 20, 20);
}
}
an example of a tile:
public class wall extends block {
public wall(int x, int y, int rot) {
this.x = x;
this.y = y;
this.rotate = rot;
r = new Rectangle(x - (int) play.camx, y - (int) play.camy, 20, 20);
id = 0;
}
public void tick() {
createCollisionRect();
if (Comp.mr && r.contains(new Point((Comp.mx), (Comp.my)))) {
remove = true;
}
}
public void render(Graphics g) {
ImageIcon i62 = new ImageIcon("res/tiles/wall.png");
img = i62.getImage();
g.drawImage(img, x - (int) play.camx, y - (int) play.camy, null);
g.setColor(Color.red);
// g.drawRect(x -(int)play.camx, y - play.camy, 20,20);
}
}
I want to check if any of the rectangles contains the mouse and set canPlaceATile to false if the mouse is inside one of the rectangles. The code above doesn't work because when I print the console and I have my mouse over one of the tiles it says:
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
and this is when my mouse is on the rectangle without moving it at all. How can I fix this so that I cannot place tiles on top of tiles. Her is where I place tiles:
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
Comp.ml = true;
if (manager.isplay && play.dragging == false) {
if (play.canPlaceATile) {
if (play.selectedID == 0) {
play.b.add(new wall((Comp.mx / 20) * 20, (Comp.my / 20) * 20, play.selectedRot));
}
}
}
}
}
I am creating a reversi game. I decided to create my board using JLabels. The problem I am having is getting the four starting pieces onto the board. This is only a 2 player game, and it is 1v1. At the beginning of the game each player starts off with 2 pieces in the very middle of the board. In my program I go to create 2 blue and 2 red pieces for the 2 players but no matter what I do I can't get the pieces to show up on the game board. When I ran my debugger it looked like i was never giving each BoardSquare the correct x and y values. I am not sure how to get the x and y values of the BoardSquares. Any and all help/criticism is welcome. I have been stuck trying to fix this for hours. Thanks.
public class ReversiRemake {
public static void main(String[] args) {
PlayGame game = new PlayGame();
}
}
class BoardSquare extends JLabel {
private int x;
private int y;
private int row;
private int column;
private MyShape circle;
private Border b = BorderFactory.createLineBorder(Color.BLACK, 2);
BoardSquare(int row, int column) {
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getButton() == 1) {
}
}
});
this.row = row;
this.column = column;
setBorder(b);
}
public void setShape(Player p){
if(p instanceof HumanPlayer){
circle = new MyShape(x, y, Color.blue);
}
if(p instanceof aiPlayer){
circle = new MyShape(x, y, Color.red);
}
}
public void setX(int x){
this.x = x;
}
public void setY(int y){
this.y = y;
}
public MyShape getShape() {
return circle;
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
circle.drawShape(g2);
}
}
class MyShape {
private Color color;
private int x;
private int y;
MyShape(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
MyShape(Color color) {
this.color = color;
}
public void drawShape(Graphics2D g) {
g.setPaint(color);
g.drawOval(x + 5, y + 2, 50, 50);
g.fillOval(x + 5, y + 2, 50, 50);
}
public void setColor(Player p) {
if (p instanceof HumanPlayer) {
color = Color.BLUE;
}
if (p instanceof aiPlayer) {
color = Color.red;
}
}
}
class GameBoard extends JPanel {
BoardSquare[][] BoardSquares = new BoardSquare[8][8];
private BoardSquare bs;
GameBoard() {
for (int row = 0; row < 8; row++) {
for (int column = 0; column < 8; column++) {
BoardSquares[row][column] = new BoardSquare(row, column);
add(BoardSquares[row][column]);
}
}
}
public void StartingPieces(HumanPlayer p1, aiPlayer p2) {
for (int row = 0; row < 8; row++) {
for (int column = 0; column < 8; column++) {
BoardSquares[row][column] = bs;
if (row == 3 && column == 3) {
bs.setShape(p1);
}
if (row == 3 && column == 4) {
bs.setShape(p2);
}
if (row == 4 && column == 3) {
bs.setShape(p2);
}
if (row == 4 && column == 4) {
bs.setShape(p1);
}
}
}
}
}
abstract class Player {
int playerType;
Color color;
int score;
Player(int playerType, Color color, int score) {
this.playerType = playerType;
this.color = color;
this.score = score;
}
}
class HumanPlayer extends Player {
HumanPlayer() {
super(1, Color.BLUE, 0);
}
}
class aiPlayer extends Player {
aiPlayer() {
super(2, Color.RED, 0);
}
}
class PlayGame {
private HumanPlayer p1 = new HumanPlayer();
private aiPlayer p2 = new aiPlayer();
private GameBoard gameBoard = new GameBoard();
private boolean p1Turn;
private boolean p2Turn;
PlayGame() {
setStartingPieces();
}
public void setStartingPieces() {
gameBoard.StartingPieces(p1, p2);
}
}
I couldn't run your code as it is posted, but I believe upon visual inspection the line
BoardSquares[row][column] = bs;
should be
bs = BoardSquares[row][column];
As it is written above, a NullPointerException would occur and bs is never actually getting set. The revision I have offered would allow the shape to be set in the GameBoard class.
I have a problem with my program. I'm trying to move trains over a rail, these trains are represented by ellipses. When I try to move these objects, they are drawn in the new position, but they are also drawn in the previous position.
trensPretos is a linkedlist of trem class:
'public LinkedList trensPretos = new LinkedList();'
Here is my code:
public void AtualizaTrensPretos()
{
int currentX;
int currentY;
// trens pretos se movem
for (Trem t:trensPretos)
{
while(t.get_x() < 1100)
{
currentX = t.get_x();
currentY = t.get_y();
t.setNew_x(currentX + moveX);
// antes da linha reta
if (t.get_x() < 270)
{
t.setNew_y(currentY + moveY);
}
else if(t.get_x() > 730)
{// depois da linha reta
t.setNew_y(currentY - (moveY+1));
}
setChanged();
notifyObservers(t);
}
// removo o trem após ele passar pelo cruzamento
// trensPretos.remove(t);
}
}
// Observer
// recebo trem e desenho
g2d = (Graphics2D) this.getGraphics();
if (arg instanceof Trem)
{
if (g2d != null)
{
g2d.setColor(((Trem) arg).getColor());
g2d.fill(((Trem) arg).getEllipse());
}
}
// Trem class
public class Trem {
private int posX;
private int posY;
private Color corTrem;
private Ellipse2D formaDoTrem;
private int sizeX = 30;
private int sizeY = 30;
public Trem(Color corDoTrem)
{
formaDoTrem = new Ellipse2D.Double();
this.corTrem = corDoTrem;
}
public Color getColor()
{
return this.corTrem;
}
public void setNew_x(int x)
{
this.posX = x;
}
public void setNew_y(int y)
{
this.posY = y;
}
public int get_x()
{
return this.posX;
}
public int get_y()
{
return this.posY;
}
public Ellipse2D getEllipse()
{
this.formaDoTrem.setFrame(posX, posY, sizeX, sizeY);
return this.formaDoTrem;
}
}
What could be the problem?
they are drawn in the new position, but they are also drawn in the previous position.
You need to clear the background area first before repainting the trains.