Forum » Programiranje » [Java] Zasnova shoot em up igre
[Java] Zasnova shoot em up igre

PecenkA ::
Pozdravljeni
Danes sem na hitro sprogramiral čisto osnovo za shoot em up igro, za katero imam idejo v glavi že dolgo časa. Če se komu da, bi lepo prosil, da poda mnenja na sledečo kodo. Razvidno je, da me čaka še ogromno dela, vendar bi rad vedel, če in kje sem ga že v startu polomil.
Main funkcija (VShooter.java)
Igra (Game.java)
En testni objekt (GameObject.java)
Tipkovnica (Input.java)
Branje nastavitev iz datoteke (Settings.java)
Danes sem na hitro sprogramiral čisto osnovo za shoot em up igro, za katero imam idejo v glavi že dolgo časa. Če se komu da, bi lepo prosil, da poda mnenja na sledečo kodo. Razvidno je, da me čaka še ogromno dela, vendar bi rad vedel, če in kje sem ga že v startu polomil.
Main funkcija (VShooter.java)
package vshooter; import javax.swing.JFrame; public class VShooter { /** * @param args the command line arguments */ public static void main(String[] args) { //Load settings from game.propertis if (Settings.Load() == true) { //init frame, game, keylistener, input JFrame frame = new JFrame("VShooter"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Game gm = new Game(); frame.add(gm); Input in = new Input(); frame.addKeyListener(in); frame.setSize(800, 600); //sets frame size when not maximized frame.setExtendedState(frame.getExtendedState()|JFrame.MAXIMIZED_BOTH); //maximize frame frame.setVisible(true); gm.Start(); //start game } } }
Igra (Game.java)
package vshooter; import java.awt.Graphics; import javax.swing.JPanel; public class Game extends JPanel { static float factorX; static float factorY; static double dT; //frame time deltaTime private float resX; //level design resolution horizontal private float resY; //level design resolution vertical private GameObject go; //test //Constructor Game() { //set object design resolution resX = 800f; resY = 600f; //Initialize object resizing factors factorX = (float)this.getWidth() / resX; factorY = (float)this.getHeight() / resY; } //Start Game void Start() { double pT; //previous time double cT; //current time pT = (double)System.nanoTime() / 1000000000; //conversion to seconds cT = (double)System.nanoTime() / 1000000000; //conversion to seconds go = new GameObject(); //test //Game loop while (1 == 1) { //Factor for object resizing to frame size factorX = (float)this.getWidth() / resX; factorY = (float)this.getHeight() / resY; //Set current time and calculate frame duration cT = (double)System.nanoTime() / 1000000000; //conversion to seconds dT = cT - pT; //Update Update(); //Draw this.repaint(); //Set previous time pT = cT; } } void Update() { go.Update(); //test } void Draw(Graphics g) { go.Draw(g); //test //FPS counter g.drawString("FPS: " + Double.toString(1 / dT), (int)(10 * factorX), (int)(20 * factorY)); //test - input status if (Input.moveLeft == true) { g.drawString("Move left", (int)(10 * factorX), (int)(35 * factorY)); } if (Input.moveRight == true) { g.drawString("Move right", (int)(10 * factorX), (int)(50 * factorY)); } if (Input.moveUp == true) { g.drawString("Move up", (int)(10 * factorX), (int)(65 * factorY)); } if (Input.moveDown == true) { g.drawString("Move down", (int)(10 * factorX), (int)(80 * factorY)); } if (Input.fireP == true) { g.drawString("Fire primary weapon", (int)(10 * factorX), (int)(95 * factorY)); } if (Input.fireS == true) { g.drawString("Fire secondary weapon", (int)(10 * factorX), (int)(110 * factorY)); } } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Draw(g); } }
En testni objekt (GameObject.java)
package vshooter; import java.awt.Graphics; public class GameObject extends Game { double posX; double posY; double speed; //Constructor GameObject() { // posX = 400; posY = 300; speed = 200; } @Override void Update() { if (Input.moveLeft == true) { posX = posX - (dT * speed); } if (Input.moveRight == true) { posX = posX + (dT * speed); } if (Input.moveUp == true) { posY = posY - (dT * speed); } if (Input.moveDown == true) { posY = posY + (dT * speed); } } @Override void Draw(Graphics g) { g.drawString("object", (int)(posX * factorX), (int)(posY * factorY)); } }
Tipkovnica (Input.java)
package vshooter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; public class Input implements KeyListener { static boolean moveLeft; static boolean moveRight; static boolean moveUp; static boolean moveDown; static boolean fireP; static boolean fireS; //Constructor Input() { //initialization moveLeft = false; moveRight = false; moveUp = false; moveDown = false; fireP = false; fireS = false; } @Override public void keyTyped(KeyEvent e) { //not implemented } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == Settings.moveLeft) { moveLeft = true; } if (e.getKeyCode() == Settings.moveRight) { moveRight = true; } if (e.getKeyCode() == Settings.moveUp) { moveUp = true; } if (e.getKeyCode() == Settings.moveDown) { moveDown = true; } if (e.getKeyCode() == Settings.fireP) { fireP = true; } if (e.getKeyCode() == Settings.fireS) { fireS = true; } } @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == Settings.moveLeft) { moveLeft = false; } if (e.getKeyCode() == Settings.moveRight) { moveRight = false; } if (e.getKeyCode() == Settings.moveUp) { moveUp = false; } if (e.getKeyCode() == Settings.moveDown) { moveDown = false; } if (e.getKeyCode() == Settings.fireP) { fireP = false; } if (e.getKeyCode() == Settings.fireS) { fireS = false; } } }
Branje nastavitev iz datoteke (Settings.java)
package vshooter; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; public class Settings { static int moveLeft; static int moveRight; static int moveUp; static int moveDown; static int fireP; //fire primary static int fireS; //fire secondary static boolean Load() { Properties prop = new Properties(); //test for getting game.properties debug location //System.out.println(System.getProperty("user.dir")); try { //load a properties file prop.load(new FileInputStream("game.properties")); //get the property values moveLeft = Integer.parseInt(prop.getProperty("KeyLeft")); moveRight = Integer.parseInt(prop.getProperty("KeyRight")); moveUp = Integer.parseInt(prop.getProperty("KeyUp")); moveDown = Integer.parseInt(prop.getProperty("KeyDown")); fireP = Integer.parseInt(prop.getProperty("KeyFirePrimary")); fireS = Integer.parseInt(prop.getProperty("KeyFireSecondary")); return true; } catch (IOException ex) { System.out.println("Error loading game.properties file."); return false; } } }

Arto ::
Jaz sem se enkrat že malo igral s temi stvarmi, pa ti za javo priporočam JGame framework, je precej enostaven in ima spisanih večino stvari, ki jih boš potreboval za tako igro, pa tudi dokumentacija je kar kul. Razen če hočeš res vse iz nule.

PecenkA ::
Hočem vse iz nule, da se čim več naučim zraven.
Še eno vprašanje. Trenutno je GameObject dedovan iz Game. Glede na to, da bodo potem vsi ostali dedovani iz GameObject ali bi bilo bolje, da bi GameObject zastavil iz nule brez dedovanja iz Game, da nimajo potem nepotrebnega balasta zraven.
Še eno vprašanje. Trenutno je GameObject dedovan iz Game. Glede na to, da bodo potem vsi ostali dedovani iz GameObject ali bi bilo bolje, da bi GameObject zastavil iz nule brez dedovanja iz Game, da nimajo potem nepotrebnega balasta zraven.

Arto ::
Ja jaz bi dal GameObject posebej, ker v bistvu ne deli ničesar z Game. Mogoče si lahko vseeno pogledaš vsaj dokumentacijo JGame, če ti zmanjka idej kako realizirat stvari, samo vidim, da maš itak že praktično enako zastavljeno


_Dormage_ ::
Zgleda lepo..
Ne razumet narobe, ampak me samo zanima ali obstaja razlog zakaj v vrtici
rabiš nanoTime in ga pol pretvarjaš v sekunde?
Kaj je razlika, če narediš
Kakšna bo pa grafika? (Največ dela po mojih izkušnjah)
Ne razumet narobe, ampak me samo zanima ali obstaja razlog zakaj v vrtici
cT = (double)System.nanoTime() / 1000000000;
rabiš nanoTime in ga pol pretvarjaš v sekunde?
Kaj je razlika, če narediš
System.currentTimeMillis()/1000
Kakšna bo pa grafika? (Največ dela po mojih izkušnjah)

Arto ::
Aja saj res, za grafiko je najbolje da si narediš nek sprite sistem (se pravi različni farme-i v eni sliki, v nekakšnem koordinatnem sistemu).

PecenkA ::
@_Dormage_
System.nanoTime() vrne čas v najnatančnejšega možnega timerja v sistemu. Pri večini sistemov danes je natančen na kakšno mikrosekundo. Lahko bi naredil tudi s System.currentTimeMillis(), natančnost 10-15 ms je dovolj dobra za moje namene. Sem pa nekje bral, da se uporabi najboljši možni timer (sourca ne vem več).
Kar se grafike tiče, bo vse narejeno z Graphics.drawPolygon(). En objekt bo lahko sestavljen iz več poligonov različnih barv. Tudi collision detection je v tem primeru dokaj "enostaven". V planu je tudi editor objektov in stopenj.
System.nanoTime() vrne čas v najnatančnejšega možnega timerja v sistemu. Pri večini sistemov danes je natančen na kakšno mikrosekundo. Lahko bi naredil tudi s System.currentTimeMillis(), natančnost 10-15 ms je dovolj dobra za moje namene. Sem pa nekje bral, da se uporabi najboljši možni timer (sourca ne vem več).
Kar se grafike tiče, bo vse narejeno z Graphics.drawPolygon(). En objekt bo lahko sestavljen iz več poligonov različnih barv. Tudi collision detection je v tem primeru dokaj "enostaven". V planu je tudi editor objektov in stopenj.
Zgodovina sprememb…
- spremenil: PecenkA ()

_Dormage_ ::
Če se boš lotu kake lepe grafike vsekakor spiši svoj Animation class, ki bo sfural animacije namesto tebe..
Teh stvari se dokaj hitro nabere.
Pa poglej si kak particle engine za eksplozije in efekte.
Enkrat ko usposobiš enega se začne zabava
EDIT:
Si me prehitel tako, da je zgornji text void.
Hvala za pojasnilo, ampak kot si že sam povedal take natančnosti ne potrebuješ za igro.
Teh stvari se dokaj hitro nabere.
Pa poglej si kak particle engine za eksplozije in efekte.
Enkrat ko usposobiš enega se začne zabava

EDIT:
Si me prehitel tako, da je zgornji text void.
Hvala za pojasnilo, ampak kot si že sam povedal take natančnosti ne potrebuješ za igro.
Zgodovina sprememb…
- spremenil: _Dormage_ ()

PecenkA ::
Sem našel odličen tutorial za Separate axis teorem za collision detection če koga zanima slučajno. http://www.codezealot.org/archives/55. Vodi pa še do enega prav tako odličnega.

PecenkA ::
GameObject sem potem predelal, da ne deduje iz Game. Zaenkrat kaže, da bo vsaj v enostavni obliki zadeva špilala, ampak dokler ne bom kakšen mesec ali deset v razvoju ne morem vedeti. Na hitro par screenshotov testa, da se vidi kakšen stil grafike bo. Ne bo nobenih pobarvanih površin ali česa podobnega. Samo barvasti poligoni. Sem dodal random ozadje na level (malo sneži :)), da imam vsaj občutek, da se premikam, to je pa to.
Zgodovina sprememb…
- spremenil: PecenkA ()

PecenkA ::
Sem preuredil zadevo tako, da je sedaj grafika uporablja Path2D.Double(). Sem prešaltal, ker sem mnogo lažje naredil collision detection z Area.intersect. Sicer je neučinkovito, ker moram pretvarjati Path2D v Area, samo za moje namene bo ok. Prav tako za izris namesto Graphics sedaj skrbi Graphics2D. Transformacije objektov sem prepustil vgrajenem AffineTransform objektu. Samo vpišeš matriko in to je to. Sicer je narejena podpora šele za translate, scale in rotate me še čakata. Finaliziral sem tudi format datoteke za objekte (videz).
Lista stvari, ki se jih bom lotil v kratkem:
- level loader + struktura datoteke z levelom
- dizajn orožij in objektov ker imam trenutno samo 4 testne
- dizajn testnega levela
- manager za zvočne efekte
Če ima kdo čas, lahko izriše kakšen objekt (malo lahko sanjam
). Prilagam sliko za občutek, kaj imam v mislih, pa da se vidi omejitve. Objekt je lahko sestavljen iz poligonov različnih barv. Glej playerja.
Tudi kakšen nasvet glede česarkoli bi bil dobrodošel.
Lista stvari, ki se jih bom lotil v kratkem:
- level loader + struktura datoteke z levelom
- dizajn orožij in objektov ker imam trenutno samo 4 testne
- dizajn testnega levela
- manager za zvočne efekte
Če ima kdo čas, lahko izriše kakšen objekt (malo lahko sanjam

Tudi kakšen nasvet glede česarkoli bi bil dobrodošel.
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | KeyloggerOddelek: Programska oprema | 2727 (1454) | Blisk |
» | Java script -> Navigacija s smernimi tipkamiOddelek: Programiranje | 907 (659) | tadejp81 |
» | [C#]Analogna uraOddelek: Programiranje | 2799 (2436) | cekr |
» | [Silverlight 4] Omejeno premikanje elementov v canvasuOddelek: Programiranje | 1274 (1154) | xordie |
» | Collision detectionOddelek: Programiranje | 1961 (1713) | Senitel |