PrettyPrint
Sunday, 17 March 2013
The Completed Game.
After finishing the game I decided to have a little write up on how the final product has differed from the original plan. First of all the biggest thing missing from the final product is the ability to be able to pick up collectables to increase the score of the player, this was removed from the game as in the time space that the game was given to get completed I deemed to to time consuming to continue trying to implement not matter how much this feature would have added to the game. Apart from this all other features of the game made it in and are fully functional which I am very pleased with and the group that I decided to work as part of have worked very well together with all of us pulling their weight getting the work that they needed to be contributing in on time. If I were to give any advice to anybody thinking about undertaking a similar project I would definitely make sure that enough time is given to the coding side as trying to learn how to code a fully functioning game, no matter how small and simple it may be, from only a very basic understanding knowledge of a programming language is very time consuming but is also immensely rewarding. Finally a video of the completed project can be seen below.
Creating The Game - 17/03/2013 (Final Post)
This will be the last post that I will posting on the development of Jetson's Journey as the game is now complete and the coding side of the project is done. In this post I will be detailing the creation of the second level and also the changes to the original plan that have been made throughout the creation of the game.
First of all I have finished the creation of the second level for the game. This was a much simpler process that first thought as the code used from the first level directly copied over to this level allowing for 85% of the base code to already be complete, but there are some slight changes in this level that needed to be added. First of all a new BlockMap and Block class needed to be created for this level to use, The code for these is shown below:
BlockMap2 Class
Block2 Class
As you can see the BlockMap2 Class is slightly different from the original as this is using different tile IDs to create the BlockMap as there have been different tiles used within the creation of this level. After this was done The AI in the second level also had to be changed as there are many more AI used in this level. The new AI code is shown below:
Initialising The AI:
Drawing The AI:
AI Logic Code:
After this code was completed I also Added an exit to this level allowing the player to complete the level of the game. This was done once again by adding some simple Code and then displayed the End Screen that Stephen had created to the user. The code for this is shown below:
Initialising The Door And End Menu:
After the code for Level 2 was fully complete I went back to the first level and added the code to continue to the second level in. The code that I added is shown below:
Completing The First Level:
After this code had been added to the Game it was fully complete from this I thought what had been completed and what had been scrapped from the original idea and I will be discussing this in the next post that will be put up after this one.
First of all I have finished the creation of the second level for the game. This was a much simpler process that first thought as the code used from the first level directly copied over to this level allowing for 85% of the base code to already be complete, but there are some slight changes in this level that needed to be added. First of all a new BlockMap and Block class needed to be created for this level to use, The code for these is shown below:
BlockMap2 Class
import java.util.ArrayList;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.tiled.TiledMap;
public class BlockMap2 {
public static TiledMap tmaps;
public static int mapWidth;
public static int mapHeight;
private int square[] = {1,1,31,1,31,31,1,31}; //square shaped tile
public static ArrayList(Object) entitiestwo;
public BlockMap2(String ref) throws SlickException {
entitiestwo = new ArrayList(Object)();
tmaps = new TiledMap(ref, "data");
mapWidth = tmaps.getWidth() * tmaps.getTileWidth();
mapHeight = tmaps.getHeight() * tmaps.getTileHeight();
for (int x = 0; x < tmaps.getWidth(); x++) {
for (int y = 0; y < tmaps.getHeight(); y++) {
int tileID = tmaps.getTileId(x, y, 0);
if ((tileID == 3) || (tileID == 11)) {
entitiestwo.add(
new Block2(x * 32, y * 32, square, "square")
);
}
}
}
}
}
Block2 Class
import org.newdawn.slick.Graphics;
import org.newdawn.slick.geom.Polygon;
public class Block2 {
public Polygon poly;
public Block2(int x, int y, int test[],String type) {
poly = new Polygon(new float[]{
x+test[0], y+test[1],
x+test[2], y+test[3],
x+test[4], y+test[5],
x+test[6], y+test[7],
});
}
public void update(int delta) {
}
public void draw(Graphics g) {
g.draw(poly);
}
}
As you can see the BlockMap2 Class is slightly different from the original as this is using different tile IDs to create the BlockMap as there have been different tiles used within the creation of this level. After this was done The AI in the second level also had to be changed as there are many more AI used in this level. The new AI code is shown below:
Initialising The AI:
ai1 = enemyLeft;
ai2 = enemyRight;
ai3 = enemyLeft;
ai4 = enemyRight;
ai5 = enemyLeft;
ai6 = enemyRight;
AIPoly1 = new Polygon(new float[]{
x,y,
x+32,y,
x+32,y+32,
x,y+32
});
AIPoly2 = new Polygon(new float[]{
x,y,
x+32,y,
x+32,y+32,
x,y+32
});
AIPoly3 = new Polygon(new float[]{
x,y,
x+32,y,
x+32,y+32,
x,y+32
});
AIPoly4 = new Polygon(new float[]{
x,y,
x+32,y,
x+32,y+32,
x,y+32
});
AIPoly5 = new Polygon(new float[]{
x,y,
x+32,y,
x+32,y+32,
x,y+32
});
AIPoly6 = new Polygon(new float[]{
x,y,
x+32,y,
x+32,y+32,
x,y+32
});
Drawing The AI:
g.drawAnimation(ai1, AI1x , AI1y);
g.drawAnimation(ai2, AI2x , AI2y);
g.drawAnimation(ai3, AI3x , AI3y);
g.drawAnimation(ai4, AI4x , AI4y);
g.drawAnimation(ai5, AI5x , AI5y);
g.drawAnimation(ai6, AI6x , AI6y);
AI Logic Code:
AIPoly1.setY(AI1y);
AIPoly2.setY(AI2y);
AIPoly3.setY(AI3y);
AIPoly4.setY(AI4y);
AIPoly5.setY(AI5y);
AIPoly6.setY(AI6y);
if(enemyR1){
AI1x -= floatDelta;
ai1 = enemyLeft;
enemyLeft.update(delta);
AIPoly1.setX(AI1x);
if(entityAICollisionWith(AIPoly1)){
enemyR1 = false;
}
} else {
AI1x += floatDelta;
ai1 = enemyRight;
enemyRight.update(delta);
AIPoly1.setX(AI1x);
if(entityAICollisionWith(AIPoly1)){
enemyR1 = true;
}
}
if(enemyR2){
AI2x += floatDelta;
ai2 = enemyRight;
enemyRight.update(delta);
AIPoly2.setX(AI2x);
if(entityAICollisionWith(AIPoly2)){
enemyR2 = false;
}
} else {
AI2x -= floatDelta;
ai2 = enemyLeft;
enemyLeft.update(delta);
AIPoly2.setX(AI2x);
if(entityAICollisionWith(AIPoly2)){
enemyR2 = true;
}
}
if(enemyR3){
AI3x -= floatDelta;
ai3 = enemyLeft;
enemyLeft.update(delta);
AIPoly3.setX(AI3x);
if(entityAICollisionWith(AIPoly3)){
enemyR3 = false;
}
} else {
AI3x += floatDelta;
ai3 = enemyRight;
enemyRight.update(delta);
AIPoly3.setX(AI3x);
if(entityAICollisionWith(AIPoly3)){
enemyR3 = true;
}
}
if(enemyR4){
AI4x += floatDelta;
ai4 = enemyRight;
enemyRight.update(delta);
AIPoly4.setX(AI4x);
if(entityAICollisionWith(AIPoly4)){
enemyR4 = false;
}
} else {
AI4x -= floatDelta;
ai4 = enemyLeft;
enemyLeft.update(delta);
AIPoly4.setX(AI4x);
if(entityAICollisionWith(AIPoly4)){
enemyR4 = true;
}
}
if(enemyR5){
AI5x -= floatDelta;
ai5 = enemyLeft;
enemyLeft.update(delta);
AIPoly5.setX(AI5x);
if(entityAICollisionWith(AIPoly5)){
enemyR5 = false;
}
} else {
AI5x += floatDelta;
ai5 = enemyRight;
enemyRight.update(delta);
AIPoly5.setX(AI5x);
if(entityAICollisionWith(AIPoly5)){
enemyR5 = true;
}
}
if(enemyR6){
AI6x += floatDelta;
ai6 = enemyRight;
enemyRight.update(delta);
AIPoly6.setX(AI6x);
if(entityAICollisionWith(AIPoly6)){
enemyR6 = false;
}
} else {
AI6x -= floatDelta;
ai6 = enemyLeft;
enemyLeft.update(delta);
AIPoly6.setX(AI6x);
if(entityAICollisionWith(AIPoly6)){
enemyR6 = true;
}
}
if(playerPoly.intersects(AIPoly1) || playerPoly.intersects(AIPoly2) ||
playerPoly.intersects(AIPoly3) || playerPoly.intersects(AIPoly4)||
playerPoly.intersects(AIPoly5) || playerPoly.intersects(AIPoly6)){
dead = true;
Level2.stop();
death.play();
}
}
After this code was completed I also Added an exit to this level allowing the player to complete the level of the game. This was done once again by adding some simple Code and then displayed the End Screen that Stephen had created to the user. The code for this is shown below:
Initialising The Door And End Menu:
door = new Image("data/Exit.png");
endMenu = new Image("data/END.png");
Drawing The Door And End Menu(Updated Render Cycle: if (!paused && !dead && !end){
BG.draw(0,0);
BlockMap2.tmaps.render(0, 0);
door.draw(1215, 865);
g.drawAnimation(player, x , y);
g.drawAnimation(ai1, AI1x , AI1y);
g.drawAnimation(ai2, AI2x , AI2y);
g.drawAnimation(ai3, AI3x , AI3y);
g.drawAnimation(ai4, AI4x , AI4y);
g.drawAnimation(ai5, AI5x , AI5y);
g.drawAnimation(ai6, AI6x , AI6y);
}else if(paused){
pauseMenu.draw(0,0);
}else if(dead){
deadMenu.draw(0,0);
}else if(end){
endMenu.draw(0,0);
}
}
Using The End Menu: if(end && !paused && !dead){
if((mouseX > 1025.0 && mouseX < 1245.0) && (mouseY > 842.0 && mouseY < 928.0)){
if (input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
Level2.stop();
Menu.MainMusic.loop();
sbg.enterState(0);
}
}
}
Completing The Level: if((x > 1214 && x < 1216) && (y > 863 && y < 867)){
end = true;
x = 57.0f;
y = 853.0f;
}
After the code for Level 2 was fully complete I went back to the first level and added the code to continue to the second level in. The code that I added is shown below:
Completing The First Level:
if((x > 1215 && x < 1217) && (y > 575 && y < 577)){
Level1.stop();
Play2.Level2.loop();
sbg.enterState(2);
y = 32f;
x= 32f;
}
After this code had been added to the Game it was fully complete from this I thought what had been completed and what had been scrapped from the original idea and I will be discussing this in the next post that will be put up after this one.
Sunday, 10 March 2013
Creating The Game - 10/03/2013 Continued
This is a continuation of the 10/03/2013 Update post. In this section of the update I will be showing how the pause and death menus were implemented into the game. To start with just like the controls page on the main menu screen I started with two boolean variables each one indication whether of not the game was paused or if the player was dead, these both started as false in the beginning. If the player hit the P button on the keyboard then the game would become paused for this I had to update every section of the play class with the code below to allow the game to draw the menu when the boolean turned to true and also allow the user to use the option that are displayed when the pause menu is shown, when the P button is hit again the menu will disappear allowing the game to continue. The code for all of this is below:
Menu Initialisation
Sound Initialisation
Render Loop Updated
Logic Loop Updated
The code above checks to see which of the states the player is currently in, if the player is paused then the game checks to see if the played is clicking in any of the correct areas to perform the desired actions from the pause menu, this is also done if the player is dead and is trying to click on the restart button on the death menu. The very last line of the code above checks to see if the user is in a normal state e.g. not dead or paused and if so the normal game logic continues uninterrupted. Because the death menu is now set up ready to be used the correct code can be added to the AI collision detection to show the death menu when hit and also when the played falls down a pit in the level. The code for both of these is shown below:
Falling Death Code:
Updated AI Collision Code:
As the main function of the game are now in place I can reuse all of the code that has been written for this level to create a second level for the game, but lastly on this level I will have to create an exit to the second level by using the door sprite that Stephen has created. The simple code to add a door to the level is below and the code to continue onto the next level will be added when the level is completed.
Initialising the Door:
Drawing the Door (Updated Render Loop):
Menu Initialisation
pauseMenu = new Image("data/PausedMenu.png");
deadMenu = new Image("data/deadMenu.png");
Sound Initialisation
death = new Sound("data/Death_Tune.ogg");
Render Loop Updated
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
if (!paused && !dead){
BG.draw(0,0);
BlockMap.tmap.render(0, 0);
g.drawAnimation(player, x , y);
g.drawAnimation(ai, AIx, AIy);
}else if(paused){
pauseMenu.draw(0,0);
}else if(dead){
deadMenu.draw(0,0);
}
}
Logic Loop Updated
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
Input input = gc.getInput();
float floatDelta = delta*0.1f;
mouseX = gc.getInput().getMouseX();
mouseY = gc.getInput().getMouseY();
if(dead && !paused){
if ((mouseX > 468.0 && mouseX < 762.0) && (mouseY > 395.0 && mouseY < 495.0)){
if(input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
y = 32f;
x = 32f;
AIx = 480;
AIy = 640;
dead = false;
Level1.play();
}
}
if ((mouseX > 468.0 && mouseX < 762.0) && (mouseY > 552.0 && mouseY < 652.0)){
if(input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
System.exit(0);
}
}
}
if(paused && !dead){
if ((mouseX > 511.0 && mouseX < 730.0) && (mouseY > 375.0 && mouseY < 460.0)){
if(input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
paused = false;
}
}
if ((mouseX > 511.0 && mouseX < 730.0) && (mouseY > 500.0 && mouseY < 585.0)){
if( input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
System.exit(0);
}
}
}
if (!paused && !dead){
The code above checks to see which of the states the player is currently in, if the player is paused then the game checks to see if the played is clicking in any of the correct areas to perform the desired actions from the pause menu, this is also done if the player is dead and is trying to click on the restart button on the death menu. The very last line of the code above checks to see if the user is in a normal state e.g. not dead or paused and if so the normal game logic continues uninterrupted. Because the death menu is now set up ready to be used the correct code can be added to the AI collision detection to show the death menu when hit and also when the played falls down a pit in the level. The code for both of these is shown below:
Falling Death Code:
if (y > 960){
dead = true;
}
Updated AI Collision Code:
if(playerPoly.intersects(AIPoly)){
dead = true;
Level1.stop();
death.play();
}
As the main function of the game are now in place I can reuse all of the code that has been written for this level to create a second level for the game, but lastly on this level I will have to create an exit to the second level by using the door sprite that Stephen has created. The simple code to add a door to the level is below and the code to continue onto the next level will be added when the level is completed.
Initialising the Door:
door = new Image("data/Exit.png");
Drawing the Door (Updated Render Loop):
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
if (!paused && !dead){
BG.draw(0,0);
BlockMap.tmap.render(0, 0);
door.draw(1216, 576);
g.drawAnimation(player, x , y);
g.drawAnimation(ai, AIx, AIy);
}else if(paused){
pauseMenu.draw(0,0);
}else if(dead){
deadMenu.draw(0,0);
}
}
Creating The Game - 10/03/2013
This week has been a little less productive than the previous two weeks but there has still been progress and the project is very close to completion which may be one more week of work before it is fully completed. This week Stephen has handed me all of the remaining Graphics assets including the bricks for level 2 and also all of the menus that will be used within the game such as the pause menu etc. After receiving all of these materials I decided to focus on the creation of all of the menus within the game allowing the user to navigate around the game.
First of all is the main menu that the user will be first greeted with when entering the game. Here the user will be able to start the game, look at the controls or exit the game. To start with I set up the main menu class allowing me to get started on adding the main menu image to the screen the code for this is as follows:
Main Menu Initial Code:
This code draws the main menu image to the screen and also get the current x and y co-ordinates of the mouse pointer on the screen, this was then used to see if the user was within the acceptable bound of the buttons before clicking allowing them to perform certain actions. After doing this I moved on to allowing the user to start the game from this screen and also looking at the controls and exiting the game. The code for that is below:
Starting The Game:
Exiting The Game:
Contols Page:
All of the code above checks if the mouse is in a certain bounded area between two sets of different co-ordinates, if that mouse if and the left mouse button is clicked then certain actions are performed. The controls page code also checks to see which page of the controls the user is on and responds accordingly either exiting back to the main menu or continuing onto the next page of controls.
As the controls page will be drawn on top of the main menu temporarily then the render code also had to be updated to draw the correct page when the correct button was pressed. The updated render code is below:
Updated Render Loop:
Updated Initialisation:
First of all is the main menu that the user will be first greeted with when entering the game. Here the user will be able to start the game, look at the controls or exit the game. To start with I set up the main menu class allowing me to get started on adding the main menu image to the screen the code for this is as follows:
Main Menu Initial Code:
import org.newdawn.slick.state.*;
import org.newdawn.slick.*;
public class Menu extends BasicGameState {
private Image mainMenu;
public static Music MainMusic;
public Menu(int state) {
}
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
mainMenu = new Image("data/MainMenu.png");
MainMusic = new Music("data/Title_Music.ogg");
MainMusic.loop();
}
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
mainMenu.draw(0,0);
}
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
Input input = gc.getInput();
float mouseX = 0, mouseY = 0;
mouseX = gc.getInput().getMouseX();
mouseY = gc.getInput().getMouseY();
}
public int getID(){
return 0;
}
}
This code draws the main menu image to the screen and also get the current x and y co-ordinates of the mouse pointer on the screen, this was then used to see if the user was within the acceptable bound of the buttons before clicking allowing them to perform certain actions. After doing this I moved on to allowing the user to start the game from this screen and also looking at the controls and exiting the game. The code for that is below:
Starting The Game:
if(!controls && !controls2){
if((mouseX > 512.0 && mouseX < 735.0) && (mouseY > 556.0 && mouseY < 642.0)){
if (input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
MainMusic.stop();
Play.Level1.loop();
sbg.enterState(1);
}
}
Exiting The Game:
if((mouseX > 512.0 && mouseX < 735.0) && (mouseY > 680.0 && mouseY < 767.0)){
if (input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
System.exit(0);
}
}
Contols Page:
if((mouseX > 512.0 && mouseX < 735.0) && (mouseY > 804.0 && mouseY < 890.0)){
if (input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
controls = true;
}
}
else if (!controls2){
if((mouseX > 1025.0 && mouseX < 1245.0) && (mouseY > 842.0 && mouseY < 928.0)){
if (input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
controls = false;
controls2=true;
}
}
if((mouseX > 42.0 && mouseX < 260.0) && (mouseY > 842.0 && mouseY < 928.0)){
if (input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
controls = false;
}
}
} else {
if((mouseX > 1025.0 && mouseX < 1245.0) && (mouseY > 842.0 && mouseY < 928.0)){
if (input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
controls2=false;
}
}
}
All of the code above checks if the mouse is in a certain bounded area between two sets of different co-ordinates, if that mouse if and the left mouse button is clicked then certain actions are performed. The controls page code also checks to see which page of the controls the user is on and responds accordingly either exiting back to the main menu or continuing onto the next page of controls.
As the controls page will be drawn on top of the main menu temporarily then the render code also had to be updated to draw the correct page when the correct button was pressed. The updated render code is below:
Updated Render Loop:
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
if(!controls && !controls2){
mainMenu.draw(0,0);
} else if(!controls2) {
controlsMenu.draw(0,0);
} else {
controlsMenu2.draw(0,0);
}
}
Updated Initialisation:
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
mainMenu = new Image("data/MainMenu.png");
controlsMenu = new Image("data/Controls.png");
controlsMenu2 = new Image("data/ControlsPageNME.png");
MainMusic = new Music("data/Title_Music.ogg");
MainMusic.loop();
}
Sunday, 3 March 2013
Creating The Game - 03/03/2013
This week has been another busy week and a lot of work has been completed on the project bringing us closer to being done with the creation of the game. This week the group only had a very small meeting but Sam had finished all sounds that are needed for the game and has given me these as well as Stephen giving me the sprite that will be used for the AI within the game and the animation frames for this. With all of the new assets that I was given I decided to get the AI within the game working as well as adding the sound effects to all of the respective actions within the game. To see the progression of the code please click read more below.
Sunday, 24 February 2013
Creating The Game - 24/02/2013
This week there has been a large amount of work that has been done on the Game but there is still a lot of work to be done on the game. There has also been no meeting between the members of the group as with it being half term some members were unable to attend due to being out of the country, but I have spoken to Stephen during the week and he has given me the completed animation frames for the character allowing me to see for the first time what the character and animation will look like now that it is in the 32x64 dimensions.
This week I myself have concentrated on getting a pseudo gravity system into the game which I severely underestimated on the complexity of the coding that would have to go into this. To start off I figured out how to get a smooth jump from the character instead of just being able to walk up and down whenever the user pleased meaning that they can press the jump key once and the character will the perform the jump, the complex part of this was handling collisions while in the air allowing for the character to come back down if they were to collide with a block above them while jumping, but this was all figured out over the week and has been successfully implemented into the game along with the feature of the character changing its sprite depending on the direction it is facing, this means that if the user presses the left key the character will now face left but there is still no animation within the game, all of these features have been implemented into the game using the code below.
Jumping Gravity + Sprite Change
Animation Code
This week I myself have concentrated on getting a pseudo gravity system into the game which I severely underestimated on the complexity of the coding that would have to go into this. To start off I figured out how to get a smooth jump from the character instead of just being able to walk up and down whenever the user pleased meaning that they can press the jump key once and the character will the perform the jump, the complex part of this was handling collisions while in the air allowing for the character to come back down if they were to collide with a block above them while jumping, but this was all figured out over the week and has been successfully implemented into the game along with the feature of the character changing its sprite depending on the direction it is facing, this means that if the user presses the left key the character will now face left but there is still no animation within the game, all of these features have been implemented into the game using the code below.
Jumping Gravity + Sprite Change
if ((input.isKeyPressed(Input.KEY_UP) || input.isKeyPressed(Input.KEY_W)) && !jumping){
if(lastKeyLeft){
player = jumpLeft;
} else {
player = jumpRight;
}
gravSpeeds = -12;
jumping = true;
}
if(jumping && gravSpeeds < 12) {
gravSpeeds += 0.5;
}
if (jumping == false){
gravSpeeds = 12;
if (lastKeyLeft == true){
player = moveLeft;
} else {
player = moveRight;
}
}
y += gravSpeeds;
origY = y - gravSpeeds;
playerPoly.setY(y);
if (entityCollisionWith()){
if (jumping && gravSpeeds < ((gravSpeeds * (-1)))){
gravSpeeds = 0;
gravSpeeds += 0.5;
y += gravSpeeds;
}
if ( gravSpeeds > 0) {
gravSpeeds = 0;
jumping = false;
y = origY;
playerPoly.setY(y);
}
}
if (input.isKeyDown(Input.KEY_DOWN) || input.isKeyDown(Input.KEY_S))
{
y += floatDelta;
playerPoly.setY(y);
if (entityCollisionWith()){
y -= floatDelta;
playerPoly.setY(y);
}
}
if (input.isKeyDown(Input.KEY_LEFT) || input.isKeyDown(Input.KEY_A))
{
lastKeyLeft = true;
if (jumping){
player = jumpLeft;
jumpLeft.update(delta);
} else {
player = moveLeft;
moveLeft.update(delta);
}
x -= floatDelta;
playerPoly.setX(x);
if (entityCollisionWith()){
x += floatDelta;
playerPoly.setX(x);
}
} else {
moveLeft.setCurrentFrame(0);
}
if (input.isKeyDown(Input.KEY_RIGHT) || input.isKeyDown(Input.KEY_D))
{
lastKeyLeft = false;
if (jumping){
player = jumpRight;
jumpRight.update(delta);
} else {
player = moveRight;
moveRight.update(delta);
}
x += floatDelta;
playerPoly.setX(x);
if (entityCollisionWith()){
x -= floatDelta;
playerPoly.setX(x);
}
}
else {
moveRight.setCurrentFrame(0);
}
Animation Code
player = new Animation();
player.setAutoUpdate(true);
Image [] walkRight = {new Image ("data/Sprites/CharStand.png"),
new Image ("data/Sprites/CharStep1.png"),
new Image ("data/Sprites/CharStep2.png")};
Image [] walkLeft = {new Image ("data/Sprites/CharStandBACKWARDS.png"),
new Image ("data/Sprites/CharStep1BACKWARDS.png"),
new Image ("data/Sprites/CharStep2BACKWARDS.png")};
Image [] jumpingLeft = {new Image ("data/Sprites/CharJumpBACKWARDS.png")};
Image [] jumpingRight = {new Image ("data/Sprites/CharJump.png")};
moveRight = new Animation(walkRight, 200, false);
moveLeft = new Animation(walkLeft , 200, false);
jumpRight = new Animation(jumpingRight, 200, false);
jumpLeft = new Animation(jumpingLeft, 200, false);
jumpRight.setPingPong(true);
jumpLeft.setPingPong(true);
moveRight.setPingPong(true);
moveLeft.setPingPong(true);
player = moveRight;
Sunday, 17 February 2013
Creating The Game - 17/02/2013
This week I have been concentrating on getting the collision within the game working, and this was one of the hardest things that I have done with the project to date. But first I will discuss the what was said at the short group discussion that we had. Stephen has created some more tiles for me to use within the map creation but we have decided that we are not going to use them, because of this he has started creating the animation frames for the character walking and jumping that I will use to animate the character in the game. Sam has completed the jump sound which will be played when the character jumps within the game to his liking and has started on a collection sound for picking up coins. Andy has started to create the real flash animation from one of his designs that he has chosen for this and the whole project is still moving in the right direction.
This week as stated before I have been focusing on getting the collision working within the game. This means that the character will not be able to move where there is a block being rendered on the screen. As I had originally thought, this was extremely hard to get the grasp of but finally after looking through many different resources I understand how this is done and have implemented it successfully into the game. The basics of the collision system are that the TileD map that I created is loaded as a blockmap allowing Slick2D to read each tile and see if anything is being drawn there according to a specific tile ID. If there is a tile meant to be there then this is added to an array of entities which store the size of the block and where it is. Once this is done a polygon box is drawn around the players character and all of the blocks that are in the map, when the user is attempting to move the game checks to see if these polygon boxes ever intersect by looking through each object in the array and making sure the co-ordinates never intersect, if they do the movement is blocked and stops the character from moving through this object. All of the code that was written for this is down below.
BlockMap Class
Block Class
Collision Check Method
Updated Game Code - Movement
This week as stated before I have been focusing on getting the collision working within the game. This means that the character will not be able to move where there is a block being rendered on the screen. As I had originally thought, this was extremely hard to get the grasp of but finally after looking through many different resources I understand how this is done and have implemented it successfully into the game. The basics of the collision system are that the TileD map that I created is loaded as a blockmap allowing Slick2D to read each tile and see if anything is being drawn there according to a specific tile ID. If there is a tile meant to be there then this is added to an array of entities which store the size of the block and where it is. Once this is done a polygon box is drawn around the players character and all of the blocks that are in the map, when the user is attempting to move the game checks to see if these polygon boxes ever intersect by looking through each object in the array and making sure the co-ordinates never intersect, if they do the movement is blocked and stops the character from moving through this object. All of the code that was written for this is down below.
BlockMap Class
import java.util.ArrayList;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.tiled.TiledMap;
public class BlockMap {
public static TiledMap tmap;
public static int mapWidth;
public static int mapHeight;
private int square[] = {1,1,31,1,31,31,1,31}; //square shaped tile
public static ArrayList(objects) entities;
public BlockMap(String ref) throws SlickException {
entities = new ArrayList(objects)();
tmap = new TiledMap(ref, "data");
mapWidth = tmap.getWidth() * tmap.getTileWidth();
mapHeight = tmap.getHeight() * tmap.getTileHeight();
for (int x = 0; x < tmap.getWidth(); x++) {
for (int y = 0; y < tmap.getHeight(); y++) {
int tileID = tmap.getTileId(x, y, 0);
if (tileID == 1) {
entities.add(
new Block(x * 32, y * 32, square, "square")
);
}
}
}
}
}
Block Class
import org.newdawn.slick.Graphics;
import org.newdawn.slick.geom.Polygon;
public class Block {
public Polygon poly;
public Block(int x, int y, int test[],String type) {
poly = new Polygon(new float[]{
x+test[0], y+test[1],
x+test[2], y+test[3],
x+test[4], y+test[5],
x+test[6], y+test[7],
});
}
public void update(int delta) {
}
public void draw(Graphics g) {
g.draw(poly);
}
}
Collision Check Method
public boolean entityCollisionWith() throws SlickException {
for (int i = 0; i < BlockMap.entities.size(); i++) {
Block entity1 = (Block) BlockMap.entities.get(i);
if (playerPoly.intersects(entity1.poly)) {
return true;
}
}
return false;
}
Updated Game Code - Movement
if (input.isKeyPressed(Input.KEY_UP)){
y -= floatDelta;
playerPoly.setY(y);
if (entityCollisionWith()){
y += floatDelta;
playerPoly.setY(y);
}
}
if (input.isKeyDown(Input.KEY_DOWN))
{
y += floatDelta;
playerPoly.setY(y);
if (entityCollisionWith()){
y -= floatDelta;
playerPoly.setY(y);
}
}
if (input.isKeyDown(Input.KEY_LEFT))
{
x -= floatDelta;
playerPoly.setX(x);
if (entityCollisionWith()){
x += floatDelta;
playerPoly.setX(x);
}
}
if (input.isKeyDown(Input.KEY_RIGHT))
{
x += floatDelta;
playerPoly.setX(x);
if (entityCollisionWith()){
x -= floatDelta;
playerPoly.setX(x);
}
}
}
Sunday, 10 February 2013
Creating The Game - 10/02/2013
This week there was no meeting due to time restraints from members of the group, but I have been speaking with Stephen as he has now completed the character sprite using the 32x64 dimensions that we discussed last week. I have not spoken with the other two members of the group about their EPQ work but we are still progressing nicely with the project and I am happy overall with the work.
This week I have been concentrating on making the character that I have drawn to the screen moving in certain directions decided by which buttons on the keyboard have been pressed. This was a much harder task than I first thought but after reading through the available documentation for Slick2D and looking once again at the sample code that is available to me I have created a working movement system for the game. The code I have written allows the user to press either WASD or The arrow keys on the keyboard to control the movement of the character, seeing if the keys are being pressed is helpfully implemented with the input class of Slick2D allowing me to easily check if a key is either been pressed or held down which is very handy indeed. If the button is pressed down the variables of Y and X which are the current co-ordinates are adjusted accordingly and then the image is redrawn at these co-ordinates once updated. The code I have written is below:
This week I have been concentrating on making the character that I have drawn to the screen moving in certain directions decided by which buttons on the keyboard have been pressed. This was a much harder task than I first thought but after reading through the available documentation for Slick2D and looking once again at the sample code that is available to me I have created a working movement system for the game. The code I have written allows the user to press either WASD or The arrow keys on the keyboard to control the movement of the character, seeing if the keys are being pressed is helpfully implemented with the input class of Slick2D allowing me to easily check if a key is either been pressed or held down which is very handy indeed. If the button is pressed down the variables of Y and X which are the current co-ordinates are adjusted accordingly and then the image is redrawn at these co-ordinates once updated. The code I have written is below:
public void update(GameContainer gc, int delta) throws SlickException {
Input input = gc.getInput();
float floatDelta = delta*0.1f;
if (input.isKeyDown(Input.KEY_UP)){
y -= floatDelta;
}
if (input.isKeyDown(Input.KEY_DOWN))
{
y += floatDelta;
}
if (input.isKeyDown(Input.KEY_LEFT))
{
x -= floatDelta;
}
if (input.isKeyDown(Input.KEY_RIGHT))
{
x += floatDelta;
}
}
Sunday, 3 February 2013
Creating The Game - 03/02/2013
This week I have been successful in rendering a map to the screen using some of the art assets that Stephen has given to me. But first as with every week I will be discussing what has been said within the group meeting on Saturday. This week me and Stephen decided that having the character a 32x32 which is the same size as the blocks used within the map would not look right, because of this we decided that a 32x64 sprite would be better used for the character and this is now what Stephen has set about designing. Sam has completed the first complete draft of the level music which now sounds a lot better after the discussion we had last week, there a a few improvements that he decided that he would like to make but after this he will start working on the sound effects that will be used within the game such as for jumping and collecting coins. Andy has finished his initial designs and has started creating some very early flash animations and posters from these designs to see what these will look like and decide from this which one he will be using.
This week I have as described up above managed to render an image of what the map will be like within the game. First of all to do this I created the map image in a program called TileD. This is a very highly praised program as it allows for the creation of 2D maps very quickly and easily using a painting style interface with the tiles that you import. Once the map has been created the program allows you to export the map as a .TMX file which can then be read instantly by Slick2D and then rendered onto the screen. This is only the image of the map first of all though as such there is no collision or any other features within the game. I have also managed to get a representation of the played rendered on the screen, for which I have just used a 32x64 coloured box until such time that I have the actual character sprite from Stephen. This is some major progress as I now know draw images onto the screen with great ease and how to draw these images at certain points. By next week I hope to have movement working with the sprite that Stephen will be sending me during the week.
This week I have as described up above managed to render an image of what the map will be like within the game. First of all to do this I created the map image in a program called TileD. This is a very highly praised program as it allows for the creation of 2D maps very quickly and easily using a painting style interface with the tiles that you import. Once the map has been created the program allows you to export the map as a .TMX file which can then be read instantly by Slick2D and then rendered onto the screen. This is only the image of the map first of all though as such there is no collision or any other features within the game. I have also managed to get a representation of the played rendered on the screen, for which I have just used a 32x64 coloured box until such time that I have the actual character sprite from Stephen. This is some major progress as I now know draw images onto the screen with great ease and how to draw these images at certain points. By next week I hope to have movement working with the sprite that Stephen will be sending me during the week.
Sunday, 27 January 2013
Creating The Game - 27/01/2013
Today I will be showing some of the simple code that I have written within for the game, but first I will be discussing what was spoken about in the weekly group meeting on Saturday. This week Stephen had completed some of the tiles that I am going to be using within the creation of the game, the tiles we decided are going to be 32x32 giving Stephen a big enough space to create something that looks aesthetically pleasing yet still fits the retro genre that we are aiming for. Sam has given me a sample of the level music that he is creating and we decided that it did not fit the sci-fi style techno music that we decided that should have been created, because of this he is going back and changing this music slightly to give it that feel that we would like. Andy is progressing well creating designs for his flash animations and poster that he is going to be creating. Once again I feel the the group is progressing in the right direction with progress being made each week.
I have been playing around with the Slick2D package this week and have got the very basic layout for the games code setup now. This will allow me to keep the code nicely structured and cleaner, it will also allow the game to run once the code has been written and compiled. The code that I have written this week after reading the documentation and looking at some basic examples of game code is :
import org.newdawn.slick.*;
public class SlickTest extends BasicGame {
public SlickTest() {
super("Jetson's Journey || EPQ Game");
}
public void render(GameContainer gc, Graphics g) throws SlickException {
}
public void init(GameContainer gc) throws SlickException {
}
public void update(GameContainer gc, int arg1) throws SlickException {
}
public static void main(String[] args) throws SlickException {
AppGameContainer app = new AppGameContainer(new Game(), 1280, 960, false);
app.start();
}
The code above, denoted by the bold and italics, is the basic structure of a Slick2D game, the render method will be used to render assets onto the screen once I have imported them into the project, the init method will initialise everything needed within the game once the game starts this includes all variables, art assets and sound assets, the update method will be the section of code that will update the game logic making everything within the game like movement, collision and collecting coins possible. The last section of code, the main method is what initialises the whole game creating the game window and starting the game code running.
Sunday, 20 January 2013
Game Features and Asset Lists
After another very quick discussion with the other members of the group we have decided to create a list of features and assets so that we know what each person will be creating and also what the game will be able to do. Below is the list of individual assets that we will each create and also a list of feature we agreed that we would like the game to have:
- Ste:
- Main Character Sprites
- Main Character Animation
- Walking
- Jumping
- Level Tiles
- Level Backgrounds
- Level Assets
- Exit
- Collectables
- Coins (Most Likely)
- Diamonds
- Sam:
- Level Music
- Make repeatable so that it can be repeated smoothly within game
- Sound FX
- Jumping Sounds
- Collecting Sounds
- Death Sounds
- Andy:
- Marketing Products
- Online Products
- Flash Animation using the sprites from the game
- Physical Products
- Poster
- Plan Testing
- Beta Test
- Group of players for when the game has been created.
- Game Features (Me):
- General Game Features
- Gravity
- Collectables
- Death
- Enemies
- Collision
- Exit
- Pause Menu
Creating The Game - 20/01/2013
Today I am going to be talking about the very start of the games development. After talking with the other members of the group we have decided that I will be the one who will be creating the maps as this is required within the coding side of the project to be imported. Due to this I have looked around and found a very helpful tool that I will be using to help with the map creation once the first art assets have been given to me by Stephen. Sam has also started work on the music that will be played while playing the game and it is proceeding nicely, Andy has also started on designing what he will be creating as the Marketing section of the games team and like the rest of the group is also proceeding very well. As a whole I feel the group is getting on well and the work is getting done at a good pace.
I myself have started reading up on the Slick2D documentation which can be found at this link. This is the JavaDoc that contains all of the packages and classes that are contained within Slick2D giving detailed write ups on each method and how they can be used within the project that I am creating. This document is going to be invaluable to me as I can quickly lookup any method that I may need and see clearly how this should be implemented into the code I am writing. The Eclipse SDK that I decided upon has been fully setup on my computer with Slick2D and its dependencies linked with the project that I have created. By next week I hope to have a few very simple lines of code written allowing for a window to be rendered ready for the game to be displayed in.
I myself have started reading up on the Slick2D documentation which can be found at this link. This is the JavaDoc that contains all of the packages and classes that are contained within Slick2D giving detailed write ups on each method and how they can be used within the project that I am creating. This document is going to be invaluable to me as I can quickly lookup any method that I may need and see clearly how this should be implemented into the code I am writing. The Eclipse SDK that I decided upon has been fully setup on my computer with Slick2D and its dependencies linked with the project that I have created. By next week I hope to have a few very simple lines of code written allowing for a window to be rendered ready for the game to be displayed in.
Sunday, 13 January 2013
Java Games Packages
To help aid me with creating a game within Java I am going to be using the help of a package that I can import into Java that will include some ready made functions that will be needed for developing the game. These features may help to import textures, music and other assess or help with the rendering and updating of what can be seen on the screen. Below is a list of the Packages that I have looked at and why I have decided to use it or not:
1) LWJGL (Lightweight Java Games Library) - The Lightweight Java Games Library or LWJGL as it will now be referred to is one of the main Java libraries that is used within Java games development. It allows people to make commercial standard games by including access to high performance libraries such as OpenGL (Open Graphics Library), OpenCL (Open Computing Language) and OpenAL (Open Audio Library) all of which are using within many different commercial games today. This makes it a very viable candidate, but due to the fact that I am going to make a 2D game the LWJGL is not what I will be using as it is mainly used within 3D Java games, because of this I have decided to go for a different option which I have described below.
2) Slick2D - Slick2D is a Java games library that has been created to provide a simple 2D API for Java games development. Slick2D is a toolset that is based around the OpenGL calls of the LWJGL making the two slightly similar but the major difference is that Slick2D has been created with 2D in mind making it a lot easier for 2D games to be created with this library instead of the LWJGL. Due to the fact that Slick2D can help with rendering, updating the game code, importing sound. graphics and other assets that will be needed all while being focused on 2D games development this is why I have decided to use this within the project.
1) LWJGL (Lightweight Java Games Library) - The Lightweight Java Games Library or LWJGL as it will now be referred to is one of the main Java libraries that is used within Java games development. It allows people to make commercial standard games by including access to high performance libraries such as OpenGL (Open Graphics Library), OpenCL (Open Computing Language) and OpenAL (Open Audio Library) all of which are using within many different commercial games today. This makes it a very viable candidate, but due to the fact that I am going to make a 2D game the LWJGL is not what I will be using as it is mainly used within 3D Java games, because of this I have decided to go for a different option which I have described below.
2) Slick2D - Slick2D is a Java games library that has been created to provide a simple 2D API for Java games development. Slick2D is a toolset that is based around the OpenGL calls of the LWJGL making the two slightly similar but the major difference is that Slick2D has been created with 2D in mind making it a lot easier for 2D games to be created with this library instead of the LWJGL. Due to the fact that Slick2D can help with rendering, updating the game code, importing sound. graphics and other assets that will be needed all while being focused on 2D games development this is why I have decided to use this within the project.
Starting The Project
Today I have started development of 'Jetson's Journey' the 2D platforming game that I am making for the extended project qualification. Below are a list of the others that are going to be joining me on creating a game and the contributions that they are going to be making to the project:
- Stephen Hendrikse - Graphics and Animation
- Sam Hignett - Sound Development
- Andrew Blackburn - Online Marketing
After having a discussion with the people above we have decided that we are going to make the game a space themed game, this is good as now we can all start creating our assets with this theme in mind. As I am in charge of the games coding and general development I will be using this time to start some simple tests within Java with some different Games Packages available to see which one I will be using to aid my in the creation of this game. I will be doing a second post this week detailing which package I have chosen and why.
Sunday, 6 January 2013
Java 1.7 IDE Decision
After searching around on the internet looking at the available IDE (Integrated Development Environment) that are available for Java. First of all is the NetBeans IDE which seems to be the most used IDE within Java.
1) NetBeans allows for quick coding using predictive code, allows for quick access to needed folders using the folder browser and comes with a slew of debugging tools for helping find bugs within the code that has been written. This seems to be a good option for a Java IDE as it includes everything that I would need to use to create my 2D Game.
Next I will be looking at Eclipse SDK which is another highly regarded IDE for Java development.
2) Eclipse SDK is also a very good option for a Java IDE as it includes everything that I would want. First of all Eclipse is completely free is use, it comes with an easy to use folder system to allow with sorting resources and code within a project, a full debugging suite built in to the IDE with some nice features allowing you to look through whole variables while code is running and also allowing for code to be edited while running and then compiled on the fly. Eclipse also comes with predictive code popups allowing for code to be completed faster using these which is a very nice feature. Because of all of this I will be using this IDE for my project.
1) NetBeans allows for quick coding using predictive code, allows for quick access to needed folders using the folder browser and comes with a slew of debugging tools for helping find bugs within the code that has been written. This seems to be a good option for a Java IDE as it includes everything that I would need to use to create my 2D Game.
Next I will be looking at Eclipse SDK which is another highly regarded IDE for Java development.
2) Eclipse SDK is also a very good option for a Java IDE as it includes everything that I would want. First of all Eclipse is completely free is use, it comes with an easy to use folder system to allow with sorting resources and code within a project, a full debugging suite built in to the IDE with some nice features allowing you to look through whole variables while code is running and also allowing for code to be edited while running and then compiled on the fly. Eclipse also comes with predictive code popups allowing for code to be completed faster using these which is a very nice feature. Because of all of this I will be using this IDE for my project.
EPQ Game Introduction
Welcome to the development blog of Jetson's Journey, a simple 2 dimensional platforming game made using Java 1.7 and an IDE that I have yet to decide on. This blog will be a weekly update, that will take place on a Sunday, of the games development talking about the troubles and successes that I encounter during the process and also showing the development of new skills that I am going to be learning throughout the development of the game.
Subscribe to:
Comments (Atom)