Group 12
Group Member | Main Responsibilities |
---|---|
Jussi Laakkonen (0237801) | All and everything |
My idea is to improve the old battleship game with:
The screen size is enough for this kind of small strategy game, so it is doable. The screen is divided into 60×60 blocks, i.e. 9×16.
The game includes open data by using a nearby coastline retrieved by the user GPS coordinates from a map service - skipped, cannot pull this alone SINCE ERNO ABANONDED ME!
Day | What to do |
---|---|
Monday | Helping others, try the SDK |
Tuesday | More OS/SDK issue fixing and support at codecamp, QML reading |
Wednesday | Coding, C++ and QML integration |
Thurday | Coding, QML, QML, QML and a bit C++ to prevent insanity |
Friday | A brief demo of the app and reset of brains afterwards |
I just had a idea to improve the old battleships game with multiple additional features and, since I got my own Jolla phone I decided to try a little bit of Qt + QML coding at the codecamp and skip all other research for a week. QML was completely new for me but I learnt a lot from it during the short stint - and keep on learning atm.
Implemented features:
changeplayertimer = true // Starts the timer ... Timer { id: changeplayertimer interval: timerdelay // In ms running: false repeat: false onTriggered: { if(pageStack.busy === false) // The app will crash if pagestack is manipulated within page transfer pageStack.clear() // Clear stack pageStack.push(Qt.resolvedUrl("PlayerTurn.qml")) // Load new page as only page in the stack // The gamedata is retrieved from C++ engine, so when turn changes, the main page will be set with another players data } } } }
Q_INVOKABLE static GameEngine* initEngine(); Q_INVOKABLE qint16 getIActivePlayer();
int main(int argc, char *argv[]) { QScopedPointer<QGuiApplication> app(SailfishApp::application(argc, argv)); QScopedPointer<QQuickView> view(SailfishApp::createView()); GameEngine* engine = GameEngine::initEngine(); // A singleton instance view->rootContext()->setContextProperty("GameEngine",engine); // Can be used as "GameEngine" in QML view->setSource(SailfishApp::pathTo("qml/coastaldefence.qml")); view->show(); return app->exec(); }
infotext.text = "Player" + GameEngine.getIActivePlayer() + " at game state: " + GameEngine.getGameState()
Grid { // Place items on a grid with specific column and row counts - the background grid for selecting coordinate (a rectangle) id: maingrid columns: GameEngine.gameAreaX() rows: GameEngine.gameAreaY() spacing: 0 Repeater { id: elements model: GameEngine.gameAreaX()*GameEngine.gameAreaY() // The amount of elements delegate: Placeblock { // A element (rectangle of 60x60, defined in "Placeblock.qml", each gets unique "index", an index number in the grid // x and y coordinates can be calculated from these } } Item { Repeater { // The ships id: ships model: page.shiplist // A property string list for elements delegate: Ship { name: page.shiplist[index] // Set name for the ship using index to list } } } // From Ship.qml Rectangle { MouseArea { onClicked: { if(GameEngine.getGameState() === 2 ) { if(GameEngine.placeShip(page.activename,xcoordinate,0,ycoordinate,0) === 0) { page.active = parent // Set the active selection in the main "page" page.activename = parent.name // And the name } } } // From Placingblock.qml Rectangle { property int xcoordinate: index % GameEngine.gameAreaX() // x coordinate inside the game engine - not gui x property int ycoordinate: Math.floor(index / GameEngine.gameAreaX()) ... MouseArea { onClicked: { if(GameEngine.getGameState() === 2 ) { if(GameEngine.placeShip(page.activename,xcoordinate,0,ycoordinate,0) === 0) { page.active.x = parent.x // Set the corner of the active (the ship in main gui) to be the same as this rectangle in the grid page.active.y = parent.y } } } }
Type | length | armor | weapons |
---|---|---|---|
Submarine | 2 | 150 | torpedo and coastal gun |
Battleship | 3 | 170 | weapons: machine gun and deck cannon |
Cruiser | 4 | 200 | weapons: torpedo and deck cannon |
Type | Damage |
---|---|
Coastal gun | 50 |
Deck cannon | 25 |
Torpedo | 40 |
Machine gun | 10 |
Sailfish SDK
Qt C++ (game engine)
QML (gui)
GIMP (editing the one ship image, retrieved from www.the-blueprints.com)
TBD
The usage of C++ in QML was eventually easy but my way may not be the best. It is also possible to use QObjects in the QML and then you should not need to use one big instance that you call everytime. When the object is inherited from QObject type it is possible to, e.g.:
property QObject object: GameEngine.getShip("cruiser") object = GameEngine.getShip("sub")
Do not pass 8bit integers from Qt C++ to QML - it does not seem to be counting the bits correctly and the 8bit values are shown as negative integers in QML. Might be an issue with signed/unsigned - didn't have time to look this further and replaced every 8bit integer with 16bits, which were handled correctly.
Element visibility is a nice feature that every QML object seems to have, it is not putting itself on top of any other object while hidden but it is completely untouchable - I will use this in future version of the game to give a full screen popup when a ship is clicked. The popup will give detailed information about the ship: name, history, weapons, ammo count, speed, size, strength (armor), etc. For example:
Rectangle { id: box1 visible: GameEngine.getGameState() === 0 ? false : true // Would set the box visible only when game is not in state 0 }