Sei sulla pagina 1di 9

Sewer Monsters

Zo Sams 1001675 Code Portfolio

Graphics Programmer 1.

Data Group Handling


1.1. Organisation of Data Groups into various scenes Data Folder 1.1.1. Main Menu 1.1.2. Level 1 1.1.3. Characters 1.1.4. Roster Scene 1.1.5. Shop Scene 1.1.6. Splash Screen 1.1.7. Settings Assistance with loading data groups Game.cpp

1.2.

Data groups in Marmalade hold the main images and sounds to be loaded in at a specific point in the program when that group is called. This means unused images do not need to be loaded in (for instance, if a character is not selected) meaning the RAM is used by the game when run on device is significantly reduced. To load in these groups to each scene a CurrentGroup variable is set to a certain scene loaded in by a function implemented within the IwGame engine. For instance;
CurrentGroup = IwGetResManager()->GetGroupNamed("SplashScreen");

2.

Texturing
2.1. Assigning images to sprites Game.cpp 2.1.1. Characters 2.1.2. Backgrounds 2.1.3. Buttons 2.1.4. Environment Assets Creating animation frames for bitmap textures Game.cpp

2.2.

Texturing each sprite was not a complicated programming process, but was a lengthy one. For every image used in game, animation frames need to be set. For still images, the frames need to be set to the full size of the image but without a pitch or frame number.
background_anim = current_scene->getAnimFrameManager()->allocImageFrames(1, 320, 480, 0, 0, 0, 0, 320);

Animated sprites however, are created using the same function but with different values.
player1_anim = current_scene->getAnimFrameManager()->allocImageFrames(10, 50, 50, 5, 4, 60, 50, 60);

The first number used is the amount of frames in one animation, followed by the x and y dimensions of the frame. The starting x and y positions are then set and the pitch (whitespace between frames) is allocated. The last number is the total width of the sprite sheet. These animation frames are then placed into the Actor::Create function which passes through to the VirtualScreenManager. This animation is stored in the visual of the sprite, and is then played according to the animation frames set. 3.

Transformations
3.1. Scaling & Rotations After Virtual Screen Size was implemented Game.cpp

Originally, each sprite needed to be transformed individually to a correct size, and then controlled by

the sprite manager to keep consistent screen resolutions across multiple devices. Although the work on this was completed, it was scrapped when we got rid of our old framework and began using the IwGame Engine. The IwGame engine uses a Virtual Screen Size which means there is no need to transform the sprite manager to keep a consistent screen resolution. Other sprites just need to be scaled to one size and the VSS handles the rest. 4.

Camera
4.1. Set boundaries on camera movement in gameplay

5.

Character Animation
5.1. Starting Animation 5.2. Organisation and definition of animation frames 5.3. Resetting animation frames for power ups ActorButton.cpp 5.4. Event Driven Animation using split sprite sheets and case statement for Animation State IwGameActor.cpp, ActorPlayer.cpp, (referenced in ActorWalls.cpp, ActorEnvironment.cpp) 5.4.1. Start 5.4.2. Idle 5.4.3. Collision 5.4.4. Win 5.4.5. Acid

Much like the textures, character animation was not a difficult process but it did have its challenges. Getting an initial animation to play was simple, although sprite sheets needed to be edited to create smooth animations. After many different iterations using sprite sheets, and seeking assistance from colleagues, a solution was not found to move the frames in the sprite sheet over to the right. Different methods were used such as increasing the total number of frames, changing the starting frame number, and changing the starting frame position, but for some reason the output would either show the same starting animation, or something entirely different such as white space or the entire sprite sheet. Event driven animation was not intended to take so long to implement, so a solution was derived to use split up sprite sheets, deleting the visual on the sprite, and replacing it with a new one.
if(InitCheck(PreviousAnimState, CurrentAnimState)) { // remove the current visual/image from the actor removeVisual(); // Create a sprite to hold the new visual data CIwGameBitmapSprite* sprite = new CIwGameBitmapSprite(); switch(CurrentAnimState) { case (as_Start): if(Player1) { sprite->setImage(GAME->getPlayer1Image()); setAnim(GAME->getPlayer1Anim(),9,1,0.1f); } if(Player2) { sprite->setImage(GAME->getPlayer2Image()); setAnim(GAME->getPlayer2Anim(),9,1,0.1f); } break; }

//set the layer for the sprite to be drawn on sprite->setLayer(7); sprite->setDestSize(getWidth(), getHeight()); //set new visual setVisual(sprite); getScene()->getSpriteManager()->addSprite(sprite); }

A new function had to be created within the IwGameActor.cpp file to reset the animation.
void CIwGameActor::setAnim(CIwGameAnimImageFrame* animframe, int frameno, int looped, float speed) { //Function created by Zoe Sams //create temp animation to be added CIwGameAnimImage* anim = new CIwGameAnimImage(); //set the frame data, number of loops and playback speed according to input anim->setFrameData(animframe, frameno); anim->setLooped(looped); anim->setPlaybackSpeed(speed); anim->Start(); if (anim != NULL) { VisualAnimManager = new CIwGameAnimManager(); VisualAnimManager->setUpdateAll(false); if (VisualAnimManager == NULL) return; VisualAnimManager->addAnimation(anim); // Set the first animation in the animation manager as the current animation VisualAnimManager->setCurrentAnimation(0); } }

6.

Menus
6.1. 6.2. 6.3. User Interface and graphics implementation for all menus Idle button animations Splash Screen 6.3.1. Functionality of Drag to Play drain cover 6.3.2. Transition between splash screen and next menu Roster Menu 6.4.1. Stamps 6.4.2. Restricted buttons 6.4.3. Clearer character selection on roster menu Implementation of new Tap To Play Scene for player 1 & player 2 Implementation of Draw screen

6.4.

6.5. 6.6.

After the framework for the menus was created by Alan Smith, it was possible to implement all graphics to be used. The initial button functionality was implemented (before restructured into ActorButton) and idle button animations were introduced.
if(Pulse) { if(isBigger())

{ setScale(getScale() + 0.0025f); setAngle(getAngle() + 0.1f); if(getScale() >= ScaleMax) { setBigger(false); } } if(!(isBigger())) { setScale(getScale() - 0.0025f); setAngle(getAngle() - 0.1f); if(getScale() <= ScaleMin) { setBigger(true); } } }

7.

Sound
7.1. Menu Music 7.2. Gameplay Music 7.3. Event Driven Sound IwGameActor.cpp, ActorPlayer.cpp, (referenced in ActorWalls.cpp, ActorEnvironment.cpp) 7.3.1. Collisions 7.3.2. Win

Sound is handled in multiple different ways dependant on the type of sound used. All event driven sound used for Characters is in .wav file format, and is implemented using the IwSound set of the IwGame Engine. A sound spec is first initialised to hold the main sound that will be played, for instance Collide, which is set to a different sound dependant on which character has collided. The current player is always the player whose reaction is played, so as not to have multiple sounds playing at once. A sound instance is then created to hold what sound to do something with either play, pause, stop, etc. IwGameActor.h
CIwSoundSpec* WinSound; //point to the sound isntance CIwSoundInst* SoundInstance; CIwSoundInst* getSoundInstance() { return SoundInstance; } void setSoundInstance(CIwSoundInst* sndinst) { SoundInstance = sndinst; } CIwSoundSpec* getWinSound() { return WinSound;} void setWinSound(CIwSoundSpec* name) { WinSound = name;}

ActorEnvironment.cpp
// Walk the scenes actors for (CIwGameScene::_Iterator it = Scene->begin(); it != Scene->end(); ++it) {

// Get the sound spec for sounds used here if((*it)->getType() == at_CurrentPlayer) { if((*it)->isPlayer1() && !(*it)->isPlayer2()) { //decide which character the player has chosen //set collide to appropriate player collide Collide = GAME->getPlayer1CollisionSound(); } if((*it)->isPlayer2() && !(*it)->isPlayer1()) { Collide = GAME->getPlayer2CollisionSound(); } }

...
// Check for physical collision if (CheckCollision(*it)) {

...
if((*it)->getType() == at_CurrentPlayer) { SoundInstance = getCollisionSound()->Play(); } } }

The background music for both the menus and game however are in .mp3 format and are loaded into the game in a different way. Instead of being loaded in with data groups, they are loaded in directly from the MKB. Marmalade has inbuilt functions to handle mp3 sounds, and they were used within the Game.cpp to play looped music.
s3eAudioPlay("GamePlay_Music.mp3", 0);

8. 9.

Exporting to Device Version Control


9.1. 9.2. Set up of Tortoise SVN although unused Merging of prototype code bases

Un-used Code:

1. Transformations
1.1. Scaling & Rotations BEFORE Virtual Screen Size was implemented 1.2. Consistency of transformations between different devices - BEFORE Virtual Screen Size was implemented Referenced in transformations used code.

2. Score Implementation
2.1. Initial 3-splat score SCRAPPED A three splat score system was implemented into the early stages of prototyping with the intention of being used within single player in the later stages of development. The program would calculate a score dependant on which characters had collided with the drain, if all characters were on the drain then the score was 3, if the player got half of the characters on the drain they scored 2, and if they only managed to get one piece on the drain then their score would be one. If the player were to miss the drain completely, they would score no splats and be unable to progress to the next level.
//player score conversion if(PlayersOnDrain == 6) { PlayerScore = 3; } if(PlayersOnDrain < 6 && PlayersOnDrain >= 3) { PlayerScore = 2; } if(PlayersOnDrain < 3 && PlayersOnDrain >= 1) { PlayerScore = 1; } if(PlayerScore = 3) { //set full score image to visible, set others to clear current_scene->findActor(IwHashString("FullScoreSplat"))->setColour(full); current_scene->findActor(IwHashString("TwoScoreSplat"))->setColour(clear); current_scene->findActor(IwHashString("OneScoreSplat"))->setColour(clear); }

3. Character Animation
3.1. Event Driven Animation using sprite sheets unsuccessful Referenced in Character animation within successful code.

4. Catapult Prototype
4.1. Basic Functionality 4.1.1. Projectile movement 4.1.1.1. Angle Change using arrow keys 4.1.2. Graphics 4.1.2.1. Creating transparent masks for sprites

//Zoe Sams void GameLogic(){ //if the player presses the up arrow if(keys[VK_UP]){ //increase the angle of the arc for(i=0; i<2; i++){ PlayerSprite[i].m_A+=0.01; } } //if the player presses the down arrow if(keys[VK_DOWN]){ //decrease the angle of the arc for(i=0; i<2; i++){ PlayerSprite[i].m_A-=0.01; } } //if the space key is pressed if(keys[VK_SPACE]||PlayerSprite[0].m_y <450){ //begin arc movement PlayerSprite[0].MovePlayer(); } //LATER STAGES OF DEV //if mouse button is down //get starting position of mouse //if mouse button is released //get end position of mouse //work out the distance travelled and the angle }

Catapult was coded in C++ in Visual Studio as a demonstration of what out game could look like to show the producer, designer, artists and Tag Games. The catapult prototype was scrapped after a meeting with Tag Games in which the idea was pitched but was not quite what the client was looking for. This prototype had a basic catapult launch when the spacebar was pressed and a change in angle using the arrow keys, but was discontinued before more functionality could be added.

Other work unrelated to code 1. Production 1.1. Heavily involved in user testing 1.1.1.Taking notes throughout 1.1.2.Asking kids opinions 1.1.3.Assisted Will in teaching kids how to play the game 1.2. Took minutes from meetings when Producer was absent

2. Art 2.1. Splitting up sprite sheets 2.2. Re-organising sprite sheets to create smoother animations Although generally well done, I noticed some sprite sheet frames were off. For instance, the first 3 frames would create a smooth animation but the second 3 would jump or be clipped at the bottom. I looked through my animation code and tweaked the frame sizes, but soon noticed it was the sprite sheets themselves that were off. By that stage I had asked for sprite sheets to be redone numerous times and noticed that it would usually take a week or so to get back to me, so I repositioned the sprites myself using GIMP 2.0. I created place holder art to get an idea of how the graphics would look while waiting for an artefact from the artists. 3. Screen Capture All screen capture for presentations and trailers was captured using Koyote Screen To Video software. This was simple to use, free, and resizable to fit around the emulator window on PC.

Potrebbero piacerti anche