When I use this code my screen will be empty. So that means
something is wrong with my paintComponent method. But what is wrong? And how do I fix it? My expected output was a dark gray rectangle, and an image.
Code:
package _47b3n.seg.main.engine;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import _47b3n.seg.main.frame.Frame;
public class Engine extends JPanel {
public int xOff;
public int yOff;
public int x;
public int y;
public int fpsInt = 199;
public boolean isRunning = true;
public FPS fps = new FPS();
public static void main(String [] args) {
Frame frame = new Frame();
frame.setFrame(800, 600, "Super easy game", "0.0.1");
new Engine();
}
public Engine() {
start();
}
public void move() {
x+=xOff;
y+=yOff;
}
public void start() {
Thread loop = new Thread () {
public void run() {
gameLoop();
addKeyListener(new keyInput());
}
};
loop.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.DARK_GRAY);
g.fillRect(10, 10, 10, 10);
g.drawImage(new ImageIcon("Poppetje.jpg").getImage(), x, y, null);
}
public void gameLoop() {
while(isRunning) {
move();
repaint();
fps.update();
fpsInt++;
if (fpsInt == 200) {
System.out.println("[Console] " + fps.getFPS() + " FPS");
fpsInt = 0;
}
try {Thread.sleep(17);} catch (InterruptedException e) {e.printStackTrace();}
}
}
public class keyInput extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_W) {
yOff = -1;
}
if (key == KeyEvent.VK_S) {
yOff = 1;
}
if (key == KeyEvent.VK_A) {
yOff = -1;
}
if (key == KeyEvent.VK_D) {
xOff = 1;
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_W) {
yOff = 0;
}
if (key == KeyEvent.VK_S) {
yOff = 0;
}
if (key == KeyEvent.VK_A) {
xOff = 0;
}
if (key == KeyEvent.VK_D) {
xOff = 0;
}
}
}
}
Thanks
Don't know if it is the only problem, but you never add the panel to the frame:
//new Engine();
Engine engine = new Engine();
frame.add(engine);
frame.setVisible(true);
Related
I am generally a very bad programmer but have been trying to learn game development for a school project. My problem is that I have a draw method that draws a white rectangle and have a key Listener for movement but for some reason it moves upward despite what key I press not just W A S and D.
If you could help with this I would appreciate.
thanks
package Main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable{
final int screenHeight = 600;
final int screenWidth = 800;
final int playerSize = 48;
int fps = 60;
KeyHandler keyH = new KeyHandler();
Thread gameThread;
//player default position
int playerX = 100;
int playerY = 100;
int playerSpeed = 1;
public GamePanel() {
this.setPreferredSize(new Dimension (screenWidth, screenHeight));
this.setBackground(Color.black);
this.setDoubleBuffered(true);
this.addKeyListener(keyH);
this.setFocusable(true);
}
public void startGameThread() {
gameThread = new Thread (this);
gameThread.start();
}
public void run() {
double drawInterval = 1000000000/fps; // 0.01666 seconds = 60 times per seconds
double nextDrawTime = System.nanoTime() + drawInterval;
while(gameThread != null) {
System.out.println("this gmae is runing");
// update information such as character positions
// draw the screen with the updated information
update();
repaint();
try {
double remainingTime = nextDrawTime - System.nanoTime();
remainingTime = remainingTime/1000000;
if(remainingTime<0) {
remainingTime = 0;
}
Thread.sleep ((long) remainingTime);
nextDrawTime += drawInterval;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void update() {
if(keyH.upPressed ==true) {
playerY = playerY - playerSpeed;
}
else if (keyH.downPressed ==true){
playerY = playerY + playerSpeed;
}
else if (keyH.leftPressed== true){
playerX = playerX - playerSpeed;
}
else if (keyH.rightPressed == true) {
playerX = playerX +playerSpeed;
}
}
public void paintComponent(Graphics g) {
// to draw something
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.white);
g2.fillRect(playerX, playerY, playerSize, playerSize);
g2.dispose();
}
}
package game;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyHandler implements KeyListener {
public boolean leftPressed;
public boolean rightPressed;
public boolean upPressed;
public boolean downPressed;
public boolean spacePressed;
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if(code == KeyEvent.VK_D);{
rightPressed = true;
}
if(code == KeyEvent.VK_A);{
leftPressed = true;
}
if(code == KeyEvent.VK_W);{
upPressed = true;
}
if(code == KeyEvent.VK_S);{
downPressed = true;
}
}
#Override
public void keyReleased(KeyEvent e) {
int code = e.getExtendedKeyCode();
if(code == KeyEvent.VK_D);{
rightPressed = false;
}
if(code == KeyEvent.VK_A);{
leftPressed = false;
}
if(code == KeyEvent.VK_W);{
upPressed = false;
}
if(code == KeyEvent.VK_S);{
downPressed = false;
}
}
}
I am trying to create a 2D Pac-Man game using Java but I'm having trouble getting the rectangle which will represent the Pac-Man to move. I think that my issue might be somewhere in my keyPressed method in the Game class but I'm not sure. This is what I have in my main class so far.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable,KeyListener {
private static final long serialVersionUID = 1L;
private boolean isRunning = false;
public static final int WIDTH = 640;
public static final int HEIGHT = 480;
public static final String TITLE = "Pac-Man";
public Thread thread;
public static Player player;
public Game() {
Dimension dimension = new Dimension(Game.WIDTH,Game.HEIGHT);
setPreferredSize(dimension);
setMinimumSize(dimension);
setMaximumSize(dimension);
addKeyListener(this);
player = new Player(Game.WIDTH/2,Game.HEIGHT/2);
}
public synchronized void start() {
if(isRunning) {
return;
} else {
isRunning = true;
thread = new Thread(this);
thread.start();
}
}
public synchronized void stop() {
if(!isRunning) {
return;
} else {
isRunning = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void tick() {
player.tick();
}
private void render() {
BufferStrategy bs= getBufferStrategy();
if(bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, Game.WIDTH, Game.HEIGHT);
player.render(g);
g.dispose();
bs.show();
}
#Override
public void run() {
int fps = 0;
double timer = System.currentTimeMillis();
long lastTime = System.nanoTime();
double targetTicks = 60.0;
double delta = 0;
double ns = 1000000000/targetTicks;
while(isRunning) {
long currentTime = System.nanoTime();
delta += (currentTime - lastTime)/ns;
lastTime = currentTime;
while(delta >= 1) {
tick();
render();
fps++;
delta--;
}
if((System.currentTimeMillis() - timer) >= 1000) {
System.out.println(fps);
fps = 0;
timer += 1000;
}
}
stop();
}
public static void main(String[] args) {
Game game = new Game();
JFrame frame = new JFrame();
frame.setTitle(Game.TITLE);
frame.add(game);
frame.setResizable(false);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
}
#Override
public void keyTyped(KeyEvent e) {}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
player.right = true;
}
if(e.getKeyCode() == KeyEvent.VK_LEFT) {
player.left = true;
}
if(e.getKeyCode() == KeyEvent.VK_UP) {
player.up = true;
}
if(e.getKeyCode() == KeyEvent.VK_DOWN) {
player.down = true;
}
}
#Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
player.right = false;
}
if(e.getKeyCode() == KeyEvent.VK_LEFT) {
player.left = false;
}
if(e.getKeyCode() == KeyEvent.VK_UP) {
player.up = false;
}
if(e.getKeyCode() == KeyEvent.VK_DOWN) {
player.down = false;
}
}
}
This is what I have in the Player class so far.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
public class Player extends Rectangle{
private static final long serialVersionUID = 1L;
public boolean right;
public boolean left;
public boolean up;
public boolean down;
private int speed = 4;
public Player(int x, int y) {
setBounds(x,y,32,32);
}
public void tick() {
if(right) {
x+=speed;
}
if(left) {
x-=speed;
}
if(up) {
y-=speed;
}
if(down) {
y+=speed;
}
}
public void render(Graphics g) {
g.setColor(Color.yellow);
g.fillRect(x,y,width,height);
}
}
So basically I wanted to create zombies to interact with them later on, but when I drew them I noticed that all of them are turning to the same direction as the player (to mouse) it happened with everything I drew. How do I fix that? (give each zombie it's own position independent from the mouse direction)
Screen.java
import java.awt.Component;
import java.awt.Dimension;
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.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
public class Screen extends JPanel implements KeyListener, MouseListener, MouseMotionListener {
private Enemy[] enemy;
private Bullet bullet;
private Player player;
boolean collisionBetweenBnZ = false;
private int mX, mY, key;
private List<Bullet> firedBullets = new ArrayList<Bullet>();
public Screen() {
player = new Player(400, 500);
enemy = new Enemy[10];
for (int i = 0; i < enemy.length; i++) {
enemy[i] = new Enemy();
}
setFocusable(true);
addKeyListener(this);
addMouseMotionListener(this);
addMouseListener(this);
this.requestFocusInWindow();
}
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
//an obstacle for zombies
g.fillRect(0, 400, 800, 4);
//drawing each bullet as soon as they are added to the list (when pressing mouse button)
for (int i = 0; i < firedBullets.size(); i++) {
firedBullets.get(i).drawBullet(g);
}
//drawing sprites
player.drawPlayer(g);
for (int i = 0; i < enemy.length; i++) {
enemy[i].drawEnemy(g);
}
}
public static int clamp(int num, int min, int max) { //method that prevents you from going beyond the window
if (num >= max) return num = max;
else if (num <= min) return num = min;
else return num;
}
public void fire() {
bullet = new Bullet(player.playerX(), player.playerY());
bullet.updateAngle(mX, mY, player.playerX(), player.playerY());
firedBullets.add(bullet);
}
public void animate() {
while (true) {
try {
Thread.sleep(10); //in milliseconds
}
catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
player.tick();
/*for (int i = 0; i < )
enemy.tick();*/
//System.out.println("X: " + mX + "\n" + "Y: " + mY);
for (int i = 0; i < firedBullets.size(); i++) {
firedBullets.get(i).launch();
}
//if () getbounds
repaint();
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
key = e.getKeyCode();
if (key == KeyEvent.VK_A) {
player.setVelX(-2);
}
else if (key == KeyEvent.VK_D) {
player.setVelX(2);
}
else if (key == KeyEvent.VK_S) {
player.setVelY(2);
}
else if (key == KeyEvent.VK_W) {
player.setVelY(-2);
}
else if (key == KeyEvent.VK_SPACE) {
//bullet.shootBullet = true;
}
else if (key == KeyEvent.VK_A && key == KeyEvent.VK_D) {
player.setVelX(0);
}
else if (key == KeyEvent.VK_W && key == KeyEvent.VK_S) {
player.setVelY(0);
}
}
public void keyReleased(KeyEvent e) {
key = e.getKeyCode();
if (key == KeyEvent.VK_A) {
player.setVelX(0);
}
else if (key == KeyEvent.VK_D) {
player.setVelX(0);
}
else if (key == KeyEvent.VK_S) {
player.setVelY(0);
}
else if (key == KeyEvent.VK_W) {
player.setVelY(0);
}
else if (key == KeyEvent.VK_SPACE) {
//bullet.shootBullet = false;
}
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
mX = e.getX();
mY = e.getY();
player.updateAngle(mX, mY);
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
fire();
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
Enemy.java
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.util.concurrent.ThreadLocalRandom;
public class Enemy {
private int health, width, height;
private int enemyX, enemyY, velY;
private BufferedImage img;
public Enemy() {
try {
img = ImageIO.read(new File("/Users/david/Desktop/Enemy_Sprite.png"));
} catch (IOException e) {
e.printStackTrace();
}
health = 100;
width = img.getWidth();
height = img.getHeight();
enemyX = ThreadLocalRandom.current().nextInt(50, 750);
enemyY = ThreadLocalRandom.current().nextInt(0, 200);
}
public Rectangle getBounds() {
return new Rectangle(enemyX, enemyY, width, height);
}
public void setVelY(int y) {
velY = y;
}
public void tick() {
enemyY += velY;
}
public boolean obstacleInteraction() {
//if (getBounds() == )
return true;
}
public void drawEnemy(Graphics g) {
g.drawImage(img, enemyX, enemyY, null);
}
}
I figured it out thanks to this person. So basically at the end of my code where I draw player and make him rotate to the mouse position put the saved original plane position
g.setTransform(oldAT);
This question already has answers here:
How to use Key Bindings instead of Key Listeners
(4 answers)
Closed 5 years ago.
When VK_UP or VK_DOWN is pressed the Graphic g I created is not changing its position whatsoever. If someone could look and see if there is something wrong with my move method etc. Would really appreciate it.
Here is all my code so far:
package ping2;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Ping2 extends Applet implements Runnable, KeyListener{
final int WIDTH = 700, HEIGHT = 500;
Thread thread;
UserPaddle user1;
public void init() {
this.resize(WIDTH, HEIGHT);
this.addKeyListener(this);
user1 = new UserPaddle(1);
thread = new Thread(this);
thread.start();
}
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
user1.draw(g);
}
public void update(Graphics g) {
paint(g);
}
public void run() {
for(;;) {
user1.move();
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP) {
user1.setUpAccel(true);
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN) {
user1.setDownAccel(true);
}
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP) {
user1.setUpAccel(false);
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN) {
user1.setDownAccel(false);
}
}
public void keyTyped(KeyEvent arg0) {
}
}
package ping2;
import java.awt.*;
public class UserPaddle implements InterfaceBar{
double y, yVelocity;
boolean upAccel, downAccel;
int player1, x;
final double FRICTION = 0.90;
public UserPaddle(int player1) {
upAccel = false;
downAccel = false;
y = 210;
yVelocity = 0;
if(player1 == 1)
x = 20;
else
x = 660;
}
public void draw(Graphics g) {
g.setColor(Color.white);
g.fillRect(x, (int)y, 20, 80);
}
public void move() {
if(upAccel) {
yVelocity -= 2;
}else if(downAccel) {
yVelocity += 2;
}
//Automatically slows bar down if key not being pressed.
else if(!upAccel && !downAccel) {
yVelocity *= FRICTION;
}
}
public void setUpAccel(boolean input) {
upAccel = input;
}
public void setDownAccel(boolean input) {
downAccel = input;
}
public int getY() {
return (int)y;
}
}
package ping2;
import java.awt.Graphics;
public interface InterfaceBar {
public void draw(Graphics g);
public void move();
public int getY();
}
I have modified your move() a bit give it a try
move()
public void move() {
if(upAccel) {
yVelocity -= 2;
y = yVelocity;
}else if(downAccel) {
yVelocity += 2;
y = yVelocity;
}
}
The program works fine, but when I hold a key or change keys the motion is not smooth. It pauses for a split second before becoming smooth. I'm still a beginner at Java so please explain in detail.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Game2015
{
JFrame frame;
DrawRect mainPanel;
GridBagLayout gridbag;
GridBagConstraints constraints;
Data data;
int width;
int height;
public static void main(String[] args)
{
new Game2015();
}
public Game2015()
{
frame = new JFrame();
width = 400;
height = 500;
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
frame.setSize(width, height);
frame.setResizable(false);
data = new Data();
mainPanel = new DrawRect(data);
mainPanel.setFocusable(true);
mainPanel.setBackground(Color.WHITE);
KeyHandler keys = new KeyHandler();
mainPanel.addKeyListener(keys);
frame.add(mainPanel);
frame.validate();
frame.setLocationRelativeTo(null);
Thread thread = new Thread(new Runnable(){
public void run()
{
while(true)
{
mainPanel.repaint();
mainPanel.requestFocus(true);
}
}
});
thread.start();
}
public class KeyHandler implements KeyListener
{
public void keyReleased(KeyEvent event)
{
}
public void keyTyped(KeyEvent event)
{
}
public void keyPressed(KeyEvent event)
{
if(event.getKeyCode() == KeyEvent.VK_W || event.getKeyCode() == KeyEvent.VK_UP)
{
if(data.getY() >= data.getSpeed())
{
data.setY(data.getY() - data.getSpeed());
}
else
{
data.setY(0);
}
}
else if(event.getKeyCode() == KeyEvent.VK_S || event.getKeyCode() == KeyEvent.VK_DOWN)
{
if(data.getY() + 95 <= height - data.getSpeed())
{
data.setY(data.getY() + data.getSpeed());
}
else
{
data.setY(height - 95);
}
}
else if(event.getKeyCode() == KeyEvent.VK_A || event.getKeyCode() == KeyEvent.VK_LEFT)
{
if(data.getX() >= data.getSpeed())
{
data.setX(data.getX() - data.getSpeed());
}
else
{
data.setX(0);
}
}
else if(event.getKeyCode() == KeyEvent.VK_D || event.getKeyCode() == KeyEvent.VK_RIGHT)
{
if(data.getX() + 75 <= width - data.getSpeed())
{
data.setX(data.getX() + data.getSpeed());
}
else
{
data.setX(width - 75);
}
}
else if(event.getKeyCode() == KeyEvent.VK_ESCAPE)
{
frame.dispose();
System.exit(0);
}
}
}
}
The code for drawing the rectangle is this:
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
public class DrawRect extends JPanel
{
BufferedImage img_player;
File file;
Data data;
public DrawRect(Data newData)
{
data = newData;
try
{
file = new File("Images\\Player.png");
img_player = ImageIO.read(file);
}
catch (Exception exception)
{
}
}
#Override
public void paintComponent(Graphics graphics)
{
super.paintComponent(graphics);
Graphics2D graphics2D = (Graphics2D) graphics;
graphics2D.drawImage(img_player, data.getX(), data.getY(), null);
}
}
and the code for the Data class is this:
public class Data
{
int x, y, speed;
public Data()
{
x = 0;
y = 0;
speed = 10;
}
public void setSpeed(int new_speed)
{
speed = new_speed;
}
public int getSpeed()
{
return speed;
}
public void setX(int new_x)
{
x = new_x;
}
public int getX()
{
return x;
}
public void setY(int new_y)
{
y = new_y;
}
public int getY()
{
return y;
}
}
This is because of have java handles events: When you first press a key, it fires an event (pressing the key), and only after a small period of time does it continue to fire events (holding the key). You can test this by printing out every time an event is fired, and it will have a small delay between the first and the rest of the events.
The way to work around this is instead of every time you press a key changing the characters position, change the characters velocity.
For example, instead of
if(event.getKeyCode() == KeyEvent.VK_W || event.getKeyCode() == KeyEvent.VK_UP){
if(data.getY() >= data.getSpeed())
{
data.setY(data.getY() - data.getSpeed());
} else {
data.setY(0);
}
} ... etc ...
it would be
if(event.getKeyCode() == KeyEvent.VK_W || event.getKeyCode() == KeyEvent.VK_UP){
data.setVelocityY(-data.getSpeed());
} ... etc ...
as well as that, you'd also need to stop their velocity when they release the key. In your keyReleased() method, just do the same thing, but instead of setting velocity to speed, set it to 0.
if(event.getKeyCode() == KeyEvent.VK_W || event.getKeyCode() == KeyEvent.VK_UP){
data.setVelocityY(0);
} ... etc ...
and then in your game loop and a method update() that handles calculations (adding velocity to position)
So
public void run() {
while(true) {
mainPanel.repaint();
mainPanel.requestFocus(true);
}
}
would be
public void run() {
while(true) {
update();
mainPanel.repaint();
mainPanel.requestFocus(true);
}
}
where the update method would be
public static void update() {
data.setY(data.getY() + data.getVelocityY());
data.setX(data.getX() + data.getVelocityX());
}
You should look up basic tutorials on java games. For example, I always found this a good introductory tutorial.