I put in a particle system but when i run the program, when I spawn some particles, they don't render. I looked at the ArrayList and its value would always be 0 even when i added a particle to it.
heres the code for main class:
package Main;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import me.mango.rendering.Particle;
//do double buffering
public class Game extends JPanel {
private static final long serialVersionUID = 1L;
public static final int height = 400;
public static final int width = height * 16 / 9;
JPanel p;
Game game;
Graphics g;
JFrame frame;
KeyListener kl;
MouseListener ml;
public boolean running = true;
private ArrayList<Particle> particles = new ArrayList<Particle>(500);
public Game(){
kl = new KeyListener(){
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
};
ml = new MouseListener(){
public void mousePressed(MouseEvent e) {
addParticle(true);addParticle(false);addParticle(true);
addParticle(false);addParticle(true);addParticle(false);
}
public void mouseReleased(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
};
}
public void addParticle(boolean b){
int dx,dy;
int x = 100;
int y = 100;
if(b){
dx = (int) (Math.random()*5);
dy = (int) (Math.random()*5);
}else{
dx = (int) (Math.random()*-5);
dy = (int) (Math.random()*-5);
}
int size = (int) (Math.random()*12);
int life = (int) Math.random()*(120)+380;
particles.add(new Particle(x,y,dx,dy,size,life,Color.blue));
}
public void update(double delta){
for(int i = 0; i<= particles.size() - 1;i++){
if(particles.get(i).update()) particles.remove(i);
}
System.out.println(particles.size());
}
#Override
public void paint(Graphics g){
g.clearRect(0, 0, getWidth(), getHeight());
//render here
renderParticles(g);
g.dispose();
}
public void renderParticles(Graphics g){
for(int i =0;i <= particles.size() - 1;i++){
particles.get(i).render(g);
System.out.println("spawned");
}
}
public void run(){
//initialize time loop variables
long lastLoopTime = System.nanoTime();
final int TARGET_FPS = 60;
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;
double lastFpsTime = 0;
//Main game loop
while(running)
{
//Calculate since last update
long now = System.nanoTime();
long updateLength = now - lastLoopTime;
lastLoopTime = now;
double delta = updateLength / ((double)OPTIMAL_TIME);
//update frame counter
lastFpsTime += updateLength;
//update FPS counter
if(lastFpsTime >= 1000000000)
{
lastFpsTime = 0;
}
//game updates
game.update(delta);
//graphics (gameState)
game.repaint();
try{
Thread.sleep((Math.abs(lastLoopTime - System.nanoTime() + OPTIMAL_TIME)/1000000));
}catch(Exception e){
System.out.println("Error in sleep");
}
}
}
public void start(){
frame = new JFrame("Game");
game = new Game();
frame.add(game);
frame.pack();
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.addKeyListener(kl);
frame.addMouseListener(ml);
frame.setVisible(true);
run();
}
public static void main(String[] args){
new Game().start();
}
}
and for the particle class:
package me.mango.rendering;
import java.awt.Color;
import java.awt.Graphics;
public class Particle {
private int x;
private int y;
private int dx;
private int dy;
private int size;
private int life;
private Color color;
public Particle(int x, int y, int dx, int dy, int size, int life, Color c){
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
this.size = size;
this.life = life;
this.color = c;
}
public boolean update(){
x += dx;
y += dy;
life--;
if(life <= 0){
return true;
}
return false;
}
public void render(Graphics g){
g.setColor(color);
g.fillRect(x-(size/2), y-(size/2), size, size);
g.dispose();
}
}
Thanks!
You have a thing called game inside the class Game: that's not good design at all. Apparently you dont understand the meaning of creating an object.
In main() you created an object game: that should be enough. That thing you have to manipulate.
Therefore calling game.something() inside the class game is a convolution. Get rid of it.
game = new Game();
Game game;
These things must go.
And any reference to game.someMethod()
should be replaced with just someMethod(), if you are inside Game.
Plus you have things like run() and start() etc: do you think you are creating some threads?? by just using those names for your methods?
No.
Related
I am working on a donkey kong type game and like I said I want the player to only jump if he is on the floor.
I made a sort of a gravity mechanic and I check collision so he don't go through a floor and I came up with an idea that your can jump only when you are colliding. But here comes the main problem that I don't know how to tell that information to a method in another class.
Hope it makes some sense, I am a beginner and don't know if I described the problem well.
I tried to separate my code but it makes more problems
Here's a class with a player:
import java.awt.*;
import java.awt.event.KeyEvent;
public class Mario extends Rectangle {
int rychlost = 5;
int xZrychleni;
int gravitace= 5;
int yZrychleni;
int vyskok = 20;
Mario(int x, int y, int SIRKA_MARIA,int VYSKA_MARIA){
super(x, y, SIRKA_MARIA, VYSKA_MARIA);
}
public void nakresli(Graphics g) {
g.setColor(Color.white);
g.fillRect(x, y, width, height);
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_A) {
nastavSmerX(-rychlost);
}
if(e.getKeyCode()== KeyEvent.VK_D) {
nastavSmerX(rychlost);
}
if(e.getKeyCode()==KeyEvent.VK_SPACE){
nastavSmerY(vyskok);
}
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_A) {
nastavSmerX(0);
}
if (e.getKeyCode() == KeyEvent.VK_D) {
nastavSmerX(0);
}
if(e.getKeyCode()==KeyEvent.VK_SPACE){
nastavSmerY(0);
}
}
public void nastavSmerX ( int SmerX){
xZrychleni = SmerX;
}
public void nastavSmerY ( int SmerY){
yZrychleni = SmerY;
}
public void move () {
x = x + xZrychleni;
y = y + gravitace;
y = y - yZrychleni;
}
}
Here is a panel class where I check collisions:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HerniPanel extends JPanel implements Runnable{
static final int HERNI_SIRKA = 1200;
static final int HERNI_VYSKA = 700;
static final Dimension SCREEN_SIZE = new Dimension(HERNI_SIRKA, HERNI_VYSKA);
static final int SIRKA_PLOSINY = 1000;
static final int VYSKA_PLOSINY = 35;
static final int SIRKA_ZEBRIKU = 25;
static final int VYSKA_ZEBRIKU = 180;
static final int MARIO_VELIKOST_XY = 50;
Thread gameThread;
Image image;
Graphics graphics;
Plosina plosina0;
Plosina plosina1;
Plosina plosina2;
Plosina plosina3;
Mario mario;
Zebrik zebrik1;
Zebrik zebrik2;
Zebrik zebrik3;
HerniPanel(){
novaPlosina();
novyMario();
novyZebrik();
this.setFocusable(true);
this.addKeyListener(new AL());
this.setPreferredSize(SCREEN_SIZE);
gameThread = new Thread(this);
gameThread.start();
}
public void novaPlosina() {
plosina0 = new Plosina(0, (HERNI_VYSKA - VYSKA_PLOSINY), HERNI_SIRKA, VYSKA_PLOSINY, 1);
plosina1 = new Plosina((HERNI_SIRKA - SIRKA_PLOSINY),(HERNI_VYSKA - VYSKA_PLOSINY - 180), SIRKA_PLOSINY, VYSKA_PLOSINY, 2 );
plosina2 = new Plosina(0, (HERNI_VYSKA - VYSKA_PLOSINY - 360), SIRKA_PLOSINY, VYSKA_PLOSINY,3 );
plosina3 = new Plosina((HERNI_SIRKA - SIRKA_PLOSINY), (HERNI_VYSKA - VYSKA_PLOSINY - 540), HERNI_SIRKA, VYSKA_PLOSINY,4);
}
public void novyMario(){
mario= new Mario(1000, (HERNI_VYSKA - VYSKA_PLOSINY - MARIO_VELIKOST_XY), MARIO_VELIKOST_XY , MARIO_VELIKOST_XY );
}
public void novyZebrik(){
zebrik1 = new Zebrik(250, (HERNI_VYSKA-VYSKA_PLOSINY-VYSKA_ZEBRIKU),SIRKA_ZEBRIKU,VYSKA_ZEBRIKU);
zebrik2 = new Zebrik(800, (HERNI_VYSKA-VYSKA_PLOSINY-VYSKA_ZEBRIKU-180),SIRKA_ZEBRIKU,VYSKA_ZEBRIKU);
zebrik3 = new Zebrik(300, (HERNI_VYSKA-360-VYSKA_PLOSINY-VYSKA_ZEBRIKU),SIRKA_ZEBRIKU,VYSKA_ZEBRIKU);
}
public void paint(Graphics g) {
image = createImage(getWidth(),getHeight());
graphics = image.getGraphics();
nakresli(graphics);
g.drawImage(image,0,0,this);
}
public void nakresli(Graphics g) {
plosina0.nakresli(g);
plosina1.nakresli(g);
plosina2.nakresli(g);
plosina3.nakresli(g);
mario.nakresli(g);
zebrik1.nakresli(g);
zebrik2.nakresli(g);
zebrik3.nakresli(g);
Toolkit.getDefaultToolkit().sync();
}
public void move() {
mario.move();
}
public void zkontrolujKolizi() {
if(mario.x<=0)
mario.x=0;
if(mario.x >= (HERNI_SIRKA-MARIO_VELIKOST_XY))
mario.x = HERNI_SIRKA-MARIO_VELIKOST_XY;
if (mario.y >= (HERNI_VYSKA-VYSKA_PLOSINY - MARIO_VELIKOST_XY)) {
mario.y = (HERNI_VYSKA - VYSKA_PLOSINY - MARIO_VELIKOST_XY);
}
if(mario.intersects(plosina1)){
mario.y = (HERNI_VYSKA-VYSKA_PLOSINY-MARIO_VELIKOST_XY-180);
}
if(mario.intersects(plosina2)){
mario.y = (HERNI_VYSKA-VYSKA_PLOSINY-MARIO_VELIKOST_XY-360);
}
if(mario.intersects(plosina3)){
mario.y = (HERNI_VYSKA-VYSKA_PLOSINY-MARIO_VELIKOST_XY-540);
}
}
public void run() {
//game loop
long lastTime = System.nanoTime();
double amountOfTicks =60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
while(true) {
long now = System.nanoTime();
delta += (now -lastTime)/ns;
lastTime = now;
if(delta >=1) {
move();
zkontrolujKolizi();
repaint();
delta--;
}
}
}
public class AL extends KeyAdapter{
public void keyPressed(KeyEvent e) {
mario.keyPressed(e);
}
public void keyReleased(KeyEvent e) {
mario.keyReleased(e);
}
}
}
I have been working on a simple animation using a Timer on a JComponent. However, I experience incredibly choppy motion when I view the animation. What steps should I take to optimize this code?
MyAnimationFrame
import javax.swing.*;
public class MyAnimationFrame extends JFrame {
public MyAnimationFrame() {
super("My animation frame!");
setSize(300,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new AnimationComponent(0,0,50,50));
setVisible(true);
}
public static void main(String[] args) {
MyAnimationFrame f = new MyAnimationFrame();
}
}
AnimationComponent
import javax.swing.*;
import java.awt.*;
public class AnimationComponent extends JComponent implements ActionListener {
private Timer animTimer;
private int x;
private int y;
private int xVel;
private int yVel;
private int width;
private int height;
private int oldX;
private int oldY;
public AnimationComponent(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.height = height;
this.width = width;
animTimer = new Timer(25, this);
xVel = 5;
yVel = 5;
animTimer.start();
}
#Override
public void paintComponent(Graphics g) {
g.fillOval(x,y,width,height);
}
#Override
public void actionPerformed(ActionEvent e) {
oldX = x;
oldY = y;
if(x + width > getParent().getWidth() || x < 0) {
xVel *= -1;
}
if(y + height > getParent().getHeight() || y < 0) {
yVel *= -1;
}
x += xVel;
y += yVel;
repaint();
}
}
Not sure if this matters, but I am using OpenJDK version 1.8.0_121.
Any help is appreciated.
After a wonderful discussion with Yago it occurred to me that the issue revolves around number of areas, alot comes down to the ability for Java to sync the updates with the OS and the hardware, some things you can control, some you can't.
Inspired by Yago's example and my "memory" of how the Timing Framework works, I tested you code by increasing the framerate (to 5 milliseconds, ~= 200fps) and decreasing the change delta, which gave the same results as using the Timing Framework, but which leaves you with the flexibility of your original design.
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Test");
frame.add(new AnimationComponent(0, 0, 50, 50));
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class AnimationComponent extends JComponent implements ActionListener {
private Timer animTimer;
private int x;
private int y;
private int xVel;
private int yVel;
private int width;
private int height;
private int oldX;
private int oldY;
public AnimationComponent(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.height = height;
this.width = width;
animTimer = new Timer(5, this);
xVel = 1;
yVel = 1;
animTimer.start();
}
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
RenderingHints hints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON
);
g2d.setRenderingHints(hints);
g2d.fillOval(x, y, width, height);
}
#Override
public void actionPerformed(ActionEvent e) {
oldX = x;
oldY = y;
if (x + width > getParent().getWidth() || x < 0) {
xVel *= -1;
}
if (y + height > getParent().getHeight() || y < 0) {
yVel *= -1;
}
x += xVel;
y += yVel;
repaint();
}
}
}
If you need to slow down the speed more, then decrease the change delta more, this will mean you have to use doubles instead, which will lead into the Shape's API which supports double values
Which should you use? That's up to you. The Timing Framework is really great for linear animations over a period of time, where you know you want to go from one state to another. It's not so good for things like games, where the state of the object can change from my cycle to another. I'm sure you could do it, but it'd be a lot easier with a simple "main loop" concept - IMHO
Timing Framework offers a way to provide animations highly optimized which may help in this case.
MyAnimationFrame
import javax.swing.*;
public class MyAnimationFrame extends JFrame {
public MyAnimationFrame() {
super("My animation frame!");
setSize(300,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new AnimationComponent(0,0,50,50));
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MyAnimationFrame f = new MyAnimationFrame();
}
});
}
}
AnimationComponent
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.TimeUnit;
import org.jdesktop.core.animation.rendering.*;
import org.jdesktop.core.animation.timing.*;
import org.jdesktop.core.animation.timing.interpolators.*;
import org.jdesktop.swing.animation.rendering.*;
import org.jdesktop.swing.animation.timing.sources.*;
#SuppressWarnings("serial")
public class AnimationComponent extends JRendererPanel {
protected int x;
protected int y;
protected int width;
protected int height;
protected Animator xAnimator;
protected Animator yAnimator;
public AnimationComponent(int x, int y, int width, int height) {
setOpaque(true);
this.x = x;
this.y = y;
this.height = height;
this.width = width;
JRendererFactory.getDefaultRenderer(this,
new JRendererTarget<GraphicsConfiguration, Graphics2D>() {
#Override
public void renderSetup(GraphicsConfiguration gc) {
// Nothing to do
}
#Override
public void renderUpdate() {
// Nothing to do
}
#Override
public void render(Graphics2D g, int w, int h) {
Color c = g.getColor();
g.setColor(g.getBackground());
g.fillRect(0, 0, w, h);
g.setColor(c);
g.fillOval(AnimationComponent.this.x, AnimationComponent.this.y,
AnimationComponent.this.width, AnimationComponent.this.height);
}
#Override
public void renderShutdown() {
// Nothing to do
}
}, false);
this.xAnimator = new Animator.Builder(new SwingTimerTimingSource())
.addTargets(new TimingTargetAdapter() {
#Override
public void timingEvent(Animator source, double fraction) {
AnimationComponent.this.x = (int) ((getWidth() - AnimationComponent.this.width) * fraction);
}})
.setRepeatCount(Animator.INFINITE)
.setRepeatBehavior(Animator.RepeatBehavior.REVERSE)
.setInterpolator(LinearInterpolator.getInstance()).build();
this.yAnimator = new Animator.Builder(new SwingTimerTimingSource())
.addTargets(new TimingTargetAdapter() {
#Override
public void timingEvent(Animator source, double fraction) {
AnimationComponent.this.y = (int) ((getHeight() - AnimationComponent.this.height) * fraction);
}})
.setRepeatCount(Animator.INFINITE)
.setRepeatBehavior(Animator.RepeatBehavior.REVERSE)
.setInterpolator(LinearInterpolator.getInstance()).build();
addComponentListener(new ComponentAdapter() {
private int oldWidth = 0;
private int oldHeight = 0;
#Override
public void componentResized(ComponentEvent event) {
Component c = event.getComponent();
int w = c.getWidth();
int h = c.getHeight();
if (w != this.oldWidth) {
AnimationComponent.this.xAnimator.stop();
AnimationComponent.this.xAnimator = new Animator.Builder()
.copy(AnimationComponent.this.xAnimator)
.setDuration(w * 5, TimeUnit.MILLISECONDS) // Original speed was 200 px/s
.build();
AnimationComponent.this.xAnimator.start();
}
if (h != this.oldHeight) {
AnimationComponent.this.yAnimator.stop();
AnimationComponent.this.yAnimator = new Animator.Builder()
.copy(AnimationComponent.this.yAnimator)
.setDuration(h * 5, TimeUnit.MILLISECONDS) // Original speed was 200 px/s
.build();
AnimationComponent.this.yAnimator.start();
}
this.oldWidth = w;
this.oldHeight = h;
}
});
}
}
I'm getting good results but has one issue: any item you resize, the animation is reset.
I'm making a space shooter game in Java. I have it set to move up when I press the up key, but it is currently not working at all. I am using the KeyPressed method in the KeyListener interface. Here is my code. It is in 2 classes.
Game.java
package main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable, KeyListener {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
public static final String TITLE = "Space Shooter";
private boolean running = false;
private Thread thread;
private Player player;
private BufferedImage playerImage;
int playerx;
int playery;
public Game() {
player = new Player((WIDTH/2)-32, 400);
try {
playerImage = ImageIO.read(this.getClass().getResourceAsStream("/res/player.png"));
} catch (IOException e) {
e.printStackTrace();
}
addKeyListener(this);
}
private synchronized void start() {
if (running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
private synchronized void stop() {
if (!running)
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(1);
}
#Override
public void run() {
long lastTime = System.nanoTime();
final double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int updates = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if (delta > 1) {
tick();
updates++;
delta--;
}
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " TICKS, " + frames + " FPS");
updates = 0;
frames = 0;
}
}
stop();
}
public void tick() {
playerx = player.getX();
playery = player.getY();
}
public void render() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(playerImage, playerx, playery, this);
g.dispose();
bs.show();
}
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_UP) {
player.setY(playery -= 5);
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
public static void main(String[] args) {
Game game = new Game();
JFrame frame = new JFrame(TITLE);
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(game);
frame.getContentPane().setBackground(Color.BLACK);
frame.setVisible(true);
game.start();
}
}
Player.java
package main;
public class Player {
int x, y;
public Player(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
When you click on the game and then press the keys does it work?
If so all you need to do is call
setFocusable(true);
requestFocus();
then it should work
Basically, I'm developing a Java game where I have to make the troops move to the nearest hall inside the panel (like in Clash of Clans).
I have a BasePanel class that initializes 5 objects (Halls) that are randomly placed anywhere in the panel. The BasePanel has a mouselistener that when clicked, drops another object (Troop) to the x and y coordinates. The Troop object has an attribute that moves in a linear pattern. My problem is that the troop object just moves in a downward direction.
The question is how do I get the Troop object move to the closest Hall object in the BasePanel?
Here is my code:
import javax.swing.*;
import java.util.*;
import java.util.List;
import java.awt.*;
import java.awt.event.*;
import javax.imageio.*;
import java.io.*;
import java.awt.image.*;
public class Test extends JFrame{
public static BasePanel panel1;
public static JButton baseClick, buttonClick, barbarian, archer, goblin;
public static int clicks=0, count1=10, count2=5, count3=7, hallCount=5, basePanelW=600, basePanelH=420;
public List<Troop> troops = new ArrayList<Troop>(20);
public List<Hall> halls = new ArrayList<Hall>(5);
public Thread gameThread;
Random rand = new Random();
float mouseX, mouseY;
float x = mouseX; // troop's center (x, y)
float y = mouseY;
double troopSpeedX = 1;
double troopSpeedY = 1;
float troopRadius = 5;
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Test Test = new Test();
}
});
}
public void update() {
for (Troop troop : troops) {
troop.move(panel1);
}
}
class Hall{
int xVal = rand.nextInt(basePanelW);
int yVal = rand.nextInt(basePanelH);
public Hall(){}
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillOval(xVal, yVal, 50, 50);
}
public int getX(){
System.out.println("xVal: "+xVal);
return xVal;
}
public int getY(){
System.out.println("yVal: "+yVal);
return yVal;
}
}
class Troop{
float x = mouseX;
float y = mouseY;
double troopSpeedX = 1;
double troopSpeedY = 1;
float troopRadius = 5;
Hall h = new Hall();
public Troop(){}
public void paint(Graphics g){
g.setColor(Color.BLUE);
g.fillOval((int) (x - troopRadius), (int) (y - troopRadius), (int)(2 * troopRadius), (int)(2 * troopRadius));
}
public void move(JPanel panel){
x += troopSpeedX;
y += troopSpeedY;
if (x - troopRadius < 0) {
troopSpeedX = -troopSpeedX;
x = troopRadius;
}else if (x + troopRadius > basePanelW) {
troopSpeedX = -troopSpeedX;
x = basePanelW - troopRadius;
}else if (y - troopRadius < 0) {
troopSpeedY = -troopSpeedY;
y = troopRadius;
}else if (y + troopRadius > basePanelH) {
troopSpeedY = -troopSpeedY;
y = basePanelH - troopRadius;
}repaint();
}
}
public void start(){
gameThread = new Thread() {
public void run() {
while (true) {
update();
repaint();
try {Thread.sleep(100/3);}catch(InterruptedException ex){}
}
}
}; gameThread.start();
}
class BasePanel extends JPanel{
private BufferedImage image;
BasePanel(){
setPreferredSize(new Dimension(basePanelW,basePanelH));
setBackground(Color.green);
while(hallCount>0){
halls.add(new Hall());
hallCount--;
}
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
mouseX = e.getX();
mouseY = e.getY();
clicks++;
}
public void mouseReleased(MouseEvent e){
troops.add(new Troop());
}
});
}
private void msgbox(String s){
JOptionPane.showMessageDialog(null, s);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Troop troop : troops){
troop.paint(g);
}
}
public void paint(Graphics g){
super.paint(g);
for (Hall hall : halls){
hall.paint(g);
}
}
}
public Test(){
panel1 = new BasePanel();
add(panel1, BorderLayout.CENTER);
setVisible(true);
setSize(700,420);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
start();
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have a input class. When up is pressed it sets player.hasJumped = true; and when hasJumped is true, it changes dy to -3 in the player class. The problem is, that hasJumped is being set to true, but the variable is not changing. I can't really figure out why this is happening. This is a short sample of my code, I can provide more if needed.
InputHandler.java
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class InputHandler implements KeyListener{
Player player = new Player();
private boolean[] keys = new boolean[120];
public boolean up;
public void tick(){
up = keys[KeyEvent.VK_UP] || keys[KeyEvent.VK_W];
if(player.jumpReady){
if(up){
player.inAir = true;
System.out.println("JUMPED " + player.inAir);
}
}
}
public void keyPressed(KeyEvent e) {
keys[e.getKeyCode()] = true;
}
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
}
Player.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Player {
int x;
int y;
int dx;
public long xElapsed = 0;
public int dy;
int width = 50;
int height = 75;
public int hangTime = 0;
int maxHangTime = 100;
int nextX = 1000;
public int playerSpeed = 7;
public int coinsCollected = 0;
public boolean isMoving = true;
public boolean hasJumped = false;
public boolean jumpReady = true;
public boolean hasCollided = false;
public boolean inAir = false;
private BufferedImage moving1 = null;
private String path1 = "res/player_moving_1.png";
public Player(){
try {
moving1 = ImageIO.read(new File(path1));
}catch (IOException e) {
e.printStackTrace();
System.err.println("Could not load image " + moving1 + " at path" + path1);
}
x = 150;
y = 250;
}
public void render(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(moving1, x, y, null);
}
public void move(){
x = x + dx;
y = y + dy;
xElapsed++;
if(xElapsed == nextX){
upSpeed();
nextX += 1000;
}
if(inAir){
System.out.println("test");
dy = -3;
}
}
public void paint(Graphics g){
g.setColor(Color.RED);
g.fillRect(x, y, width, height);
}
public void upSpeed(){
playerSpeed++;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public long getXElapsed(){
return xElapsed;
}
public double getSpeed(){
return playerSpeed;
}
public int getNextX(){
return nextX;
}
public int getCoinsCollected(){
return coinsCollected;
}
public Rectangle bounds(){
return (new Rectangle(x, y, width, height));
}
}
Game.java
private static final long serialVersionUID = 1L;
public static final int WIDTH = 350;
public static final int HEIGHT = WIDTH / 16 * 9;
public static final int SCALE = 2;
private Thread thread;
private JFrame frame;
private InputHandler input;
private boolean running = false;
private Screen screen;
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
Player player = new Player();
public Game() {
Dimension size = new Dimension(WIDTH * SCALE, HEIGHT * SCALE);
setPreferredSize(size);
screen = new Screen(WIDTH, HEIGHT);
frame = new JFrame();
input = new InputHandler();
addKeyListener(input);
setFocusable(true);
}
public void run() {
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int ticks = 0;
while(running){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1){
tick();
ticks++;
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer > 1000){
timer += 1000;
System.out.println(ticks + " tps, " + frames + " fps");
ticks = 0;
frames = 0;
}
}
stop();
}
public void tick(){
input.tick();
player.move();
collision();
obstacleHole.move();
obstacleWolf.move();
coin.move();
}
Within Game.java pass the object player as argument within the constructor of InputHandler as follows:
public Game() {
Dimension size = new Dimension(WIDTH * SCALE, HEIGHT * SCALE);
setPreferredSize(size);
screen = new Screen(WIDTH, HEIGHT);
frame = new JFrame();
input = new InputHandler(player);//pass player object as argument
addKeyListener(input);
setFocusable(true);
}
And change the InputHandler class as follows:
public class InputHandler implements KeyListener{
Player player ; //Don't initialize it.
//Create a parametric constructor
public InputHandler(Player player)
{
this.player = player;
}
//...And then proceed with other stuffs
}