Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have some Processing code where I need to create a new rectangular box when a certain key is pressed and I need to have multiples of these on screen. I have all the code setup so that when I press a key something can happen, but I've tried to create new objects infinitely and I can't get it to work.
Code:
public float translateX = 0;
public float translateY = 260;
public float translateZ = 10000;
float bulletX, bulletY, bulletZ;
public int rotationBlue = 1;
public int rotationGreen = 1;
public int rotationRed = 1;
public boolean shootBool = false;
public boolean shootBoolVal = true;
void setup() {
size(1280, 720, P3D);
frameRate(60);
}
void draw() {
background(0);
translate(640, 360, -10000);
fill(0);
box(100000);
ship();
control();
}
void control() {
if (keyPressed) {
if (key == 'a' || key == 'A') {
translateX = translateX - 5;
}
if (key == 'd' || key == 'D') {
translateX = translateX + 5;
}
if ((key == 's' || key == 'S')) {
translateZ = translateZ + 5;
}
if ((key == 'w' || key == 'W')) {
translateZ = translateZ - 5;
}
if ((key == 'q' || key == 'Q')) {
translateY = translateY - 5;
}
if ((key == 'e' || key == 'E')) {
translateY = translateY + 5;
}
if (key == 'f' || key == 'F') {
}
}
}
public void ship() {
fill(0, 0, 255);
stroke(255);
strokeWeight(3);
translate(translateX, translateY, translateZ);
//translate(mouseX, mouseY, 0);
rotateX(radians(rotationBlue));
rotateY(radians(rotationBlue));
rotateZ(radians(rotationBlue));
rotationBlue++;
box(100);
fill(0, 255, 0);
rotateX(radians(rotationGreen));
rotateY(radians(rotationGreen));
rotateZ(radians(rotationGreen));
rotationGreen--;
box(100);
fill(255, 0, 0);
rotateX(radians(rotationRed));
rotateY(radians(rotationRed));
rotateZ(radians(rotationRed));
rotationRed = rotationRed + 2;
box(100);
//translateZ = translateZ - 5;
}
This is all the code that I have so far. I need to be able to have it so that when I press the "F" key (which is already defined in the function control), a new box is created at the coordinates of the ship which has it's own Z direction decreasing constantly. Remember, I must be able to have more than one of these boxes at once.
I would like someone to tell me what steps I must take to do this.
These are the steps required to obtain what you need:
define a custom Bullet object containing position, velocity and other required attributes, possibly also a draw function
declare a collection of these Bullet objects
when you want to shoot a bullet just add it to the collection
to draw all the bullets iterate over the collection in the draw() method
to update the attributes of all the bullets define an update() method which updates velocity, position etc. for every bullet, called by the draw() function too
Related
I'm currently learning Java through Stanford's Programming Methodology (2008) course. I'm trying to create the game Breakout and am trying to currently animate the paddle, which is a GRect type object. Here's my code:
// moves paddle via keyboard
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_RIGHT && paddle.getX() < getWidth() - paddle.getWidth()) {
paddle.move(5, 0);
}
if (key == KeyEvent.VK_LEFT && paddle.getX() > 0) {
paddle.move(-5, 0);
}
}
//moves paddle via mouse
public void mouseMoved(MouseEvent e) {
while (e.getX() > paddle.getX() + PADDLE_WIDTH/2 && paddle.getX() < getWidth() - PADDLE_WIDTH) {
paddle.move(1, 0);
}
while (e.getX() < paddle.getX() + PADDLE_WIDTH/2 && paddle.getX() > 0) {
paddle.move(-1, 0);
}
The problem is, if I move the paddle with mouse, it follows just fine, it's much smoother than when I try to move it with keyboard. Changing the values in move() method only changes the speed at which the paddle moves.
I've tried googling and one of the things people do is to gradually increase and decrease the speed at which the paddle moves, but I'm not sure how to implement that correctly through this library. Here's my attempt:
private double acceleration(double finalSpeed) {
if (finalSpeed > initialSpeed) {
initialSpeed += delta;
} else if (finalSpeed < initialSpeed) {
initialSpeed -= delta;
}
return initialSpeed;
}
private double initialSpeed = 0;
private double delta = 0.5;
After this I just set the paddle.move(acceleration(5),0) instead of paddle.move (5,0). And I've also added the KeyReleased method that sets the speed to the initial value:
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_RIGHT || key == KeyEvent.VK_LEFT) {
initialSpeed = 0;
}
However, the movement of the paddle when I switch between left and right arrow keys is not responsive. It has about 0.5 sec delay to start moving the other direction, I've spend whole day trying to figure out the solution but to no avail. Please give me any tips, thanks!
It seems that there's some problem with the threads (which I don't fully understand). Doing this helped:
Instead of moving the paddle directly with listeners, I created two booleans: left_key_downand right_key_down and set them to true if corresponding key was pressed. After that I moved the paddle using: if (left_key_down) move (-5,0) And similarly with right motion. This resulted in smooth motion.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
Im using append on an empty array to create multiple projectiles, but every time I hit the spacebar Im getting a NullPointerException on keyPressed when it checks if the spacebar was pressed. I can't figure out why this is hapenning. Help would be really good.
MAIN CLASS:
int naveX, naveY;
int inimigoX, inimigoY;
Tiro [] tiros;
boolean tiroVisivel;
boolean naveDireita, naveEsquerda;
void setup(){
size (800, 600);
naveX = 375; naveY = height - 120;
inimigoX = 385; inimigoY = 0;
tiroVisivel = false;
naveDireita = naveEsquerda = false;
}
void draw(){
background (0);
nave();
movimentoNave();
if (tiroVisivel == true && tiros != null){
for (int i = 0; i < tiros.length; i++){
tiros[i].display();
tiros[i].update();
}
}
inimigo();
}
void nave(){
stroke (255);
fill (255, 0, 0);
rect (naveX, naveY, 50, 100);
}
void movimentoNave(){
if (naveEsquerda == true && naveX > 0){
naveX = naveX - 5;
}
if (naveDireita == true && naveX < width - 50){
naveX = naveX + 5;
}
}
void inimigo(){
stroke (255);
fill (0, 100, 255);
rect (inimigoX, inimigoY, 30, 50);
}
void keyPressed(){
if (key == ' '){
append(tiros, new Tiro(naveX + 20, naveY - 30));
tiroVisivel = true;
}
if(key == 'a' || key == 'A'){
naveEsquerda = true;
}
if(key == 'd' || key == 'D'){
naveDireita = true;
}
if (key == 'r' || key == 'R'){
setup();
}
}
void keyReleased(){
if(key == 'a' || key == 'A'){
naveEsquerda = false;
}
if(key == 'd' || key == 'D'){
naveDireita = false;
}
}
PROJECTILE CLASS:
public class Tiro {
private int tiroX = naveX + 20;
private int tiroY = naveY - 30;
public Tiro(int x, int y){
this.tiroX = x;
this.tiroY = y;
}
void display(){
stroke (255);
fill (255, 0, 100);
rect (tiroX, tiroY, 10, 20);
}
void update(){
if (tiroY > 0){
tiroY = tiroY - 10;
}
}
}
Im using append on an empty array [...]
No, you are not. Your array isn't empty, it is uninitialized and therefore null.
That's because you declared, but never initialized your tiros array:
Tiro [] tiros;
Trying to access tiros as is will yield a NullPointerException.
To fix the problem, add this line in setup():
tiros = new Tiro[0];
And allow me this unrelated advice: if you can (and it looks as if you do), try to code in English. It is standard in the industry and will also benefit you in situations as these, when you seek help from an international community.
so I have this code, I'm trying to learn Java and this is basically my first game, it's similar to SubmarineKiller where you are a boat, launching bombs at the submarine.
My class below is the bomb. When I press the Down arrow, the bomb launches but I can't launch another one until it hits the submarine or it goes out of screen. My question is: How can I fire the next bomb as soon as the first one left the boat? Basically launch a bomb anytime I press my down key.
public void keyPressed(KeyEvent evt) {
int code = evt.getKeyCode();
if (code == KeyEvent.VK_DOWN) {
if (bomb.isFalling == false)
bomb.isFalling = true;
}
}
-
private class Bomb {
int centerX, centerY;
boolean isFalling;
Bomb() {
isFalling = false;
}
void updateForNewFrame() {
if (isFalling) {
if (centerY > height) {
isFalling = false;
}
else
if (Math.abs(centerX - sub.centerX) <= 36 && Math.abs(centerY - sub.centerY) <= 21) {
sub.isExploding = true;
sub.explosionFrameNumber = 1;
isFalling = false; // Bomba reapare in barca
}
else {
centerY += 10;
}
}
}
void draw(Graphics g) {
if ( !isFalling ) {
centerX = boat.centerX;
centerY = boat.centerY + 23;
}
g.setColor(Color.RED);
g.fillOval(centerX - 8, centerY - 8, 16, 16);
}
}
You need to rewrite your code in terms of a list of bombs rather than a single bomb. Then, your key pressed event needs to change to add a new bomb to the list rather than just setting the properties of the single bomb. Your processing code will then also need to change - you'll need to loop over the list and process each bomb in turn.
i created a pacman game with everything in it but the problem is that the ghosts and their animation require a lot of code.
example:
every ghost needs 3 if statements at the moment that is 20 lines of code per ghost and if i have 3 ghosts in the game that is 3 x 20 = 60 lines of useless coding..
with my php experience i would say.. use a foreach loop or something similar.. but how should i do this in Java? can someone give me an example? the way i do it now is published below:
creating ghost objects;
DrawPacMan ghost1 = new DrawPacMan();
DrawPacMan ghost2 = new DrawPacMan();
and the painting goes like:
int g1x = 0;
boolean g1r = true;
public void paintComponent(Graphics g) {
super.paintComponent(g);
// pacman movement
diameter = 75;
pacman.drawPacMan(g, getHorPlaats(), getVerPlaats(), diameter, getView(), Color.yellow);
// ghosts movement
if(g1r == true) {
g1x += ghostSpeed;
}
if(g1r == false) {
g1x -= ghostSpeed;
}
if(g1x == 500 || g1x == 0) {
g1r = !g1r;
}
System.out.println(g1r);
ghost1.drawGhost(g, g1x, 40, diameter, Color.red);
ghost2.drawGhost(g, 170, 70, diameter, Color.blue);
}
It looks to me like you're not approaching this in a object-oriented fashion. Why not use a collection of ghosts eg. List<Ghost> and define a Ghost object with it's location, colour etc?
This line:
ghost1.drawGhost(g, g1x, 40, diameter, Color.red);
would then be replace with
ghost.draw(g);
and you'd iterate through the list, calling draw() for each.
for(Ghost ghost : ghosts) {
ghost.draw(g); // pass in the graphics context
}
Each ghost knows it's location, colour, state etc. and you can create as many as you like:
List<Ghost> ghosts = new ArrayList<Ghost>();
for (int i = 0; i < 10; i++) {
ghosts.add(new Ghost());
}
Since you seem to be new to Java and still getting to know the best idioms, I'll advise on something that is not directly an answer to your question, but is so in a more general sense. Your code
if(g1r == true) {
g1x += ghostSpeed;
}
if(g1r == false) {
g1x -= ghostSpeed;
}
can be rewritten as just
g1x += ghostSpeed * (g1r? 1 : -1);
A general note: never compare booleans to literal values. b == true is the same as just b and b == false is the same as !b.
This code
if (g1x == 500 || g1x == 0) {
g1r = !g1r;
}
will probably result in a bug at runtime as you don't precede it with fencing-in code: g1x can easily step over your limits. You should write instead
if (g1x >= 500) { g1x = 500; g1r = false; }
else if (g1x <= 0) { g1x = 0; g1r = true; }
Pass the ghost object as another parameter in the same function paintComponent(Graphics g, Ghost gr)
You can make the conditional statements inline, e.g. g1r == true ? g1x += ghostSpeed : g1x -= ghostSpeed
I'm trying to move sprites to stop the frames in center(or move them to certain x position) when right or left pressed on screen. There are 3 sprites created using box.java in the view, placed one after another with padding, stored in arraylist.
The problem: No smooth movement and doesn't stop in the center of each frames after movement has begun, sometimes all boxes are moving on top of each others, padding is totally lost. Please let me know what I'm doing wrong, thanks a lot!
//BEGINING OF BOX.JAVA >> The problem is in this class!
//This goes in Update();
private void boxMove()
{
int get_moved_pos = getMovedPos(); //get moved pos
int sprite_size = view.getSpriteSize(); //get sprite arraylist size
currentDirection = view.getDirection(); //get direction "left" or "right" from view
if(currentDirection == "right" && isMoving == false)
{
setSpriteMovedNext();
}else
if(currentDirection == "left" && isMoving == false)
{
setSpriteMovedPrev();
}
if(currentDirection != lastDirection)
{
lastDirection = currentDirection;
//MOVE RIGHT
if(currentDirection == "right" && get_moved_pos > 0) //move left and make sure that moved pos isn't overlapping / or moving to empty space
{
//Animate left until it reaches the new x position
if(x > get_new_pos_left)
{
x -= pSpeedX;
}
Log.d("RIGHT","POS: " + get_moved_pos);
}else
//MOVE LEFT
if(currentDirection == "left" && get_moved_pos < sprite_size-1) //move left and make sure that moved pos isn't overlapping / or moving to empty space
{
//Animate right until it reaches the new x position
if(x < get_new_pos_right)
{
x += pSpeedX;
}
}
}
}
//Call when screen is touched (in View.java), to set a new position to move to.
public void resetMoving()
{
isMoving = false;
this.lastDirection = "";
Log.d("RESET", "MOVING RESET");
}
public int getMovedPos()
{
return this.smoved_pos;
}
private void setSpriteMovedNext()
{
int get_max_moved = getMovedPos();
int s_size = view.getSpriteSize();
if (isMoving == false) //take a break between movements
{
if(get_max_moved < s_size-1)
{
Log.d("NEXT", "CALLED");
this.get_new_pos_right = x + view.getNextPosX(); //current x and next stop position
this.smoved_pos += 1;
this.isMoving = true; //set to avoid double touch
Log.d("NEXT", "X POS SET: " + get_max_moved);
}
}
}
private void setSpriteMovedPrev()
{
int get_max_moved = getMovedPos();
if (isMoving == false) //take a break between movements
{
if(get_max_moved > 0)
{
Log.d("PREV", "CALLED");
this.get_new_pos_left = x - view.getNextPosX(); //get current x pos and prev stop position
this.smoved_pos -= 1; //to limit the movements
this.isMoving = true; //set to avoid double touch
Log.d("PREV", "X POS SET: " + get_max_moved);
}
}
}
//END OF BOX.JAVA
//VIEW
//Add boxes
public void addBox()
{
int TOTAL_BOXES = 3;
int padding_left = 200;
int padding_tmp = this.getWidth()/2;
box.clear(); //clear old
//Box 1
box.add(new Boxes(box, this, "box1",
padding_tmp,
this.getHeight()/2,
boxSpriteImage, 1, 2, 0, 0));
padding_tmp += boxSpriteImage.getWidth()/TOTAL_BOXES + padding_left;
//Box 2
box.add(new Boxes(box, this, "box2",
padding_tmp,
this.getHeight()/2,
boxSpriteImage, 1, 2, 1, 1));
padding_tmp += boxSpriteImage.getWidth()/TOTAL_BOXES + padding_left;
//Box 3
box.add(new Boxes(box, this, "box3",
padding_tmp,
this.getHeight()/2,
boxSpriteImage, 1, 2, 2, 1));
}
public boolean onTouchEvent(MotionEvent event){
if (System.currentTimeMillis() - lastClick > 100){
lastClick = System.currentTimeMillis();
float x = event.getX();
float y = event.getY();
synchronized (getHolder())
{
if(isBoxWindow() == true)
{
if(x >= this.getWidth()/2)
{
Direction = "right";
}else
{
Direction = "left";
}
}
}
}
//called in box.java to get next x pos to move
public float getNextPosX()
{
int PADDING = 200; //padding between frames
next_pos_x = boxSprite.getWidth()/TOTAL_COLUMNS + PADDING;
return next_pos_x;
}
I think your error is in the if statements, where you compare currentDirection and lastDirection (I'm assuming that lastDirection is a String) with other Strings using the == operator. The == almost operator never works when you want to compare Objects for equality. You should use the equals() method.
For eg.
if(currentDirection != lastDirection)
should be written as:
if(!currentDirection.equals(lastDirection)
Make such changes in your code(They are needed at many places!) and I think your problem should be solved.
A good debugging practice would be logging data about your app, from each of the if blocks, to see if each of them is executed. You could have found out if your if statements are being executed.
EDIT: Why have you put this code?
if (System.currentTimeMillis() - lastClick > 100)
This means onTouchEvents are only interpreted after 100ms. remove it and check, probably that's what is causing the problem.
Alrite, decided to use onFling() method and call via View instead of adding the animations separately into the class itself, works really well when called box.get(i).update() in a loop of all added boxes, all of them animated equally. Thanks udiboy.