The Intro to IM GP is on!
Well not yet but on its way at least..
For my midterm I decided to try my hand at a racing game. The game will be a top down 2D style game. The car will not move relative to the center of the screen but instead the track will move relative to it. This will make the car look like its moving with focus remaining at the center of the screen. This technique is simulating a chase cam that many other games utilize.
This weeks focus was the game setup and art needed to create the game. Sprite sheets took a lot longer then I expected and all the art I found online needed adaptations to fit my game’s needs. First I started on the cars. I attempted to draw them.. big mistake. I then found a screensaver with all the cars I needed on them so with some resizing and cropping I had a sprite sheet. The same problem came up when trying to get icons for the teams. I found a wallpaper but it needed cropping and manipulation from imperfections. This photo editing took a long time but once I had a sprite sheet properly laid out it was easy to bring it into Processing.
Here is a video of the cars looping through the sprites at first
With media being brought into the game, I needed a menu where a player could select a team. I first displayed just the team and the associated car but decided that was not very intuitive. I then created a menu where a player could use the arrow keys to move across and vertically through the listed teams. I made it clear which one was selected by drawing all of them with a tint, and then the one selected with no tint making it look highlighted. I really liked this effect. I also listed the team name up top and have shown the car on the right.
To finish off the menu I need to play with the typefaces a bit, add a nice background and some music and of course the “play” button.
Next Steps:
With the art in and the cars begging to work I have begun movement. This is tricky as it is all relative. If a car is moving at ‘+10’ in the x direction then the background is actually moving at -10. I also am trying to use smoothing to make the car handle nicer and less jerky.
Here is my code thus far
//======= Global variables ======== int gameMode = 1; //0 is main menu, 1 select your car, 2 running game Team teams[] = new Team[10]; int teamSelector = 0; //Which team from array is selected int[][] teamDict = {{7,0,7,0,0},{8,1,8,0,1},{5,2,5,0,2},{4,3,4,0,3},{0,4,0,0,4},{2,5,2,1,0},{1,6,1,1,1},{6,7,6,1,2},{9,8,9,1,3},{3,9,3,1,4}}; //Dictonary containing index of car sprite, associated team image sprite index, team name index, menu row, menu col //====== Team Selection Menu Variables PImage teamMenuImg; void setup() { fullScreen(); //Set up the team array //======================================================================================= PImage[] carSprites; PImage[] teamSprites; String[] nameArray = {"McLaren F1 Team", "Scuderia AlphaTauri Honda", "Mercedes-AMG Petronas F1 Team", "ROKiT Williams Racing", "Haas F1 Team", "BWT Racing Point F1 Team", "Scuderia Ferrari", "Alfa Romeo Racing ORLEN", "Aston Martin Red Bull Racing", "Renault F1 Team" }; //Alfa Romeo, Red Bull, Racing Point, Haas, Mclaren, Mercedes, AlphaTauri, Ferrari, Renault, Williams //Set sprite sheets carSprites = getCarSpriteSheet("SpriteSheetCars.png"); //Load the car sprite sheet into sprites teamSprites = getTeamSpriteSheet("Teams.png"); //Load the team sprite sheet into sprites //Set teams array with appropiate info for(int i = 0; i < 10; i++){ Team newTeam = new Team(); newTeam.setName(nameArray[teamDict[i][2]]); //Set team name newTeam.setTeamImg(carSprites[teamDict[i][0]]); //Set team img newTeam.setCarImg(teamSprites[teamDict[i][1]]); //Set team car img teams[i] = newTeam; } //======================================================================================= //Load menu img teamMenuImg = loadImage("Teams.png"); } void draw() { //Main Gamemode Control selector switch(gameMode){ //Select a car ------------------ case 1: background(170); //Redraw background imageMode(CENTER); //Image mode tint(80); //Darken unselected cars float menuWidth = (7*width)/10; float menuHeight = (7*height)/10; float menuX = (4.5*width)/10; float menuY = (11*height)/20; image(teamMenuImg, menuX, menuY, menuWidth, menuHeight); //Menu tint(255); float teamImageWidth = menuWidth/5; float teamImageHeight = menuHeight/2; float teamImageX = (menuX - menuWidth/2) + (teamDict[teamSelector][4] * teamImageWidth) + (teamImageWidth/2); //Where to draw the overlay team iamge on the menu x and y float teamImageY = (menuY - menuHeight/2) + (teamDict[teamSelector][3] * teamImageHeight) + (teamImageHeight/2); image(teams[teamSelector].getCarImg(), teamImageX, teamImageY, teamImageWidth, teamImageHeight); //Draw team image(teams[teamSelector].getTeamImg(), (9*width)/10, height/2); //Draw car fill(0); stroke(0); textSize(32); text("Select a team", width/10, height/10); textSize(64); text(teams[teamSelector].getName(), width/10, height/10 + 70); noLoop(); //Save performance break; //------------------------------- } } //Keyboard input controller void keyPressed(){ //Arrow keys during car selection if(gameMode == 1){ if(keyCode == LEFT){ //Left key selection int temp = teamSelector - 1; //Check if on 0 or 5, if(!(teamSelector == 0 || teamSelector == 5)){ teamSelector = temp; } loop(); } else if(keyCode == RIGHT){ //Right key selection int temp = teamSelector + 1; //Check if on 4 or 9, if(!(teamSelector == 4 || teamSelector == 9)){ teamSelector = temp; } loop(); } else if(keyCode == UP){ //Left up selection int temp = teamSelector - 5; //Check if not below 0 to set new value if(temp >= 0){ teamSelector = temp; } loop(); } else if(keyCode == DOWN){ //Left up selection int temp = teamSelector + 5; //Check if not above to set new value if(temp <= 9){ teamSelector = temp; } loop(); } } } //Function which returns the array of sprites from the spritesheet of all the cars PImage[] getCarSpriteSheet(String fileName){ PImage spritesheet; PImage[] sprites; int counter = 0; //Used to sepcify which car to display in sprite list int w = 151; //Width of one car int h = 404; //Height of one car spritesheet = loadImage(fileName); sprites = new PImage[12]; // 12 images across, 4 down, in the spritesheet //Loop through 5 rows for (int i = 0; i < 5; i++) { //Loop through 2 columns for (int j = 0; j < 2; j++) { sprites[counter] = spritesheet.get(j*w, i*h, w, h); counter++; } } return sprites; } //Function which returns the array of sprites from the spritesheet of all the teams PImage[] getTeamSpriteSheet(String fileName){ PImage spritesheet; PImage[] sprites; sprites = new PImage[12]; // 12 images across, 4 down, in the spritesheet spritesheet = loadImage(fileName); int counter = 0; //Used to sepcify which car to display in sprite list int w = spritesheet.width / 5; //Width of one car int h = spritesheet.height / 2; //Height of one car //Loop through 2 rows for (int i = 0; i < 2; i++) { //Loop through 5 columns for (int j = 0; j < 5; j++) { sprites[counter] = spritesheet.get(j*w, i*h, w, h); counter++; } } return sprites; }
class Team{ String name; PImage carImg; PImage teamImg; //Default constructor does nothing Team(){ name=""; carImg = null; teamImg = null; } //Getters and setters void setName(String name){ this.name = name; } String getName(){ return name; } void setCarImg(PImage img){ carImg = img; } PImage getCarImg(){ return carImg; } void setTeamImg(PImage img){ teamImg = img; } PImage getTeamImg(){ return teamImg; } }