How do you restart a Java applet? - java
I'm making a game for a school project and have been stuck on this part for a few days. How would I go about restarting the following applet? I have tried to make a restart() method, but lack the necessary skills.
package main;
import game.framework.Animation;
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.lang.Thread.State;
import java.net.URL;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JPanel;
//add speedboost
public class Main extends Applet implements Runnable, KeyListener{
enum GameState {
Running, Dead
}
static GameState state = GameState.Running;
private Background bg2, bg1;
private boolean restart = false;
private Player player;
private SpeedBoost sb1;
private Image image;
private Image backsprite1, backsprite2;
private Image player1, dad1, dad2, dad3;
private Image player2;
private Image player3;
private Image back1;
private Image back2, endscreen;
private Image back3, coin, bigcoin;
private Image back4, sbimg;
public Image tilebase, platform;
private Block block1, block2, block3, block4;
private Coin coin1, coin2, coin3, coin4, coin5;
private LargeCoin bc1;
//use for the base...
private Dad dad;
private Graphics second;
private Animation playwalk, dadwalk;
private URL base;
private Platform plat1, plat2, plat3, plat4, plat5, plat6, plat7;
public static int score = 1, coinsint = 1;
public static String score2, coins = "1";
public static int scorespeed = 1;
public int hs1, hs2, hs3, hs4, hs5, totcoins;
public String hs1s, hs2s, hs3s, hs4s, hs5s, totcoinss;
public Ends ends;
#Override
public void init() {
setSize(800, 480);
setBackground(Color.WHITE);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Game v1.2.2");
try {
base = getDocumentBase();
} catch (Exception e) {
// TODO: handle exception
}
endscreen = getImage(base, "data/endscreen.png");
coin = getImage(base, "data/coin.png");
bigcoin = getImage(base, "data/bigcoin.png");
tilebase = getImage(base, "data/tilebase.png");
platform = getImage(base, "data/blocksmall.png");
back1 = getImage(base, "data/back1.png");
back2 = getImage(base, "data/back2.png");
back3 = getImage(base, "data/back3.png");
back4 = getImage(base, "data/back4.png");`enter code here`
sbimg = getImage(base, "data/speedboost.png");
player1 = getImage(base, "data/player1.png");
player2 = getImage(base, "data/player2.png");
player3 = getImage(base, "data/player3.png");
dad1 = getImage(base, "data/dad1.png");
dad2 = getImage(base, "data/dad2.png");
dad3 = getImage(base, "data/dad3.png");
backsprite1 = back1;
backsprite2 = back2;
playwalk = new Animation();
playwalk.addFrame(player1, 80);
playwalk.addFrame(player2, 80);
playwalk.addFrame(player3, 80);
dadwalk = new Animation();
dadwalk.addFrame(dad1, 80);
dadwalk.addFrame(dad2, 80);
dadwalk.addFrame(dad3, 80);
}
public void animate() {
playwalk.update(15);
dadwalk.update(15);
}
#Override
public void start() {
state = state.Running;
ends = new Ends(-3, 0);
//create objects at positions
coin1 = new Coin(-100, -10);
coin2 = new Coin(-10, -10);
coin3 = new Coin(-10, -10);
coin4 = new Coin(-10, -10);
coin5 = new Coin(-10, -10);
player = new Player();
dad = new Dad();
bg1 = new Background(1, 0);
bg2 = new Background(2099, 0);
plat1 = new Platform(0,0);
plat2 = new Platform(-100,0);
plat3 = new Platform(-200,0);
plat4 = new Platform(-300,0);
plat5 = new Platform(-400,0);
plat6 = new Platform(-500,0);
plat7 = new Platform(-600,0);
sb1 = new SpeedBoost(-100, 0);
bc1 = new LargeCoin(-99, 0);
block1 = new Block(0, 0);
block2 = new Block(0, 0);
block3 = new Block(0, 0);
block4 = new Block(0, 0);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void run() {
if (state == GameState.Running) {
while (true) {
//selecting sprites for the background
//updates go here
if(bg1.getBgX() < -2100){
bg1.setBgX(2100);
}
if(bg2.getBgX() < -2100){
bg2.setBgX(2100);
}
//backgrounds arent working
if(bg1.getBgX() > 2000){
Random rand = new Random();
int nel = rand.nextInt(4) + 1;
if(nel == 1){
backsprite1 = back1;
}if(nel == 2){
backsprite1 = back2;
}if(nel == 3){
backsprite1 = back3;
}if(nel == 4){
backsprite1 = back4;
}
}
if(bg2.getBgX() > 2000){
Random rand = new Random();
int n1 = rand.nextInt(4) + 1;
if(n1 == 1){
backsprite2 = back1;
}if(n1 == 2){
backsprite2 = back2;
}if(n1 == 3){
backsprite2 = back3;
}if(n1 == 4){
backsprite2 = back4;
}
}
block4.update();
block3.update();
block2.update();
block1.update();
sb1.update();
bc1.update();
player.update();
dad.update();
bg1.update();
bg2.update();
coin1.update();
coin2.update();
coin3.update();
coin4.update();
coin5.update();
plat1.update();
plat2.update();
plat3.update();
plat4.update();
plat5.update();
plat6.update();
plat7.update();
if(Block.lives < 0){
state = GameState.Dead;
}
animate();
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();
}
//other updates go here
block1.update();
block2.update();
block3.update();
block4.update();
sb1.update();
bc1.update();
coin1.update();
coin2.update();
coin3.update();
coin4.update();
coin5.update();
plat1.update();
plat2.update();
plat3.update();
plat4.update();
plat5.update();
plat6.update();
plat7.update();
bg1.update();
bg2.update();
player.update();
dad.update();
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) {
if (state == GameState.Running) {
//main graphics identifyers here
// first are drawn below last
//need to make the platform lower down, see class for explanation
g.drawImage(backsprite1, bg1.getBgX(), bg1.getBgY(), this);
g.drawImage(backsprite2, bg2.getBgX(), bg2.getBgY(), this);
g.drawImage(playwalk.getImage(), player.getCenterX(), player.getCenterY(), this);
g.drawImage(platform, plat1.getCenterX(), plat1.getCenterY(), this);
g.drawImage(platform, plat2.getCenterX(), plat2.getCenterY(), this);
g.drawImage(platform, plat3.getCenterX(), plat3.getCenterY(), this);
g.drawImage(platform, plat4.getCenterX(), plat4.getCenterY(), this);
g.drawImage(platform, plat5.getCenterX(), plat5.getCenterY(), this);
g.drawImage(platform, plat6.getCenterX(), plat6.getCenterY(), this);
g.drawImage(platform, plat7.getCenterX(), plat7.getCenterY(), this);
g.drawImage(sbimg, sb1.getCenterX(), sb1.getCenterY(), this);
g.drawImage(bigcoin, bc1.centerX, bc1.centerY, this);
g.drawImage(dadwalk.getImage(), dad.centerX, dad.centerY, this);
g.drawImage(tilebase, block1.getCenterX(), block1.getCenterY(), this);
g.drawImage(tilebase, block2.getCenterX(), block2.getCenterY(), this);
g.drawImage(tilebase, block3.getCenterX(), block3.getCenterY(), this);
g.drawImage(tilebase, block4.getCenterX(), block4.getCenterY(), this);
g.drawImage(coin, coin1.getCenterX(), coin1.getCenterY(), this);
g.drawImage(coin, coin2.getCenterX(), coin2.getCenterY(), this);
g.drawImage(coin, coin3.getCenterX(), coin3.getCenterY(), this);
g.drawImage(coin, coin4.getCenterX(), coin4.getCenterY(), this);
g.drawImage(coin, coin5.getCenterX(), coin5.getCenterY(), this);
g.setColor(Color.MAGENTA);
g.drawString(score2, 700, 25);
Font font = new Font("Serif", Font.PLAIN, 36);
g.setFont(font);
g.drawString(coins, 20, 25);
}else if (state == GameState.Dead) {
totcoins += coinsint;
coinsint = 0;
hs1s = String.valueOf(hs1);
hs2s = String.valueOf(hs2);
hs3s = String.valueOf(hs3);
hs4s = String.valueOf(hs4);
hs5s = String.valueOf(hs5);
totcoinss = String.valueOf(totcoins);
if(score > hs1){
hs1 = score;
}else if(score > hs2){
hs2 = score;
}else if(score > hs3){
hs3 = score;
}else if(score > hs4){
hs4 = score;
}else if(score > hs5){
hs5 = score;
}
scorespeed = 0;
//format this shit up in here
//when restart is init, then this will be tested
g.setColor(Color.BLACK);
g.fillRect(0, 0, 800, 480);
g.setColor(Color.WHITE);
g.drawString(hs1s, 230, 220);
g.drawString(hs2s, 230, 250);
g.drawString(hs3s, 230, 280);
g.drawString(hs4s, 230, 310);
g.drawString(hs5s, 230, 340);
g.drawString(totcoinss, 700, 100);
g.drawImage(endscreen, ends.cornX, ends.cornY, this);
}
}
//fix the android stuff
#Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
player.jump();
Player.jumps += 1;
break;
}
switch (e.getKeyCode()) {
case KeyEvent.VK_SPACE:
if(state == state.Dead){
}
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
break;
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public Background getBg1() {
return bg1;
}
public void setBg1(Background bg1) {
this.bg1 = bg1;
}
public Background getBg2() {
return bg2;
}
public void setBg2(Background bg2) {
this.bg2 = bg2;
}
public Player getPlayer() {
return player;
}
public void setPlayer(Player player) {
this.player = player;
}
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
public Image getBacksprite() {
return backsprite1;
}
public void setBacksprite(Image backsprite) {
this.backsprite1 = backsprite;
}
public Image getBacksprite1() {
return backsprite1;
}
public void setBacksprite1(Image backsprite1) {
this.backsprite1 = backsprite1;
}
public Image getBacksprite2() {
return backsprite2;
}
public void setBacksprite2(Image backsprite2) {
this.backsprite2 = backsprite2;
}
public Image getPlayer1() {
return player1;
}
public void setPlayer1(Image player1) {
this.player1 = player1;
}
public Image getPlayer2() {
return player2;
}
public void setPlayer2(Image player2) {
this.player2 = player2;
}
public Image getPlayer3() {
return player3;
}
public void setPlayer3(Image player3) {
this.player3 = player3;
}
public Image getBack1() {
return back1;
}
public void setBack1(Image back1) {
this.back1 = back1;
}
public Image getBack2() {
return back2;
}
public void setBack2(Image back2) {
this.back2 = back2;
}
public Image getBack3() {
return back3;
}
public void setBack3(Image back3) {
this.back3 = back3;
}
public Image getBack4() {
return back4;
}
public void setBack4(Image back4) {
this.back4 = back4;
}
public Graphics getSecond() {
return second;
}
public void setSecond(Graphics second) {
this.second = second;
}
public Animation getPlaywalk() {
return playwalk;
}
public void setPlaywalk(Animation playwalk) {
this.playwalk = playwalk;
}
public URL getBase() {
return base;
}
public void setBase(URL base) {
this.base = base;
}
public static Image getTilebase() {
// TODO Auto-generated method stub
return null;
}
public GameState getState() {
return state;
}
public void setState(GameState state) {
this.state = state;
}
public SpeedBoost getSb1() {
return sb1;
}
public void setSb1(SpeedBoost sb1) {
this.sb1 = sb1;
}
public Image getCoin() {
return coin;
}
public void setCoin(Image coin) {
this.coin = coin;
}
public Image getSbimg() {
return sbimg;
}
public void setSbimg(Image sbimg) {
this.sbimg = sbimg;
}
public Image getPlatform() {
return platform;
}
public void setPlatform(Image platform) {
this.platform = platform;
}
public Block getBlock1() {
return block1;
}
public void setBlock1(Block block1) {
this.block1 = block1;
}
public Block getBlock2() {
return block2;
}
public void setBlock2(Block block2) {
this.block2 = block2;
}
public Block getBlock3() {
return block3;
}
public void setBlock3(Block block3) {
this.block3 = block3;
}
public Block getBlock4() {
return block4;
}
public void setBlock4(Block block4) {
this.block4 = block4;
}
public Coin getCoin1() {
return coin1;
}
public void setCoin1(Coin coin1) {
this.coin1 = coin1;
}
public Coin getCoin2() {
return coin2;
}
public void setCoin2(Coin coin2) {
this.coin2 = coin2;
}
public Coin getCoin3() {
return coin3;
}
public void setCoin3(Coin coin3) {
this.coin3 = coin3;
}
public Coin getCoin4() {
return coin4;
}
public void setCoin4(Coin coin4) {
this.coin4 = coin4;
}
public Coin getCoin5() {
return coin5;
}
public void setCoin5(Coin coin5) {
this.coin5 = coin5;
}
public Platform getPlat1() {
return plat1;
}
public void setPlat1(Platform plat1) {
this.plat1 = plat1;
}
public Platform getPlat2() {
return plat2;
}
public void setPlat2(Platform plat2) {
this.plat2 = plat2;
}
public Platform getPlat3() {
return plat3;
}
public void setPlat3(Platform plat3) {
this.plat3 = plat3;
}
public Platform getPlat4() {
return plat4;
}
public void setPlat4(Platform plat4) {
this.plat4 = plat4;
}
public Platform getPlat5() {
return plat5;
}
public void setPlat5(Platform plat5) {
this.plat5 = plat5;
}
public Platform getPlat6() {
return plat6;
}
public void setPlat6(Platform plat6) {
this.plat6 = plat6;
}
public Platform getPlat7() {
return plat7;
}
public void setPlat7(Platform plat7) {
this.plat7 = plat7;
}
public static int getScore() {
return score;
}
public static void setScore(int score) {
Main.score = score;
}
public static int getCoinsint() {
return coinsint;
}
public static void setCoinsint(int coinsint) {
Main.coinsint = coinsint;
}
public static String getScore2() {
return score2;
}
public static void setScore2(String score2) {
Main.score2 = score2;
}
public static String getCoins() {
return coins;
}
public static void setCoins(String coins) {
Main.coins = coins;
}
public static int getScorespeed() {
return scorespeed;
}
public static void setScorespeed(int scorespeed) {
Main.scorespeed = scorespeed;
}
public void setTilebase(Image tilebase) {
this.tilebase = tilebase;
}
}
A good approach might be to use the methods like this:
init (should be called once, and by the browser only). Set up any common GUI elements and call the startNewGame() method.
start (called when the user restores the browser). Un-pause the action (paused in stop) and continue the game.
stop pause the current game.
startNewGame() set the initial lives, layout of pieces/characters, score etc.
When the user wants to start a new game, also call startNewGame().
I know this is an old question.
but the format of the applet above seems to be the issue. I would use something basic that would allow more control of the applet.
"Namely using a while(true) is never a good option in my opinion"
public class TestAppletCycle extends JApplet implements Runnable {
private Thread thread;
private boolean running;
#Override
public void init() {
// Init Game
}
#Override
public void start() {
if(!running) {
running = true;
thread = new Thread(this);
thread.start();
}
}
#Override
public void run() {
while(running) {
// Game Loop
}
}
#Override
public void stop() {
logger.log(Level.INFO, "TestAppletCycle.stop();");
if(running) {
running = false;
try {
thread.join();
} catch(Exception e) {
}
}
}
#Override
public void destroy() {
// Clean Up Game
}
}
Now to restart the applet you only need to stop and start the applet.
Related
Java Swing MVC based Snake game. Issue switching difficulty level
I am writing a game for a snake in Java Swing using the MVC pattern. The code of Controller and View are shown below. I am trying to implement a button that will help player choose a difficulty level. The difficulty level is controlled by a timer in the Controller class. I am beginner in Java and help is appreciated. Code of Controller class: public class Controller implements KeyListener, ActionListener{ private Renderer renderer; private Timer mainTimer; private Snake snake; public Controller() { snake = new Snake(); renderer = new Renderer(this); this.renderer.addKeyListener(this); this.mainTimer = new Timer(150, this); mainTimer.start(); } public void stopGame(){ mainTimer.stop(); } public void startGame(){ mainTimer.start(); } public void keyPressed(KeyEvent e) { snake.onMove(e.getKeyCode()); } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } public void actionPerformed(ActionEvent arg0) { renderer.moveForward(); } public Snake getSnake(){ return snake; } View class: class Renderer extends JFrame { private final int WIDTH = 500; private final int HEIGHT = 300; private Snake snake; public int LevelConst; private Controller controller; public JPanel pamel1, panel2; public JButton[] ButtonBody = new JButton[200]; public JButton bonusfood; public JTextArea textArea; public Fruit fruit; public int score; public Random random = new Random(); public JMenuBar mybar; public JMenu game, help, levels; public void initializeValues() { score = 0; } Renderer(Controller controller) { super("Snake: Demo"); this.controller = controller; snake = controller.getSnake(); fruit = new Fruit(); setBounds(200, 200, 506, 380); creatbar(); initializeValues(); // GUI pamel1 = new JPanel(); panel2 = new JPanel(); // Scoreboard setResizable(false); textArea = new JTextArea("Счет : " + score); textArea.setEnabled(false); textArea.setBounds(400, 400, 100, 100); textArea.setBackground(Color.GRAY); // Eating and growing up bonusfood = new JButton(); bonusfood.setEnabled(false); // createFirstSnake(); pamel1.setLayout(null); panel2.setLayout(new GridLayout(0, 1)); pamel1.setBounds(0, 0, WIDTH, HEIGHT); pamel1.setBackground(Color.GRAY); panel2.setBounds(0, HEIGHT, WIDTH, 30); panel2.setBackground(Color.black); panel2.add(textArea); // will contain score board // end of UI design getContentPane().setLayout(null); getContentPane().add(pamel1); getContentPane().add(panel2); show(); setDefaultCloseOperation(EXIT_ON_CLOSE); } public void createFirstSnake() { for (int i = 0; i < 3; i++) { ButtonBody[i] = new JButton(" " + i); ButtonBody[i].setEnabled(false); pamel1.add(ButtonBody[i]); ButtonBody[i].setBounds(snake.x[i], snake.y[i], 10, 10); snake.x[i + 1] = snake.x[i] - 10; snake.y[i + 1] = snake.y[i]; } } // Creating of menu bar public void creatbar() { mybar = new JMenuBar(); game = new JMenu("Game"); JMenuItem newgame = new JMenuItem("New Game"); JMenuItem exit = new JMenuItem("Exit"); newgame.addActionListener(e -> reset()); exit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); game.add(newgame); game.addSeparator(); game.add(exit); mybar.add(game); levels = new JMenu("Level"); JMenuItem easy = new JMenuItem("Easy"); easy.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { LevelConst = 0; } }); JMenuItem middle = new JMenuItem("Medium"); middle.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { LevelConst = 1; } }); JMenuItem hard = new JMenuItem("Hard"); hard.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { LevelConst = 2; } }); levels.add(easy); levels.addSeparator(); levels.add(middle); levels.addSeparator(); levels.add(hard); mybar.add(levels); help = new JMenu("Help"); JMenuItem creator = new JMenuItem("There must be a button"); creator.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(pamel1, "Random text"); } }); help.add(creator); mybar.add(help); setJMenuBar(mybar); } void reset() { initializeValues(); pamel1.removeAll(); controller.stopGame(); createFirstSnake(); textArea.setText("Score: " + score); controller.startGame(); } void growup() { ButtonBody[snake.getLength()] = new JButton(" " + snake.getLength()); ButtonBody[snake.getLength()].setEnabled(false); pamel1.add(ButtonBody[snake.getLength()]); ButtonBody[snake.getLength()].setBounds(snake.getPointBody()[snake.getLength() - 1].x, snake.getPointBody()[snake.getLength() - 1].y, 10, 10); snake.setLength(snake.getLength() + 1); } void moveForward() { for (int i = 0; i < snake.getLength(); i++) { snake.getPointBody()[i] = ButtonBody[i].getLocation(); } snake.x[0] += snake.getDirectionX(); snake.y[0] += snake.getDirectionY(); ButtonBody[0].setBounds(snake.x[0], snake.y[0], 10, 10); for (int i = 1; i < snake.getLength(); i++) { ButtonBody[i].setLocation(snake.getPointBody()[i - 1]); } if (snake.x[0] == WIDTH) { controller.stopGame(); } else if (snake.x[0] == 0) { controller.stopGame(); } else if (snake.y[0] == HEIGHT) { controller.stopGame(); } else if (snake.y[0] == 0) { controller.stopGame(); } createFruit(); collisionFruit(); pamel1.repaint(); } private void collisionFruit() { if (fruit.isFood()) { if (fruit.getPoint().x == snake.x[0] && fruit.getPoint().y == snake.y[0]) { pamel1.remove(bonusfood); score += 1; growup(); textArea.setText("Score: " + score); fruit.setFood(false); } } } private void createFruit() { if (!fruit.isFood()) { pamel1.add(bonusfood); bonusfood.setBounds((10 * random.nextInt(50)), (10 * random.nextInt(25)), 10, 10); fruit.setPoint(bonusfood.getLocation()); fruit.setFood(true); } } Class Model: Fruit: public class Fruit { private Point point; private boolean food; public Fruit() { point = new Point(); } public Point getPoint() { return point; } public void setPoint(Point point) { this.point = point; } public boolean isFood() { return food; } public void setFood(boolean food) { this.food = food; } Class Model: Snake: public class Snake { private Point[] pointBody = new Point[300]; private int length; private boolean isLeft; private boolean isRight; private boolean isUp; private boolean isDown; private int directionX; private int directionY; public int[] x = new int[300]; public int[] y = new int[300]; public Snake() { isLeft = false; isRight = true; isUp = true; isDown = true; setDirectionX(10); setDirectionY(0); length = 3; y[0] = 100; x[0] = 150; } public void onMove(int side) { switch (side) { case KeyEvent.VK_LEFT: if (isLeft) { setDirectionX(-10); setDirectionY(0); isRight = false; isUp = true; isDown = true; } break; case KeyEvent.VK_UP: if (isUp) { setDirectionX(0); setDirectionY(-10); isDown = false; isRight = true; isLeft = true; } break; case KeyEvent.VK_DOWN: if (isDown) { setDirectionX(0); setDirectionY(+10); isUp = false; isRight = true; isLeft = true; } break; case KeyEvent.VK_RIGHT: if (isRight) { setDirectionX(+10); setDirectionY(0); isLeft = false; isUp = true; isDown = true; } break; default: break; } } public int getLength() { return length; } public void setLength(int length) { this.length = length; } public Point[] getPointBody() { return pointBody; } public void setPointBody(Point[] pointBody) { this.pointBody = pointBody; } public int getDirectionX() { return directionX; } public void setDirectionX(int directionX) { this.directionX = directionX; } public int getDirectionY() { return directionY; } public void setDirectionY(int directionY) { this.directionY = directionY; } Main: public class Main { public static void main(String[] args) { new Controller(); } }
Make a property change listener in Controller: public PropertyChangeListener getViewListener() { return new ViewListener(); } private class ViewListener implements PropertyChangeListener { #Override public void propertyChange(PropertyChangeEvent evt) { System.out.println("Level is "+ evt.getNewValue()); //use level } } Invoke createbar by: creatbar(controller.getViewListener()); And use listener : public void creatbar(PropertyChangeListener listener) { mybar = new JMenuBar(); mybar.addPropertyChangeListener(listener);//add listener to menu bar game = new JMenu("Game"); JMenuItem newgame = new JMenuItem("New Game"); JMenuItem exit = new JMenuItem("Exit"); newgame.addActionListener(e -> reset()); exit.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { System.exit(0); } }); game.add(newgame); game.addSeparator(); game.add(exit); mybar.add(game); levels = new JMenu("Level"); JMenuItem easy = new JMenuItem("Easy"); easy.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { mybar.firePropertyChange("Level", LevelConst, 0); //use listener LevelConst = 0; } }); JMenuItem middle = new JMenuItem("Medium"); middle.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { mybar.firePropertyChange("Level", LevelConst, 1); LevelConst = 1; } }); JMenuItem hard = new JMenuItem("Hard"); hard.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { mybar.firePropertyChange("Level", LevelConst, 2); LevelConst = 2; } }); levels.add(easy); levels.addSeparator(); levels.add(middle); levels.addSeparator(); levels.add(hard); mybar.add(levels); help = new JMenu("Help"); JMenuItem creator = new JMenuItem("There must be a button"); creator.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(pamel1, "Random text"); } }); help.add(creator); mybar.add(help); setJMenuBar(mybar); }
How to move magic tile by tile on a game?
I have a 2D tile game and my hero can use magic(in this case fire), and the goal is to make the fireball move tile by tile until it finds either a wall or an enemy and to make the game stop while the fire is moving. I already have the fire moving and stopping if there is a wall or an enemy(and damaging the enemy). The problem is i can't seem to make the game show the fireball change from tile to tile, which means when i launch the fireball the game automatically shows me the fireball in its last position before collision, and then it disappears from the tiles. Anyone got any ideas as to what I am doing wrong or what i should do to make the game update the fire tile by tile? (Btw i thought it might have something to do with my observer but I've tried thread.sleep and wait() and it isn't quite working, maybe I am doing it the wrong way).Thank you for your help and if you guys need any code just ask. public class ImageMatrixGUI extends Observable { private static final ImageMatrixGUI INSTANCE = new ImageMatrixGUI(); private final String IMAGE_DIR = "images"; private final int SQUARE_SIZE; private final int N_SQUARES_WIDTH; private final int N_SQUARES_HEIGHT; private JFrame frame; private JPanel panel; private JPanel info; private Map<String, ImageIcon> imageDB = new HashMap<String, ImageIcon>(); private List<ImageTile> images = new ArrayList<ImageTile>(); private List<ImageTile> statusImages = new ArrayList<ImageTile>(); private int lastKeyPressed; private boolean keyPressed; private ImageMatrixGUI() { SQUARE_SIZE = 48; N_SQUARES_WIDTH = 10; N_SQUARES_HEIGHT = 10; init(); } public static ImageMatrixGUI getInstance() { return INSTANCE; } public void setName(final String name) { frame.setTitle(name); } private void init() { frame = new JFrame(); panel = new RogueWindow(); info = new InfoWindow(); panel.setPreferredSize(new Dimension(N_SQUARES_WIDTH * SQUARE_SIZE, N_SQUARES_HEIGHT * SQUARE_SIZE)); info.setPreferredSize(new Dimension(N_SQUARES_WIDTH * SQUARE_SIZE, SQUARE_SIZE)); info.setBackground(Color.BLACK); frame.add(panel); frame.add(info, BorderLayout.NORTH); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); initImages(); new KeyWatcher().start(); frame.addKeyListener(new KeyListener() { #Override public void keyTyped(KeyEvent e) { } #Override public void keyReleased(KeyEvent e) { } #Override public void keyPressed(KeyEvent e) { lastKeyPressed = e.getKeyCode(); keyPressed = true; releaseObserver(); } }); } synchronized void releaseObserver() { notify(); } synchronized void waitForKey() throws InterruptedException { while (!keyPressed) { wait(); } setChanged(); notifyObservers(lastKeyPressed); keyPressed = false; } private void initImages() { File dir = new File(IMAGE_DIR); for (File f : dir.listFiles()) { assert (f.getName().lastIndexOf('.') != -1); imageDB.put(f.getName().substring(0, f.getName().lastIndexOf('.')), new ImageIcon(IMAGE_DIR + "/" + f.getName())); } } public void go() { frame.setVisible(true); } public void newImages(final List<ImageTile> newImages) { synchronized (images) { // Added 16-Mar-2016 if (newImages == null) return; if (newImages.size() == 0) return; for (ImageTile i : newImages) { if (!imageDB.containsKey(i.getName())) { throw new IllegalArgumentException("No such image in DB " + i.getName()); } } images.addAll(newImages); } } public void removeImage(final ImageTile image) { synchronized (images) { images.remove(image); } } public void addImage(final ImageTile image) { synchronized (images) { images.add(image); } } public void clearImages() { synchronized (images) { images.clear(); } public void newStatusImages(final List<ImageTile> newImages) { synchronized (statusImages) { if (newImages == null) return; if (newImages.size() == 0) return; for (ImageTile i : newImages) { if (!imageDB.containsKey(i.getName())) { throw new IllegalArgumentException("No such image in DB " + i.getName()); } } statusImages.addAll(newImages); } } public void removeStatusImage(final ImageTile image) { synchronized (statusImages) { statusImages.remove(image); } public void addStatusImage(final ImageTile image) { synchronized (statusImages) { statusImages.add(image); } } public void clearStatus() { synchronized (statusImages) { statusImages.clear(); } } #SuppressWarnings("serial") private class RogueWindow extends JPanel { #Override public void paintComponent(Graphics g) { // System.out.println("Thread " + Thread.currentThread() + " // repainting"); synchronized (images) { for (ImageTile i : images) { g.drawImage(imageDB.get(i.getName()).getImage(), i.getPosition().getX() * SQUARE_SIZE, i.getPosition().getY() * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE, frame); } } } } #SuppressWarnings("serial") private class InfoWindow extends JPanel { #Override public void paintComponent(Graphics g) { synchronized (statusImages) { for (ImageTile i : statusImages) g.drawImage(imageDB.get(i.getName()).getImage(), i.getPosition().getX() * SQUARE_SIZE, 0, SQUARE_SIZE, SQUARE_SIZE, frame); } } } private class KeyWatcher extends Thread { public void run() { try { while (true) waitForKey(); } catch (InterruptedException e) { } } } public void update() { frame.repaint(); } public void dispose() { images.clear(); statusImages.clear(); imageDB.clear(); frame.dispose(); } public Dimension getGridDimension() { return new Dimension(N_SQUARES_WIDTH, N_SQUARES_HEIGHT); } public void update(Observable arg0, Object arg1) { Integer keycode = (Integer) arg1; if (keycode == KeyEvent.VK_DOWN || keycode == KeyEvent.VK_UP || keycode == KeyEvent.VK_LEFT || keycode == KeyEvent.VK_RIGHT){ moveTheHero(keycode); } if(keycode == KeyEvent.VK_1 || keycode == KeyEvent.VK_2 || keycode == KeyEvent.VK_3){ System.out.println("Key pressed " + KeyEvent.getKeyText(keycode)); dropItem(keycode); } if(keycode == KeyEvent.VK_SPACE){ System.out.println("Key pressed " + KeyEvent.getKeyText(keycode)); launchMagic(); } } public void launchMagic(){ if(hero.getMagic()!=0){ hero.removeStatus(hero.getMagic()-1); hero.loseMagic(); Fire fire = new Fire(hero.getPosition()); fire.changeInGame(); Direction direction = fire.closestEnemyDirection(currentRoom); currentRoom.getTiles().add(fire); while(fire.getInGame()){ fire.move(currentRoom, direction); } currentRoom.removeTiles(fire.getName(), fire.getPosition()); manageEnemies(); gui.newStatusImages(hero.getStatus()); gui.newImages(currentRoom.getTiles()); }else System.out.println("You don't have any magic"); }
2D AI Fighting game, I need threads so that the human player and AI can both move at once
//This is the human class //I have added runnable method to make it work but the AI is not moving. import java.awt.Graphics2D; import java.awt.event.KeyEvent; import java.util.Random; import java.awt.Color; public class Human implements Runnable{ private double position=100000; private double xa=0; private int attack=0; private Game game; private long time; private long lastTime; private long MIN_DELAY; private int health; private int combo; private Random r; Thread thread; public void start(){ thread = new Thread (this); thread.start(); public void stop(){ thread.stop(); } public void run1(){ Thread.currentThread().setPriority(Thread.MIN_PRIORITY); while (true) { game.move(); if (Game.() < 0){ } try { Thread.sleep (10); } catch (InterruptedException ex) { break; } Thread.currentThread().setPriority(Thread.MAX_PRIORITY); } } public Human(Game game){ this.game = game; MIN_DELAY = 150; lastTime=0; health=100; combo=0; r = new Random(); } public Human getPlayer(){ return this; } public double getPosition(){ return position; } public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_LEFT){ xa = -1; } if (e.getKeyCode() == KeyEvent.VK_RIGHT){ xa = 1; } if(e.getKeyCode()== KeyEvent.VK_Z){ attack = 1; } if(e.getKeyCode()== KeyEvent.VK_X){ attack = 2; } if(e.getKeyCode()== KeyEvent.VK_C){ attack = 3; } } public String printHealth(){ String st = "Human Health: "; st = st + Integer.toString(health); return st; } public String printCombo(){ String st = "Combo: "; st = st + Integer.toString(combo); return st; } public boolean isAlive(){ if(health>0){ return true; }else{ return false; } } public int attack(){ int dam = 0; time = System.currentTimeMillis(); if(time-lastTime>MIN_DELAY){ System.out.println("COMBO" + combo); if(combo<3){ if(attack==1){ System.out.println("Human Punch"); dam = r.nextInt(6-1)+1;; combo++; }else if(attack==2){ System.out.println("Human Kick"); dam = r.nextInt(11-5)+5; combo++; }else if(attack==3){ System.out.println("Human Uppercut"); dam = r.nextInt(16-10)+10; combo++; } }else{ if(attack == 1){ System.out.println(" SUPER Human PUNCH"); dam = r.nextInt(11-1)+1; combo = 0; }else if(attack ==2){ System.out.println(" SUPER Human KICK"); dam = r.nextInt(21-10)+10; combo = 0; }else if(attack == 3){ System.out.println(" SUPER Human UPPERCUT"); dam = r.nextInt(31-20)+20; combo = 0; } } } lastTime = time; return dam; } public void keyReleased(KeyEvent e) { xa = 0; attack = 0; } public int getAttack(){ return attack; } public void paint(Graphics2D g) { g.fillRect(position-30, 200, 30, 30); } public void move(double opp) { //if(time-lastTime>mDelay){ if (position + xa > 30 && position + xa < opp-17000) position = position + xa/500; //} } public int getHealth(){ return health; } public void takeHealth(int dam){ health = health - dam; combo = 0; } // private Thread t; public void run() { try { move(game.getAIPosition()); // Let the thread sleep for a while. Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Human Thread interrupted."); } System.out.println("Human Thread exiting."); } /*public void start () { System.out.println("Starting Human" ); if (t == null) { t = new Thread (this); t.start (); } }*/`` // This is the game class import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.geom.Ellipse2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; #SuppressWarnings("serial") public class Game extends JPanel{ public Human human = new Human(this); public AIPlayer ai = new AIPlayer(this); public Game(){ setPreferredSize(new Dimension(WIDTH, HEIGHT)); setFocusable(true); requestFocus(); init(); addKeyListener(new KeyListener() { #Override public void keyTyped(KeyEvent e) { } #Override public void keyReleased(KeyEvent e) { human.keyReleased(e); } #Override public void keyPressed(KeyEvent e) { human.keyPressed(e); } }); setFocusable(true); } double x=ai.getPosition(); int z=75; //Enemy Position int y = 200; public void move(){ human.move(ai.getPosition()); ai.move((ai.getPosition()-human.getPosition()), human.getHealth(), human.getPosition()); //CAN'T GET THIS TO WORK WITH HUMAN MOVING System.out.println("Human position: " + human.getPosition()); System.out.println("AI Position: " + ai.getPosition()); System.out.println("Range: " + (ai.getPosition()-human.getPosition())); } public void makeSound(){ Random r = new Random(); int x = r.nextInt(10); if(x==5 || x==6){ ai.makeSound(human.getHealth()); } } public double getAIPosition(){ return ai.getPosition(); } public double getHumanPosition(){ return human.getPosition(); } public int getHumanHealth(){ return human.getHealth(); } public double getDistance(){ return (ai.getPosition()-human.getPosition()); } public void attack(){ int hDec = human.getAttack(); System.out.println("Human Decision: " + hDec); if(checkDistance(hDec)){ ai.takeHealth(human.attack()); } human.takeHealth(ai.attack(ai.getPosition()-human.getPosition())); ai.attack(ai.getPosition()-human.getPosition()); } public boolean checkDistance(int mve){ double dist = ai.getPosition() - human.getPosition(); if(mve==1 && dist<=25364){ return true; }else if(mve ==2 && dist<=29040){ return true; }else if(mve==3 && dist<=20536){ return true; }else{ return false; } } public void decreaseAnger(){ ai.decreaseAnger(); } public boolean gameAlive(){ if(ai.isAlive()&&human.isAlive()){ return true; }else{ return false; } } public void displayDetails(Graphics g){ Font myFont = new Font("Courier New", 1, 17); g.setColor(Color.YELLOW); g.setFont(myFont); g.drawString(human.printHealth(), 10,15); g.drawString(human.printCombo(), 10, 30); g.drawString(ai.printHealth(), 550,15); g.drawString(ai.printCombo(), 550, 30); g.drawString(ai.printAnger(), 550, 45); } public static void main(String[] args) throws Exception { TODO Auto-generated method stub JFrame frame = new JFrame("Mini Tekken"); Game game = new Game(); frame.add(game); frame.setSize(300, 300); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); while (game.gameAlive()) { game.move(); game.attack(); game.decreaseAnger(); game.repaint(); game.makeSound(); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args){ Game game = new Game(); JFrame window = new JFrame("Mini-Tekken"); window.setContentPane(game); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setResizable(false); window.pack(); window.setLocationRelativeTo(null); window.setVisible(true); while(game.gameAlive()){ game.move(); game.attack(); game.decreaseAnger(); game.makeSound(); game.repaint(); } } //Dimensions public static final int WIDTH = 736; public static final int HEIGHT = 309; BufferedImage background; BufferedImage playerOne; BufferedImage playerTwo; public void paintComponent(Graphics g){ super.paintComponent(g); if (background != null) { g.drawImage(background, 0, 0, null); } if(playerOne != null){ g.drawImage(playerOne, ((int)human.getPosition()/500), 200, null); } if(playerTwo != null){ g.drawImage(playerTwo, ((int)ai.getPosition()/500), 210, null); } displayDetails(g); } private void init() { try { background = ImageIO.read(getClass().getResourceAsStream("/images/background.jpg")); playerOne = ImageIO.read(getClass().getResourceAsStream("/images/p1.fw.png")); playerTwo = ImageIO.read(getClass().getResourceAsStream("/images/p2.fw.png")); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
How to improve character control for my 3D game?
Since I changed from the helper class CharacterControl to the new BetterCharacterControl I notice some improvements such as pushing other characters is working but my main character has started sliding over steps and can't climb higher steps. I must jump the step above which is not the right way of playing, it should be just walking over. The old helper class CharacterControl had a default way of not sliding, just walking over steps and I think it can be corrected by altering the code where I create the main character. private void createNinja() { ninjaNode = (Node) assetManager .loadModel("Models/Ninja/Ninja.mesh.xml"); ninjaNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); ninjaNode.setLocalScale(0.06f); ninjaNode.setLocalTranslation(new Vector3f(55, 3.3f, -60)); ninjaControl = new BetterCharacterControl(2, 4, 0.5f); ninjaControl.setJumpForce(new Vector3f(6, 6, 6)); ninjaNode.addControl(ninjaControl); rootNode.attachChild(ninjaNode); bulletAppState.getPhysicsSpace().add(ninjaControl); getPhysicsSpace().add(ninjaControl); animationControl = ninjaNode.getControl(AnimControl.class); animationChannel = animationControl.createChannel(); } The complete code is package adventure; import com.jme3.system.AppSettings; import java.io.File; import com.jme3.renderer.queue.RenderQueue; import com.jme3.renderer.queue.RenderQueue.ShadowMode; import com.jme3.animation.AnimChannel; import com.jme3.animation.AnimControl; import com.jme3.animation.AnimEventListener; import com.jme3.animation.LoopMode; import com.jme3.app.SimpleApplication; import com.jme3.asset.BlenderKey; import com.jme3.asset.plugins.HttpZipLocator; import com.jme3.asset.plugins.ZipLocator; import com.jme3.bullet.BulletAppState; import com.jme3.bullet.PhysicsSpace; import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; import com.jme3.bullet.control.BetterCharacterControl; import com.jme3.bullet.control.CharacterControl; import com.jme3.bullet.control.RigidBodyControl; import com.jme3.input.ChaseCamera; import com.jme3.input.KeyInput; import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.KeyTrigger; import com.jme3.light.AmbientLight; import com.jme3.light.DirectionalLight; import com.jme3.material.MaterialList; import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; import com.jme3.post.FilterPostProcessor; import com.jme3.post.filters.BloomFilter; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.plugins.ogre.OgreMeshKey; import com.jme3.input.controls.MouseButtonTrigger; import com.jme3.input.MouseInput; public class PyramidLevel extends SimpleApplication implements ActionListener, AnimEventListener { private Node gameLevel; private static boolean useHttp = false; private BulletAppState bulletAppState; private AnimChannel channel; private AnimControl control; // character private BetterCharacterControl goblinControl; private BetterCharacterControl ninjaControl; private Node ninjaNode; boolean rotate = false; private Vector3f walkDirection = new Vector3f(0, 0, 0); private Vector3f viewDirection = new Vector3f(1, 0, 0); private boolean leftStrafe = false, rightStrafe = false, forward = false, backward = false, leftRotate = false, rightRotate = false; private Node goblinNode; Spatial goblin; RigidBodyControl terrainPhysicsNode; // animation AnimChannel animationChannel; AnimChannel shootingChannel; AnimControl animationControl; float airTime = 0; // camera private boolean left = false, right = false, up = false, down = false, attack = false; ChaseCamera chaseCam; private boolean walkMode = true; FilterPostProcessor fpp; private Spatial sceneModel; private RigidBodyControl landscape; public static void main(String[] args) { File file = new File("quake3level.zip"); if (!file.exists()) { useHttp = true; } PyramidLevel app = new PyramidLevel(); AppSettings settings = new AppSettings(true); settings.setTitle("Dungeon World"); settings.setSettingsDialogImage("Interface/splash.png"); app.setSettings(settings); app.start(); } #Override public void simpleInitApp() { this.setDisplayStatView(false); bulletAppState = new BulletAppState(); bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); stateManager.attach(bulletAppState); bulletAppState.setDebugEnabled(false); setupKeys(); DirectionalLight dl = new DirectionalLight(); dl.setColor(ColorRGBA.White.clone().multLocal(2)); dl.setDirection(new Vector3f(-1, -1, -1).normalize()); rootNode.addLight(dl); AmbientLight am = new AmbientLight(); am.setColor(ColorRGBA.White.mult(2)); rootNode.addLight(am); if (useHttp) { assetManager .registerLocator( "http://jmonkeyengine.googlecode.com/files/quake3level.zip", HttpZipLocator.class); } else { assetManager.registerLocator("quake3level.zip", ZipLocator.class); } // create the geometry and attach it MaterialList matList = (MaterialList) assetManager .loadAsset("Scene.material"); OgreMeshKey key = new OgreMeshKey("main.meshxml", matList); gameLevel = (Node) assetManager.loadAsset(key); gameLevel.setLocalScale(0.1f); gameLevel.addControl(new RigidBodyControl(0)); getPhysicsSpace().addAll(gameLevel); rootNode.attachChild(gameLevel); getPhysicsSpace().addAll(gameLevel); createCharacters(); setupAnimationController(); setupChaseCamera(); setupFilter(); } private void setupFilter() { FilterPostProcessor fpp = new FilterPostProcessor(assetManager); BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects); fpp.addFilter(bloom); viewPort.addProcessor(fpp); } private PhysicsSpace getPhysicsSpace() { return bulletAppState.getPhysicsSpace(); } private void setupKeys() { inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T)); inputManager.addListener(this, "wireframe"); inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A)); inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D)); inputManager.addMapping("CharUp", new KeyTrigger(KeyInput.KEY_W)); inputManager.addMapping("CharDown", new KeyTrigger(KeyInput.KEY_S)); inputManager .addMapping("CharSpace", new KeyTrigger(KeyInput.KEY_SPACE)); inputManager.addMapping("CharShoot", new MouseButtonTrigger( MouseInput.BUTTON_LEFT)); inputManager.addListener(this, "CharLeft"); inputManager.addListener(this, "CharRight"); inputManager.addListener(this, "CharUp"); inputManager.addListener(this, "CharDown"); inputManager.addListener(this, "CharSpace"); inputManager.addListener(this, "CharShoot"); } private void createNinja() { ninjaNode = (Node) assetManager .loadModel("Models/Ninja/Ninja.mesh.xml"); ninjaNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); ninjaNode.setLocalScale(0.06f); ninjaNode.setLocalTranslation(new Vector3f(55, 3.3f, -60)); ninjaControl = new BetterCharacterControl(2, 4, 0.5f); ninjaControl.setJumpForce(new Vector3f(6, 6, 6)); ninjaNode.addControl(ninjaControl); rootNode.attachChild(ninjaNode); bulletAppState.getPhysicsSpace().add(ninjaControl); getPhysicsSpace().add(ninjaControl); animationControl = ninjaNode.getControl(AnimControl.class); animationChannel = animationControl.createChannel(); } private void createGoblin() { goblinNode = (Node) assetManager .loadModel("objects/goblin.j3o"); goblinNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); goblinNode.setLocalScale(4f); goblinNode.setLocalTranslation(new Vector3f(51.5f, 3.3f, -60)); goblinControl = new BetterCharacterControl(2, 4, 0.5f); goblinControl.setJumpForce(new Vector3f(6, 6, 6)); goblinNode.addControl(goblinControl); rootNode.attachChild(goblinNode); bulletAppState.getPhysicsSpace().add(goblinControl); getPhysicsSpace().add(goblinControl); animationControl = goblinNode.getControl(AnimControl.class); animationChannel = animationControl.createChannel(); } private void createCharacters() { CapsuleCollisionShape capsule = new CapsuleCollisionShape(0.05f, 0.05f); createNinja(); ninjaControl.setViewDirection(new Vector3f(0, 0, 1)); //getPhysicsSpace().add(ninjaControl); createGoblin(); BlenderKey blenderKey = new BlenderKey("Models/Oto/Oto.mesh.xml"); Spatial man = (Spatial) assetManager.loadModel(blenderKey); man.setLocalTranslation(new Vector3f(69, 15, -60)); man.setShadowMode(ShadowMode.CastAndReceive); rootNode.attachChild(man); //goblin = assetManager.loadModel("objects/goblin.j3o"); //goblin.scale(4f, 4f, 4f); //goblinControl = new BetterCharacterControl(2,3,0.5f); //goblin.addControl(goblinControl); //goblinControl.setPhysicsLocation(new Vector3f(60, 3.5f, -60)); //goblin.setLocalTranslation(new Vector3f(150,70.5f, -5)); //control = goblin.getControl(AnimControl.class); //control.addListener(this); //channel = control.createChannel(); // for (String anim : control.getAnimationNames()) // System.out.println("goblin can:"+anim); //channel.setAnim("walk"); //goblin.setLocalTranslation(new Vector3f(51.5f, 3, -55)); //rootNode.attachChild(goblin); //getPhysicsSpace().add(goblinControl); Spatial monster = assetManager .loadModel("objects/creatures/monster/monster.packed.j3o"); Spatial monster2 = assetManager.loadModel("Models/Jaime/Jaime.j3o"); monster2.scale(5f, 5f, 5f); monster.scale(2f, 2f, 2f); monster.setLocalTranslation(new Vector3f(53, 3, -55)); monster2.setLocalTranslation(new Vector3f(48, 3, -55)); rootNode.attachChild(monster2); rootNode.attachChild(monster); } private void setupChaseCamera() { flyCam.setEnabled(false); chaseCam = new ChaseCamera(cam, ninjaNode, inputManager); chaseCam.setDefaultDistance(37); } private void setupAnimationController() { animationControl = ninjaNode.getControl(AnimControl.class); animationControl.addListener(this); animationChannel = animationControl.createChannel(); } #Override public void simpleUpdate(float tpf) { //goblinControl.setWalkDirection(goblin.getLocalRotation() // .mult(Vector3f.UNIT_Z).multLocal(0.4f)); Vector3f camDir = cam.getDirection().clone().multLocal(8f); Vector3f camLeft = cam.getLeft().clone().multLocal(8f); camDir.y = 0; camLeft.y = 0; walkDirection.set(0, 0, 0); if (left) { walkDirection.addLocal(camLeft); } if (right) { walkDirection.addLocal(camLeft.negate()); } if (up) { walkDirection.addLocal(camDir); } if (down) { walkDirection.addLocal(camDir.negate()); } // if (attack) { // animationChannel.setAnim("Attack1"); // animationChannel.setLoopMode(LoopMode.DontLoop); // } if (!ninjaControl.isOnGround()) { airTime = airTime + tpf; } else { airTime = 0; } if (walkDirection.length() == 0) { if (!"Idle1".equals(animationChannel.getAnimationName())) { animationChannel.setAnim("Idle1", 1f); } } else { ninjaControl.setViewDirection(walkDirection.negate()); if (airTime > .3f) { if (!"stand".equals(animationChannel.getAnimationName())) { animationChannel.setAnim("Idle1"); } } else if (!"Walk".equals(animationChannel.getAnimationName())) { animationChannel.setAnim("Walk", 1f); } } ninjaControl.setWalkDirection(walkDirection); } /* * Ninja can: Walk Ninja can: Kick Ninja can: JumpNoHeight Ninja can: Jump * Ninja can: Spin Ninja can: Attack1 Ninja can: Idle1 Ninja can: Attack3 * Ninja can: Idle2 Ninja can: Attack2 Ninja can: Idle3 Ninja can: Stealth * Ninja can: Death2 Ninja can: Death1 Ninja can: HighJump Ninja can: * SideKick Ninja can: Backflip Ninja can: Block Ninja can: Climb Ninja can: * Crouch */ public void onAction(String binding, boolean value, float tpf) { if (binding.equals("CharLeft")) { if (value) { left = true; } else { left = false; } } else if (binding.equals("CharRight")) { if (value) { right = true; } else { right = false; } } else if (binding.equals("CharUp")) { if (value) { up = true; } else { up = false; } } else if (binding.equals("CharDown")) { if (value) { down = true; } else { down = false; } } else if (binding.equals("CharSpace")) { // character.jump(); ninjaControl.jump(); } else if (binding.equals("CharShoot") && value) { // bulletControl(); Vector3f origin = cam.getWorldCoordinates( inputManager.getCursorPosition(), 0.0f); Vector3f direction = cam.getWorldCoordinates( inputManager.getCursorPosition(), 0.0f); // direction.subtractLocal(origin).normalizeLocal(); // character.setWalkDirection(location); System.out.println("origin" + origin); System.out.println("direction" + direction); // character.setViewDirection(direction); animationChannel.setAnim("Attack3"); animationChannel.setLoopMode(LoopMode.DontLoop); } } public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) { if (channel == shootingChannel) { channel.setAnim("Idle1"); } } public void onAnimChange(AnimControl control, AnimChannel channel, String animName) { } public Node getGameLevel() { return gameLevel; } public void setGameLevel(Node gameLevel) { this.gameLevel = gameLevel; } public static boolean isUseHttp() { return useHttp; } public static void setUseHttp(boolean useHttp) { PyramidLevel.useHttp = useHttp; } public BulletAppState getBulletAppState() { return bulletAppState; } public void setBulletAppState(BulletAppState bulletAppState) { this.bulletAppState = bulletAppState; } public AnimChannel getChannel() { return channel; } public void setChannel(AnimChannel channel) { this.channel = channel; } public AnimControl getControl() { return control; } public void setControl(AnimControl control) { this.control = control; } public BetterCharacterControl getGoblincharacter() { return goblinControl; } public void setGoblincharacter(BetterCharacterControl goblincharacter) { this.goblinControl = goblincharacter; } public BetterCharacterControl getCharacterControl() { return ninjaControl; } public void setCharacterControl(BetterCharacterControl characterControl) { this.ninjaControl = characterControl; } public Node getCharacterNode() { return ninjaNode; } public void setCharacterNode(Node characterNode) { this.ninjaNode = characterNode; } public boolean isRotate() { return rotate; } public void setRotate(boolean rotate) { this.rotate = rotate; } public Vector3f getWalkDirection() { return walkDirection; } public void setWalkDirection(Vector3f walkDirection) { this.walkDirection = walkDirection; } public Vector3f getViewDirection() { return viewDirection; } public void setViewDirection(Vector3f viewDirection) { this.viewDirection = viewDirection; } public boolean isLeftStrafe() { return leftStrafe; } public void setLeftStrafe(boolean leftStrafe) { this.leftStrafe = leftStrafe; } public boolean isRightStrafe() { return rightStrafe; } public void setRightStrafe(boolean rightStrafe) { this.rightStrafe = rightStrafe; } public boolean isForward() { return forward; } public void setForward(boolean forward) { this.forward = forward; } public boolean isBackward() { return backward; } public void setBackward(boolean backward) { this.backward = backward; } public boolean isLeftRotate() { return leftRotate; } public void setLeftRotate(boolean leftRotate) { this.leftRotate = leftRotate; } public boolean isRightRotate() { return rightRotate; } public void setRightRotate(boolean rightRotate) { this.rightRotate = rightRotate; } public Node getModel() { return goblinNode; } public void setModel(Node model) { this.goblinNode = model; } public Spatial getGoblin() { return goblin; } public void setGoblin(Spatial goblin) { this.goblin = goblin; } public RigidBodyControl getTerrainPhysicsNode() { return terrainPhysicsNode; } public void setTerrainPhysicsNode(RigidBodyControl terrainPhysicsNode) { this.terrainPhysicsNode = terrainPhysicsNode; } public AnimChannel getAnimationChannel() { return animationChannel; } public void setAnimationChannel(AnimChannel animationChannel) { this.animationChannel = animationChannel; } public AnimChannel getShootingChannel() { return shootingChannel; } public void setShootingChannel(AnimChannel shootingChannel) { this.shootingChannel = shootingChannel; } public AnimControl getAnimationControl() { return animationControl; } public void setAnimationControl(AnimControl animationControl) { this.animationControl = animationControl; } public float getAirTime() { return airTime; } public void setAirTime(float airTime) { this.airTime = airTime; } public boolean isLeft() { return left; } public void setLeft(boolean left) { this.left = left; } public boolean isRight() { return right; } public void setRight(boolean right) { this.right = right; } public boolean isUp() { return up; } public void setUp(boolean up) { this.up = up; } public boolean isDown() { return down; } public void setDown(boolean down) { this.down = down; } public boolean isAttack() { return attack; } public void setAttack(boolean attack) { this.attack = attack; } public ChaseCamera getChaseCam() { return chaseCam; } public void setChaseCam(ChaseCamera chaseCam) { this.chaseCam = chaseCam; } public boolean isWalkMode() { return walkMode; } public void setWalkMode(boolean walkMode) { this.walkMode = walkMode; } public FilterPostProcessor getFpp() { return fpp; } public void setFpp(FilterPostProcessor fpp) { this.fpp = fpp; } public Spatial getSceneModel() { return sceneModel; } public void setSceneModel(Spatial sceneModel) { this.sceneModel = sceneModel; } public RigidBodyControl getLandscape() { return landscape; } public void setLandscape(RigidBodyControl landscape) { this.landscape = landscape; } } You can download a demo of my game but how do I improve the walking? Update My followup at the jmonkeyforum also had 0 replies.
To do this you change the value of the max slope: setMaxSlope() From the jmonkey site: "How steep the slopes and steps are that the character can climb without considering them an obstacle. Higher obstacles need to be jumped. Vertical height in world units." Reading this I believe it works in a way similar to, when moving 1 unit in the world what is the maximum change in height a character can experience. If you set this to the size of the steps (or a larger by <1 for safety) you'r character should be able to walk up steps Sources: http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:walking_character#charactercontrol Developing for Jmonkey before
How to create a pause menu for a simple side-scroller game in Java
I'm trying to create a simple sideScroller in java, so far my game runs as expected but i have no idea on how to create a pause menu to go to the main menu and stuff (haven't got any idea on how to create a main manu for that mater) what do you think it's the best idea? this is the relevant code of my game, this panel is called inside a frame: Game Code package videojuegoalpha; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.Timer; public class Background extends JPanel implements ActionListener, Runnable { BufferedImage img, marco; Character character; Obstacle[] obstacleArray; Timer time; //CONSTANTS final static int largoPantalla = 800; final static int borderWidth=24; final static int diferencialPantalla = 74; final static int characterFlow=10; final static int fontSize=18; final static int flickerTime=150; final static int invincibilityTime=2000; int largonivel; int controlPaso; int actualHeight; int standardHeight; int maxHeightValue; int deltaObstaculo; Thread brinco; static boolean debug=false; boolean jumpCycleDone; boolean runDone; boolean maxHeight; boolean shrinkHeart; boolean pause; static Font fontScore,fontMultiplier; Lives lives; static MultithreadSystem sounds = new MultithreadSystem(); static Thread MusicPlayer = new Thread(sounds); static String BackgroundMusic; String hitSound; String score; public Background(int actualHeight, int maxHeightValue, String characterImage,String characterHitImage, int pasosPersonaje,int speed, String imagenFondo,String imagenMarco, String lowObstacleImage,String highObstacleImage,int obstacleDistance, String musicFile,String jumpSound,String hitSound, String dashSound) { controlPaso=0; this.standardHeight = actualHeight; this.actualHeight = this.standardHeight; this.maxHeightValue = maxHeightValue; jumpCycleDone = false; runDone = false; maxHeight = false; shrinkHeart=false; pause=false; character = new Character(characterImage,characterHitImage,pasosPersonaje, speed,jumpSound,dashSound); lives=new Lives(); obstacleArray=Obstacle.getObstacleArray(5200,obstacleDistance, standardHeight+deltaObstaculo+borderWidth, (standardHeight+deltaObstaculo)/,lowObstacleImage,highObstacleImage); addKeyListener(new AL()); setFocusable(true); try { img = CompatibleImage.toCompatibleImage(ImageIO.read(new File( "Images"+File.separator+"Background"+ File.separator+imagenFondo))); marco = CompatibleImage.toCompatibleImage(ImageIO.read(new File( "Images"+File.separator+imagenMarco))); fontScore=(Font.createFont(Font.TRUETYPE_FONT,new FileInputStream(new File( "Fonts"+File.separator+"score.ttf")))).deriveFont(Font.BOLD, 18); fontMultiplier=(Font.createFont(Font.TRUETYPE_FONT, new FileInputStream(new File("Fonts"+File.separator+"multi.ttf")))) .deriveFont(Font.BOLD, fontSize+10); } catch (IOException | FontFormatException e) { System.out.println("Error al cargar" + ":" + e.toString()); } deltaObstaculo=(character.getImage(character.pasoActual). getHeight(null))- (obstacleArray[0].getImage().getHeight(null)); time = new Timer(5, this); time.start(); BackgroundMusic = "Music/"+musicFile; backMusic(BackgroundMusic); this.hitSound=hitSound; } public static void backMusic(String MusisBck) { sounds.newThread(BackgroundMusic); MusicPlayer.start(); if (MusicPlayer.isAlive() != true) { sounds.newThread(BackgroundMusic); MusicPlayer.start(); } } #Override public void actionPerformed(ActionEvent e) { if(!pause){ character.move(); } condWin(5200); condLose(); avanzaPaso(); repaint(); } public void avanzaPaso() { if(!pause){ controlPaso++; } if (controlPaso % characterFlow == 0) { character.pasoActual++; if (character.pasoActual > character.pasos-3) { character.pasoActual = 0; } debugMode("Paso: " + character.pasoActual); } if(controlPaso%(characterFlow*(character.pasos-2))==0){ shrinkHeart = !shrinkHeart;//oscilación para encojer/desencojer } } public void condWin(int dist) { if (character.getPositionX() == dist) { MultithreadSystem sounds = new MultithreadSystem(); sounds.newThread("Music/FF3Victory.wav"); Thread sounds_player = new Thread(sounds); MusicPlayer.stop(); sounds_player.start(); JOptionPane.showMessageDialog(null, "YOU WIN!"); System.exit(0); } } public void condLose() { if (character.lives == 0) { character.isAlive = false; if (!character.isAlive) { MultithreadSystem sounds = new MultithreadSystem(); sounds.newThread("Music/gameOver01.wav"); Thread sounds_player = new Thread(sounds); MusicPlayer.stop(); sounds_player.start(); JOptionPane.showMessageDialog(null, "YOU SUCK"); System.exit(0); } } } #Override public void paint(Graphics g) { debugMode("Altura: " + actualHeight); if (character.deltaY == 1 && runDone == false) { runDone = true; brinco = new Thread(this); brinco.start(); } super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.drawImage(img, largoPantalla - character.getnX2(), 0, null); if (character.getPositionX() > diferencialPantalla) { g2d.drawImage(img, largoPantalla - character.getnX(), 0, null); } for (int i = 0; i < obstacleArray.length; i++) { if (obstacleArray[i] != null) { if (obstacleArray[i].getPositionX() == -character.posicionFija) { obstacleArray[i] = null; } if (obstacleArray[i] != null) { if(!pause){ obstacleArray[i].move(character.pixPerStep); } if (obstacleArray[i].getPositionX() == largoPantalla + character.posicionFija) { obstacleArray[i].setVisible(true); } if (obstacleArray[i].isVisible()) { g2d.drawImage(obstacleArray[i].getImage(), obstacleArray[i].getPositionX(), obstacleArray[i].getPositionY(), null); } checkCollisions(obstacleArray[i]); } } } if (character.paintCharacter) { g2d.drawImage(character.getImage(character.pasoActual), character.posicionFija, actualHeight, null); } character.hit(flickerTime); if (shrinkHeart) { g2d.drawImage(lives.getImage(character.getLives()), borderWidth + 5, borderWidth + 5, (int) (lives.getImage(character.getLives()).getWidth() * .95), (int) (lives.getImage(character.getLives()).getHeight() * .95), null); } else { g2d.drawImage(lives.getImage(character.getLives()), borderWidth + 5, borderWidth + 5, null); } g2d.drawImage(marco, 0, 0, null); g2d.setFont(fontScore); g2d.setColor(Color.BLACK); score = String.format("%08d", character.score); g2d.drawString("score:" + score, 500, borderWidth * 2); g2d.setFont(fontMultiplier); g2d.drawString(character.multiplier + "", (largoPantalla / 2) - 75, (borderWidth * 2) + 10); } private class AL extends KeyAdapter { #Override public void keyReleased(KeyEvent e) { character.keyReleased(e); } #Override public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if(!pause){ character.keyPressed(e); } if (key == KeyEvent.VK_D) { debug=(!debug); } if(key==KeyEvent.VK_P){ pause=(!pause); } if (key == KeyEvent.VK_ESCAPE) { System.exit(0); } } } public void checkCollisions(Obstacle obstacle) { if (character.posicionFija == obstacle.getPositionX()) { if (obstacle instanceof LowObstacle) { debugMode("Obstaculo Bajo, Altura: "+obstacle.getPositionY()); if (actualHeight <= (standardHeight - obstacle.getImage().getHeight(null))){ if (character.multiplier < 4) { character.multiplier++; } } else { if (character.hitAllowed) { sounds = new MultithreadSystem(); sounds.newThread("SFX/" + hitSound); Thread sounds_player = new Thread(sounds); sounds_player.start(); character.multiplier = 1; character.lives--; character.hitAllowed = false; } } } else{ debugMode("Obstaculo Alto, Altura: "+obstacle.getPositionY()); if (character.dashPressed) { if (character.multiplier < 4) { character.multiplier++; } } else { if (character.hitAllowed) { sounds = new MultithreadSystem(); sounds.newThread("SFX/" + hitSound); Thread sounds_player = new Thread(sounds); sounds_player.start(); character.multiplier = 1; character.lives--; character.hitAllowed = false; } } } } } public void cycle() { if(!pause){ if (maxHeight == false) { actualHeight--; } if (actualHeight == maxHeightValue) { maxHeight = true; } if (maxHeight == true && actualHeight <= standardHeight) { actualHeight++; if (actualHeight == standardHeight) { jumpCycleDone = true; } } } } #Override public void run() { character.isJumping = true; character.keyAllowed = false; long beforeTime, timeDiff, sleep; beforeTime = System.currentTimeMillis(); while (jumpCycleDone == false) { cycle(); timeDiff = System.currentTimeMillis() - beforeTime; sleep = 8 - timeDiff; if (sleep < 0) { sleep = 2; } try { Thread.sleep(sleep); } catch (InterruptedException e) { } beforeTime = System.currentTimeMillis(); } jumpCycleDone = false; maxHeight = false; runDone = false; character.keyAllowed = true; character.isJumping = false; } public static void debugMode(String string){ if(debug){ System.out.println(string); } } // Getters y Setters // public Character getCharacter() { return character; } public void setCharacter(Character character) { this.character = character; } } As you can see I already have a pause variable which pauses everything, but I would like to have a little window popup in the middle while pause its true
The problem is that your class Background is directly where you draw. Normally your game handles all the frames and stuff, but then you have some kind of GameState object which your main game calls, like this: public void update() { if (pause) { gameState = pauseState; } else { gameState = playState; } gameState.update(); } #Override public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; gameState.paint(g2d) } The idea is that you can have as many gameStates as you want. Simply make an interface GameState that provides methods for Update, Paint, Initialize and Dispose (or something like this). Then you can have all kinds of GameStates, for example Play, Pause, MainMenu, SaveGameMenu, etc., each one in charge of updating and drawing itself. It's the main class (where your game loop is) where you handle the logic to swap the GameStates.