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;
}
}
