I have a Main class of game named BrickBreaker
public class BrickBreaker extends Activity {
// there is lot of other code but i am only pointing to the issue
class BreakoutView extends SurfaceView implements Runnable {
// The size of the screen in pixels
int screenX;
int screenY;
// Get a Display object to access screen details
Display display = getWindowManager().getDefaultDisplay();
// Load the resolution into a Point object
Point size = new Point();
display.getSize(size);
screenX = size.x;
screenY = size.y;
}}
And from another class (below) I want to access screenX from the Main class:
public class Paddle {
// This the the constructor method
// When we create an object from this class we will pass
// in the screen width and height
public Paddle(int screenX, int screenY){
// 130 pixels wide and 20 pixels high
length = 130;
height = 20;
// Start paddle in roughly the sceen centre
x = screenX / 2;
y = screenY - 20;
rect = new RectF(x, y, x + length, y + height);
// How fast is the paddle in pixels per second
paddleSpeed = 550;
}
public void update(long fps){
rect.left = x;
rect.right = x + length;
if (x<0){
x=0;
}
else if (x+length > screenX){
x = screenX-length;
}
}
}
How can I access screenX from the Paddle class?
In Paddle class modify field screenX
Java static variable
If you declare any variable as static, it is known static variable.
The static variable can be used to refer the common property of all objects (that is not unique for each object) e.g. company name of employees,college name of students etc.
The static variable gets memory only once in class area at the time of class loading.
Advantage of static variable
Please check this : STATIC
It makes your program memory efficient (i.e it saves memory).
public class Paddle {
public static int screenX;
// This the the constructor method
// When we create an object from this class we will pass
// in the screen width and height
public Paddle(int screenX, int screenY){
this.screenX = screenX;
// 130 pixels wide and 20 pixels high
length = 130;
height = 20;
// Start paddle in roughly the sceen centre
x = screenX / 2;
y = screenY - 20;
rect = new RectF(x, y, x + length, y + height);
// How fast is the paddle in pixels per second
paddleSpeed = 550;
}
public void update(long fps){
rect.left = x;
rect.right = x + length;
if (x<0){
x=0;
}
else if (x+length > screenX){
x = screenX-length;
}
}
}
And to acces in BrickBeaker you need to:
Paddle.screenX
Enjoy
You need to get access to BreakoutView's member screenX from your Paddle class.
For this, your Paddle class first needs to get access to the BreakoutView instance.
You could do this by passing it for example in the constructor:
public class Paddle {
BreakoutView view;
public Paddle (BreakoutView view) {
this.view = view;
}
public void update(long fps){
...
}
}
And where you create it:
BreakoutView view = new BreakoutView(.....);
Paddle paddle = new Paddle(view);
....
Next, you need to get access to the screenX member. There are two options:
First: make it public:
// The size of the screen in pixels
public int screenX;
public int screenY;
With this solution, you could access it in your Paddle class with this.view.screenX.
But this would allow other code, for example from inside your Paddle class, to modify these values, which is often not desired. Thus, the safer way is:
Second: Provide a getter.
In BreakoutView, add the following method:
public int getScreenX() {
return this.screenX;
}
and then, in your Paddle class, you could access it like this.view.getScreenX() instead of just screenX.
Related
So I'm trying to program snake on a JFrame and doing all graphical stuff (moving the 'snake', random food generation, etc.) on a JPanel. I'm in the beginning stages so all I'm trying to do right now is move a black square around on my frame using arrow keys. My while loop in the Panel class won't get interrupted by a key press in the Snake class, so is there a way to edit JPanel graphics from the same class with all my other code?
Here's all the code. My Panel class at the bottom follows the template I found here.
public class Snake {
// panel width and height
static int pW;
static int pH;
static int x = 10;
static int y = 10;
static int k;
static JFrame frame = new JFrame("SNAKE");
// getters for panel class
public int getPW() { return pW; }
public int getPH() { return pH; }
public int getX() { return x; }
public int getY() { return y; }
public static void main(String[] args) {
// get screen dimensions
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int sH = (int) screenSize.getHeight();
int sW = (int) screenSize.getWidth();
pW = (int) sW/2;
pH = (int) sH/2;
// initialize frame
frame.setSize (pW/1,pH/1);
frame.setLocation(pW/2,pH/2);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addKeyListener( new KeyAdapter() {
public void keyPressed(KeyEvent e) {
k = e.getKeyCode();
switch(k) {
case 38: /* y -= square size */ break; // up
case 40: /* y += square size */ break; // down
case 37: /* x -= square size */ break; // left
case 39: /* x += square size */ break; // right
case 27: System.exit(0);
}
}
});
Panel panel = new Panel();
frame.add(panel);
frame.setVisible(true);
}
}
class Panel extends JPanel {
Snake snake = new Snake();
//square size and separation between squares
int sep = 0;
int size = 50;
// initial location of square on the panel/frame
int x = sep + size;
int y = sep + size;
// holding values to check if x or y have changed
int xH = x;
int yH = x;
public void paint(Graphics g) {
int pW = snake.getPW();
int pH = snake.getPH();
int i; int o;
Color on = Color.BLACK;
Color off = Color.GRAY;
// gray background
g.setColor(Color.GRAY);
g.fillRect(0,0,pW,pH);
// black square initialization
g.setColor(Color.BLACK);
g.fillRect(x, y, size, size);
/* this loop is supposed to check if the black
* rectangle has moved by repeatedly grabbing x & y
* values from the Snake class. When a key is pressed
* and the values change, a gray rectangle is placed at the old location
* and a black one is placed at the new location.
*
* When I run the program, I get stuck in this while loop.
* If I had the while loop in the same class I check for keys,
* I don't think I would have this problem
*/
while(true) {
x = snake.getX();
y = snake.getY();
if(x != xH || y != yH) {
g.setColor(off);
g.fillRect(xH, yH, size, size);
g.setColor(on);
g.fillRect(snake.getX(), snake.getY(), size, size);
xH = x;
yH = y;
}}
}
}
You should never have a while(true) loop in a painting method. This will just cause an infinite loop and your GUI will not be able to respond to events.
Instead you need to add methods to your snake class to move the snake. So when one of the arrow keys is pressed you update the starting position of the snake. Then the method will invoke repaint() and the snake will repaint itself when the paintComponent() method is invoked by Swing.
So your painting code should override paintComponent() not paint() and you should invoke super.paintComponent(g) as the first statement in the method.
Don't call your custom class "Panel", there is an AWT class with that name. Make your class name more descriptive.
I am currently working on a project called Rectangle project in which I am supposed to do the following on Java:
Make the following methods:
setOrigin
area
move
Also make a method that determines if two rectangles intersect and returns a new intersection Rectangle. Test all your methods in the ObjectDemo program for the following rectangles:
A: Origin 0,0: width 10: height 20
B: Origin 5,5: width 15, height 15
C: Origin 20,12: width 10: height 20
What is the area of each? Test if each of them intersect with the other two and what is the intersection area. Move A by 5,5; B by -5,-5: and C by -20, 0. Now give the intersection area of each.
I need to finish this by Monday but I keep getting a ton of errors like unrecognized variables, etc., and I'm not sure how to fix them. Please let me know!
I have three files: Point, RectangleTest, and Rectangle.
Here are their codes:
Point code:
public class Point
{
//Class variables
private int xCoord; //Private (instead of Public) because we are going to use this class in the other file
//We don't want people changing the values unless we let them
private int yCoord; //Variables are not in a function so will maintain their value
//Constructor
Point()
{
xCoord = 0;
yCoord = 0;
}
//Constructor
Point(int startX, int startY)
{
xCoord = startX;
yCoord = startY;
}
public int getX()
{
return xCoord;
}
public int getY()
{
return yCoord;
}
public void setX(int newX)
{
xCoord = newX;
}
public void setY(int newY)
{
yCoord = newY;
}
public void move(int moveX, int moveY)
{
xCoord+=moveX;
yCoord+=moveY;
}
Point(Point p)
{
xCoord = p.getX();
yCoord = p.getY();
}
}
RectangleTest Code:
public class RectangleTest
{
public static void main(String [] args)
{
Rectangle A = new Rectangle(0,0,10,20);
Rectangle B = new Rectangle(5,5,15,15);
Rectangle C = new Rectangle(20,12,10,20);
//Move rectangles
A.moveby(5,10);
B.moveby(-5,-5);
C.moveby(-20,0);
int areaA = A.getarea;
System.out.println("The area of rectangle A is " +areaA);
int areaB = B.getarea;
System.out.println("The area of rectangle B is " +areaB);
int areaC = C.getarea;
System.out.println("The area of rectangle C is " +areaC);
Rectanlge iAB = A.intersect(B);
Rectangle iAC = A.intersect(C);
Rectangle iBC = B.intersect(C);
if(iab != null)
{
System.out.println("The area of intersection rectangle iab = " +iAB.area());
}
if(iac != null)
{
System.out.println("The area of intersection rectangle iac = " +iAC.area());
}
if (ibc != null)
{
System.out.println("The area of intersection area ibc = " +iBC.area());
}
}
}
Rectangle Code:
public class Rectangle
{
Point origin;
int height;
int width;
//Constructor for rectangle object
Public Rectangle(int startX, int startY, int startW, int startH)
{
origin = new Point (startX, startY);
width = startW;
height = startH;
}
//Set origin point for NEW rectangle origins
//FIX
public void setOrigin(int newX, int newY)
{
origin.setX(newX);
origin.setY(newY);
}
public int moveBy(int moveX, int moveY)
{
origin.move(moveX, moveY);
}
public int getArea()
{
int recArea = height*width;
return recArea;
}
public Rectangle intersect(Rectangle testR)
{
int meTRX = origin.getX() + width;
int meTRY = origin.getY() + height;
int testTRX = testR.origin.getX() + width;
int testTRY = testR.origin.getY() + height;
//Boolean to get iTRX
if(meTRX>testTRX)
{
int iTRX = testTRX;
}
else
{
int iTRX = meTRX;
}
//Boolean to get iTRY
if(meTRY>testTRY)
{
int iTRY = testTRY;
}
else
{
int iTRY = meTRY;
}
//Boolean to get iBLX
if(testBLX>meBLX)
{
int iBLX = testBLX;
}
else
{
int iBLX = meBLX;
}
//Boolean to get iBLY
if(testBLY>meBLY)
{
int iBLY = testBLY;
}
else
{
int iBLY = meBLY;
}
//Testing for whether or not there is an intersection rectangle
if(iTRX-iBLX<0 || iTRY-iBLY<0)
{
return null;
}
int iH = iTRY - iBLY;
int iW = iTRX - iBLX;
int intersectArea = iH * iW;
}
}
Please point out any problems! I'm rather new to programming, so I usually make a lot of simple mistakes. Also, I would appreciate if there are no newly introduced commands or anything because my teacher is pretty strict about doing it this way.
Thanks!
P.S. I would appreciate any extra knowledge or info on code improvement (just in general). Thanks!
Couple of Issues:
Java is case sensitive so Public is not same as public in your rectangle class.
When your method doesnt return anything you should use void as return type. So in your method public int moveBy(int moveX, int moveY), you should change it to public void moveBy(int moveX, int moveY)
You need to define variables before using them. So variables like testBLX, meBLX, testBLY, meBLY, iTRX, iTRY, iBLX, iBLY are undefined. I am not sure from where the values will get populated. But you could avoid the compilation error by defining them as int testBLX = 0; and similarly the others.
In your Rectangle class:
In the constructor your wrote Public Rectangle(int startX, int startY, int startW, int startH), but you actually want public Rectangle(int startX, int startY, int startW, int startH). In Java keywords start always with a lower case.
Your method for changing the origin of a rectangle public int moveBy(int moveX, int moveY) has int as a return type, so the compiler wants you to return an integer value. I suppose you did not want to return anything at all so you can change the return type to void.
In your intersect method public Rectangle intersect(Rectangle testR) you declare your variables (iTRX, iTRY, iBLX, iBLY) such as int iTRX = testTRX; only in the scope of your if/else statements which means that after every if/else statement these variables are not available anymore. To learn more about the different scopes of variables: Variable scopes
In your RectangleTest class:
You forgot a part of your task: What is the area of each? Test if each of them intersect with the other two and what is the intersection area.
Some general leads:
The use of more descriptive variable names improves the readability. For example the variable name meTRX does not have any meaning for me as person who did not work on your code or maybe for you if you review your code two months later.
Before you start coding, you could check if Java has built-in classes which you can use. In your case Java provides a Point class in the package java.awt.Point. You do not have to reinvent the wheel.
I would also recommend to read the Java Code Conventions Code Conventions which can bring you and others who read your code on a common denominator in the future.
I'm following a textbook and have become stuck at a particular point.
This is a console application.
I have the following class with a rotate image method:
public class Rotate {
public ColorImage rotateImage(ColorImage theImage) {
int height = theImage.getHeight();
int width = theImage.getWidth();
//having to create new obj instance to aid with rotation
ColorImage rotImage = new ColorImage(height, width);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color pix = theImage.getPixel(x, y);
rotImage.setPixel(height - y - 1, x, pix);
}
}
//I want this to return theImage ideally so I can keep its state
return rotImage;
}
}
The rotation works, but I have to create a new ColorImage (class below) and this means I am creating a new object instance (rotImage) and losing the state of the object I pass in (theImage). Presently, it's not a big deal as ColorImage does not house much, but if I wanted it to house the state of, say, number of rotations it has had applied or a List of something I'm losing all that.
The class below is from the textbook.
public class ColorImage extends BufferedImage {
public ColorImage(BufferedImage image) {
super(image.getWidth(), image.getHeight(), TYPE_INT_RGB);
int width = image.getWidth();
int height = image.getHeight();
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
setRGB(x, y, image.getRGB(x, y));
}
public ColorImage(int width, int height) {
super(width, height, TYPE_INT_RGB);
}
public void setPixel(int x, int y, Color col) {
int pixel = col.getRGB();
setRGB(x, y, pixel);
}
public Color getPixel(int x, int y) {
int pixel = getRGB(x, y);
return new Color(pixel);
}
}
My question is, how can I rotate the image I pass in so I can preserve its state?
Unless you limit yourself to square images or to 180° rotations, you need a new object, as the dimensions would have changed. The dimensions of a BufferedImage object, once created, are constant.
If I wanted it to house the state of, say, number of rotations it has had applied or a List of something I'm losing all that
You can create another class to hold that other information along with the ColorImage/BufferedImage, then limit the ColorImage/BufferedImage class itself to holding only the pixels. An example:
class ImageWithInfo {
Map<String, Object> properties; // meta information
File file; // on-disk file that we loaded this image from
ColorImage image; // pixels
}
Then you can replace the pixels object freely, while preserving the other state. It's often helpful to favor composition over inheritance. In brief that means, instead of extending a class, create a separate class that contains the original class as a field.
Also note that the rotation implementation from your book seems to be mainly for learning purposes. It's fine for that, but will show its performance limitations if you manipulate very big images or for continuous graphics rotation at animation speeds.
I have a game of a rocket landing game, where the player is the rocket and you must land it safely at the right speed on the landing pad. This was taken from www.gametutorial.net
Its actually for educational purposes and I recently added a still meteor in the game.
When the player hits the meteor (touches) the game is over.
if(...) {
playerRocket.crashed = true;
}
My problem is there I need to replace the "..." with the actual condition that "Has the rocket crashed into the meteor?"
Plus the following variables (coordinates, height and width) for use -
[All Integers]:
X and Y coordinates: playerRocket.x, playerRocket.y, meteor.x, meteor.y
Height and Width: playerRocket.rocketImgHeight, playerRocket.rocketImgWidth, meteor.meteorImgHeight, meteor.meteorImgWidth
For collision detection in 2D games, you can use rectangles. I'd use a base class called GObject and inherit all objects in the game from it.
public class GObject
{
private Rectangle bounds;
public float x, y, hspeed, vspeed;
private Image image;
public GObject(Image img, float startx, float starty)
{
image = img;
x = startx;
y = starty;
hspeed = vspeed = 0;
bounds = new Rectangle(x, y, img.getWidth(null), img.getHeight(null));
}
public Rectangle getBounds()
{
bounds.x = x;
bounds.y = y;
return bounds;
}
}
There's also other methods like update() and render() but I'm not showing them. So to check for collision between two objects use
public boolean checkCollision(GObject obj1, GObject obj2)
{
return obj1.getBounds().intersects(obj2.getBounds());
}
Also, there's a specific site for game related questions. Go to Game Development Stack Exchange
You need to check if you hit the object, meaning, if the click coordinates are within the object's Rectangle.
if( playerRocket.x + playerRocket.width >= clickX && playerRocket.x <= clickX &&
playerRocket.y + playerRocket.height >= clickY && playerRocket.Y <= clickY ) {
playerRocket.crashed = true;
}
How would you go about creating a line graph using outputs from a thread, the threads are simulations of incoming and outgoing bill that run over a course of 52 seconds and this will be dipicted on a line graph as shown below
I want to use the paint component not any third party classes like JChart.
Assuming you have some JPanel object that you are using to paint on, I would add the following to your object:
public class GraphPanel extends JPanel{
//static constants for defining the size and positioning of the graph on canvas
//Ignore the values I chose, they were completely random :p
private static final int X_AXIS_LENGTH = 1000;
private static final int Y_AXIS_LENGTH = 500;
private static final int X_AXIS_OFFEST = 50;
private static final int Y_AXIS_OFFSET = 50;
...
These should all be constant values that define the size you want your graph to be on the canvas (the axis lengths) and its positioning (the offsets).
You can then refer to these values in the paintComponent method to find the actual position of the line you want to draw for this update on the canvas.
...
#Override
public void paintComponent(Graphics g){
int x, y;
int prevX, prevY;
int maxX, maxY;
...
//retrieve values from your model for the declared variables
...
//calculate the coords of your line on the canvas
int xPos = ((x / maxX) * X_AXIS_LENGTH) + X_AXIS_OFFSET;
...
//do the same for y, prevX, prevY and then you can use g.drawLine
}
...
Note that you want to change maxX and maxY because the x and y values are moving above those limits, you will need to add some extra code to check for that change and redraw the whole graph with the new limits in place.