I am new to Java and new to this site and have been taking a tutorial and need some help. The tutorial teaches you how to make a simple game. The players are represented by colored squares. I got up to the part where he talks about how to make the player move with a "KeyInput" class. It doesn't say there are any errors so I'm not sure what I'm doing wrong or if I missed something. I followed what he did in the video very closely. There are 6 classes and an Enum. The classes are called "Game.java", "GameObject.java", "Handler.java", "KeyInput.java", "Player.java" and "Window.java." The Enum is called "ID.java." I will post the code for the classes and the enum below.
KeyInput.java
package com.tutorial.game;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class KeyInput extends KeyAdapter {
private Handler handler;
public KeyInput(Handler handler) {
this.handler = handler;
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
for(int i = 0; i < handler.object.size(); i++) {
GameObject tempObject = handler.object.get(i);
if(tempObject.getId() == ID.Player) {
if(key == KeyEvent.VK_W) tempObject.setVelY(tempObject.getY() - 1);
}
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
}
}
Player.java
package com.tutorial.game;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
public class Player extends GameObject {
Random r = new Random();
public Player(int x, int y, ID id) {
super(x, y, id);
}
public void tick() {
x += velX;
Y += velY;
}
public void render(Graphics g) {
if(id == ID.Player)g.setColor(Color.white);
else if(id == ID.Player2) g.setColor(Color.red);
g.fillRect(x, Y, 32, 32);
}
}
ID.java
package com.tutorial.game;
public enum ID {
Player(),
Enemy(), Player2();
}
GameObject.java
package com.tutorial.game;
import java.awt.Graphics;
public abstract class GameObject {
protected int x, Y;
protected ID id;
protected int velX, velY;
public GameObject(int x, int Y, ID id) {
this.x = x;
this.Y = Y;
this.id = id;
}
public abstract void tick();
public abstract void render(Graphics g);
public void setX(int x) {
this.x = x;
}
public void setY(int Y) {
this.Y = Y;
}
public int getX() {
return x;
}
public int getY() {
return Y;
}
public void setId(ID id) {
this.id = id;
}
public ID getId() {
return id;
}
public void setVelX(int velX) {
this.velX = velX;
}
public void setVelY(int velY) {
this.velY = velY;
}
public int getVelX(){
return velX;
}
public int getVelY() {
return velY;
}
}
Game.java
package com.tutorial.game;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.util.Random;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = -7728264178317937023L;
public static final int WIDTH = 640, HEIGHT = 640;
private Thread thread;
private boolean running = false;
private Random r;
private Handler handler;
public Game(){
this.addKeyListener(new KeyInput(handler));
handler = new Handler();
new Window(WIDTH, HEIGHT, "Let's build a game", this);
r = new Random();
handler.addObject(new Player(WIDTH/2-32, HEIGHT/2-32, ID.Player));
handler.addObject(new Player(WIDTH/2+64, HEIGHT/2-32, ID.Player2));
}
public synchronized void start(){
thread = new Thread(this);
thread.start();
running = true;
}
public synchronized void stop(){
try {
thread.join();
running = false;
}catch(Exception e) {
e.printStackTrace();
}
}
public void run(){
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while(running){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1) {
tick();
delta--;
}
if(running)
render();
frames++;
if(System.currentTimeMillis() - timer > 1000) {
timer += 1000;
//System.out.println("FPS: " + frames);
frames = 0;
}
}
stop();
}
private void tick(){
handler.tick();
}
private void render() {
BufferStrategy bs = this.getBufferStrategy();
if(bs == null) {
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
handler.render(g);
g.dispose();
bs.show();
}
public static void main(String args[]) {
new Game();
}
}
Handler.java
package com.tutorial.game;
import java.awt.Graphics;
import java.util.LinkedList;
public class Handler {
LinkedList<GameObject> object = new LinkedList<GameObject>();
public void tick() {
for(int i = 0; i < object.size(); i++) {
GameObject tempObject = object.get(i);
tempObject.tick();
}
}
public void render(Graphics g) {
for(int i = 0; i < object.size(); i++) {
GameObject tempObject = object.get(i);
tempObject.render(g);
}
}
public void addObject(GameObject object) {
this.object.add(object);
}
public void removeObject(GameObject object) {
this.object.remove(object);
}
}
Window.java
package com.tutorial.game;
import java.awt.Canvas;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Window extends Canvas {
private static final long serialVersionUID = -1413099016987259526L;
public Window(int WIDTH, int HEIGHT, String title, Game game) {
JFrame frame = new JFrame(title);
frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
frame.setMaximumSize(new Dimension(WIDTH, HEIGHT));
frame.setMinimumSize(new Dimension(WIDTH, HEIGHT));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.add(game);
frame.setVisible(true);
game.start();
}
}
try this with new Thread loop(in Game.java) :
Game.this.requestFocus();
You should add some delay between two request focus.
Code in thread
while(isDisplayable()){
Game.this.requestFocus();
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
Related
I want it so when my player goes off the platform, (in checkCollision() method PlatformerPanel class) it will fall and then do something when gone off the screen, i haven't set up an end game screen yet but that's what I'm planning to do. Anyway, the problem is that it goes way too fast for some reason and falls too early, and also when an arrow key is pressed while its falling it will go back up to the platform.
Please try to help me overcome this or think of a new, easy to understand, way to do this/make this work the way i am planning.
EDIT 1:
I fixed the thing where it falls too early so don't worry about that
```
public class PlatformerMain {
public static void main(String[] args) {
PlatformerGameFrame platformerGame = new PlatformerGameFrame();
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class PlatformerGameFrame extends JFrame{
PlatformerGamePanel panel;
PlatformerGameFrame() {
panel = new PlatformerGamePanel();
this.add(panel);
this.setTitle("Platformer Game");
this.setResizable(false);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.pack();
this.setVisible(true);
this.setLocationRelativeTo(null);
this.getContentPane().setBackground(new Color(0,0,0));
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class PlatformerGamePanel extends JPanel implements Runnable{
PlatformerPlayer player1;
PlatformerMap map1;
static final int SCREEN_WIDTH = 1000;
static final int SCREEN_HEIGHT = 600;
static final int PLAYER_WIDTH = 50;
static final int PLAYER_HEIGHT = 60;
static final Dimension SCREEN_SIZE = new Dimension(SCREEN_WIDTH,SCREEN_HEIGHT);
static boolean falling = false;
Image backgroundImage;
Thread gameThread;
Image image;
Graphics graphics;
PlatformerMap map;
public PlatformerGamePanel() {
java.net.URL imgIcon = Main.class.getResource(
"/Resources/spaceImage.jpg");
backgroundImage = new ImageIcon(imgIcon).getImage();
newPlayer();
newMap();
this.setFocusable(true);
this.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {}
#Override
public void keyPressed(KeyEvent e) {
player1.KeyPressed(e);
}
#Override
public void keyReleased(KeyEvent e) {
player1.KeyReleased(e);
}
});
this.setPreferredSize(SCREEN_SIZE);
this.setOpaque(true);
gameThread = new Thread(this);
gameThread.start();
}
public void paint(Graphics g) {
image = createImage(getWidth(),getHeight());
graphics = image.getGraphics();
draw(graphics);
g.drawImage(image, 0,0, null);
}
public void draw(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(backgroundImage, 0,0, null);
player1.paint(g);
map.paint(g);
}
public void newPlayer() {
player1 = new PlatformerPlayer((SCREEN_WIDTH/2)-(PLAYER_WIDTH/2), (SCREEN_HEIGHT/2)-(PLAYER_WIDTH/2), PLAYER_WIDTH, PLAYER_HEIGHT);
}
public void newMap() {
map = new PlatformerMap();
}
public void checkCollision() {
if(player1.x > SCREEN_WIDTH-PLAYER_WIDTH) {
player1.x = SCREEN_WIDTH-PLAYER_WIDTH;
}
else if(player1.x < 0) {
player1.x = 0;
}
if(!(player1.x >map.PLATFORM_WIDTH)) {
if(player1.y > SCREEN_HEIGHT-250) {
player1.y = SCREEN_HEIGHT-250;
}
} else if(player1.x > map.PLATFORM_WIDTH) {
gravity();
}
}
public void falling() {
}
public void gravity() {
player1.gravity();
}
public void move() {
player1.move();
}
public void run() {
long lastTime = System.nanoTime();
double amountOfTicks = 120.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
while(true) {
long now = System.nanoTime();
delta += (now - lastTime)/ns;
lastTime = now;
if(delta >= 1) {
move();
checkCollision();
gravity();
repaint();
delta--;
}
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class PlatformerPlayer extends Rectangle {
/*static int playerPosX = 100;
static int playerPosY = 100;*/
static double velocityY = 0;
static double velocityX = 0;
static int vertical_position;
static final int TERMINAL_VELOCITY = 200;
static final int PLAYER_WIDTH = 50;
static final int PLAYER_HEIGHT = 50;
static int speed = 2;
protected boolean falling = true;
protected boolean jumping = false;
double gravity = 0.05;
public PlatformerPlayer(int x, int y, int PLAYERWIDTH, int PLAYERHEIGHT) {
super(x,y,PLAYERWIDTH,PLAYERHEIGHT);
}
public void KeyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_LEFT) {
setXDirection(-speed);
move();
}
else if(e.getKeyCode()==KeyEvent.VK_RIGHT) {
setXDirection(speed);
move();
}
}
public void KeyReleased(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_LEFT) {
setXDirection(0);
move();
}
else if(e.getKeyCode()==KeyEvent.VK_RIGHT) {
setXDirection(0);
move();
}
}
public void paint(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.setColor(Color.red);
g2D.fillRect(x, y, PLAYER_WIDTH, PLAYER_HEIGHT);
}
public void setYDirection(int YDirection) {
velocityY = YDirection;
}
public void setXDirection(int XDirection) {
if(speed > 10) {
speed = 10;
}
velocityX = XDirection;
}
public void move() {
y += velocityY;
x += velocityX;
}
public void gravity() {
velocityY += gravity;
if (velocityY > TERMINAL_VELOCITY)
{
velocityY = TERMINAL_VELOCITY;
}
vertical_position -= velocityY;
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class PlatformerMap extends Rectangle {
int PLATFORM_WIDTH = 600;
int PLATFORM_HEIGHT = 150;
public PlatformerMap() {
}
public void paint(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.setColor(Color.gray);
g2D.fillRect(100,400,PLATFORM_WIDTH,PLATFORM_HEIGHT);
}
}
I am trying to get images to display in my game. The background of my game works, but I am unable to get my playerIcon, bulletIcon and heartIcon images working.
My imageLoader class: (Working correctly)
package BullHellSpel;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageLoader {
public static BufferedImage loadImage(String path){
try {
return ImageIO.read(ImageLoader.class.getResource(path));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(1);
}
return null;
}
}
The important parts of my Game Class: (Which correctly loads my bg.png image)
public void run()
{
init();
}
private void init(){
bg = ImageLoader.loadImage("/bg.png");
}
private void render(){
BufferStrategy bs = this.getBufferStrategy();
if(bs == null){
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
//You can draw here
g.drawImage(bg, 0, 0, null);
handler.render(g);
g.dispose();
bs.show();
}
My Bullet Class: (Not working correctly)
package BullHellSpel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.Random;
public class Bullet extends GameObject {
private BufferedImage bulletIcon;
private Handler handler;
public Bullet(int x, int y, ID id, Handler handler) {
super(x, y, id);
this.handler = handler;
Random rand = new Random();
velX = rand.nextInt(5) + 3;
velY = rand.nextInt(3) + 2;
}
public Rectangle getBounds(){
return new Rectangle(x, y, 10, 10);
}
public void run()
{
init();
}
private void init(){
bulletIcon = ImageLoader.loadImage("/bullet.png");
}
public void tick() {
x += velX;
y += velY;
if(x <= 0 || x >= Game.WIDTH - 16) velX *= -1;
}
public void repaint() {
Graphics g = null;
g.drawImage(bulletIcon, x, y, null);
//g.setColor(Color.yellow);
//g.fillRect(x, y, 10, 10);
}
public void repaint(Graphics g) {
g.drawImage(bulletIcon, x, y, null);
//g.setColor(Color.yellow);
//g.fillRect(x, y, 10, 10);
}
}
My GameObject Class:
package BullHellSpel;
import java.awt.Graphics;
import java.awt.Rectangle;
public abstract class GameObject {
protected int x, y;
protected ID id;
protected int velX, velY;
public GameObject(int x, int y, ID id){
this.x = x;
this.y = y;
this.id = id;
}
public abstract void tick();
public abstract void repaint(Graphics g);
public abstract Rectangle getBounds();
public void setX(int x){
this.x = x;
}
public void setY(int y){
this.y = y;
}
public void getY(int y){
this.y = y;
}
public void getX(int x){
this.x = x;
}
public void setId(ID id){
this.id = id;
}
public ID getId(){
return id;
}
public void setVelX(int velX){
this.velX = velX;
}
public void setVelY(int velY){
this.velY = velY;
}
public int getVelX(int velX){
return velX;
}
public int getVelY(int velY){
return velY;
}
}
My Handler class:
package BullHellSpel;
import java.awt.Graphics;
import java.util.LinkedList;
public class Handler {
LinkedList<GameObject> object = new LinkedList<GameObject>();
public void tick(){
for(int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.tick();
}
}
public void render(Graphics g){
for(int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.repaint(g);
}
}
public void addObject(GameObject object){
this.object.add(object);
}
public void removeObject(GameObject object){
this.object.remove(object);
}
}
I have tried drawing with render(), render(Graphics g), repaint() and repaint(Graphics g), but nothing seems to work. I'm 99% sure that the path of my image is correct and the placeholder squares I used before I had my images work fine with both the render(Graphics g) and the repaint(Graphics g). When I launch the game I don't get any errors. Why is my image not being displayed?
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.
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
I am supposed to make a little game simulation. in this game there are three button . when user click start tank and car will close each other in 90 degrees when user click shut button tank will throw bullet to car.
i made and a simulation for this. tank throw bullet to car but when bullet crash car i couldn't this. i just need increase score of how many times tank hit car.
here is the source code
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Vehicle extends Thread {
private JPanel box;
private int XSIZE;
private int YSIZE;
private int time;
private int x;
private int y;
private int dx = 5;
private int dy = 5;
private int dim;
public Vehicle(JPanel b, int i) {
box = b;
this.dim = i;
if (i == 0) {
x = 0;
y = 100;
time = 1000;
XSIZE = 9;
YSIZE = 20;
} else {
time = 200;
y = box.getSize().height;
x = box.getSize().width / 2;
XSIZE = 6;
YSIZE = 10;
}
}
public void draw() {
Graphics g = box.getGraphics();
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
public void moveHorizontal() {
if (!box.isVisible())
return;
Graphics g = box.getGraphics();
g.setColor(Color.BLUE);
g.setXORMode(box.getBackground());
g.fillOval(x, y, XSIZE, YSIZE);
x += dx;
Dimension d = box.getSize();
if (x < 0) {
x = 0;
dx = -dx;
}
if (x + XSIZE >= d.width) {
x = d.width - XSIZE;
dx = -dx;
}
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
public JPanel getBox() {
return box;
}
public void setBox(JPanel box) {
this.box = box;
}
public void moveVertical() {
if (!box.isVisible())
return;
Graphics g = box.getGraphics();
g.setXORMode(box.getBackground());
g.fillOval(x, y, XSIZE, YSIZE);
y += dy;
Dimension d = box.getSize();
if (y < 0) {
y = 0;
dy = -dy;
}
if (y + YSIZE >= d.height) {
y = d.height - YSIZE;
dy = -dy;
}
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
public void move(int i) {
if (i == 0) {
moveHorizontal();
} else {
moveVertical();
}
}
public int getYSIZE() {
return YSIZE;
}
public void setYSIZE(int ySIZE) {
YSIZE = ySIZE;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public int getXSIZE() {
return XSIZE;
}
public void setXSIZE(int xSIZE) {
XSIZE = xSIZE;
}
public void setY(int y) {
this.y = y;
}
public void run() {
try {
draw();
for (;;) {
move(dim);
sleep(time);
}
} catch (InterruptedException e) {
}
}
}
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Bullet extends Thread {
private JPanel box;
private int XSIZE = 3;
public int getXSIZE() {
return XSIZE;
}
public void setXSIZE(int xSIZE) {
XSIZE = xSIZE;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
private int YSIZE = 1;
private int x;
private int y;
private int dx = 3;
public Bullet(JPanel b, Vehicle tank, Vehicle car) {
box = b;
x = tank.getX() + tank.getXSIZE();
if (x >= tank.getBox().getSize().width / 2)
dx = -dx;
y = tank.getY() + tank.getYSIZE() / 2;
;
}
public void draw() {
Graphics g = box.getGraphics();
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
public void move() {
if (!box.isVisible())
return;
Graphics g = box.getGraphics();
g.setColor(Color.RED);
g.setXORMode(box.getBackground());
g.fillOval(x, y, XSIZE, YSIZE);
x += dx;
Dimension d = box.getSize();
if (x < 0) {
x = 0;
}
if (x + XSIZE >= d.width) {
x = d.width - XSIZE;
}
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
public void run() {
try {
draw();
for (;;) {
move();
sleep(20);
}
} catch (InterruptedException e) {
}
}
}
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
#SuppressWarnings("serial")
public class Tank_Shut_Car_ThreadFrame extends JFrame {
private JPanel canvas;
private boolean isOn = false;
private Vehicle tank;
private Vehicle car;
private JLabel score;
public static int sc = 0;
public Tank_Shut_Car_ThreadFrame() {
setResizable(false);
setSize(600, 400);
setTitle("Tank Shut Car");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Container contentPane = getContentPane();
canvas = new JPanel();
contentPane.add(canvas, "Center");
canvas.setLayout(null);
score = new JLabel("0");
score.setBounds(527, 11, 36, 14);
canvas.add(score);
JLabel lblScore = new JLabel("score");
lblScore.setBounds(481, 11, 36, 14);
canvas.add(lblScore);
JPanel p = new JPanel();
addButton(p, "Start", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (!isOn) {
tank = new Vehicle(canvas, 0);
tank.start();
car = new Vehicle(canvas, 1);
car.start();
isOn = true;
}
}
});
addButton(p, "Shut", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (isOn) {
Bullet bullet = new Bullet(canvas, tank, car);
bullet.start();
score.setText("" + sc);
}
}
});
addButton(p, "Close", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
canvas.setVisible(false);
System.exit(0);
}
});
contentPane.add(p, "South");
}
public void addButton(Container c, String title, ActionListener a) {
JButton button = new JButton(title);
c.add(button);
button.addActionListener(a);
}
}
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
JFrame frame = new Tank_Shut_Car_ThreadFrame();
frame.setVisible(true);
}
}
Okay, so I had a play around with this (just for fun)
Now, this is far from a "proper" or "complete" game engine, but it provides a basic idea of how it might be possible to mix a core thread engine with UI components.
Rather then pasting the entire code, I've uploaded the source it to Tank.zip
But the basic engine looks like this...
public class GameEngine extends Thread {
public static final Object ASSET_LOCK = new Object();
private List<GameAsset> lstAssets;
private GameScreen screen;
public GameEngine(GameScreen screen) {
// Let the thread die when the JVM closes
setDaemon(true);
// Want to be below the UI thread (personal preference)
setPriority(NORM_PRIORITY - 1);
// A list of game assests
lstAssets = new ArrayList<GameAsset>(25);
// A reference to the screen
this.screen = screen;
// Add global key listener, this is simpler to the trying to attach a key listener
// to the screen.
Toolkit.getDefaultToolkit().addAWTEventListener(new EventHandler(), AWTEvent.KEY_EVENT_MASK);
}
public GameAsset[] getAssets() {
synchronized (ASSET_LOCK) {
return lstAssets.toArray(new GameAsset[lstAssets.size()]);
}
}
/*
* Allows for assets to be added
*/
public void addAsset(GameAsset asset) {
synchronized (ASSET_LOCK) {
lstAssets.add(asset);
}
}
#Override
public void run() {
while (true) {
try {
sleep(40);
} catch (InterruptedException ex) {
}
synchronized (ASSET_LOCK) {
GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
for (GameAsset asset : assets) {
if (lstAssets.contains(asset)) {
asset.update(this, screen);
}
}
screen.repaint(new ArrayList<GameAsset>(lstAssets));
}
}
}
/**
* Allows the removal of an asset...
*/
public void removeAsset(GameAsset asset) {
synchronized (ASSET_LOCK) {
lstAssets.remove(asset);
}
}
/**
* Key event handling...
*/
protected class EventHandler implements AWTEventListener {
#Override
public void eventDispatched(AWTEvent event) {
KeyEvent keyEvent = (KeyEvent) event;
if (keyEvent.getID() == KeyEvent.KEY_PRESSED) {
synchronized (ASSET_LOCK) {
GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
for (GameAsset asset : assets) {
if (lstAssets.contains(asset)) {
asset.processKeyPressed(GameEngine.this, screen, keyEvent);
}
}
}
} else if (keyEvent.getID() == KeyEvent.KEY_RELEASED) {
synchronized (ASSET_LOCK) {
GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
for (GameAsset asset : lstAssets) {
if (lstAssets.contains(asset)) {
asset.processKeyReleased(GameEngine.this, screen, keyEvent);
}
}
}
}
}
}
}
Swing is not thread safe. Events should be fired on the event-dispatching thread.
http://www.javamex.com/tutorials/threads/invokelater.shtml