A simple question with a perhaps not so simple solution. My code is supposed to show a triangle on a black background that can be moved around onscreen. Only nothing displays, just a white area that can't be right-clicked on. It does not work in either the appletviewer or an HTML document, and shows no syntax errors. What is wrong with my code?
import java.awt.*;
import java.applet.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
public class Shipmovementtest extends Applet implements Runnable,KeyListener{
Graphics2D g2d;
Ship ship1 = new Ship();
BufferedImage backbuffer;
AffineTransform identity = new AffineTransform();
Shape ship1shape;
Thread gameloop;
public void start()
{
gameloop = new Thread(this);
gameloop.start();
}
public void run()
{
Thread t = Thread.currentThread();
while(gameloop==t)
{
try
{
Thread.sleep(20);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
repaint();
}
}
public void stop()
{
gameloop = null;
}
public void init()
{
ship1shape = ship1.getShape();
backbuffer = new BufferedImage(640,480,BufferedImage.TYPE_INT_RGB);
g2d = backbuffer.createGraphics();
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
}
public void update(Graphics g)
{
g2d.setTransform(identity);
g2d.setPaint(Color.BLACK);
g2d.fillRect(0,0,getSize().width,getSize().height);
drawShip();
paint(g);
}
public void keyTyped(KeyEvent e){}
public void keyPressed(KeyEvent e)
{
int ke = e.getKeyCode();
switch(ke)
{
case KeyEvent.VK_LEFT:
ship1.setFaceAngle(ship1.getFaceAngle()-5);
break;
case KeyEvent.VK_RIGHT:
ship1.setFaceAngle(ship1.getFaceAngle()+5);
break;
case KeyEvent.VK_UP:
ship1.incX(-ship1.calcAngleMoveX(ship1.getFaceAngle())*ship1.velocity);
ship1.incY(-ship1.calcAngleMoveY(ship1.getFaceAngle())*ship1.velocity);
break;
case KeyEvent.VK_DOWN:
ship1.incX(ship1.calcAngleMoveX(ship1.getFaceAngle())*ship1.velocity);
ship1.incY(ship1.calcAngleMoveY(ship1.getFaceAngle())*ship1.velocity);
break;
}
}
public void paint(Graphics g)
{
g2d.drawImage(backbuffer,0,0,this);
}
public void keyReleased(KeyEvent e){}
public void drawShip()
{
g2d.setTransform(identity);
g2d.translate(ship1.getX(),ship1.getY());
g2d.rotate(Math.toRadians(ship1.getFaceAngle()));
g2d.setColor(ship1.getColor());
g2d.fill(ship1.getShape());
}
}
In the end of paint you need to actually draw the buffer to the real graphics g. Currently you are only painting in the buffer.
So correct code would be
public void paint(Graphics g)
{
g.drawImage(backbuffer,0,0,this);
}
Related
My program has 3 java files, namely Frame, Dude(which contains the character) and Board(which implements the actionListener). My program is not throwing any error and the images(background and character) are rendering good. But the character is not moving forward.
import javax.swing.*;
public class Frame {
public static void main(String[] args){
JFrame frame= new JFrame("2D Game");
frame.add(new Board());
frame.setVisible(true);
frame.setSize(1200, 600);
}
}
import java.awt.*;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class Dude {
int x, dx, y;
Image still;
public Dude(){
ImageIcon i = new ImageIcon("/home/amitabh/Pictures/man1.jpg");
still= i.getImage();
x=10;
y=172;
}
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_LEFT);
dx= -1;
if(key== KeyEvent.VK_RIGHT);
dx= 1;
}
public void keyReleased(KeyEvent e){
int key= e.getKeyCode();
if(key==KeyEvent.VK_LEFT);
dx=0;
if(key==KeyEvent.VK_RIGHT);
dx=0;
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Board extends JPanel implements ActionListener{
Image img;
Timer time;
Dude p;
public Board(){
p= new Dude();
addKeyListener(new AL());
setFocusable(true);
ImageIcon i= new ImageIcon("/home/amitabh/Pictures/game1.png");
img= i.getImage();
time= new Timer(5,this);
time.start();
}
#Override
public void actionPerformed(ActionEvent e) {
p.move();
repaint();
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d= (Graphics2D)g;
g2d.drawImage(img, 0,0, null);
g2d.drawImage(p.getImage(), p.getX(), p.getY(), null);
}
public class AL extends KeyAdapter{
public void keyReleased(KeyEvent e){
p.keyReleased(e);
}
public void KeyPressed(KeyEvent e){
p.keyPressed(e);
}
}
}
Start by talking a very close look at:
if (key == KeyEvent.VK_LEFT);
Does that look funny to you?
if (key == KeyEvent.VK_LEFT); // <--- What's the ; doing here?
Change it to be more like...
if (key == KeyEvent.VK_LEFT) {
dx = 0;
}
And, yes, this is why you're encouraged to use { ... }
Next, take a closer look at...
public void KeyPressed(KeyEvent e) {
See anything wrong there? Why does it start with an uppercase K, that's not the correct method signature
Change to something more like...
#Override
public void keyReleased(KeyEvent e) {
p.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
p.keyPressed(e);
}
Yes, this is why you're encouraged to use #Override ;)
And finally change your paint method to paintComponent
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
You are encouraged to override paintComponent when performing custom painting, it tends to cause less issues
I'd also encorage you to have a look at the Key Bindings API and favour it over KeyListener as it provides better control of the focus level required to trigger the key events
I'd also encourage your to override getPreferredSize of the Board and return your preferred size from there, rather then setting the frame's size. The frame size includes the frame's decorations, so you content is smaller then the frame size
I'd like to make something similar to a cursor, ( I get no errors )
So basically I get the coordinates once I enter the applet, and based on them I have my image drawn.
Here's the code... Can you please tell me where I'm wrong ? Thanks
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
public class Z_applets extends Applet implements
KeyListener, MouseListener, MouseMotionListener {
int z = 100;
int t = 100;
// boolean gigel = true;
//----------------- Images
Image image;
//-----------------
//----------------- Mouse Coordinates
Point p = null;
int x;
int y;
//----------------------------------
Color color = Color.GREEN;
public void init() {
addKeyListener(this);
addMouseListener(this);
}
public void paint(Graphics g) {
setBackground(Color.BLACK);
g.setColor(color);
g.drawImage(image, x, y, this);
g.fillOval(z, t, 15, 15);
}
public void update(Graphics g) {
paint(g);
}
public void loadImage() {
//URL url = getClass().getResource("borat.jpg");
//image = getToolkit().getImage(url);
try {
URL url = new URL(getCodeBase(), "trollface.png");
System.out.println(getCodeBase());
image = ImageIO.read(url);
} catch (IOException e) {
System.out.println("error" + e.getMessage());
}
}
#Override
public void keyTyped(KeyEvent ke) {
}
#Override
public void keyPressed(KeyEvent ke) {
char option;
option = ke.getKeyChar();
switch (option) {
case 'w': {
t--;
repaint();
break;
}
case 's': {
t++;
repaint();
break;
}
case 'a': {
z--;
repaint();
break;
}
case 'd': {
z++;
repaint();
break;
}
case '1': {
color = Color.GREEN;
break;
}
case '2': {
color = Color.RED;
break;
}
case '3': {
color = Color.YELLOW;
break;
}
// case 'r':
// {
// loadImage();
// repaint();
// break;
// }
}
}
#Override
public void keyReleased(KeyEvent ke) {
}
#Override
public void mouseClicked(MouseEvent me) {
// p = me.getPoint();
// x = p.x;
// y = p.y;
// repaint();
}
#Override
public void mousePressed(MouseEvent me) {
}
#Override
public void mouseReleased(MouseEvent me) {
}
#Override
public void mouseEntered(MouseEvent me) {
// p=me.getPoint();
//-------Debug--------
System.out.println(p);
System.out.println(p.x);
System.out.println(p.y);
//----------------------
// x = p.x;
// y = p.y;
// repaint();
}
#Override
public void mouseExited(MouseEvent me) {
}
#Override
public void mouseDragged(MouseEvent me) {
}
#Override
public void mouseMoved(MouseEvent me) {
p = me.getPoint();
x = p.x;
y = p.y;
repaint();
}
}
Without knowing what problem you have exactly, I suppose the image isn't being moved.
I looks you don't register a MouseMotionListener so do that and implement the mouseMoved method.
I'm trying to make a game in Eclipse that runs on Windows 8 using type keys.
Whenever I run the app using extends Applet I just get a blank screen. I can change the color of the background but none of my images are showing. I can even play with the app and use my arrow keys to get the returns but I can't see anything on the screen. I'm not sure if I should extend Applet or JApplet.
Here's my code
package kiloboltgame;
import java.applet.Applet;
import java.awt.*;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Graphics;
import java.net.URL;
public class StartingClass extends Applet implements Runnable, KeyListener {
private Robot robot;
private Image image, currentSprite, character, characterDown, characterJumped, background;
private Graphics second;
private URL base;
private static Background bg1, bg2;
#Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Q-Bot Alpha");
try {
base = getDocumentBase();
} catch (Exception e){
//TODO: handle exception
}
character = getImage(base, "data/character.png");
characterDown = getImage(base, "data/down.png");
characterJumped = getImage(base, "data/jumped.png");
currentSprite = character;
background = getImage(base, "data/background.png");
}
#Override
public void start() {
bg1 = new Background(0,0);
bg2 = new Background(2160, 0);
robot = new Robot();
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
//super.stop();
}
#Override
public void destroy() {
//super.destroy();
}
#Override
public void run() {
while (true) {
robot.update();
if (robot.isJumped()){
currentSprite = characterJumped;
} else if (robot.isJumped() == false && robot.isDucked() == false){
currentSprite = character;
}
bg1.update();
bg2.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void update(Graphics g){
if (image == null){
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g){
g.drawImage(background, bg1.getBgX(), bg1.getBgY(), this);
g.drawImage(background, bg2.getBgX(), bg2.getBgY(), this);
g.drawImage(currentSprite, robot.getCenterX()-61, robot.getCenterY()-63, this);
}
#Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
System.out.println("Move Up");
break;
case KeyEvent.VK_DOWN:
currentSprite = characterDown;
if (robot.isJumped() == false){
robot.setDucked(true);
robot.setSpeedX(0);
}
break;
case KeyEvent.VK_LEFT:
robot.moveLeft();
robot.setMovingLeft(true);
break;
case KeyEvent.VK_RIGHT:
robot.moveRight();
robot.setMovingRight(true);
break;
case KeyEvent.VK_SPACE:
robot.jump();
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
System.out.println("Stop moving up");
break;
case KeyEvent.VK_DOWN:
currentSprite = character;
break;
case KeyEvent.VK_LEFT:
robot.stopLeft();
break;
case KeyEvent.VK_RIGHT:
robot.stopRight();
break;
case KeyEvent.VK_SPACE:
//System.out.println("Stop jumping");
break;
}
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
public static Background getBg1(){
return bg1;
}
public static Background getBg2(){
return bg2;
}
}
I'm having a bit of trouble developing my first Java game using images instead of vector graphics. Currently I'm experimenting with moving an Image on a key press with the AffineTransform object. Only it won't move. What am I doing wrong?
I haven't tried using threads yet, but I am not sure how to do this. If you think it would help, please include it in your answer.
Here is my code:
import java.awt.*;
import java.net.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.applet.*;
public class DisplayImage extends Applet implements KeyListener{
AffineTransform identity = new AffineTransform();
boolean left = false;
boolean right = false;
public URL getURL(String filename)
{
URL url = null;
try
{
url = this.getClass().getResource(filename);
}
catch(Exception e){e.printStackTrace();}
return url;
}
private Image image;
public void init()
{
image = getImage(getURL("spaceship.png"));
addKeyListener(this);
}
public void update(Graphics g){paint(g);}
public void paint(Graphics g)
{
AffineTransform trans = new AffineTransform();
trans.setTransform(identity);
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.BLACK);
g2d.fillRect(0,0,getSize().width,getSize().height);
if(left==true)
{
trans.translate(-10,0);
left = false;
repaint();
}
if(right==true)
{
trans.translate(10,0);
right = false;
repaint();
}
g2d.drawImage(image,0,0,this);
}
public void keyPressed(KeyEvent e)
{
int keycode = e.getKeyCode();
switch(keycode)
{
case KeyEvent.VK_RIGHT:
right = true;
repaint();
case KeyEvent.VK_LEFT:
left = true;
repaint();
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){}
}
Can someone please comment or answer? I feel a "tumbleweed" badge heading my way.
Overall, the approach you're learning from your book is far from ideal for games but I touched up the code anyway.
import java.awt.*;
import java.net.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.applet.*;
public class DisplayImage extends Applet implements KeyListener{
int coordX=0;//ship x axis position
int coordY=0;//ship y axis position
/*
0-------------------------x
0|
|
|
|
|
|
y
*/
public URL getURL(String filename)
{
URL url = null;
try
{
url = this.getClass().getResource(filename);
}
catch(Exception e){e.printStackTrace();}
return url;
}
private Image image;
public void init()
{
image = getImage(getURL("spaceship.png"));
addKeyListener(this);
}
public void update(){repaint();}//let update control the calls to repaint
public void paint(Graphics g)
{
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.BLACK);
g2d.fillRect(0,0,getSize().width,getSize().height);
g2d.drawImage(image,coordX,coordY,this);//paint the spaceship to the updated coordinates
}
public void keyPressed(KeyEvent e)
{
int keycode = e.getKeyCode();
//37=left arrow. 39=right arrow. 38=up & 40=down
if(keycode==37){coordX-=1;}else if(keycode==39){coordX+=1;}
if(keycode==38){coordY-=1;}else if(keycode==40){coordY+=1;}
update();//request repaint when logic has updated
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){}
}
Cheers
EDIT::
This is the basic concept you want to work on.
private void mainGameLoop(){
while(pause==false){
updateLogic();//process movement, detect collisions etc
renderGraphics();//draw a new frame
try{Thread.sleep(25);}catch(InterruptedException e){e.printStackTrace();}//sleep the thread to control the frame rate. (there are more efficient ways to sleep a thread but this is the most simplistic)
}
}
I have a java program which displays an ellipse on the screen and changes its direction through the use of the arrow keys. I constantly call repaint() on the ellipse using a while loop.
The ellipse moves, but the problem is that it leaves a trail of ellipses on its path. How do I make it so that it removes the old ellipses and then repaint the new one?
Code:
public void run(){
while (animator != null)
{
setBackground(Color.GREEN);
repaint();
// The direction works and the rest works fine.
player1.move(player1, player1.direction);
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
break;
}
}
}
// The paintComponent of my player1 is fine.
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D)g;
player1.paintComponent(g2, player1);
}
The problem is likely that your paintComponent(Graphics) overriden method is not calling super.paintComponent(g), which clears the canvas, among other things:
// Bad:
#Override
public void paintComponent(Graphics g) {
// paint the ellipse, etc.
}
// Good:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// paint the ellipse, etc.
}
Here is some basic code which does the very basics (without the use of a continuous while loop):
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
#SuppressWarnings("serial")
public class Ellipses extends JFrame {
public static void main(String[] args){
//Ensures application is not run on the main thread
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Ellipses myEllipses = new Ellipses();
myEllipses.init();
}
});
}
public Ellipses(){
//Set up the frame
this.setTitle("Ellipses Example");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setSize(400, 400);
}
private Ellipse ellipse1;
public void init(){
Container contentPane = this.getContentPane();
//Create a new ellipse and add to the content pane
ellipse1 = new Ellipse();
contentPane.add(ellipse1);
//Add the keyListener to the contentPane
contentPane.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
ellipse1.decreaseY();
}
if(e.getKeyCode() == KeyEvent.VK_DOWN){
ellipse1.increaseY();
}
if(e.getKeyCode() == KeyEvent.VK_LEFT){
ellipse1.decreaseX();
}
if(e.getKeyCode() == KeyEvent.VK_RIGHT){
ellipse1.increaseX();
}
//Repaint the ellipse
ellipse1.repaint();
}
});
//Request the focus so key presses can be detected
contentPane.setFocusable(true);
contentPane.requestFocus();
}
//Create an ellipse which can be drawn to the screen
public class Ellipse extends JComponent{
private int x , y; //Coordinates of the oval
public Ellipse(){
setCoordinates(100, 100);
}
public void setCoordinates(int x, int y){
this.x = x;
this.y = y;
}
public void increaseY(){
y+=10;
}
public void increaseX(){
x+=10;
}
public void decreaseY(){
y-=10;
}
public void decreaseX(){
x-=10;
}
public void paint(Graphics g){
//Ensures previous paint is cleared
super.paintComponents(g);
g.setColor(Color.RED);
g.fillOval(x, y, 100, 100);
}
}
}
You should draw the background Color before drawing the ellipse in the game loop :)
Also you can call repaint() , it actually calls update() to do
the dirty work of clearing the screen and calling paint().
When you use repaint the update method inherit
public void update(Graphics g) {
g.setColor(getBackground());
g.fillRect(0, 0, width, height);
g.setColor(getForeground());
paint(g)
}
so the background return to it's original color and the trail of ellipses will be removed