2015-12-17 2 views
1

В моей текущей игре должны быть разные состояния, например, когда я нахожусь в главном меню игры, состояние превратится в «MainMenu», если я нахожусь в игре (Game GAME), состояние будет "Игра".Как я могу добавить Штаты в свою игру?

Как сейчас, это только начинается игра GAME, а не MainMenu. Поэтому мой вопрос заключается в том, как я могу добавить его так, чтобы он работал так, как должен?

EDIT: Я хочу, чтобы игра начиналась в MainMenu-STATE, конечно, если это было непонятно :) И затем нажмите «play», чтобы запустить Game GAME, «Exit» для выхода или «опции», и так далее.

EDIT 2: Первый код имеет нерабочую функцию штата. Код внизу имеет функцию State, которая работает. Почему я не могу заставить его работать для первого кода?

Код:

package Game.Window; 

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.image.BufferStrategy; 
import java.awt.image.BufferedImage; 
import java.util.Random; 

import Game.Framework.AudioPlayer; 
import Game.Framework.KeyInput; 
import Game.Framework.ObjectId; 
import Game.Framework.Texture; 
import Game.Interfaces.MainMenu; 
import Game.Objects.Block; 
import Game.Objects.Player; 

public class Game extends Canvas implements Runnable{ 
    private static final long serialVersionUID = -3258890003398871268L; 

    private boolean running = false; 
    private Thread thread; 

    public static int WIDTH, HEIGHT; 

    // Buffers the "Level" and "Background" 
    private BufferedImage Level = null, Background = null; 

    Handler handler; 
    Camera cam; 
    static Texture tex; 

    Random rand = new Random(); 

    public enum STATE{ 
     MainMenu, 
     Game, 
    }; 

    public static STATE gameState = STATE.MainMenu; 

    public void init(){ 
     WIDTH = getWidth(); 
     HEIGHT = getHeight(); 

     AudioPlayer.load(); 
     AudioPlayer.getMusic("music").loop(); 

     tex = new Texture(); 

     BufferedImageLoader loader = new BufferedImageLoader(); 
     Level = loader.loadImage("/Level.png"); // Loads the image "Level" 
     Background = loader.loadImage("/BackGround.png"); // Loads the image "Background" 

     handler = new Handler(); 

     cam = new Camera(0, 0); 

     LoadImageLevel(Level); 

     this.addKeyListener(new KeyInput(handler, null)); 
    } 
    public synchronized void start(){ 
     if(running) 
      return; 
     running = true; 
     thread = new Thread(this); 
     thread.start(); 
    } 
    // The Game_Loop 
    public void run(){ 
     init(); 
     this.requestFocus(); 
     long lastTime = System.nanoTime(); 
     double amountOfTicks = 60.0; 
     double ns = 1000000000/amountOfTicks; 
     double delta = 0; 
     long timer = System.currentTimeMillis(); 
     int updates = 0; 
     int frames = 0; 

     while(running){ 
      long now = System.nanoTime(); 
      delta += (now - lastTime)/ns; 
      lastTime = now; 

      while(delta >= 1){ 
       tick(); 
       updates++; 
       delta--; 
      } 
      render(); 
      frames++; 

      if(System.currentTimeMillis() - timer > 1000){ 
       timer += 1000; 
       System.out.println("FPS: " + frames + " - TICKS: " + updates); 
       frames = 0; 
       updates = 0; 
      } 
     } 
    } 
    private void tick(){ 
     if(Game.gameState == STATE.Game){ 
      handler.tick(); 
     }else if(Game.gameState == STATE.MainMenu){ 
      //MainMenu.tick(); 
     } 

     for(int i = 0; i < handler.object.size(); i++){ 
      if(handler.object.get(i).getId() == ObjectId.Player){ 
       cam.tick(handler.object.get(i)); 
      } 
     } 
    } 
    private void render(){ 
     BufferStrategy bs = this.getBufferStrategy(); 
     if(bs == null){ 
      this.createBufferStrategy(3); 
      return; 
     } 

     Graphics g = bs.getDrawGraphics(); 
     Graphics2D g2d = (Graphics2D) g; 
     // The background 
     g.setColor(new Color(25, 191, 224)); 
     g.fillRect(0, 0, getWidth(), getHeight()); 

     // Beginning of the Camera 
     g2d.translate(cam.getX(), cam.getY()); 

      for(int xx = 0; xx < Background.getWidth() * 10; xx += Background.getWidth()) 
       g.drawImage(Background, xx, 50, this); 
      handler.render(g); 

     g2d.translate(-cam.getX(), -cam.getY()); 
     // Ending of the Camera 
     g.dispose(); 
     bs.show(); 
    } 
    private void LoadImageLevel(BufferedImage image){ 
     int w = image.getWidth(); 
     int h = image.getHeight(); 

     System.out.println("Width, Height: " + w + " " + h); 

     for(int xx = 0; xx < h; xx++){ 
      for(int yy = 0; yy < h; yy++){ 
       int pixel = image.getRGB(xx, yy); 
       int red = (pixel >> 16) & 0xff; 
       int green = (pixel >> 8) & 0xff; 
       int blue = (pixel) & 0xff; 

       if(red == 255 && green == 255 && blue == 255) handler.addObject(new Block(xx*32, yy*32, 0, ObjectId.Block)); 
       if(red == 0 && green == 255 && blue == 0) handler.addObject(new Block(xx*32, yy*32, 1, ObjectId.Block)); 
       if(red == 0 && green == 38 && blue == 255) handler.addObject(new Player(xx*32, yy*32, handler, ObjectId.Player)); 
      } 
     } 
    } 
    public static Texture getInstance(){ 
     return tex; 
    } 
} 

MainMenu:

package Game.Interfaces; 

import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

import Game.Framework.AudioPlayer; 
import Game.Window.Game; 
import Game.Window.Game.STATE; 
import Game.Window.Handler; 

public class MainMenu extends MouseAdapter{ 

    private Game game; 
    private Handler handler; 

    public MainMenu(Game game, Handler handler){ 
     this.game = game; 
     this.handler = handler; 
    } 

    public void mousePressed(MouseEvent e){ 
     int mx = e.getX(); 
     int my = e.getY(); 

     if(Game.gameState == STATE.MainMenu){ 
      if(mouseOver(mx, my, 10, 10, 50, 50)){ 
       AudioPlayer.getSound("menu_sound").play(); 
       Game.gameState = STATE.Game; 
       return; 
      } 
     } 
    } 
    public void mouseReleased(MouseEvent e){ 
    } 
    private boolean mouseOver(int mx, int my, int x, int y, int WIDTH, int HEIGHT){ 
     if(mx > x && mx < x + WIDTH){ 
      if(my > y && my < y + HEIGHT){ 
       return true; 
      }else return false; 
     }else return false; 
    } 
    public void tick(){ 
    } 
    public void render(Graphics g){ 
     if(Game.gameState == STATE.MainMenu){ 
      Font fnt1 = new Font("Arial", 1, 50); 

      g.setFont(fnt1); 
      g.setColor(Color.WHITE); 
      g.drawRect(10, 10, 100, 100); 
      g.drawString("Main Menu", 10, 10); 
     } 
    } 
} 

В клеща и визуализации методы, которые я знаю, что мне нужно будет поставить галочку и оказывать только специфическое состояние, так что если бы я был в MainMenu он будет только тикать и отображать его.

Эти состояния работы в этой игре:

package 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 = 7364682855700581664L; 

    public static final int WIDTH = 800, HEIGHT = WIDTH/12 * 9; 

    private Thread thread; 
    private boolean running = false; 

    public static boolean paused = false; 
    public int diff = 0; 

    // 0 = EASY 
    // 1 = NORMAL 
    // 2 = HARD 

    private Random r; 
    private Handler handler; 
    private HUD hud; 
    private Spawner spawner; 
    private Menu menu; 

    public enum STATE { 
     Menu, 
     Options, 
     Game, 
     Select, 
     Lose 
    }; 

    public static STATE gameState = STATE.Menu; 

    public Game(){ 
     hud = new HUD(); 
     handler = new Handler(); 
     menu = new Menu(this, handler, hud); 
     this.addKeyListener(new KeyInput(handler, this)); 
     this.addMouseListener(menu); 

     AudioPlayer.load(); 
     AudioPlayer.getMusic("music").loop(); 

     new Window(WIDTH, HEIGHT, "Test Game", this); 

     spawner = new Spawner(handler, hud, this); 
     r = new Random(); 

     if(gameState == STATE.Game){ 
      handler.addObject(new Player(WIDTH/2-32, HEIGHT/2-32, ID.Player, handler)); 
      handler.addObject(new BasicEnemy(r.nextInt(Game.WIDTH - 50), r.nextInt(Game.HEIGHT - 50), ID.BasicEnemy, handler)); 
     } 
    } 

    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(){ 
     this.requestFocus(); 
     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(){ 
     if(gameState == STATE.Game){ 
      if(!paused){ 
       hud.tick(); 
       spawner.tick(); 
       handler.tick(); 

       if(HUD.PlayerHealth < 1){ 
        HUD.PlayerHealth = 100; 
        //hud.setLevel(1); 
        //hud.setScore(0); 
        gameState = STATE.Lose; 
        handler.clearEnemies(); 
       } 
      } 

     }else if(gameState == STATE.Menu || gameState == STATE.Lose || gameState == STATE.Select){ 
      menu.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); 

     if(paused){ 
      g.setColor(Color.RED); 
      g.drawString("PAUSED", 370, 260); 
     } 

     if(gameState == STATE.Game){ 
      hud.render(g); 
     }else if(gameState == STATE.Menu || gameState == STATE.Options || gameState == STATE.Lose || gameState == STATE.Select){ 
      menu.render(g); 
    } 

     g.dispose(); 
     bs.show(); 
    } 

    public static float clamp(float var, float min, float max){ 
     if(var >= max) 
      return var = max; 
     else if(var <= min) 
      return var = min; 
     else 
      return var; 
    } 

    public static void main(String args[]){ 
     new Game(); 
    } 
} 

ответ

0

Наследовать от общего класса, а затем использовать стек и сделать элемент в верхней части его. Отправьте события ввода в этот элемент. После изменения состояния просто нажмите новый в верхней части стека и поместите его, когда закончите, чтобы вернуться к предыдущему.
Конечно, когда игра начинается, вы должны положить в стек первое состояние, которое будет отображаться, это ваше меню.

Если состояниям всего два, вы также можете просто использовать переменную, которая хранит активное состояние для рендеринга и отправлять отправленные события и т. Д., А затем обновлять эту переменную при изменении состояния.
В этом случае, когда игра начинается, просто установите в качестве активной сцену, содержащую ваше меню.

+0

Извините, но я не совсем понимаю, что вы имеете в виду. Не могли бы вы привести пример? –

+0

Слишком широкий. Вы знаете, что такое стек? В любом случае, сколько штатов имеет ваша игра? – skypjack

+0

Есть 2 заявления. MainMenu и игра. –

0

Вы можете перепроектировать игру двумя разными способами.

Вариант 1:

Finite State machine with a pre-defined workflow: Рекомендуется, если вы знаете, все состояния вашей игры заранее и состояние машины почти фиксирована без изменений в будущем

Вариант 2:

Behavioural tress : Рекомендуется, если есть частые изменения в поведении игры. Вы можете динамически добавлять поведение к существующему дереву, не влияя на текущее поведение.

Для получения более подробной информации см. Ниже соответствующий вопрос SE.

How to implement a FSM - Finite State Machine in Java

+0

Спасибо! Я посмотрю! –

Смежные вопросы