I'm in the process of making a simple 2-D game, however I am having trouble drawing images. Below are a few classes that are relevant to the problem
private Vector<Bullet> ammo = new Vector<Bullet>(100);
public class Bullet{
Image img;
int x, y, speed;
boolean show;
Bullet(Image img,int x, int y, int speed, boolean show){
this.x = x;
this.y = y;
this.speed = speed;
this.img = img;
this.show = show;
}
public void draw(ImageObserver obs) {
if(show)
g2.drawImage(img, this.x, this.y, obs);
}
public void update(){
this.y -= 1;
}
}
public class Movement{
....
Movement(....){
.....
}
public void fly(){
......
ammo.add(new Bullet(bullet1, m.x, m.y, 7, true));
}
public class MyPlane {
KeyControl key;
Movement flight;
Image img;
int x, y, speed, move = 0;
int boom;
...
}
public void drawDemo() {
...
for(Bullet bullets: ammo)
bullets.update();
...
for(Bullet bullets: ammo)
bullets.draw(this);
}
}
When I call bullets.draw(this) nothing actually is drawn on the screen. I know however that the ammo vector does contain the correct information, such as the x coordinate, y coordinate... I'm using Graphics 2-D by the way. Any help and or suggestions would be greatly appreciated thanks.
public void paint(Graphics g) {
if(bimg == null) {
Dimension windowSize = getSize();
bimg = (BufferedImage) createImage(windowSize.width,
windowSize.height);
g2 = bimg.createGraphics();
}
drawDemo();
g.drawImage(bimg, 0, 0, this);
}
I think you should draw the image like this:
public void draw(Graphics g2) {
if(show)
g2.drawImage(img, this.x, this.y, null);
}
Then in your plane class you have to add Graphics as an argument of the drawDemo() method:
public void drawDemo(Graphics g2) {
...
for(Bullet bullets: ammo)
bullets.update();
...
for(Bullet bullets: ammo)
bullets.draw(g2);
}
}
and finally in you paint(Graphics g) method you call this:
public void paint(Graphics g) {
/*
...
*/
drawDemo(g2);
g.drawImage(bimg, 0, 0, this);
}
Related
I am attempting to draw Sierpinski's triangle on a pixel-by-pixel basis that resizes itself any time the window size is changed. I believe I have most of the project done but I don't quite know how to draw the rectangle from the separate recursive function that is outside of the paintComponent method.
public class SierpTriangle extends JPanel
{
public final int x = this.getWidth();
public final int y = this.getHeight();
public final int side = getsize();
public int getsize()
{
int width = this.getWidth();
int height = this.getHeight();
if (width <= height)
{
return width;
}
else
{
return height;
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
drawSierpTriangle(this.x, this.y, this.side);
g.drawRect(x,y,1,1);
}
public void drawSierpTriangle(int x, int y, int size)
{
if (size == 1)
{
//Draw rectangle? This is where I need help
g.drawRect(x,y,1,1); //this does not work, passing Graphics g into the method also does not work
}
else
{
drawSierpTriangle(x/2, y, size/2);
drawSierpTriangle(x,y/2,size/2);
drawSierpTriangle(x/2,y/2,size/2);
}
}
public static void main(String[] args)
{
new SierpFrame();
}
}
Pass the reference of Graphics from paintComponent to drawSierpTriangle
public void paintComponent(Graphics g)
{
super.paintComponent(g);
drawSierpTriangle(g, this.x, this.y, this.side);
g.drawRect(x,y,1,1);
}
public void drawSierpTriangle(Graphics g, int x, int y, int size)
{
if (size == 1)
{
//Draw rectangle? This is where I need help
g.drawRect(x,y,1,1); //this does not work, passing Graphics g into the method also does not work
}
else
{
drawSierpTriangle(g, x/2, y, size/2);
drawSierpTriangle(g, x,y/2,size/2);
drawSierpTriangle(g, x/2,y/2,size/2);
}
}
This results in: Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError at the first recursive call of the method. Any input?
public final int side = getsize();
will make side for ever 0.
Replace it with something more like...
public int getSide() {
int width = this.getWidth();
int height = this.getHeight();
if (width <= height) {
return width;
} else {
return height;
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int side = getSide();
if (side == 0) return;
drawSierpTriangle(g, this.x, this.y, side);
g.drawRect(x, y, 1, 1);
}
This will evaluate side every time the component is painted. It will also skip painting the shape if side is 0
You'll also have the same problem with x and y, since there state is never changed
I am trying to make this program that has two images that move in the straight line and when they read the end of frame, they turn their direction... But the thing is, the images aren't appearing on the screen idk why.. Here is my code for Actor class
public class Actor {
private Image img;
private int x,y,width,height;
private final int RIGHT=1,LEFT=-1;
private byte direction=RIGHT;
public Actor(Image img, int x,int y, int width, int height){
this.x=x;
this.y=y;
this.width=width;
this.height=height;
}
public Image getImg() {
return img;
}
public void setImg(Image img) {
this.img = img;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public void movement(int frameWidth){
setX(getX()+direction);
if(getX()<0) direction= RIGHT;
if(getX()>(frameWidth-width)) direction= LEFT;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
and here is my main class:
public class game extends JFrame implements Runnable{
private int framewidth=1000;
private int frameheight=1500;
Image image= new ImageIcon("pics/buffy.png").getImage();
Image image2= new ImageIcon("pics/buffythelayer.jpg").getImage();
private Thread thread;
private int picX=100;
private int c=1;
private int xSpeed=3;
private int xFly=1;
private int yFly=100;
private Actor greenCar,pinkCar;
public game(){
setBounds(100,100,framewidth,frameheight);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
thread= new Thread(this);
thread.start();
greenCar=new Actor(image,30,70,98,40);
pinkCar=new Actor(image2,400,70,98,40);
}
public void paint(Graphics g){
g.fillRect(xFly, yFly, 10, 10);
g.drawImage(greenCar.getImg(), greenCar.getX(), greenCar.getY(), null);
g.drawImage(pinkCar.getImg(), pinkCar.getX(), pinkCar.getY(), null);
if(c==2){
g.setColor(Color.CYAN);
g.fillOval(100, 200, 150, 200);
}
}
public static void main(String[] args) {
new game();
}
public void run() {
while(true)
{
xFly++;
greenCar.movement(framewidth);
pinkCar.movement(framewidth);
/*if(picX>280){
xSpeed=-xSpeed;
picX=picX+xSpeed;
c=2;
}
if(picX>=100){
xSpeed=3;
picX=picX+xSpeed;
}*/
repaint();
try{
thread.sleep(13);
}
catch(InterruptedException e){
}
}
}
}
I think I see the problem. When you run the code below, you set the last value, the ImageObserver, to null.
g.drawImage(greenCar.getImg(), greenCar.getX(), greenCar.getY(), null);
g.drawImage(pinkCar.getImg(), pinkCar.getX(), pinkCar.getY(), null);
Instead, you should write it like this:
g.drawImage(greenCar.getImg(), greenCar.getX(), greenCar.getY(), this);
g.drawImage(pinkCar.getImg(), pinkCar.getX(), pinkCar.getY(), this);
Therefore, the JFrame is the object that is notified as the image loads and can be drawn on the screen correctly.
If that's not the case, then you should add super.paint(g) to your paint method.
Your paint(g) method should look like this:
public void paint(Graphics g){
super.paint(g);
g.fillRect(xFly, yFly, 10, 10);
g.drawImage(greenCar.getImg(), greenCar.getX(), greenCar.getY(), this);
g.drawImage(pinkCar.getImg(), pinkCar.getX(), pinkCar.getY(), this);
if(c==2){
g.setColor(Color.CYAN);
g.fillOval(100, 200, 150, 200);
}
}
I hope this helps.
The problem is you run thread before you construct the car object, so
creat object first, the run the thread
greenCar=new Actor(image,30,70,98,40);
pinkCar=new Actor(image2,400,70,98,40);
thread.start();
and you forget set image in Actor constructor
public Actor(Image img, int x,int y, int width, int height){
this.x=x;
this.y=y;
this.width=width;
this.height=height;
this.img = img;
}
I try to make a ping pong game but my ball don't move so how to make the ball is move?
This is my code
package test;
import java.awt.*;
import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class pingpong1 extends JFrame implements Runnable {
public static void main(String[] args) {
pingpong1 ping = new pingpong1("PingPong Hard Game");
new Thread(ping).start();
ping.setSize(600, 300);
ping.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
ping.setVisible(true);
} private int width, height;
private User user;
private Computer computer;
private Ball ball;
static int UserScore = 0;
int ComputerScore=0;
public pingpong1(String title){
}
#Override
public void paint(Graphics g){
super.paint(g);
Image img2;
ImageIcon img = new ImageIcon("pingpong.png");
img2 = img.getImage();
g.drawImage(img2,0,0, this);
ball.paint(g);
}
#Override
public void run(){
while(true){
ball.moveBall();
repaint();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
Logger.getLogger( getName()).log(Level.SEVERE,null,e);
}
}
}
public void paintComponent(Graphics g) {
if (user == null) {
width = getWidth();
height = getHeight();
user = new User();
computer = new Computer();
ball = new Ball();
}
ball.draw(g);
}
public class User{
}
public class Computer{
}
public class Ball{
private int x,y;
private int centerX , centerY;
private Color color;
boolean go;
Ball(){
go=false;
}
public void paint(Graphics g) {
// TODO Auto-generated method stub
}
public Ball(int x,int y,Color color){
this.x=x;
this.y=y;
this.color=color;
this.centerX=5;
this.centerY=5;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public void moveBall(){
centerX=5;
x+=centerX;
y+=centerY;
} void draw(Graphics g){
Image img2;
ImageIcon img = new ImageIcon("pingpong.png");
img2 = img.getImage();
g.drawImage(img2, centerX - -35, centerY -10 , null);
}
}
}
Firstly your code for moving it, need to have some sort of input to actually move the ball. Right now it doesn't do anything but add x, y and doesnt repaint it, so you basically tell it to do nothing.
if you are looking for user controlled something like this will work?
public void moveIt(KeyEvent evt) {
switch (evt.getKeyCode()) {
case KeyEvent.VK_DOWN:
myY += 5;
break;
case KeyEvent.VK_UP:
myY -= 5;
break;
case KeyEvent.VK_LEFT:
myX -= 5;
break;
case KeyEvent.VK_RIGHT:
myX += 5;
break;
}
}
If you are looking for a way to move the ball automatically, then you will need to look at a few things in your code. As you don't take in to consideration the speed/ direction etc...
This is a basic example of a moving ball http://introcs.cs.princeton.edu/java/34nbody/Ball.java.html
I would of made a comment but my rep is under 50.
In your code you are correctly updating the ball's position in your game loop:
class pingpong1
while(true){
ball.moveBall(); // You update movement here
repaint();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
System.err.println("Interrupted.");
}
}
But you never actually redraw the ball at the updated position:
public void paint(Graphics g){
super.paint(g);
Image img2;
ImageIcon img = new ImageIcon("pingpong.png");
img2 = img.getImage();
g.drawImage(img2,0,0, this);
ball.paint(g); // this method is empty
}
Because the ball method paint is empty:
class Ball
public void paint(Graphics g) {
// TODO Auto-generated method stub
}
To correct that:
public void paint(Graphics g) {
ImageIcon icon = new ImageIcon("ball.png");
Image image = icon.getImage();
g.drawImage(image, x, y, null);
}
Or just call ball.draw() instead but you still have to correct the x and y because they are currently constant, change:
g.drawImage(img2, centerX + 35, centerY - 10, null);
To:
g.drawImage(img2, x, y, null);
This is my bullet class. I have been trying to make my bullet go in a direction I get from the mouse.
But the problem is when I shoot a bullet it is not going in the direction I want. Sometimes it is right but mostly it is off by around 20 pixels.
public class Bullet extends Entity {
public Bullet(int x, int y, int width, int height, boolean solid, Id id,
GameHandler handler,int targetPosX, int targetPosY, int speed) {
super(x, y, width, height, solid, id, handler);
this.setTargetPosX(targetPosX);
this.setTargetPosY(targetPosY);
this.speed = speed;
angle = Math.toDegrees(Math.atan2(targetPosY-y, targetPosX-x));
}
#Override
public void render(Graphics g) {
g.setColor(Color.BLACK);
g.fillOval(x-(width/2), y-(height/2), width, height);
}
#Override
public void update() {
x += (float)(Math.cos(Math.toRadians(angle)))*speed;
y += (float)(Math.sin(Math.toRadians(angle)))*speed;
}
public void moveToTarget(){
}
public int getTargetPosX() {
return targetPosX;
}
private void setTargetPosX(int targetPosX) {
this.targetPosX = targetPosX;
}
public int getTargetPosY() {
return targetPosY;
}
private void setTargetPosY(int targetPosY) {
this.targetPosY = targetPosY;
}
public int getSpeed() {
return speed;
}
}
This is my Cursor class:
public class GameCursor extends Entity {
private LinkedList<Bullet> bulletList = new LinkedList<Bullet>();
private enum State{
AIM,
DEFULT,
RELODING;
}
public GameCursor(Entity en,GameHandler handler) {
super(MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo().getLocation().y, 0, 0, false, Id.cursor , handler);
this.state = State.AIM;
this.en = en;
}
#Override
public synchronized void render(Graphics g) {
switch(this.state){
case AIM:
g.setColor(Color.red);
g.drawOval(x-15, y-15, 30, 30);
g.fillRect(x, y, 1, 1);
break;
}
for(Bullet b: getBulletList()){
b.render(g);
}
}
#Override
public synchronized void update() {
x = MouseInput.getMousePosX()-(-en.getX() + Frame.WIDTH/2);
y = MouseInput.getMousePosY()-(-en.getY() + Frame.HEIGHT/2 + 100);
for(Bullet b: getBulletList()){
b.update();
}
}
public void shoot(){
Bullet b = new Bullet(en.getX() + (en.width/2) ,en.getY()+ (en.height/2),10,10,true, Id.bullet, handler, getX(), getY(), 12);
addBullet(b);
}
}
I have this code:
public Juego() {
setFocusable(true);
loop = new Timer(10, this);
loop.start();
jugador = new Jugador(400, 400);
}
public void pintar(Graphics g) {
super.paint(g);
Graphics2D g2D = (Graphics2D) g;
jugador.dibujar(g2D);
}
that is supposed to draw the player into the screen, and this is the code for the actual player:
public class Jugador extends PosicionGlobal {
private String imagendejugador = "/imagenes/jugador.png";
public Jugador(int x, int y) {
super(x, y);
}
public void actualizar() {
}
public void dibujar(Graphics2D g2D) {
g2D.drawImage(imagendejugador(), x, y, null);
}
public Image imagendejugador(){
ImageIcon icono = new ImageIcon(getClass().getResource(imagendejugador));
return icono.getImage();
}
}
When I run it the player doesn't appear its just the same white screen as before. PD: I do have a JFrame and I already add this class to it.
In case its is needed here is the PosicionGlobal class:
public class PosicionGlobal {
public int x;
public int y;
public PosicionGlobal(int x, int y) {
this.x = x;
this.y = y;
}
}
You need to be overriding paint() not pintar()..
change
public void pintar(Graphics g) {
to
#Override public void paint(Graphics g) {
and make sure you call super.paint(g);