Προς το περιεχόμενο

[C] - Minesweeper clone


bnvdarklord

Προτεινόμενες αναρτήσεις

Βασικά με αυτή την λογική ανάπτυξης σχεδόν καταργείς τον βασικό ρόλο ύπαρξης GUI (που όπως λέει και το όνομά του είναι η αλληλεπίδραση με τον χρήστη) και το χρησιμοποιείς κυρίως ως έναν απλό καμβά, για να οπτικοποιήσεις τα περιεχόμενα του backbuffer.

GUI σημαίνει graphical user interface. Τι σημασία έχει αν το εχω φτιαξει με sprites in game(σκεψου το gui των μενου σε ενα παιχνιδι σαν το besiege ας πουμε που ειχες αναφέρει) ή αν ειναι windows controls. Απλά υποκειμενικά προτιμω το 1ο :P

 

αλλάζοντας την υλοποίηση στο core-game θα πρέπει να αλλάξει και ο κώδικας στο gui.

Μόνο αν θες να υποστηρίξεις περισσότερα κουμπιά, το οποίο ειναι λογικό. Αν κοιτάξεις το game_raw_input ειναι απλά το input σε "raw" μορφή : συντεταγμένες ποντικιου, τι πληκτρο πατηθηκε στο πληκτρολογιο, αν ειναι Down το left του mouse. Αυτά ειναι στάνταρ πράγματα. Το παιχνίδι, αυτό το input θα το μετατρέψει στο πιο game specific game_input(οπου ας πουμε ψευτικο παράδειγμα: το KEYBOARD_PLUS γινεται INCREASE_MINE) και θα χρησιμοποιείσει αυτό.

 

 

Απλά data όπως είναι το board-size και το πλήθος των ναρκών, είναι πολύ πιο απλά από το input που ήδη το κάνεις ;)

Δεν είναι θέμα πολυπλοκότητας, πανεύκολα γινεται αυτο που λες. Απλά, υποκειμενική επιλογή φυσικά, δεν ήθελα να ασχολείται με τετοια πράγματα το windows layer.

 

Το να φτιαχτεί τώρα όπως είναι π.χ. ένα gtk_mainsweeper.cpp που θα είναι ένας απλός καμβάς με λίγο input sending, δεν είναι και πολύ intriguing :)

Ε αυτό ομως ειναι που πρέπει να κανει κανεις για το port. Προφανως το platform layer είναι ο πιο βαρετος κωδικας :P

 

Thanks, αν και μέχρι εκεί το είχα κάνει τελικά κι εγώ figure-out. Οι απορίες μου αφορούν πιο εξειδικευμένα στοιχεία. Όπως π.χ. τελικά η PermanentStorage και το SpriteMap είναι το ίδιο και το αυτό; Όταν λες πως στην PermanentStorage αποθηκεύεις τα κομμένα (από το spritesheet) sprites, σε τι μορφή τα αποθηκεύεις. Με άλλα λόγια, γιατί υπάρχει και PermanentStorage και SpriteMap[] στον κώδικα, αν και τα 2 αυτά αποθηκεύουν μεμονωμένα sprites?

Οι εικόνες ειναι σε raw rgba 32bit format. Έτσι υπάρχουν στο PermanentStorage. Το SpriteMap ειναι ενα ευρετηριο στο PermanentStorage, για να μπορώ πχ να λεω SpriteMap[bLOCK] ή SpriteMap[FACE_SMILE].

 

 

(btw, άσχετο με τα παραπάνω, αλλά επειδή δεν το έχω κοιτάξει, τα sprites τα έχεις κάνεις να μπορούν να είναι αλλάζουν διαστάσεις, ή τις έχεις fixed σύμφωνα με το τρέχον spritesheet? )

Τα sprites εχουν στανταρ διαστάσεις. Αν πειραξεις τα height, width απλα θα διαβαζεις λαθος την μνήμη. 

 

Σε έχασα εδώ :(

Τίποτα βλακείες εγραφα.

 

Απλά μου φαινεται αυτη τη στιγμή που το σκεφτομαι και ειναι 12:15 το βραδυ ότι θα είναι ασκοπα πολυπλοκο αυτο που σκεφτεσαι με το game_memory, και καλυτερη ειναι η απλουστερη λυση. Κάντο οπως θες βασικα και θα δω εκ του αποτελέσματος :P

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 106
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

GUI σημαίνει graphical user interface. Τι σημασία έχει αν το εχω φτιαξει με sprites in game(σκεψου το gui των μενου σε ενα παιχνιδι σαν το besiege ας πουμε που ειχες αναφέρει) ή αν ειναι windows controls. Απλά υποκειμενικά προτιμω το 1ο :P

Προφανώς για τον τελικό χρήστη δεν έχει σημασία αν έχεις υλοποιήσει το gui σου με κάποιο έτοιμο framework/api ή αν έχεις φτιάξει δικό σου. Δεν είναι εκεί το point της κουβέντας.

 

Το point είναι το decoupling μεταξύ του gui και του core-game, με τέτοιο τρόπο ώστε αφενός να μπορεί το gui να εκμεταλλεύεται όσο το δυνατόν περισσότερες από τις παραμετροποιήσιμες δυνατότητες του core-game (είτε ως viewer είτε ως controller, αν σε βοηθάει καλύτερα να το σκεφτείς με MVC terms), κι αφετέρου να μπορεί να το κάνει χωρίς να χρειάζεται να ξέρει πως ακριβώς υλοποιεί τα εσωτερικά του το core-game.

 

Άσχετο: το game ήταν το Banished (παιχνιδάρα!)

 

Μόνο αν θες να υποστηρίξεις περισσότερα κουμπιά, το οποίο ειναι λογικό. Αν κοιτάξεις το game_raw_input ειναι απλά το input σε "raw" μορφή : συντεταγμένες ποντικιου, τι πληκτρο πατηθηκε στο πληκτρολογιο, αν ειναι Down το left του mouse. Αυτά ειναι στάνταρ πράγματα. Το παιχνίδι, αυτό το input θα το μετατρέψει στο πιο game specific game_input(οπου ας πουμε ψευτικο παράδειγμα: το KEYBOARD_PLUS γινεται INCREASE_MINE) και θα χρησιμοποιείσει αυτό.

Όχι :P

 

Ας υποθέσουμε πως έχεις φτιάξει ήδη 3 gui για το game: ένα win32, ένα gtk+ κι ένα qt. Όπως το έχεις τώρα, και στα 3 αυτά gui όταν υπάρξει π.χ. keyboard input έχουν μια μεταβλητή τύπου game_raw_input που την ενημερώνουν με το ποιο κουμπί πατήθηκε ως εξής:

...
switch (keypressed) {
    case ARROWUP:   // gui specific
        GameRawInput->KeyUp = GameRawInput->KEYB_UP  // core-game specific
        break;
        ...
}
...
και κατόπιν περνάνε την GameRawInput στο core-game.

 

Το GameRawInput το έχεις ορίσει στο core-game ως εξής:

 

struct game_raw_input
{
	int MouseX;
	int MouseY;

	bool LeftMouseDown;
	bool LeftMouseUp;

	bool RightMouseDown;
	bool RightMouseUp;

	enum { KEYB_OTHER, KEYB_UP, KEYB_DOWN, KEYB_LEFT, KEYB_RIGHT, KEYB_PLUS, KEYB_MINUS, KEYB_SUGGEST } KeyUp;
};

 

και το έχεις publicly exposed.

 

Στην επόμενη έκδοση του game, μεταξύ διάφορων αλλαγών αποφασίζεις πως επειδή θέλεις να υποστηρίξεις κι άλλα input-devices, πλέον σε εξυπηρετεί καλύτερα να ομαδοποιήσεις τα devices στο game_raw_input και να το υλοποιήσεις ας πούμε ως εξής:

 

 

enum key_code{
  KEYB_OTHER, KEYB_UP, KEYB_DOWN, KEYB_LEFT, KEYB_RIGHT, KEYB_PLUS, KEYB_MINUS, KEYB_SUGGEST
};
struct game_raw_input
{
	struct {
		int X;
		int Y;

		bool LeftDown;
		bool LeftUp;

		bool RightDown;
		bool RightUp;
	} mouse;

	struct {
		 enum key_code KeyUp;
	} keyboard;

	struct {
		...
	} joystick;

	struct {
		...
	} touchpad;
};

 

Πλέον πρέπει να πας να αλλάξεις τον κώδικα και στα 3 gui σου.

 

Consider τώρα να ήταν εξαρχής opaque type το game_raw_input και να παρείχε έναν keyboard setter, ας πούμε:

bool game_input_set_keyboard_keyup(game_raw_input *GameRawInput, int KeyUp);
Ο κώδικας των gui θα ήταν εξαρχής:

...
switch (keypressed) {
    case ARROWUP:   // gui specific
        game_input_set_keyboard_keyup( GameRawInput, KEYB_UP );  // core-game specific
        break;
        ...
}
...
Οι αλλαγές που έκανες στην εσωτερική υλοποίηση του game_raw_input ΔΕΝ θα επηρέαζαν τον κώδικα των gui, με την προϋπόθεση προφανώς πως μετά τις αλλαγές θα προσάρμοζες ανάλογα τον setter.

 

Το μόνο που θα χρειάζεται είναι ένα απλό compilation των gui (είτε μαζί με τα αλλαγμένα πηγαία του core-game, είτε απλά με τα object files τους).

Αν κάποιο gui το είχε φτιάξει κάποιος 3ος, το μόνο που θα χρειαζόταν να του δώσεις θα ήταν τα object files (ούτε καν τον κώδικα δηλαδή).

 

Δεν είναι θέμα πολυπλοκότητας, πανεύκολα γινεται αυτο που λες. Απλά, υποκειμενική επιλογή φυσικά, δεν ήθελα να ασχολείται με τετοια πράγματα το windows layer.

Καμία αντίρρηση ως προς το υποκειμενικό της πρόθεσης. Απλά λέω πως συνηθίζεται το gui (ή σκέτο UI στην ορολογία των games, από τα ελάχιστα που ξέρω) να έχει πρόσβαση σε όλες τις παραμετροποιήσεις του core, για τον απλούστατο λόγο πως οι παραμετροποιήσεις αποκτούν βασικό νόημα όταν μπορεί να τις ορίζει ο χρήστης (UX στην ορολογία των games).

Και το UI είναι το module που επωμίζεται την αλληλεπίδραση με τον χρήστη (όχι μόνο στα games, παντού).

 

Ε αυτό ομως ειναι που πρέπει να κανει κανεις για το port. Προφανως το platform layer είναι ο πιο βαρετος κωδικας :P

Ναι. Απλώς όταν είπα πως σκέφτομαι να του φτιάξω GTK+ gui, υπέθεσα πως θα το έκανα πιο πλούσιο από το πολύ απλό που εχει τώρα, αλλά διαπίστωσα τελικά πως ο κώδικας δεν είναι flexible σε εξωτερικές παραμετροποιήσεις. Για αυτό και η όλη κουβέντα ;)

 

Οι εικόνες ειναι σε raw rgba 32bit format. Έτσι υπάρχουν στο PermanentStorage. Το SpriteMap ειναι ενα ευρετηριο στο PermanentStorage, για να μπορώ πχ να λεω SpriteMap[bLOCK] ή SpriteMap[FACE_SMILE].

 

Τα sprites εχουν στανταρ διαστάσεις. Αν πειραξεις τα height, width απλα θα διαβαζεις λαθος την μνήμη.

Thanks! Χρήσιμες πληροφορίες :)

 

ΥΓ. Πάντως δεν είναι σίγουρο πως θα το κάνω τελικά, γιατί για να το κάνω όπως το είχα φανταστεί στην αρχή πρέπει να αλλάξω πολύ κώδικα (ήδη έχω αλλάξει πολύ κώδικα, αλλά θέλει πολύ ακόμα και όπως είπα ασχολούμαι περιστασιακά). Θα δούμε.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...