I've done quite a bit of searching for an answer to this, and some editing and I cant get it to work. I think there's something wrong with my boolean method, getColor(). Im trying to use it in a loop from a different class.
herse my getColor method, from the AvatarPanel class
public boolean setColor(boolean good)
{
if (good == true)
what--;
avatars.get(0).setBackground(colors.get(what));
repaint();
if (good == false)
what++;
avatars.get(0).setBackground(colors.get(what));
repaint();
return good;
}
And here's the attackPerformed method from the Background class that Im trying to use getColor in. Im not sure if I wrote one of the methods wrong, or if attackPerformed needs a listener. The game is still running normally and working fine. I just wanted some help making sure these were at least written correctly.
I decided it might be a good idea to show the background constructor because I think its where I need to call attackPerformed. I can't figure out where it is that I need to call the attackPerformed, though I'm pretty sure it'll be in the background constructor. The attackPerformed method is shown below, constructor is at top.
public class Background extends JPanel implements Constants, ActionListener
{
private static final long serialVersionUID = 1L;
private final Color BACK_COLOR = Color.GRAY;
private ArrayList<Sprite> sprites;
private Avatar avatar;
/** Constructor */
public Background()
{
sprites = new ArrayList<Sprite>();
reset(0);
setBackground(BACK_COLOR);
KeyboardFocusManager manager =KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new KeyEventDispatcher()
{
public boolean dispatchKeyEvent(KeyEvent event)
{
int x = 0, y = 0;
double angle = 0;
Point p = avatar.getPosition();
switch (event.getKeyCode())
{
case KeyEvent.VK_DOWN:
y=6;
angle=270;
break;
case KeyEvent.VK_UP:
y = -6;
angle = 90;
break;
case KeyEvent.VK_LEFT:
x = -6;
break;
case KeyEvent.VK_RIGHT:
x = 6;
angle = 180;
break;
}
avatar.setParameters();
p.x += x;
p.y += y;
avatar.setPosition(p);
avatar.setAngle(angle);
if (!getBounds().contains(avatar.getBounds()))
{
avatar.restore();
Toolkit.getDefaultToolkit().beep();
return true;
}
repaint();
return true;
}
});
Timer timer = new Timer(15, this);
timer.start();
} //end of constructor
public void attackPerformed()
{
for(Sprite s : sprites)
{
AvatarPanel panel = new AvatarPanel();
Rectangle r = new Rectangle(sprites.get(0).getBounds());
Rectangle p = new Rectangle(sprites.get(1).getBounds());
if(r.intersects(p))
{
panel.setColor(false);
}
}
}
public void actionPerformed(ActionEvent e)
{
for (Sprite s : sprites)
{
if (s instanceof Move)
{
s.setParameters();
for (int i=0; i<3; i++)
{
((Move)s).nextPosition();
if (!getBounds().contains(s.getBounds()))
{
((Move) s).moveFailed();
}
else break;
}
}
}
repaint();
}
public #Override void paintComponent(Graphics g)
{
super.paintComponent(g); /* Let the parent class do its painting */
for (Sprite sprite: sprites)
{
sprite.draw(g);
}
}
public void reset(int level)
{
Sprite sprite = null;
int x, y, angle;
double scale, min, max;
sprites.clear();
int[] figures = FIGURES[level];
for (int f=0; f<figures.length; f++)
{
for (int i=0; i<figures[f]; i++)
{
x = (int)(Math.random()*600 + 100);
y = (int)(Math.random()*400 + 100);
switch (f)
{
case 0:
sprite = avatar = new Avatar(x,y);
break;
case 1:
sprite = new Predator(x,y);
break;
case 2:
sprite = new Mine(x,y);
break;
case 3:
sprite = new Shield(x,y);
break;
}
angle = (int)(Math.random()*360);
sprite.setAngle(angle);
min = sprite.getMinScaleFactor();
max = sprite.getMaxScaleFactor();
scale = Math.random() * (max - min) + min;
sprite.setScale(scale);
sprites.add(sprite);
repaint();
}
}
}
}
Looks like your if and else case are very similar.
You can simplify it to this.
public boolean setColor(boolean good)
{
what+=good?-1:+1;
avatars.get(0).setBackground(colors.get(what));
repaint();
return good;
}
I would strongly recommend to use brackets, as the method repaint() would execute outside of if statement. Since, boolean can only have two possible values you can use 'else' instead of second if...
public boolean setColor(boolean good)
{
if (good == true)
{
what--;
avatars.get(0).setBackground(colors.get(what));
repaint();
}
else
{
what++;
avatars.get(0).setBackground(colors.get(what));
repaint();
}
Related
I'm trying to make a small app that bounces balls around the frame of the window. When I add more than 1 ball to the list; it doesn't loop through them as expected.
Here's my code:
The Main Class:
public class Main extends JFrame {
private static final long serialVersionUID = 1L;
private List<Ball> balls = new ArrayList<Ball>();
private List<Ball> tempballs = new ArrayList<Ball>();
private static Timer t;
public void addBall(Ball b) {
tempballs.add(b);
}
public void initUI() {
this.setSize(500, 500);
this.setDefaultCloseOperation(3);
this.setVisible(true);
}
private BufferStrategy bs;
private Random r = new Random();
public void paint() {
if (!tempballs.isEmpty()) {
balls.addAll(tempballs);
tempballs = new ArrayList<Ball>();
}
int i = 0;
System.out.println(balls.size());
for (Ball b : new ArrayList<Ball>(balls)) {
i++;
System.out.println(i);
if ((bs = this.getBufferStrategy()) == null) {
this.createBufferStrategy(2);
return;
}
if (bs.contentsLost() || bs.contentsRestored()) {
return;
}
if (b.y >= this.getHeight() - 100) {
b.ydirection = -r.nextDouble() * 5;
}
if (b.y < 20) {
b.ydirection = r.nextDouble() * 5;
}
if (b.x >= this.getWidth() - 100) {
b.xdirection = -r.nextDouble() * 5;
}
if (b.x < 0) {
b.xdirection = r.nextDouble() * 5;
}
b.x += b.xdirection;
b.y += b.ydirection;
if (b.xdirection > 0)
b.xdirection += 0.1;
else
b.xdirection += -0.1;
if (b.ydirection > 0)
b.ydirection += 0.1;
else
b.ydirection += -0.1;
Graphics g = bs.getDrawGraphics();
g.fillOval((int) b.x, (int) b.y, 100, 100);
bs.show();
g.dispose();
bs.dispose();
}
i = 0;
}
public static void main(String[] args) {
try {
final Main m = new Main();
m.addMouseListener(new Mouse(m));
m.initUI();
t = new Timer();
TimerTask tt = new TimerTask() {
#Override
public void run() {
m.paint();
}
};
t.schedule(tt, Calendar.getInstance().getTime(), 20);
} catch (ConcurrentModificationException e) {
e.printStackTrace();
}
}
}
Here's the Ball class:
public class Ball {
private Random r = new Random();
public double y, x, ydirection, xdirection;
public Ball(int x, int y) {
this.y = y;
this.x = x;
ydirection = r.nextGaussian() * 5;
xdirection = r.nextGaussian() * 5;
}
}
and the mouse listener:
public class Mouse implements MouseListener {
Main m;
public Mouse(Main m) {
this.m = m;
}
#Override
public void mouseClicked(MouseEvent e) {
m.addBall(new Ball(e.getX(), e.getY()));
System.out.println("cl");
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
Additional details:
It only loops through the first item in the list, but the list size grows.
I'm using java 6, but I will change versions if needed.
If your loop does not behave as intended, try to find out why it is cancelled. You have two return statements in your loop which could cause this behavior. Make sysouts before those returns to figure out which one is the cause. Then find out why your if around the return is true. To digg deeper you can use your IDE's debugging mode and place breakpoints at interesting lines or use the step mode to run one line of code at a time.
Besides this you can place both if before the loop, the values they are checking should not change while you are in the paint() function (you are using the UI thread which might change them).
You have below return statements inside the loop. If the execution reaches any of the return statements, the loop ends.
Figure out, if you are entering these conditions and returning for the first value in the list.
if ((bs = this.getBufferStrategy()) == null) {
this.createBufferStrategy(2);
return;
}
if (bs.contentsLost() || bs.contentsRestored()) {
return;
}
I'm trying to make it so when I press down the right key a new picture pops up making it look like my character is walking, not quite sure how to do that though... Here's my code:
import java.awt.*;
public class Dude {
int x, dx, y;
Image still;
public Dude() {
ImageIcon i = new ImageIcon("Ken3.png");
ImageIcon ii = new ImageIcon("KenTurn1.png");
still = i.getImage();
x = 50;
y = 785;
}
public void move() {
x = x + dx;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return still;
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_A)
dx = -2;
if (key == KeyEvent.VK_D)
dx = 2;
if (key == KeyEvent.VK_SPACE)
dx = 5;
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_A)
dx = 0;
if (key == KeyEvent.VK_D)
dx = 0;
Any help would be awesome thanks!
something like this, i commented it. Good luck
public class Dude {
private int walkingIndex;
private Image walkingFrames;
private Image still;
private String state;
public Dude() {
// say were starting off standing
state = "standing";
// init our still frame
still = (new ImageIcon("Ken3.png")).getImage();
// set our walking frame to 0 to start
walkingIndex = 0;
walkingFrames = new Image[3]; // or however many images you have in your walking animation
// go through each frame and initialize the image to KenWalking{index}.png
for(int i=0;i<walkingFrames.length;i++) {
walkingFrames[i] = (new ImageIcon("KenWalking"+i+".png")).getImage();
}
}
public void move() {
x+=dx;
// add 1 to the walking index and make sure its not greater than our number of walking frames, % means get the remainder of
// so 12 % 10 = 2, and 8 % 7 = 1
walkingIndex = (walkingIndex+1)%walkingFrames.length;
}
public Image getImage() {
// if our state is walking then give out a walking frame
if(state.equals("walking")) {
return walkingFrames[walkingIndex];
} else {
// otherwise we can assume were standing, so show that image instead
return still;
}
}
public void keyPressed(KeyEvent e) {
... same stuff
state = "walking";
}
public void keyReleased(KeyEvent e) {
... same stuff
state = "standing";
}
}
If i understand the question right, you are looking for a keyListener. In that case, you can do two things. Add keybindings or add an KeyListener.
Please have in mind that i haven't tested the code on your template, it work well for me in an AWT frame. Hope it helps
First implement the EventListener to Dude
public class Dude implements KeyListener{ ...
For the KeyListener to work you must have a focusable component..
component.addKeyListener(this);
component.setFocusable(true);
component.setFocusTraversalKeysEnabled(false);
The method below will be implemented with the KeyListener
#Override
public void keyPressed(KeyEvent e) {
int x = e.getKeyCode();
switch(x){
case KeyEvent.VK_UP:
// Do Your stuff
break;
case KeyEvent.VK_DOWN:
// Do Your stuff
break;
case KeyEvent.VK_RIGHT:
// Do Your stuff
break;
case KeyEvent.VK_LEFT:
// Do Your stuff
break;
}
}
I am making a game in Java, and I am working on player movement, but whenever a press a directional key, the player moves but doesn't stop when I release the key.
I can't seem to see what I am doing wrong. May someone point me in the right direction?
// Input class implements KeyListener
public static final int LEFT = 0;
public static final int RIGHT = 1;
public static final int UP = 2;
public static final int DOWN = 3;
public boolean[] keys = new boolean[64];
public void getKeys(KeyEvent e, boolean move) {
switch(e.getKeyCode()) {
case KeyEvent.VK_LEFT:
keys[LEFT] = move;
break;
case KeyEvent.VK_RIGHT:
keys[RIGHT] = move;
break;
case KeyEvent.VK_UP:
keys[UP] = move;
break;
case KeyEvent.VK_DOWN:
keys[DOWN] = move;
break;
case KeyEvent.VK_BACK_QUOTE:
keys[BQUOTE] = move;
break;
}
keys[OTHER] = move;
}
#Override
public void keyPressed(KeyEvent e) {
getKeys(e, true);
}
#Override
public void keyReleased(KeyEvent e) {
getKeys(e, false);
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
// Player Class
public void tick() {
if (Engine.key_input.keys[KInput.LEFT]) {
dx = -speed;
animDir = SpriteLoader.L;
sprite = SpriteLoader.anim(SpriteLoader.ANIM_PLAYER, animDir);
}
if (Engine.key_input.keys[KInput.RIGHT]){
dx = speed;
animDir = SpriteLoader.R;
sprite = SpriteLoader.anim(SpriteLoader.ANIM_PLAYER, animDir);
}
if (Engine.key_input.keys[KInput.UP]){
dy = -speed;
animDir = SpriteLoader.U;
sprite = SpriteLoader.anim(SpriteLoader.ANIM_PLAYER, animDir);
}
if (Engine.key_input.keys[KInput.DOWN]){
dy = speed;
animDir = SpriteLoader.D;
sprite = SpriteLoader.anim(SpriteLoader.ANIM_PLAYER, animDir);
}
}
// Engine Class
public class Engine {
public Input key_input;
public Engine() {
key_input = new Input();
}
// add keyListener(Input) to component
}
This is not enough info from you. But this is suspicious:
public boolean[] keys = new boolean[64]
Where is the code that says, "I've used this keys value, now I want to ignore it next time"?
In your tick method, you only ever check for a "pressed" state, you never reset the movement delta
For example...
public void tick() {
if (Engine.key_input.keys[KInput.LEFT]) {
dx = -speed;
} else {
dx = 0;
}
I would make determinations of animDir and sprite based on the dx and dy variables after you've updated the deltas.
I would also check the left and right, and up and down in a single if block...
For example
if (Engine.key_input.keys[KInput.LEFT]) {
dx = -speed;
} else if (Engine.key_input.keys[KInput.RIGHT]) {
dx = speed;
} else{
dx = 0;
}
This ensures that you don't accidentally reset the movement
In your handler, you are only ever setting the keys[] = true, but you are not ever returning them back to false.
You need to add a keyReleased() method that will un-move all keys that have been released.
I'm in dire need of help. I've spent 3 hours pulling my hair over the fact that I don't know how to make my collision with one single platform work!
I want the player to be able to jump on the platform and not glitch on it, or fall through it. However, there is also the case that if the player holds up and the left arrow key or right arrow key and comes in contact with the edge of the platform! I really need your help on how I can make the simple aspects of collision with a platform work with my code.
Here is my code:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Form1 extends Applet implements Runnable, KeyListener
{
private Image dbImage;
private Graphics dbg;
Thread t1;
int x = 300;
int y = 300;
boolean jumping = false;
double yVel = 0;
double termVel = 10;
int loop_cnt = 0;
int start_cnt = loop_cnt;
boolean falling = false;
boolean left, right, up, down;
double counter2 = 4;
int counter;
int num = 7;
int prevY = y;
int prevX = x;
int d = 0;
Rectangle player;
Rectangle platform;
public void init()
{
setSize(600, 400);
}
public void start()
{
player = new Rectangle();
platform = new Rectangle();
addKeyListener(this);
t1 = new Thread(this);
t1.start();
}
public void stop()
{
}
public void destroy()
{
}
#Override
public void run()
{
while (true)
{
//this code will be used if the player is on a platform and then walks off it by pressing either right or left
if (y <= 300 && !up)
{
y += 10;
}
if (left)
{
prevX = x;
x -= 2;
}
if (right)
{
prevX = x;
x += 2;
}
if (up)
{
counter2 += 0.05;
prevY = y;
y = y + (int) ((Math.sin(counter2) + Math.cos(counter2)) * 5);
if (counter2 >= 7)
{
counter2 = 4;
up = false;
}
}
if (y >= 300)
{
falling = false;
y = 300;
}
repaint();
try
{
t1.sleep(17);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public Rectangle IntersectPlatform()
{
return platform;
}
public void update(Graphics g)
{
dbImage = createImage (this.getSize().width, this.getSize().height);
dbg = dbImage.getGraphics();
// initialize buffer
if (dbImage == null)
{
}
// clear screen in background
dbg.setColor(getBackground());
dbg.fillRect(0, 0, this.getSize().width, this.getSize().height);
// draw elements in background
dbg.setColor(getForeground());
paint(dbg);
// draw image on the screen
g.drawImage(dbImage, 0, 0, this);
}
public void paint(Graphics g)
{
String string = String.valueOf(y);
g.setColor(Color.RED);
g.fillRect(x, y, 40, 100);
player.setBounds(x, y, 40, 100);
g.setColor(Color.BLUE);
platform.setBounds(180, 300, 100, 40);
g.fillRect(180, 300, 100, 40);
g.drawString(string, 100, 100);
}
#Override
public void keyPressed(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_RIGHT:
right = true;
break;
case KeyEvent.VK_LEFT:
left = true;
break;
case KeyEvent.VK_UP:
up = true;
break;
case KeyEvent.VK_DOWN:
down = true;
break;
}
}
#Override
public void keyReleased(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_RIGHT:
right = false;
break;
case KeyEvent.VK_LEFT:
left = false;
break;
case KeyEvent.VK_UP:
break;
case KeyEvent.VK_DOWN:
down = false;
break;
}
}
#Override
public void keyTyped(KeyEvent arg0)
{
// TODO Auto-generated method stub
}
}
I am creating a pacman game in Java and I have 1 problem I can't get rid of.. The problem is as follows:
I have 4 buttons in the game screen for each way: up, down, left, right. The problem is that I can not use the buttons in the same time in x position as in the y position because I always get a value of 0 ( you understand this if you see my code below )
Below you can find my class for the pacman that i think is related to the problem ( see setBesturing(int besturing) method )
package h04PacMan;
/*
* PacMan laten bewegen
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PacMan extends JPanel implements ActionListener {
private int horizontalePlaats = 250; // x location
private int verticalePlaats = 150; // y location
private int richtingEnSnelheid = +10; // speed
private final int WACHTTIJD = 500; // DELAY
int diameter;
int waarde;
public PacMan() {
// create timer and start timer
javax.swing.Timer autoKlik = new javax.swing.Timer(WACHTTIJD, this);
autoKlik.start();
}
public int getHorPlaats() {
return horizontalePlaats;
}
// current y positie
public int getVerPlaats() {
return verticalePlaats;
}
// speed and way;
public int getRichtingEnSnelheid() {
return richtingEnSnelheid;
}
// new x position
public void setHorPlaats(int nieuweHorPlaats) {
if(nieuweHorPlaats > getWidth()) {
nieuweHorPlaats = 0;
}
else if(nieuweHorPlaats < 0) {
nieuweHorPlaats = getWidth();
}
horizontalePlaats = nieuweHorPlaats;
}
// new y position
public void setVerPlaats(int nieuweVerPlaats) {
if(nieuweVerPlaats > getHeight()) {
nieuweVerPlaats = 0;
}
else if(nieuweVerPlaats < 0) {
nieuweVerPlaats = getHeight();
}
verticalePlaats = nieuweVerPlaats;
}
public void setRichtingEnSnelheid(int nieuweRichtingEnSnelheid) {
richtingEnSnelheid = nieuweRichtingEnSnelheid;
}
//movement
public void setBesturing(int besturing) {
besturing = waarde;
if(waarde == 0) {
setVerPlaats( getVerPlaats() + richtingEnSnelheid);
}
else if(waarde == 1){
setHorPlaats( getHorPlaats() + richtingEnSnelheid);
}
}
#Override
public void actionPerformed(ActionEvent e) {
setBesturing(waarde);
System.out.println(waarde);
repaint();
}
DrawPacMan pacman = new DrawPacMan();
DrawPacMan ghost1 = new DrawPacMan();
DrawPacMan ghost2 = new DrawPacMan();
public void paintComponent(Graphics g) {
super.paintComponent(g);
// pacman movement
diameter = 75;
pacman.drawPacMan(g, getHorPlaats(), getVerPlaats(), diameter, Color.yellow);
// ghosts movement
int g1x;
for(g1x = 0; g1x < 10; g1x++) {
pacman.drawGhost(g, g1x, 40, diameter, Color.red);
}
pacman.drawGhost(g, 170, 70, diameter, Color.blue);
}
}
and this is the actionListener in my gamecontrol class
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == links) {
pacman.setRichtingEnSnelheid( -10 );
pacman.setBesturing(1);
System.out.println("links");
}
else if(e.getSource() == rechts) {
pacman.setRichtingEnSnelheid( +10 );
pacman.setBesturing(1);
System.out.println("rechts");
}
else if(e.getSource() == boven) {
pacman.setRichtingEnSnelheid( -10);
pacman.setBesturing(0);
System.out.println("boven");
}
else {
pacman.setRichtingEnSnelheid( +10);
pacman.setBesturing(0);
System.out.println("beneden");
}
}
Here is your problem:
//movement
public void setBesturing(int besturing) {
besturing = waarde; <-- THIS LINE
if(waarde == 0) {
setVerPlaats( getVerPlaats() + richtingEnSnelheid);
}
else if(waarde == 1){
setHorPlaats( getHorPlaats() + richtingEnSnelheid);
}
}
You are overwriting the value of besturing with the old value waarde. It should be the other way around.
//movement
public void setBesturing(int besturing) {
waarde = besturing; <-- THIS LINE
if(waarde == 0) {
setVerPlaats( getVerPlaats() + richtingEnSnelheid);
}
else if(waarde == 1){
setHorPlaats( getHorPlaats() + richtingEnSnelheid);
}
}
I think inside the method setBesturing(int besturing) should be:
waarde = besturing;
In your setBesturing method: -
besturing = waarde;
This line never changes the value of your waarde.. It is always zero.
You should do the assignment the other way : -
this.waarde = besturing;
You'll need to keep track of whether the button is pressed or not indepentently. Also, you're model doesn't support a diagonal movement at all (I'm not sure what your nederlands names exactly mean, i can interprete snelheid=Schnelligkeit=speed and some more).
You'll need to put diagonal movement into the model (e.g. give him an x and y velocity indepent from each other)