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 | 2844 (1571) | Blisk |
» | Java script -> Navigacija s smernimi tipkamiOddelek: Programiranje | 934 (686) | tadejp81 |
» | [C#]Analogna uraOddelek: Programiranje | 2856 (2493) | cekr |
» | [Silverlight 4] Omejeno premikanje elementov v canvasuOddelek: Programiranje | 1318 (1198) | xordie |
» | Collision detectionOddelek: Programiranje | 2022 (1774) | Senitel |