How to share same GCanvas in a GraphicsProgram in java? - java

I'm new at the Java world, and I started to take the Stanford cs106A course. I made the "breakout" problem which consists of making a simple breakout game.
I want to go even further, and my point is to create new Classes that can incorporate objects on the GCanvas of the main class.
So, now I have something like this:
public class Breakout extends GraphicsProgram {
//...
public void run();
private void playGame();
private void checkForPaddleCollisions();
private boolean passedBorderline();
private boolean moreBricksRemainig();
private void checkForCollisions();
private void updatePuntuation(GObject obj);
private void changeDirection(int temp);
private GObject getCollidingObject(double x, double y);
private void moveBall();
private void checkForBounderies();
private boolean hitsLeftWall();
private boolean hitsRightWall();
private boolean hitsRoof();
private void setRandomVx();
private void setBall();
private void setUp();
private void setLabels();
private void setPaddle();
public void mouseDragged (MouseEvent e);
public void mousePressed(MouseEvent i);
private void placeBricks();
private GOval ball;
private GRect paddle;
private GLabel win, lose, lifes, puntuationLabel;
private GPoint last;
private double vx, vy = 3.0;
private RandomGenerator rgen = RandomGenerator.getInstance();
private int Delay = 50;
private int counterBricks = NBRICKS_PER_ROW * NBRICK_ROWS;
private AudioClip bounceClip = MediaTools.loadAudioClip("bounce.au");
private int noPaddleBugs = 0;
private int puntuation = 0;
private int actualPunt = 0;
}
This is the main class of the game. What I want to do is to create a new class named PowerUps. This class can put any object on the GCanvas object of the main class at any point of the game. I tried to access the GCanvas of the main class by saying something like Breakout."canvasproperty".add(newObject), but it seems like it's not permitted.
Then I thought: I can create a class that extends GCanvas and then initialize a public property in the main class of that "new" canvas. With this method, I am able to insert new objects in this canvas from outer classes, but the problem is that when I run the Breakout class, the "new" canvas property doesn't show...
I don't know if I expressed myself well, but I tried, if anyone can help me, i would be very grateful?
Thanks in advance.

Related

Moving a circle on a map using Observer pattern

I have a (probably an easy) problem with my java program. I'm trying to create a circle that will move from one place to another. The map is a part of an easy dialogue game that says "go here" and the map should react to it. It has to be using an Observer design pattern.
So far I have the map in the game implemented but I just can't fathom how to make the circle function as it should, while using Observer, too. Thanks for any help
package GUI;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Circle;
import logika.Game;
import logika.IGame;
import main.Main;
import utils.Observer;
public class Mapa extends AnchorPane implements Observer{
private IGame game;
private Circle dot;
//private double posTop = 0.0;
//private double posLeft = 0.0;
public Mapa(IGame game){
this.game = game;
game.getGamePlan().registerObserver(this);
init();
}
private void init(){
ImageView obrazekImageView = new ImageView(new Image(Main.class.getResourceAsStream("/zdroje/mapa.gif"),255,255,false,true));
tecka = new Circle(10, Paint.valueOf("red"));
//this.setTopAnchor(tecka, 15.0);
//this.setLeftAnchor(tecka, 20.0);
this.getChildren().addAll(obrazekImageView, dot);
update();
}
public void newGame(IGame newGame){
game.getGamePlan().removeObserver(this);
game= newGame;
game.getGamePlan().registerObserver(this);
update();
}
#Override
public void update(){
this.setTopAnchor(this, game.getGamePlan().getCurrentPlace().getPosTop());
this.setLeftAnchor(this, game.getGamePlan().getCurrentPlace().getPosLeft());
}
}
You should implement the pattern like seen in this UML diagram from Wikipedia:
That is you will have an interface like CommandObserver with a method like notify that is called on each observer every time the event occurs. The event contains the exact command and all stuff that is neccessary to move the circle around. I'll assume you can move it by only having the reference to the circle. All in all it may look like
public interface CommandObserver {
void notify(String command, Circle circle);
}
Next the invoker (let's call it CommandReceiver) of the event must have some register method where all observers can be registered. And it must have some kind of notifyObservers that it calls if the event occurs:
public class CommandReceiver {
// The reference to the circle
private Circle circle = ...
private Set<CommandObserver> observers = new HashSet<>();
public void registerObserver(CommandObserver observer) {
observers.add(observer);
}
public void unregisterObserver(CommandObserver observer) {
observers.remove(observer);
}
private void notifyObserver(String command, Circle circle) {
for (CommandObserver observer : observers) {
observer.notify(command, circle);
}
}
// If a command was entered
public void commandEntered(String command) {
notifyObserver(command, circle);
}
}
And last you will implement observers for all possible commands like:
public PositionMoveObserver implements CommandObserver {
private int x;
private int y;
private String command;
public PositionMoveObserver(int x, int y, String command) {
this.x = x;
this.y = y;
this.command = command;
}
#Override
public void notify(String command, Circle circle) {
// Not interested in, reject
if (!this.command.equals(command)) {
return;
}
// Move the circle to our destination
circle.moveTo(x, y);
}
}
And then create and register it for every location:
private void createObservers(CommandReceiver invoker) {
invoker.registerObserver(new PositionMoveObserver(0, 5, "bottomLeft"));
invoker.registerObserver(new PositionMoveObserver(100, 5, "bottomRight"));
invoker.registerObserver(new PositionMoveObserver(0, 50, "middleLeft"));
...
}
Note that for a specific command only one observer should listen to it, otherwise multiple instances will move the circle around and the result will depend on the iteration order of invokers HashSet.

why does my Jframe open an empty window?

I'm trying to make a game for school, like Puralax. This is my first year of Java.
Currently I'm testing through 'viewTest' and the 'DitMoetWerken.java' class to make my complete JFrame.
My guess is that the VakUI doesn't get painted but I don't know why. These should be the squares in my matrix.
This is where I call all my JFrames:
public class DitMoetWerken extends JFrame {
Spel spel;
public DitMoetWerken(Spel spel, int level) throws HeadlessException {
this.spel = spel;
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(800,500);
setTitle("Puralax");
setVisible(true);
spel.beginLevel(level);
SpelFrame spelFrame = new SpelFrame(spel,new JButton("terugknop"),new JButton("resetknop"));
this.add(spelFrame,BorderLayout.CENTER);
This is where I make my roster for my game. It is a matrix where the length is 3x3 in this level:
public class SpelbordUI extends JPanel {
private final Spel spel;
private SpelRooster spelRooster;
private boolean vakChecker = false;
private Vak bewaardVak;
public SpelbordUI(Spel spel) {
this.spel = spel;
this.spelRooster = spel.getSpelRooster();
initAll();
}
private void initAll(){
this.removeAll();
this.setLayout(new GridLayout(spelRooster.getLengte(),spelRooster.getLengte(),20,20));
for (int i = 0; i < spelRooster.getLengte(); i++) {
for (int j = 0; j < spelRooster.getLengte(); j++) {
VakUI vak = new VakUI(spelRooster.getRooster()[i][j]);
this.add(vak);
}
}
}}
A 'vak' is meant to be a square in my language. Sorry for any possible confusion.
The class of this VakUI looks like this, where I think my problem is with the paintComponent. I think it should just fill up the vak's in VakUI because of the this.setBackground(kleur) or should I draw them in new squares?
public class VakUI extends JPanel {
private Color kleur;
private Vak vak;
public VakUI(Vak vak) {
this.vak = vak;
this.kleur = vak.getKleur();
}
public Vak getVak() {
return vak;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(kleur);
}}
In the class DitMoetWerken. setVisible(); is supposed to be placed underneath this.add(spelFrame,BorderLayout.CENTER);. this solved my empty window problem.

dealing with tictactoe detecting the buttons

So, I'm working on a project that uses a GridLayout and an array of tictactoetile, which is a class which extends JButton.
For an example of the first thing I'm trying to do, I want to find out what button is clicked, and then set that button's text to equal either x or o depending on which turn it is. I have the logic for that down, I just don't know how to get the row and column of the button clicked.
Sorry if this is not worded well.
public class tictactoetile extends JButton implements ActionListener {
private int cory;
private int corx;
//Create your own GameObj class with the necessary members
//Some examples for members below...
private GameObj game;
public tictactoetile(int x,int y,GameObj gam) {
cory = y;
corx = x;
game = gam;
super();
}
public void actionPerformed(ActionEvent e) {
this.setText(game.getTurnMarker()); //returns either x or o
game.updateGameState(game.getTurn(),cory,corx);
game.nextTurn();
}
}

Cannot remove shapes in Java using mouseEvents

I am trying to make an original game in Eclipse and I am having some trouble writing code that will remove GObjects and change the properties of others, using the mouseClicked method.
The problem seems to be that the private instant variables are not being recognised in the mousePressed method.
Can someone please advise on what I'm getting wrong here? I have spent a whole day on this and some help will be greatly appreciated.
Kind regards,
Mehul
*/*
* File: Linesv1.java
* 07/08/2012
*
*/
import acm.graphics.*;
import acm.program.*;
import acm.util.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.MenuEvent;
public class Linesv1 extends GraphicsProgram {
/** Width and height of application window in pixels */
public static final int BACKGROUND_WIDTH = 400;
public static final int BACKGROUND_HEIGHT = 600;
/** Dimensions of game board (usually the same) */
private static final int WIDTH = BACKGROUND_WIDTH;
private static final int HEIGHT = BACKGROUND_HEIGHT;
/** Dimensions of triangle*/
private static final int LENGTH_OF_TRIANGLE_SIDE = 100;
/** Dimensions of arc height*/
private static final int ARC_HEIGHT = 100;
/** Dimensions of radius of switches*/
private static final int SWITCH_RADII = 5;
// private instant variables
private GObject switchA;
private GOval switchB;
private GObject triangle;
private GObject bottomArc;
public void run() {
addMouseListeners();
setUpGame();
}
public void setUpGame(){
//add central triangle
GPolygon triangle = new GPolygon (WIDTH/2,HEIGHT/2);
triangle.addVertex(0,-LENGTH_OF_TRIANGLE_SIDE*2/3);
triangle.addVertex(LENGTH_OF_TRIANGLE_SIDE/2,+LENGTH_OF_TRIANGLE_SIDE*1/3);
triangle.addVertex(-LENGTH_OF_TRIANGLE_SIDE/2,+LENGTH_OF_TRIANGLE_SIDE*1/3);
triangle.setFilled(true);
triangle.setFillColor(Color.green);
add(triangle);
//add topArc
GArc bottomArc = new GArc (WIDTH/2-LENGTH_OF_TRIANGLE_SIDE/2, HEIGHT/2+LENGTH_OF_TRIANGLE_SIDE*1/3-ARC_HEIGHT/2, ARC_HEIGHT,ARC_HEIGHT,0,-180);
bottomArc.setFilled(true);
bottomArc.setFillColor(Color.green);
add(bottomArc);
//add switches to the bottom of the triangle
GOval switchA = new GOval (WIDTH/2-LENGTH_OF_TRIANGLE_SIDE/2-SWITCH_RADII, HEIGHT/2+LENGTH_OF_TRIANGLE_SIDE*1/3-SWITCH_RADII,SWITCH_RADII*2,SWITCH_RADII*2);
switchA.setFilled(true);
switchA.setFillColor(Color.black);
add(switchA);
//add switches to the bottom of the triangle
GOval switchB = new GOval (WIDTH/2+LENGTH_OF_TRIANGLE_SIDE/2-SWITCH_RADII, HEIGHT/2+LENGTH_OF_TRIANGLE_SIDE*1/3-SWITCH_RADII,SWITCH_RADII*2,SWITCH_RADII*2);
switchB.setFilled(true);
switchB.setFillColor(Color.black);
add(switchB);
}
public void mousePressed(MouseEvent e) {
findObject(e.getX(),e.getY());
GObject check = findObject(e.getX(),e.getY());
if (check!=null){
remove(triangle);
switchA.setColor(Color.cyan);
}
}
private GObject findObject(int a, int b){
if(getElementAt(a,b) != null) {
return getElementAt(a,b);
} else {
return null;
}
}
}*
The triangle you are trying to remove is not the one you added. You created a local GPolygon called triangle in setupGame() and added that, not the private member.
private GObject triangle; // this is uninitialized
public void setUpGame(){
GPolygon triangle = new GPolygon (WIDTH/2,HEIGHT/2); // this is hiding your member variable
// THIS IS LOCAL COPY, NOT MEMBER VARIABLE
add(triangle);
And then later you try to remove the uninitialized member variable, so nothing happens. You probably don't want a separate local copy of triangle. You probably want
public void setUpGame() {
triangle = new GPolygon (WIDTH/2, HEIGHT/2);
// ...
add(triangle); // Now, you are adding the member
}

Creating a moving object when user presses a key (Java)

The idea of my program is to create a picture and have that picture move up in a graphical window, which is exactly what the rollBall() method does. The method works when I put the rollBall() method in the run() method. But the issue lies it cannot run when I put the rollBall() method inside the keyPressed() method.
I am using the acm.jar library as it is a useful tool for creating java graphical program much easier.
Could someone please point me in the right direction.
This is my code...
import java.awt.Color;
import java.awt.event.KeyEvent;
import acm.graphics.GImage;
import acm.graphics.GOval;
import acm.program.GraphicsProgram;
import acm.util.RandomGenerator;
public class BallDrop extends GraphicsProgram {
/** width and height of application window in pixels */
public static final int APPLICATION_WIDTH = 900;
public static final int APPLICATION_HEIGHT = 768;
private static final double GRAVITY = 1;
/** Radius of the ball in pixels */
private static final int BALL_RADIUS = 50;
private static final int WIDTH = APPLICATION_WIDTH;
public void run() {
setSize(APPLICATION_WIDTH, APPLICATION_HEIGHT);
addKeyListeners();
}
public void keyPressed(KeyEvent e){
char linkMoveRightKey = e.getKeyChar();
if(linkMoveRightKey == 'z'){
rollBall();
}
}
private void rollBall(){
setup_Ball();
game_Loop();
}
private void setup_Ball(){
pic = new GImage("link.png");
add(pic,gameBallInitialLocationX, gameBallInitialLocationY);
}
private void game_Loop(){
while(pic.getX() > 0 ){
move_Ball();
pause(DELAY);
}
}
private void move_Ball() {
ballVelocityX = 0;
ballVelocityY -= GRAVITY;
pic.move(ballVelocityX, ballVelocityY);
}
private RandomGenerator rgen = RandomGenerator.getInstance();
private GImage pic;
private int gameBallInitialLocationX = 500;
private int gameBallInitialLocationY = 500;
private int ballVelocityX = (int) rgen.nextDouble(3.0, 5.0);
private int ballVelocityY =10;
private static final int DELAY = 50;
}
I just read the manual and it is my understanding that you are calling the wrong method:
Instead of calling run() method, define the init() method.
Also the setup_Ball() should be inside init() and not inside rollBall() - You only want to initialize the ball when the program starts and not when every time the key is pressed.
So instead of run() define init() and also remove setup_Ball() from rollBall() method :
public void init() {
setSize(APPLICATION_WIDTH, APPLICATION_HEIGHT);
setup_Ball();
addKeyListeners();
}
Note: You can use the run() method when you want some animation to appear when the program starts without waiting for key to be pressed. In that case, you can call the appropriate methods in run()

Categories