What if you put extra efforts on video game assignments----7
A downloadable game for Windows
Dragster
Project Description
A recreation of classic Atari dragster game with better graphics.
Assignment Rubrics
- 1 point - have a title screen on which pressed a given key to starts the countdown timer
- 3 points - have a countdown timer of some sort (during which pressing the accelerator will result in a false start)
- 1 point - pressing a given key will start moving the player forward
- 1 point - the player accelerates the longer they hold down the key
- 1 point - a results screen appears after crossing the finish line or false starting
- 2 points - the total travel time (time from the end of the countdown to crossing the finish line)/if the player false started is shown on the results screen
- 1 point - a given key allows the game to restart when on the results screen
- Extra Credit (2 points) - implement a system of gear shifting or another method of changing the player's speed
- Extra Credit (1 point) - add particles
My Code
# Dragster Game, Phew AIR_COEFF = 3 GEAR_SHIFT_CD = 30 gearFrameAfterFirstPress = 0 renderQueue = [] particles = [] MAIN_MENU = 0 COUNT_DOWN = 1 PLAYING = 2 RESULT = 3 gameState = MAIN_MENU countdownTime = 3 # second gameTimer = 0 startTime = 0 countdownStarted = False gameOver = False GOMsg = "Err" def setup(): global car, renderQueue, fg, particles size(800,600) loadAssets() car = Car(7000, 4, 90, 500000) bg = CityBackground(T_BG1, T_BG2, 000, car, 100.0) mg = CityBackground(T_MG1, T_MG2, 000, car, 60.0) fg = CityBackground(T_FG1, T_FG2, 000, car, 30.0) renderQueue.append(bg) renderQueue.append(mg) renderQueue.append(fg) renderQueue.append(car) #Particle Init for i in range(42): particles.append(Particle(random(800), random(600), car.spd / -100, 200)) print("init success") def draw(): global renderQueue, car, gameState, countdownTime, startTime, gameTimer, gameOver, GOMsg, countdownStarted if gameState == MAIN_MENU: mainMenu() elif gameState == COUNT_DOWN: #Init all data if countdownStarted: carInit() gameTimer = millis() #print(millis()) countdownStarted = False gameOver = False startTime = gameTimer + 1000 * countdownTime else: for obj in renderQueue: obj.update() obj.render() if car.gear > 0: gameOver = True #print(car.gear) gameState = RESULT GOMsg = "Early Fault Start!" if millis() > gameTimer + countdownTime * 1000: gameState = PLAYING ShowCountdown() ControllerUpdate() displayUI() elif gameState == PLAYING: background(0) ControllerUpdate() for obj in renderQueue: obj.update() obj.render() for p in particles: p.update() p.render() if p.lifespan <= 0: particles.remove(p) particles.append(Particle(random(width + 400), random(height), car.spd / -100, 200)) displayUI() #displayDebugInfo() checkGameOver() #print("displayed Debug info") elif gameState == RESULT: resultPage() def ControllerUpdate(): global gearFrameAfterFirstPress if keyPressed: # Shift Gear Up if key == ' ': if gearFrameAfterFirstPress == 0: car.gearSwitch = True gearFrameAfterFirstPress += 1 else: car.gearSwitch = False gearFrameAfterFirstPress += 1 # Full Throttle if key == 'a': car.throttle = True else: if gearFrameAfterFirstPress < GEAR_SHIFT_CD and gearFrameAfterFirstPress != 0: gearFrameAfterFirstPress += 1 car.gearSwitch = False elif gearFrameAfterFirstPress >= GEAR_SHIFT_CD: gearFrameAfterFirstPress = 0 car.gearSwitch = False print("CD complete") car.gearSwitch = False car.throttle = False def displayDebugInfo(): global car, fg textSize(20) fill(0) textAlign(LEFT) text("Speed: " + str(car.spd), 0, 30) text("Acce: " + str(car.acce), 0, 60) text("airRes:" + str(car.airRes), 0, 90) text("Gear: " + str(car.gear), 0, 120) text("Dist: " + str(car.curDist) + "/" + str(car.goalDist), 0, 150) text("Rev: " + str(car.rev) + "/" + str(car.maxRev), 0, 180) text("fgPosX:" + str(fg.imgAX) + "/" + str(fg.imgBX) + str(fg.imgAX - fg.imgBX), 0, 210) text("GState:" + str(gameState), 0, 240) def loadAssets(): global T_BG1, T_BG2, T_MG1, T_MG2, T_FG1, T_FG2, T_Car, T_Tire T_BG1 = loadImage("BackGround.png") T_BG2 = loadImage("BackGround.png") T_MG1 = loadImage("MiddleGround.png") T_MG2 = loadImage("MiddleGround.png") T_FG1 = loadImage("ForeGround.png") T_FG2 = loadImage("ForeGround.png") T_Car = loadImage("car.png") T_Tire = loadImage("tire.png") def mainMenu(): background(0) fill(255) textSize(32) textAlign(CENTER) text("Press P to Play", width / 2, height / 2) textAlign(LEFT) textSize(20) text("Press SpaceBar to shift gear up", width / 2 - 300, height / 2 + 100) text("Press A to throttle Up", width / 2 - 300, height / 2 + 130) def resultPage(): background(50) fill(255) textSize(32) textAlign(CENTER) text("Press R to Reset", width / 2, height / 2) textSize(50) text(GOMsg, width / 2, height / 2 - 100) def ShowCountdown(): remainingTime = countdownTime - int((millis() - gameTimer) / 1000) #print(startTime) fill(0, 0, 0, 120) rectMode(CORNER) rect(0, 0, width, height) fill(255) textSize(200) textAlign(CENTER) text(str(remainingTime), width / 2, height / 2) def carInit(): global car car.selfInit() def checkGameOver(): global gameOver, GOMsg, gameState if car.rev > car.maxRev: GOMsg = "You lose! Engine Exploded" gameOver = True elif car.curDist > car.goalDist: tempSec = int(millis() - startTime) / 1000 tempMils = nf(int(millis() - startTime) % 1000, 3) GOMsg = ("You win! Time: " + str(tempSec) + "." + str(tempMils) + "s") gameOver = True if gameOver: gameState = 3 def displayUI(): global car # Display Rev revRatio = float(car.rev) / float(car.maxRev) fill(0, 255, 0) if revRatio > 0.8: fill(255, 0, 0) rect(20, height - 50, revRatio * 200, 30) #print(revRatio) # Display Gear fill(255) textSize(20) text("Gear: " + str(car.gear), 250, height - 30) # Display Current Time if gameState == COUNT_DOWN: text("Time: 0.000", 400, height - 30) else: tempSec = int(millis() - startTime) / 1000 tempMils = nf(int(millis() - startTime) % 1000, 3) text("Time: " + str(tempSec) + "." + str(tempMils), 400, height - 30) def keyPressed(): global gameState, countdownStarted if key == 'p' or key == 'P': if gameState == MAIN_MENU: gameState = COUNT_DOWN countdownStarted = True elif key == 'r' or key == 'R': #if gameState == RESULT: gameState = MAIN_MENU class Car(object): def __init__(self, tempMaxRev, tempMaxGear, tempFrameToFullRev, tempGoalDistance): self.spd = 0.0 self.acce = 0.0 self.airRes = 0.0 self.rev = 1000 self.frameToFullRev = tempFrameToFullRev self.maxRev = tempMaxRev self.throttle = False self.blown = False self.gearSwitch = False self.gear = 0 self.maxGear = tempMaxGear self.curDist = 0 self.goalDist = tempGoalDistance def selfInit(self): self.spd = 0.0 self.acce = 0.0 self.airRes = 0.0 self.rev = 1000 self.throttle = False self.blown = False self.gearSwitch = False self.gear = 0 self.curDist = 0 def update(self): # Check if car is blown first self.checkBlown() if self.blown: # if Blown, slowly decrease it's spd till 0 if self.spd < 1: self.spd = 0 else: self.spd -= self.spd / 7 else: self.GearShifting() self.Calculating() # Shifting the car's gear def GearShifting(self): if self.gearSwitch == True: if self.gear < self.maxGear: self.gear += 1 else: self.rev += self.maxRev / 5 # Calculate Current Acce, spd, distance def Calculating(self): if self.throttle: self.rev += (self.maxRev / self.frameToFullRev) / (self.gear + 1) # print("Throttle on") else: if self.rev > 1000: self.rev -= (self.maxRev / self.frameToFullRev) / (self.gear + 1) * 2 mappedRev = map(self.rev, 0, self.maxRev, 0, 1) if self.gear == 0: engineForce = 0 else: engineForce = mappedRev * (5 - self.gear) # print(self.rev, self.maxRev, self.frameToFullRev, self.gear) # TODO?: Make car move more realistically # mappedRev = map(self.rev, 0, maxRev, 0, 1) # engineForce = -0.63 * sq(mappedRev) + 0.47 * mappedRev + 0.76 self.airRes = AIR_COEFF * sq(self.spd) # self.acce = engineForce - self.airRes # engineForce = self.rev * self.gear self.acce = engineForce self.spd += self.acce self.curDist += self.spd def render(self): self.renderCar() #self.renderBackground() def renderCar(self): global T_Car, T_Tire imageMode(CENTER) tempX = map(self.curDist, 0, self.goalDist, 150, width + 150) tempY = 500 image(T_Car, tempX, tempY) tireX = map(self.curDist, 0, self.goalDist, 45, width + 45) tireY = 506 pushMatrix() translate(tireX, tireY) if self.spd != 0: rotate(random(0,PI)) image(T_Tire, 0, 0) popMatrix() # This function is useless now # def renderBackground(self): # global T_BG1, T_BG2, T_MG1, T_MG2, T_FG1, T_FG2 # imageMode(CENTER) # bgPosX = map(self.goalDist - self.curDist, 0, self.goalDist, 0, 1792 * 2) % (1792 * 2) + (1792 / 2) # bgPosY = 200 # image(T_BG1, bgPosX - 400, bgPosY) # image(T_BG2, bgPosX + 1792 - 400, bgPosY) def checkBlown(self): if self.rev > self.maxRev: self.blown = True class CityBackground(object): def __init__(self, tempImgA, tempImgB, tempY, tempCar, tempSpdCoeff): self.imgA = tempImgA self.imgB = tempImgB self.spd = 0 self.imgHeight = tempY self.imgAX = 0 self.imgBX = 1792 self.car = tempCar self.spdCoe = tempSpdCoeff def update(self): self.spd = int(self.car.spd / self.spdCoe) if self.imgAX < -1 * (1792): self.imgAX += 1792 * 2 self.imgAX -= self.spd if self.imgBX < -1 * (1792): self.imgBX += 1792 * 2 self.imgBX -= self.spd def render(self): imageMode(CORNER) image(self.imgA, self.imgAX, self.imgHeight) image(self.imgB, self.imgBX, self.imgHeight) class Particle: def __init__(self, tempX, tempY, tempSpd, tempLife): #print(30) self.initialX = tempX self.initialY = tempY self.position = PVector(tempX, tempY) self.velocity = PVector(random(tempSpd, tempSpd / 3), 0) self.amplitude = random(5, 20) self.angle = 0 self.angleVelocity = random(tempSpd/100, tempSpd/30) self.trail = [] self.lifespan = int(random(tempLife - tempLife/10, tempLife + tempLife+10)) #print(25) def update(self): self.position.x += self.velocity.x self.position.y = self.initialY + self.amplitude * sin(self.angle) self.angle += self.angleVelocity self.trail.append(self.position.copy()) if len(self.trail) > 20: self.trail.pop(0) self.lifespan -= 1 def render(self): if self.lifespan > 0: noFill() opacity = map(self.lifespan, 0, 200, 0, 255) stroke(255, opacity) for i in range(1, len(self.trail)): p1 = self.trail[i - 1] p2 = self.trail[i] segmentRatio = float(i) / len(self.trail) if segmentRatio < 0.5: width = map(segmentRatio, 0, 0.5, 0.5, 3) else: width = map(segmentRatio, 0.5, 1, 3, 0.5) angle = atan2(p2.y - p1.y, p2.x - p1.x) + HALF_PI xOff = width * cos(angle) yOff = width * sin(angle) beginShape() vertex(p1.x + xOff, p1.y + yOff) vertex(p1.x - xOff, p1.y - yOff) vertex(p2.x - xOff, p2.y - yOff) vertex(p2.x + xOff, p2.y + yOff) endShape(CLOSE)
Screenshot
Download
Download
application.windows64.zip 44 MB
Install instructions
Java 8 required
Leave a comment
Log in with itch.io to leave a comment.